Webhook Events Reference
All event payloads share the same flat data structure built from the payment record. Fields that do not apply to the current state are null. Decimal values are JSON strings.
Common data fields (all payment.* events):
| Field | Type | Description |
|---|---|---|
payment_id | string (UUID) | Payment identifier |
status | string | Current payment status (lowercase snake_case) |
amount_usd | string | Payment amount |
received_crypto | string | Total crypto received so far |
crypto_symbol | string | null | e.g. "ETH" |
crypto_name | string | null | e.g. "Ethereum" |
chain | string | null | Chain short name, e.g. "eth" |
locked_rate_usd | string | null | Locked rate |
fee_payer | string | "user" or "payer" |
fees | object | null | { "service_fee_usd": "...", "conversion_fee_usd": "..." } — present once fees are computed |
net_amount_usd | string | null | Net settlement (present at completion) |
selection_expires_at | string | null | Selection window deadline |
created_at | string | Creation timestamp |
completed_at | string | null | Completion timestamp |
redirect_url | string | null | Merchant redirect URL |
Payment events
payment.created
Fired when a merchant creates a payment request.
{
"event": "payment.created",
"timestamp": "2026-05-16T12:00:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "awaiting_selection",
"amount_usd": "150.00",
"received_crypto": "0",
"crypto_symbol": null,
"crypto_name": null,
"chain": null,
"locked_rate_usd": null,
"fee_payer": "user",
"fees": null,
"net_amount_usd": null,
"selection_expires_at": null,
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": null,
"redirect_url": "https://yourstore.com/thank-you"
}
}payment.awaiting
Fired when the payer confirms their token selection and the rate is locked. The payment is now waiting for an on-chain transaction. A selection_expires_at countdown starts.
{
"event": "payment.awaiting",
"timestamp": "2026-05-16T12:01:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "awaiting_payment",
"amount_usd": "150.00",
"received_crypto": "0",
"crypto_symbol": "ETH",
"crypto_name": "Ethereum",
"chain": "eth",
"locked_rate_usd": "2000.00",
"fee_payer": "user",
"fees": null,
"net_amount_usd": null,
"selection_expires_at": "2026-05-16T12:31:00.123456+00:00",
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": null,
"redirect_url": "https://yourstore.com/thank-you"
}
}The wallet address the payer should send to is available via
GET /v1/pay/{payment_id}(or the API-key-authenticated payment detail endpoint).
payment.partial
Fired when a transaction is detected at the payment wallet but the received amount is less than required (status: "partially_paid").
{
"event": "payment.partial",
"timestamp": "2026-05-16T12:03:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "partially_paid",
"amount_usd": "150.00",
"received_crypto": "0.030000000000000000",
"crypto_symbol": "ETH",
"crypto_name": "Ethereum",
"chain": "eth",
"locked_rate_usd": "2000.00",
"fee_payer": "user",
"fees": null,
"net_amount_usd": null,
"selection_expires_at": "2026-05-16T12:31:00.123456+00:00",
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": null,
"redirect_url": "https://yourstore.com/thank-you"
}
}payment.confirming
Fired when the required amount has been received and the payment is waiting for block confirmations.
{
"event": "payment.confirming",
"timestamp": "2026-05-16T12:04:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "confirming",
"amount_usd": "150.00",
"received_crypto": "0.075000000000000000",
"crypto_symbol": "ETH",
"crypto_name": "Ethereum",
"chain": "eth",
"locked_rate_usd": "2000.00",
"fee_payer": "user",
"fees": null,
"net_amount_usd": null,
"selection_expires_at": "2026-05-16T12:31:00.123456+00:00",
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": null,
"redirect_url": "https://yourstore.com/thank-you"
}
}payment.completed
Fired when the payment is fully confirmed, swept, and settled. This is the primary event to trigger order fulfilment. Fees and net_amount_usd are populated.
{
"event": "payment.completed",
"timestamp": "2026-05-16T12:05:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "completed",
"amount_usd": "150.00",
"received_crypto": "0.075000000000000000",
"crypto_symbol": "ETH",
"crypto_name": "Ethereum",
"chain": "eth",
"locked_rate_usd": "2000.00",
"fee_payer": "user",
"fees": {
"service_fee_usd": "0.75",
"conversion_fee_usd": "1.50"
},
"net_amount_usd": "147.75",
"selection_expires_at": "2026-05-16T12:31:00.123456+00:00",
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": "2026-05-16T12:05:00.123456+00:00",
"redirect_url": "https://yourstore.com/thank-you"
}
}payment.expired_selection
Fired when the chain selection window expires. The payer can return to the payment page and reselect a token. No funds are lost — any partial payments already received are preserved (and shown via received_crypto).
{
"event": "payment.expired_selection",
"timestamp": "2026-05-16T12:31:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "expired_selection",
"amount_usd": "150.00",
"received_crypto": "0.030000000000000000",
"crypto_symbol": "ETH",
"crypto_name": "Ethereum",
"chain": "eth",
"locked_rate_usd": "2000.00",
"fee_payer": "user",
"fees": null,
"net_amount_usd": null,
"selection_expires_at": "2026-05-16T12:31:00.123456+00:00",
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": null,
"redirect_url": "https://yourstore.com/thank-you"
}
}payment.reselected
Fired when the payer reselects a token after expired_selection. A new rate is locked and a new selection window starts (status returns to awaiting_payment).
{
"event": "payment.reselected",
"timestamp": "2026-05-16T12:45:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "awaiting_payment",
"amount_usd": "150.00",
"received_crypto": "0.030000000000000000",
"crypto_symbol": "ETH",
"crypto_name": "Ethereum",
"chain": "eth",
"locked_rate_usd": "2100.00",
"fee_payer": "user",
"fees": null,
"net_amount_usd": null,
"selection_expires_at": "2026-05-16T13:15:00.123456+00:00",
"created_at": "2026-05-16T12:00:00.123456+00:00",
"completed_at": null,
"redirect_url": "https://yourstore.com/thank-you"
}
}payment.blacklisted
Fired when a transaction is detected from an address on the platform blacklist. The payment cannot proceed.
{
"event": "payment.blacklisted",
"timestamp": "2026-05-16T12:03:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "blacklisted",
"amount_usd": "150.00",
"received_crypto": "0",
...
}
}No sender address or reason is included for security reasons.
payment.failed
Fired when a system error occurs during payment processing that requires investigation (including sweep failures).
{
"event": "payment.failed",
"timestamp": "2026-05-16T12:03:00.123456+00:00",
"data": {
"payment_id": "9f1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "sweep_failed",
...
}
}Check
GET /v1/payments/{payment_id}for details; contact support if a payment enters this state.
Withdrawal events
Status note (2026-08-31): withdrawal events are not yet emitted by the live platform — they are valid, subscribable, and documented here as the contract for their emission, but subscribing to them today yields no notifications. Track withdrawal status via
GET /v1/withdrawalsuntil emission is wired. This note will be removed when the events go live. (Internal tracking: spec 008 drift register, entry 1.)
withdrawal.completed
Fired when a withdrawal transaction has been confirmed on-chain and the funds have arrived at your wallet.
{
"event": "withdrawal.completed",
"timestamp": "2026-05-16T14:00:00.123456+00:00",
"data": {
"withdrawal_id": "w1x2y3z4-...",
"status": "completed",
"amount_usd": "147.75",
"fee_usd": "1.00",
"net_amount_usd": "146.75",
"chain": "eth",
"destination_address": "0xyourwallet...",
"tx_hash": "0xwithdrawal...",
"failure_reason": null,
"completed_at": "2026-05-16T14:00:00.123456+00:00"
}
}withdrawal.failed
Fired when a withdrawal transaction fails and cannot be automatically retried. failure_reason describes the cause where available.
{
"event": "withdrawal.failed",
"timestamp": "2026-05-16T14:00:00.123456+00:00",
"data": {
"withdrawal_id": "w1x2y3z4-...",
"status": "failed",
"amount_usd": "147.75",
"fee_usd": "1.00",
"net_amount_usd": "146.75",
"chain": "eth",
"destination_address": "0xyourwallet...",
"tx_hash": null,
"failure_reason": "Transaction broadcast failed: insufficient gas",
"completed_at": null
}
}Event subscription
You can subscribe to specific event types in the Client Portal → Dashboard → Webhooks, or via PUT /v1/webhooks:
{
"events": [
"payment.completed",
"payment.expired_selection",
"payment.reselected",
"withdrawal.completed",
"withdrawal.failed"
]
}Use ["*"] to receive all events. Invalid event names are rejected with a validation error.

