All posts
Internet Fundamentals

Receiving Webhooks Without Losing Money: Signatures, Retries, Duplicates and Order

By

October 26, 2026

5 min read

Payment, auth and email providers tell your app what happened through webhooks. They arrive late, twice, out of order or not at all, and anyone can send a fake one. Using Stripe's documented behaviour as the example, the handler pattern that survives all of it.

Internet Fundamentals
Webhooks
Stripe
APIs
Reliability

A webhook is an HTTP POST from another company's servers to yours. If it is the only way you learn that a subscription renewed or a payment failed, its delivery guarantees become your app's. They are weaker than most people assume.

What Stripe documents

  • Undelivered events are retried for up to three days with exponential backoff in live mode; sandbox events three times over a few hours.

  • Order is not guaranteed: invoice.paid can arrive before invoice.created.

  • The same event can arrive more than once, and occasionally two different events describe one change.

  • Your endpoint must return 2xx quickly, before slow work. Redirects count as failures.

  • Each event carries an HMAC-SHA256 signature with a timestamp; the libraries reject events older than 5 minutes by default. Verification needs the raw body exactly as received.

Other providers differ in detail, rarely in kind. Assume these properties unless a provider's documentation says otherwise.

Want a second opinion on this for your system?

Book a free 30-minute call. You'll leave knowing what we'd do first and roughly what it costs, whether or not you hire us.

A handler that survives

  1. Verify the signature against the raw body and reject failures. Without this, anyone who finds the URL can mark orders paid.

  2. Store the event under a unique constraint on its ID. A conflict means a duplicate: return 200 and stop.

  3. Return 200.

  4. Process from a queue or background worker, so a burst (every subscription renewing on the 1st) does not swamp the web server.

  5. Treat the event as a prompt, not the truth: fetch the object's current state from the provider's API before acting. Order stops mattering.

  6. Run a reconciliation job that lists recent objects from the provider and repairs anything a missed webhook left wrong.

Common mistakes

  • A JSON body parser runs before the webhook route, verification always fails, and someone "fixes" it by turning verification off.

  • All the work happens before the response, the request times out, and the provider retries a half-processed event.

  • Access is granted on the checkout redirect rather than from the webhook, so a closed tab means paying without access.

  • Nobody is alerted when the provider disables the endpoint after repeated failures.

hoolco Monthly Review

Once a month: what changed in tech that month and what it means for you, from cloud and AI to security and the tools you build with. Every item links to its source. No sales pitch, unsubscribe in one click.

As of October 26, 2026. Provided as is, for general information, and accurate to the best of our knowledge on the date shown. Not legal, compliance, tax, financial or other professional advice. Prices, limits and vendor services change; check current vendor documentation before relying on anything here. Terms of use.