Fix: Stripe Webhooks Not Receiving Events
Quick Answer
Check that your webhook endpoint URL is correct in Stripe Dashboard > Developers > Webhooks, and that you're using the correct webhook signing secret (not the API key).
Symptoms
- !Stripe dashboard shows failed webhook deliveries
- !Webhook endpoint returns 400 or 500 errors
- !Payments succeed but app doesn't update
- !Webhook signature verification fails
Step-by-Step Fix
Verify the webhook URL
In Stripe Dashboard > Developers > Webhooks, check that the endpoint URL is your production URL (not localhost). It must be HTTPS.
Use the correct signing secret
Each webhook endpoint has its own signing secret (whsec_...). This is different from your Stripe API key. Find it in Stripe Dashboard > Webhooks > your endpoint > Signing secret.
Handle the raw request body
Stripe signature verification requires the raw request body, not parsed JSON. In Next.js, export const config = { api: { bodyParser: false } }; in your webhook route.
Test locally with Stripe CLI
Install Stripe CLI and run 'stripe listen --forward-to localhost:3000/api/webhooks/stripe' to test webhooks locally.
Check event types
Make sure your webhook is subscribed to the events you need (checkout.session.completed, customer.subscription.updated, etc.).
Frequently Asked Questions
Usually because: (1) you're using the API key instead of the webhook signing secret, or (2) the request body was parsed before verification.
Yes, use the Stripe CLI to forward events to localhost. Run: stripe listen --forward-to localhost:3000/api/webhooks/stripe
Related
Weekly Newsletter
Get next week's fix before you need it.
Join developers getting weekly vibe coding tips, error fixes, and tool updates.
Subscribe on Substack →