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 param | Values | Description |
|---|---|---|
status | pending delivered failed | Filter by delivery status |
order_id | uuid | Filter by order |
page | integer | Page number |
limit | integer | Items 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
| Status | Description |
|---|---|
pending | Queued, not yet attempted |
delivering | Currently being sent |
delivered | Received 2xx from your endpoint |
failed | All 10 attempts exhausted |
retrying | Failed at least once, will retry |
All webhook event types
| Event | Trigger |
|---|---|
payment.detected | Transfer seen on-chain |
payment.confirmed | Required confirmations reached |
payment.completed | Webhook delivered successfully |
payment.expired | Order expired without payment |
payment.underpaid | Received less than required amount |
payment.sweep_completed | Funds 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.