Specify a Stripe webhook handler that survives production
Stripe sends events to your endpoint to tell you when a payment succeeded, a subscription renewed, or an invoice failed. Getting that handler right means three things that are easy to forget: verifying the signature, deduplicating retried events, and returning the correct status code. This builder turns your chosen events into a precise specification covering all three.
How it works
The generated spec fixes the processing order, which matters because each step depends on the previous one. First you read the raw body and call stripe.webhooks.constructEvent(rawBody, signature, endpointSecret). This both authenticates the request (only Stripe knows the signing secret) and protects against replay via the timestamp in the signature. A failure here returns 400 and stops.
Next comes idempotency. Because Stripe may deliver the same event more than once, the handler checks event.id against a uniquely-keyed store before acting and skips anything already seen. Only then does it dispatch on event.type, run your per-event action, record the ID as processed, and return 200. For each common event the spec also lists the object type and the payload fields you will actually read, like amount_total on a checkout.session or attempt_count on a failed invoice.
Response contract and reliability
The status code is the entire contract with Stripe’s retry engine. A 200 means “handled — stop.” A 400 means “rejected — never retry,” which is correct for a bad signature. A 5xx or timeout means “try again,” and Stripe will retry with exponential backoff for up to three days. Because of retries and the lack of ordering guarantees, every handler should be idempotent and tolerant of out-of-order delivery. Keep handlers fast: return 200 immediately and push slow fulfilment work onto a background queue.