Guides · Free check · $9 fix pack

Guides

Stripe webhook not working? Check these 7 things in order

Most "my webhook doesn't fire" problems are one of seven things. Work down the list; each step takes a minute.

1. Look at the delivery log first

In the Stripe Dashboard, open your webhook endpoint (under Developers or Workbench, depending on your Dashboard version) and open the event deliveries. Every attempt shows the HTTP status your server returned. That status tells you which step below applies. Stripe documents the common error statuses on its webhooks page (Stripe docs: Receive events).

2. A 3xx status means a redirect, and Stripe treats it as a failure

Stripe does not follow redirects for webhooks: "We consider redirect responses to webhook requests as failures." (source). Typical causes: example.com redirecting to www.example.com, http to https, or a trailing-slash rule. Fix: paste the final URL (the one the redirect points to) into the endpoint settings. See the 307/308 guide.

3. 401 or 403 means something is asking Stripe to log in

Stripe cannot pass a login or JWT. Common culprits: Vercel deployment protection on preview URLs, Supabase Edge Functions with JWT verification on, or a bot challenge from a CDN. Supabase's own Stripe example deploys the function with verify_jwt = false because "Stripe verifies the request via its signature" (Supabase docs).

4. 404 or 405 means the path or method is wrong

Check the exact path (/api/webhooks/stripe vs /api/webhook) and that the route accepts POST.

5. 400 usually means signature verification failed

Stripe needs the raw request body to verify the signature, and "any manipulation to the raw body of the request causes the verification to fail" (source). The other common cause is the wrong signing secret: test and live endpoints have different secrets (source). Full fix: signature verification failed.

6. Timeouts mean your handler does too much before answering

Your endpoint must "quickly return a successful status code (2xx) before any complex logic that could cause a timeout" (source). Verify, record the event, return 200, then do the slow work.

7. 200 but nothing happens: you're not listening for the right event

For Checkout, Stripe's fulfillment guide handles checkout.session.completed and, for delayed payment methods, checkout.session.async_payment_succeeded (Stripe docs: Fulfill orders). Make sure the endpoint is subscribed to those events in the mode you're testing.

After you fix it

Stripe retries failed live-mode deliveries for up to three days with exponential backoff, and sandbox deliveries three times over a few hours (source). To recover missed events sooner, Stripe documents how to list and process undelivered events (Stripe docs).

Check yours in 10 seconds (free).

Paste your webhook URL. WebhookProof sends 3 harmless test requests and tells you whether Stripe can reach it and whether it rejects unsigned events.

Run the free check

FAQ

Does Stripe follow redirects on webhook URLs?

No. Stripe treats any 3xx response to a webhook request as a failed delivery. Use the final URL in your endpoint settings.

How long does Stripe retry failed webhooks?

In live mode, up to three days with exponential backoff. In a sandbox, three times over a few hours.

Where can I see why a webhook failed?

In the Stripe Dashboard, open your webhook endpoint and look at its event deliveries; each attempt shows the HTTP status your server returned.

More guides

A customer paid but didn't get access. What went wrong? · Stripe webhook signature verification failed · Stripe webhook getting a 307 or 308 redirect · Stripe webhook on Supabase Edge Functions: fixing 401s and signature errors

Last reviewed 2026-10-18. WebhookProof is an independent tool, not affiliated with Stripe, Inc. Quotes are from the linked documentation.