Docs · Billing · Stripe webhooks
Handling Stripe webhooks reliably
This guide walks through verifying signatures, idempotency, and recovering from delivery failures when integrating Stripe webhooks with Acme.
Stuck? Click the Kwieri button (bottom right) to open a live session — our
AI assistant will pull the page context in automatically and can route you to a human expert
if it doesn't have the answer.
1. Verify the signature
const event = stripe.webhooks.constructEvent(
payload,
request.headers["stripe-signature"],
process.env.STRIPE_WEBHOOK_SECRET
);
2. Use idempotency keys
Stripe may deliver the same event more than once. Persist event.id and treat
duplicates as no-ops.
3. Common failure: customer.subscription.updated
Many handlers fail on subscription updates because previous_attributes is undefined
for the first event in a session. Always guard your reads.
const prev = event.data.previous_attributes ?? {};
if (prev.status === "trialing" && event.data.object.status === "active") {
// billing started
}