Skip to content

Webhooks API

Webhook delivery is automatic based on the webhook_url set on each order. This page covers the webhook management API endpoints available in the admin interface.

Webhook delivery object

json
{
  "id": "wh_abc123",
  "order_id": "ord_def456",
  "event": "payment.confirmed",
  "url": "https://your-backend.com/webhooks/paywarden",
  "status": "delivered",
  "attempts": 1,
  "last_attempt_at": "2025-01-01T00:05:01Z",
  "delivered_at": "2025-01-01T00:05:01Z",
  "response_status": 200,
  "next_attempt_at": null
}

List webhook deliveries

http
GET /api/v1/admin/webhooks?status=failed&page=1&limit=20
Authorization: Bearer <admin-jwt>
Query paramValuesDescription
statuspending delivered failedFilter by delivery status
order_iduuidFilter by order
pageintegerPage number
limitintegerItems per page (max 100)

Retry a failed webhook

http
POST /api/v1/admin/webhooks/:id/retry
Authorization: Bearer <admin-jwt>

Immediately re-enqueues the webhook for delivery. Resets the attempt counter.

Response 200:

json
{
  "id": "wh_abc123",
  "status": "pending",
  "attempts": 0,
  "next_attempt_at": "2025-01-01T01:00:00Z"
}

Webhook delivery statuses

StatusDescription
pendingQueued, not yet attempted
deliveringCurrently being sent
deliveredReceived 2xx from your endpoint
failedAll 10 attempts exhausted
retryingFailed at least once, will retry

All webhook event types

EventTrigger
payment.detectedTransfer seen on-chain
payment.confirmedRequired confirmations reached
payment.completedWebhook delivered successfully
payment.expiredOrder expired without payment
payment.underpaidReceived less than required amount
payment.sweep_completedFunds swept to hot wallet

Webhook payload schema

All events share this envelope:

typescript
interface WebhookPayload {
  event: string                  // event type
  order_id: string               // PayWarden order ID
  external_id: string            // your order ID
  merchant_id: string            // merchant identifier
  amount: string                 // requested amount
  currency: 'USDT'
  created_at: string             // ISO 8601
  // event-specific fields below:
  amount_received?: string
  address?: string
  tx_hash?: string
  confirmations?: number
  confirmed_at?: string
  expired_at?: string
  sweep_tx_hash?: string
}

Testing webhooks locally

Use ngrok or Cloudflare Tunnel to expose your local server:

bash
# ngrok
ngrok http 3001

# Then use the ngrok URL as webhook_url when creating test orders
curl -X POST http://localhost:3000/api/v1/payments \
  -H "X-API-Key: your-api-key" \
  -d '{
    "amount": "1.00",
    "currency": "USDT",
    "external_id": "test_001",
    "webhook_url": "https://abc123.ngrok.io/webhooks/paywarden"
  }'

With the Nile testnet, you can use the Nile faucet to send test USDT to your payment address and trigger the full webhook flow.

Released under the BSL 1.1 License.