Payments webhooks
Configure your endpoint
Set your webhook URL (and enable wallet/deposit events) in the Payments dashboard under Developers → Webhooks. The dashboard shows your signing secret (whsec_…) once — store
it to verify signatures.
Headers on every delivery
Events & exact payloads
There are two payload shapes: checkout/remittance events are flat; wallet (WaaS) events wrap the data in anevent + data envelope.
- payment.confirmed / payment.failed
- wallet.deposit.detected
- wallet.deposit.confirmed
- wallet.transfer.*
Sent for Crypto Gateway checkout sessions. Flat payload:
network, tx_hash, paid_at and metadata are omitted when not applicable.
payment.failed carries the same shape with status: "failed" and no paid_at.Verify the signature
Compute the HMAC over the raw body and compare in constant time:Test it
Send a test event and rotate your signing secret from the Payments dashboard (Developers → Webhooks). Rotating invalidates the old secret — update your verifier immediately.CaaS webhooks
Register your webhook endpoints and choose which events to receive from your CaaS dashboard.Delivery & verification (every event)
Every webhook is an HTTPPOST with a JSON body and these headers:
Signature verification (Node)
Conventions
- Delivery is best-effort — settlement already happened on-chain; the notification
never blocks it. Only webhooks subscribed to that event type receive it. Return
2xx. - Amounts are decimal strings with 6 dp (e.g.
"5.000000"). tx_hashis the real on-chain EVM transaction hash (explorer-lookupable), not the internaluserOpHash.- Timestamps are RFC3339 UTC.
- On
*.settled/*.failed, empty fields are omitted, not null (reasonabsent on success;amount_*/token/tx_hashabsent on a pre-broadcast failure). Treat missing = unknown.
Transaction events
- transfer.received
- transfer.settled
- transfer.failed
- swap.settled
- swap.failed
Fires when a wallet belonging to your business receives funds (incl. cross-merchant).
Not sent if the recipient is an unaffiliated phone — they get an SMS instead. Delivered
to the recipient merchant.
Account / membership events
Best practices
- Respond fast (
2xx) then work async — Rach retries non-2xxdeliveries. - Be idempotent — dedupe on
X-Webhook-ID(Payments, ordeposit_idfor deposits). - Credit only when safe — for deposits, wait for
safe_to_credit: true.

