Acme Docs
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
}