Webhooks are how a payments platform tells your system that money moved. Getting them right — signatures, idempotency, retries — is the difference between a payment flow you can trust and one that quietly loses events.
A webhook is a message a platform sends to your server when something happens — a payin is credited, a payout settles, a conversion completes. In a payments integration, webhooks are usually the source of truth for state changes, which means they deserve the same care you would give to any part of the money path.
Verify every signature
Anyone who learns your webhook URL can POST to it. Before you trust a payload, verify its signature. A common approach is an HMAC over the raw request body using a shared secret; you recompute the HMAC on your side and compare it to the header. Compare using a constant-time function, and always sign and verify the raw bytes — reserialising the JSON first is a frequent source of mismatches.
Handle events idempotently
Networks are unreliable, so a well-behaved sender will retry. That means you should expect to receive the same event more than once. Every event carries a stable identifier; record the ones you have processed and make reprocessing a no-op. Idempotent handling is what lets a sender retry safely without ever crediting a wallet twice.
Acknowledge fast, work later
Return a 2xx as soon as you have durably stored the event. Do the heavier work — updating ledgers, notifying users — asynchronously. If you do your processing inline and it is slow, you risk timeouts that the sender reads as failures, triggering yet more retries.
A practical checklist
- Verify the signature on the raw body before parsing anything.
- Deduplicate on the event id; treat repeats as no-ops.
- Persist the event first, then acknowledge, then process.
- Make processing steps retry-safe end to end.
- Log with a trace id so a single event can be followed across systems.
- Reconcile against the API periodically so a missed webhook is never the only record of truth.
None of these steps are exotic, but skipping any one of them tends to surface at the worst possible time — during an incident, at volume, with money on the line. Build them in from the first integration.