← All notes

May 2026

Stripe in production: idempotent webhooks

The payment succeeds on Stripe, but your database does not always know it. Reliability comes from idempotent webhooks, not the happy path.

Integrating Stripe for the happy path takes an hour. Making it reliable in production takes the rest. The real subject is not the checkout page, it is reconciliation.

Why the webhook is the source of truth

The browser return after payment is not reliable: the user closes the tab, the network drops. Only the server webhook confirms state. It must trigger activation, never the front-end redirect.

Stripe can send the same event several times. Without a guard, you credit twice or send two emails. The fix: store the event id and process each event once.

Reconcile, do not trust

You verify the webhook signature, make processing idempotent, and handle intermediate states: pending, failed, refunded. A reconciliation cron catches missed events.

A payment system is judged on its edge cases. That is where disputes live, not in the happy path.