Free tool / Stripe webhooks

Paste your Stripe webhook handler. 7 checks run in your browser.

The most-viewed Stripe question on Stack Overflow is “No signatures found matching the expected signature for payload”89,816 views. Right behind it, the same root cause wearing a different hat: “Webhook payload must be provided as a string or a Buffer” (25,121 views), Express raw body (5,504) and Next.js raw body (5,492).

It is almost always rule 1 below — and it is only one of the 7 things that go wrong in webhook handlers. So instead of another checklist you have to read against your code: paste the handler and press Scan.

Nothing leaves your machine. This page is plain HTML and JavaScript with no backend, no analytics on the input and no network calls. It never asks for an API key or a whsec_ signing secret — and you should never paste one into any website, including this one.

What the 7 rules are

  1. Raw body must reach constructEvent. Stripe signs the exact bytes it sent. express.json(), bodyParser.json(), request.get_json() or await req.json() hand you a re-serialized object — key order, spacing and unicode escaping all change, so the HMAC can never match.
  2. The signature is actually verified. No constructEvent means anyone who learns your URL can POST a fake checkout.session.completed and get free product.
  3. No hardcoded sk_ / rk_ / whsec_ literals. Every endpoint (CLI forwarding, test, live) has a different signing secret, so a hardcoded one is both a leak and a guaranteed production failure.
  4. idempotencyKey on create calls. Stripe retries any delivery that times out or answers non-2xx. Without a key derived from event.id, the retry charges again.
  5. De-duplication by event.id. At-least-once delivery is a documented guarantee, not an edge case.
  6. Amount never read from request data. amount: req.body.amount is editable by the caller. Derive it server-side.
  7. No legacy Charges/Sources API. No SCA/3DS support means European cards get declined.

What this tool cannot see

It runs static pattern checks on one pasted file. It does not know your environment variables, your proxy or API gateway, whether that express.json() is mounted on a different router, or what your database actually does with event.id. A clean result means “none of the 7 known shapes are visible in this file”, not “your integration is correct”. That limitation is exactly why the paid version is a human reading the whole repository.

Want the same 7 rules run against your whole repo, by a human?

We read your actual Stripe code — webhooks, checkout, subscriptions, refunds — and send back a written report with file:line references and the fix for each finding. Flat $39, delivered in 48h, full refund if the repo cannot be reviewed.

Get the Stripe Integration Audit — $39

Paste the repo URL at checkout. The tool above is free and stays free.

Hitting “Webhook payload must be provided as a string or a Buffer”? Full fix for Express, Next.js, Flask, FastAPI, Django, Bun and Lambda →