Stripe·Fixpaymentsintermediate

Stripe Webhook Signature Verification Failed

Quick Answer

The raw request body must be used for signature verification, not the parsed JSON body. Start with "Use raw body for verification" before making broader code changes.

You're in the right place if...

  • !Error: webhook signature verification failed
  • !Webhooks received but rejected
  • !400 errors on webhook endpoint

Why this happens

The raw request body must be used for signature verification, not the parsed JSON body.

Fix

1

Use raw body for verification

The most common mistake — using parsed JSON instead of raw text:

// WRONG — body is already parsed:
const body = await req.json()

// CORRECT — use raw text:
const body = await req.text()

const event = stripe.webhooks.constructEvent(
  body,
  req.headers.get('stripe-signature'),
  process.env.STRIPE_WEBHOOK_SECRET
)

Prevent this next time

Always use req.text() (not req.json()) for the body in webhook handlers. This preserves the exact bytes Stripe signed.

Frequently Asked Questions

Stripe signs the raw bytes. JSON parsing and re-stringifying changes formatting (whitespace, key order), breaking the signature.

Stripe Dashboard → Developers → Webhooks → your endpoint → Signing secret (starts with whsec_).

Related fixes

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 →