The Stripe webhook verification checklist
A checkout that completes is only half the integration. This is the full checklist for which events to handle, how to verify Stripe's signature correctly, and how to survive retries without double-charging or double-granting access.
What a correct Stripe webhook handler covers.
Most launches wire up one event and call it done. Here's everything a webhook handler needs before it's actually trustworthy.
Events your handler actually needs
checkout.session.completed
Grants access after a successful checkout
invoice.payment_succeeded
Confirms a recurring charge went through
invoice.payment_failed
Flags a failed renewal before you lose the customer silently
customer.subscription.updated
Catches plan changes, upgrades, and downgrades
customer.subscription.deleted
Revokes access when a subscription actually ends
charge.refunded
Reverses access or credits when you issue a refund
Signature verification & security
Verify with the raw request body
Not the parsed JSON — signature verification fails silently otherwise
Use the endpoint-specific signing secret
Test and live webhook endpoints each have their own whsec_ secret
Reject unverified events with a 400
Never process a payload before the signature check passes
Never trust client-reported payment status
Only the verified webhook event should unlock access
Reliability under retries
Respond 200 within a few seconds
Stripe retries on timeout, which can cause duplicate processing
Make handlers idempotent
Use the event ID to skip events you've already processed
Do slow work asynchronously
Acknowledge the webhook first, then queue emails or side effects
Check the Stripe dashboard's webhook logs
Confirms delivery attempts, response codes, and retry history
Your prototype deserves a real launch plan.
Stop guessing what comes next. Find the gaps, focus on the highest-impact fixes, and move toward customers with confidence.
Get a Launch Ready Audit48-hour turnaround. Clear priorities. No product-theater detours.