Launch special — let's split the check with SPLITCHECK for 50% off

Glossary

Raw Body

The unparsed, byte-for-byte request body. Webhook signatures are computed over it, so reading the parsed body instead is the #1 cause of verification failures.

The raw body is the request payload exactly as it arrived — every byte, in order, before any middleware touches it. HMAC signatures are computed over these bytes, so verification only works if you hash the *same* bytes the sender did.

The classic bug: a framework like Express auto-parses JSON (express.json()), so by the time your handler runs, the body is a JavaScript object. Re-serializing it (JSON.stringify) reorders keys and changes whitespace — the recomputed signature no longer matches. The fix is to capture the raw body before the JSON parser runs (e.g. express.raw({ type: 'application/json' })).

Every major provider's docs say the same thing: verify against the raw body. If signature checks fail on payloads you're sure are genuine, this is the first thing to rule out.

Capture the raw body in Express before parsing

app.post(
  "/webhooks",
  express.raw({ type: "application/json" }), // req.body is a Buffer
  (req, res) => {
    verifySignature(req.body, req.header("Stripe-Signature"));
    const event = JSON.parse(req.body.toString());
    // ...
  },
);

How HookSense helps

HookSense stores the exact raw body it received and shows you the byte length — so you can confirm whether a signature mismatch is a body-mangling bug or a genuinely wrong secret.

Get a free webhook URL

Related terms