TL;DR: Stripe Signature Verification Failed — most cases trace to a config mismatch, a hidden assumption, or a step skipped during setup. The fix path below covers the high-percentage causes first. If you're still stuck after 10 minutes, text PJ — most issues answered in one reply. 858-461-8054.
SideGuy North County San Diego
Stripe · Problem Fix

Stripe Signature Verification Failed

Your webhook endpoint is receiving Stripe events but signature verification throws an error. This is almost always a raw body parsing issue — your framework is parsing the JSON before Stripe can verify the original signature.

1. Body parsed before stripe.webhooks.constructEvent()

Stripe's signature is computed against the raw bytes of the request body. If your framework (Express, Next.js, etc.) parses the JSON body first (converting it to a JavaScript object), the raw bytes are gone. You must pass the raw buffer, not the parsed object. In Express: use express.raw({type: 'application/json'}) for the webhook route. In Next.js App Router: read req.text() not req.json().

2. Wrong webhook secret (endpoint secret vs API key)

stripe.webhooks.constructEvent() takes your webhook signing secret — not your Stripe API key. The signing secret starts with 'whsec_' and is found in Dashboard > Developers > Webhooks > your endpoint > Signing secret. Using your API key (sk_live_ or sk_test_) here will always fail.

3. Using test webhook secret with live events

Stripe has separate signing secrets for test mode and live mode webhooks. If you're testing with test events, use the test endpoint's whsec_. If receiving live events, use the live endpoint's whsec_. Cross-mode secrets always fail verification.

4. Timestamp tolerance exceeded

Stripe includes a timestamp in the webhook payload and rejects verification if the timestamp is more than 5 minutes old (configurable). If your server clock is off or you're replaying old events for testing, verification fails. Use stripe.webhooks.constructEvent(payload, header, secret, {tolerance: 300}) or increase tolerance for testing.

5. Middleware modifying the request body before your handler

Body-parsing middleware (body-parser, next.js default JSON parser) applied globally will consume the raw body before your webhook handler sees it. Ensure your webhook route explicitly bypasses the global JSON parser and reads the raw body directly.

Still stuck? Text PJ.

Real operator. No ticket queue. San Diego-based. Most issues resolved in one thread.

Text PJ → 858-461-8054

Related problems in this cluster:

Stripe webhook not working Vercel env var not loading Webhook works local not prod
💬 Text PJ
Still not sure what to do?
Text PJ — real human, honest answer, fast. No sales pitch.
💬 Text PJ — 858-461-8054
Looking for business help?
Payment Processing Help
Read the Guide 💬 Text PJ

Know someone who should see this? Share the idea and the feeling in one tap.

Seen this before — usually one of these:
• Check your Stripe dashboard for failed charges
• Look for webhook errors or timeout issues
• Verify bank account and payout settings
Not sure? I'll look at it with you →
PJ
▶ Play intro
👇 Tap me
How this works
Google brings the question.
PJ explains it simply.
You decide what to do next.
Ready to start?Operator Audit · $250 · 3-5 days · operator-honest signal-quality audit · credited if you upgrade · text PJ at 858-461-8054.
Related operator pages
Stripe webhook not working — root cause Stripe webhook not firing — trigger checklist Stripe webhook works local not prod — deploy fix Stripe CLI webhook not working
💬 Text PJ