Crypto-order webhook events
The crypto-orders surface emits two event types server-side:
crypto.order.paid when a customer's payment
settles, and crypto.order.failed when an order
moves to a terminal failure state. Both are subscribable via
POST /v1/webhooks.
Subscribing
Subscribe an HTTPS endpoint to one or both event types in a single call:
POST /v1/webhooks
Authorization: Bearer ds_live_…
Content-Type: application/json
{
"url": "https://example.com/webhooks/driftstack",
"events": ["crypto.order.paid", "crypto.order.failed"]
}
Deliveries are signed with the standard
X-Driftstack-Signature header described in
/docs/webhooks; the retry policy
+ secret-rotation grace + DLQ semantics are identical to every
other live event family.
Polling alternative
For integrations that cannot accept inbound HTTPS callbacks,
poll GET /v1/billing/crypto-orders/<order_id>
instead. The order's status transitions to
paid or failed on the same triggers
that fire the webhook events:
GET /v1/billing/crypto-orders/ord_…
Authorization: Bearer ds_live_…
→ 200 OK
{
"order_id": "ord_…",
"status": "paid",
"product": "team_manual",
"price_cents": 4900,
"price_currency": "EUR",
"payment_id": "pi_…",
"paid_at": "2026-05-12T13:00:00.000Z",
…
} The order lifecycle endpoints are documented under /docs/billing-crypto-overview; a deeper polling-vs-webhooks tradeoff piece is at /docs/crypto-orders-polling-vs-webhooks. The full subscribable event-type list is on /docs/webhooks.
Event shape
The wire format mirrors the standard webhook envelope from
/docs/webhooks; the payload
data object for each event type is documented
below.
crypto.order.paid
Fires once when a pending order transitions to
paid — i.e. when the NowPayments IPN reports
finished. Idempotent: applying the same terminal
IPN twice will not re-fire.
| Field | Type | Description |
|---|---|---|
order_id | string | The Driftstack-internal order id. |
product | string | The tier or product code (e.g.
team_manual). |
price_cents | integer | Order total in fiat-cents. |
price_currency | string | ISO 4217 fiat currency (e.g. EUR). |
payment_id | string | NowPayments-side payment id. |
paid_at | ISO 8601 string | Server timestamp at the moment the order was marked paid. |
crypto.order.failed
Fires once when an order transitions to failed
— a terminal state. Three triggers, distinguished by the
reason field on the payload:
ipn— NowPayments reported a terminal failure status (failed,expired, orrefunded) via the standard IPN.expired— the order's pay-window elapsed without a settled payment.swept— a background sweep retired long-pending orders that NowPayments never delivered an IPN for.
| Field | Type | Description |
|---|---|---|
order_id | string | The Driftstack-internal order id. |
product | string | The tier or product code. |
price_cents | integer | Order total in fiat-cents. |
price_currency | string | ISO 4217 fiat currency. |
payment_id | string | null | NowPayments-side payment id, or null for
orders that never received an IPN before being swept /
expired. |
reason | string | One of ipn, expired,
swept. |
failed_at | ISO 8601 string | Server timestamp at the moment the order entered
failed. |