Integrating a crypto payment API follows a predictable shape regardless of provider: you create an invoice, redirect or embed a checkout, receive asynchronous webhooks as the payment progresses, verify them, and reconcile against your own records. The hard part isn't the happy path — it's the edges.
The core flow
Most gateways expose a REST API with the same lifecycle. You call it server-side (never expose an API key in the browser), and you treat the webhook — not the browser redirect — as the source of truth for whether an order is paid.
Design your order state machine first: pending → underpaid/paid → confirmed → complete, with explicit branches for expired and overpaid. Wiring that up front prevents the tangled conditionals that cause double-fulfilment.
- Create an invoice with amount, currency, order ID, and a webhook URL.
- Show the hosted checkout or render the address and amount yourself.
- Receive webhooks for each state change and verify their signature.
- Confirm the payment reached the required confirmations before fulfilling.
- Reconcile the webhook against the on-chain transaction and your order.
Creating an invoice
An invoice ties a specific amount to a specific order for a limited time. Send your order ID as metadata so the webhook can be matched back without guesswork, and store the invoice ID the gateway returns.
Quotes expire — the gateway locks a rate for a few minutes. Persist the invoice's expiry and status so your UI can show a countdown and so a late payment is handled as a reconciliation case, not a lost order.
Webhooks are the source of truth
The browser redirect after payment is a convenience, not a guarantee — the user may close the tab. The webhook your server receives is what you act on. Verify every webhook: check the signature (usually an HMAC over the raw body with your secret) before trusting a single field.
Make webhook handling idempotent. Gateways retry deliveries, so the same 'paid' event can arrive twice; key your processing on the event or invoice ID and make repeated deliveries a no-op. Return a 2xx quickly and do slow work asynchronously so the gateway doesn't time out and retry needlessly.
Confirmations and finality
A payment can be seen (in the mempool or with zero confirmations) long before it's final. Decide a confirmation threshold appropriate to the amount and chain, and only fulfil once it's met. For small stablecoin payments on fast chains this is quick; for large amounts, wait for more.
Guard against reorgs and double-spends by trusting the gateway's 'confirmed' state rather than your own first sighting, and by not releasing goods on a zero-confirmation payment unless you accept the risk.
Reconciliation and the failure modes
Reconciliation is the daily job of proving that every 'paid' order maps to a real on-chain transaction and vice versa. Store the transaction hash, the amount received, and the network on each order so a discrepancy is a query, not an investigation.
Plan explicitly for underpayments (buyer sent too little), overpayments (refund the difference or credit it), wrong-network sends, and expired-then-paid invoices. These are not rare edge cases at volume — they're weekly events, and a system that handles them quietly is what 'production-ready' actually means.
Frequently asked questions
Should I trust the browser redirect or the webhook?
The webhook. The redirect can be lost if the user closes the tab, and it can be spoofed. Verify the webhook's signature server-side and treat it as the authoritative signal that an order is paid.
How do I stop a webhook from being processed twice?
Make handling idempotent. Gateways retry deliveries, so key your logic on the invoice or event ID and make a repeat a no-op. Never fulfil an order twice because the same 'paid' event arrived again.
How many confirmations should I wait for?
It depends on amount and chain. Small stablecoin payments on fast networks can be treated as final almost immediately; larger amounts justify more confirmations. Use the gateway's 'confirmed' state rather than your own first sighting.
What happens if a customer underpays or overpays?
Handle both explicitly. Gateways flag underpayments so you can request the difference or refund; for overpayments you refund the excess or credit it. Building these branches up front is the difference between a demo and production.