Stripe: No signatures found matching the expected signature for payload
StripeSignatureVerificationError: No signatures found matching the expected signature for payload.
In short: Stripe signs the raw request body. Your code verified a parsed or modified body, or used the wrong signing secret.
Why it happens
Frameworks parse JSON automatically, and re-serialized JSON no longer matches Stripe's signature. The other common cause is the wrong whsec_ secret: the Stripe CLI (stripe listen) prints its own secret that differs from the dashboard endpoint's secret, and test vs. live endpoints each have their own.
How to fix it
- Verify with the raw body: in Next.js App Router use
await req.text(); in Express useexpress.raw({ type: 'application/json' })on that route only. - Pass the exact
stripe-signatureheader tostripe.webhooks.constructEvent(rawBody, sig, secret). - Local testing: use the secret printed by
stripe listen. Production: use the secret from that endpoint in the Dashboard (Developers → Webhooks). - Check you're using test-mode secrets with test events and live with live.
- Return a 2xx quickly and do slow work afterwards so Stripe doesn't time out and retry.
Example
// app/api/stripe/webhook/route.ts
export async function POST(req: Request) {
const body = await req.text();
const sig = req.headers.get("stripe-signature")!;
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
// handle event.type ...
return new Response(null, { status: 200 });
}
Copy-paste fix prompt
I'm getting this error in my app: StripeSignatureVerificationError: No signatures found matching the expected signature for payload. [Paste the full error, stack trace, and the file it points to here] Likely cause: Stripe signs the raw request body. Your code verified a parsed or modified body, or used the wrong signing secret. Task: Make my Stripe webhook route verify the signature against the raw request body with the correct endpoint secret for each environment, without disabling verification. Rules: - First explain the root cause in 2 sentences and list the files you'll change. - Make the smallest change that fixes it. Don't refactor unrelated code. - Don't disable security or checks (RLS, auth, signature verification, type checking, CORS allow-all) to make the error disappear. - Never print or hard-code secret keys. - Finish by telling me exactly how to verify the fix.
Common with: Cursor, Bolt, Lovable, Replit. Last reviewed 2026-11-13.