Webhook signature mismatch debugger
Payment webhook signature errors are usually not cryptography bugs. They are raw-body, secret, header, middleware, or replay bugs. Use this checklist to narrow the route fix before changing billing side effects.
Open the free debuggerMost common causes
JSON was parsed, re-stringified, trimmed, pretty-printed, reordered, or decoded before HMAC verification.
The handler uses an API key, product key, old endpoint secret, or the staging secret in production.
The route compares a prefixed, uppercase, whitespace-padded, or wrong provider signature header.
Next.js, Hono, Express, or middleware consumes the body before the webhook route verifies the digest.
Fix order
Capture exact raw bytes first, compute the HMAC with the endpoint webhook signing secret, normalize only the documented signature header format, then parse JSON after the digest matches.
curl -X POST "$WEBHOOK_URL" \
-H "content-type: application/json" \
-H "x-signature: $SIGNATURE" \
--data-binary @fixture.json
Framework notes
In Next.js App Router, call await request.text() before parsing. In Hono, read await c.req.text(). In Express, use route-specific raw body middleware instead of global JSON parsing for the webhook endpoint.
FAQ
Why does a webhook signature mismatch when the JSON looks identical?
HMAC signatures are computed over exact raw bytes. Parsing JSON and re-stringifying it can change whitespace, ordering, encoding, or line endings, which makes the digest different even when the data looks identical.
What should I test after fixing a webhook signature mismatch?
Keep a fixture file, sign the exact fixture bytes, verify the route accepts that signature, and add a negative test for a changed body or wrong secret.
Use the free sample before wiring production checkout
Download a public sample pack with fake Lemon Squeezy fixtures, signature tests, contract checks, duplicate replay tests, and CI skeletons. The Pro Kit preview shows the full paid package structure without exposing the private archive.