Browser callbacks fire only if the customer’s tab is still open. Webhooks do not depend on it. Fulfil from webhooks.
Set up
Build an endpoint
A public HTTPS URL that accepts POST and responds 2xx quickly.
Register it
Settings → Webhooks in the dashboard. Add the URL.Then reveal your signing secret — once — and store it where your server reads it. If you lose it, rotate it on the same page.
Verify every delivery
Reject anything that fails. Signatures.
Test it
Use Send test payload on the Webhooks tab, then make a real testnet payment.The test is a real signed delivery — same header, same envelope — with event
payment.test and data.test: true. If your handler verifies it, it verifies production.The payload
Every delivery has the same envelope, including the dashboard’s test send.string
Stable per transition. Use it as your idempotency key.
string
The event type —
pool.deposit.confirmed, pool.swept, pool.distributed, pool.refunded, or pool.tamper_suspected. Fulfil at capture: pool.deposit.confirmed when the customer sent a plain transfer, pool.swept when they paid from a connected wallet. Full list.string
ISO 8601 timestamp.
object
The payment.
orderId is the id you passed to updateCart; match on it to find the order. Amounts are token base units as strings (6 decimals for USDC, USDT and EURC). EVM and TRON deliveries carry the same fields; pool.distributed describes a payout rather than one payment, so it carries pool fields instead.Headers
Every delivery carries these headers, including the dashboard’s test send.
A correct handler
Raw body
Parsing and re-serialising changes the bytes and breaks the signature.
Verify first
Before parsing, before touching your database.
Acknowledge fast
We time out at 10 seconds. Do slow work in a queue.
Signature verification in detail
With replay protection and language examples.