Why Payment Webhooks Fail HMAC Signature Verification

Why Payment Webhooks Fail HMAC Signature Verification
When integrating Dodo Payments webhooks in intent-canvas, standard express.json() middleware silently broke HMAC SHA256 signature verification.
The root cause was request lifecycle ordering: express.json() parses the raw stream into JavaScript objects before handlers run. Re-stringifying JSON.stringify(req.body) alters whitespace, key ordering, and unicode encoding, invalidating the calculated cryptographic digest.
To fix this reliably:
Capture the raw immutable binary Buffer during request streaming via
express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }).Calculate the HMAC SHA256 signature against
req.rawBodyand compare it to the incoming webhook header usingcrypto.timingSafeEqualto prevent timing attacks.Pass the validated
req.bodyinto Zod schema pipelines only after cryptographic authenticity has been verified.
Never verify signatures on parsed JSON. Always bind your HMAC check directly to the raw byte stream before application validation executes.
Drishtant Ghosh
Follow for daily systems engineering & code teardowns.
🔗 Reference & Source Breakdown
- Source Material: Drix10/intent-canvas: Visual Workspace Mapping Natural Language to Agent Graphs ↗
- Recommended Visual Asset: Real-world visual artifact: Clean dark-mode terminal screenshot of code from Drix10/intent-canvas running or compiling.
- Syndicated Channel: LinkedIn & Personal Blog Hub