# Stripe webhook: "No signatures found matching the expected signature for payload"

- Fix ID: APP-19
- Exact error: `No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?`
- Status: Manually verified (CI: pending, no CI results exist yet)
- Last verified: 2026-10-26
- Platforms: Stripe, Cursor, Bolt, Lovable, Vercel
- Versions: os=Debian 13 (container); node=20.19.2; express=5.3.0; stripe=23.0.1 (stripe-node)
- Repro: https://stucktoshipped.com/repros/APP-19/ (file hashes only; files are in the paid repro bundle)
- Canonical: https://stucktoshipped.com/fixes/stripe/webhook-no-signatures-found/

## In brief
Stripe signs the raw request bytes, and your server changes them before verification. The full fix gives the exact Express route order and body handling, the secret checks, and our 4-case test table.

## Symptom
You added Stripe Checkout to an app built with Cursor, Bolt or Lovable, with a Node/Express or Next.js backend. Payments go through, but your webhook endpoint returns **400**, and your logs show one of these:

```
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
```
```
Webhook payload must be provided as a string or a Buffer ... Payload was provided as a parsed JavaScript object instead.
```
So orders never get marked as paid.

## Why it happens
- **Stripe signs the exact bytes it sends.** `stripe.webhooks.constructEvent()` needs those same, untouched bytes, plus the signing secret (`whsec_...`) for that endpoint.
- **AI-generated servers usually add `app.use(express.json())` at the top.** That turns the body into an object before your webhook code sees it:
  - Passing that object gives the "must be provided as a string or a Buffer" error.
  - "Fixing" it with `JSON.stringify(req.body)` creates *different* bytes, which gives "No signatures found".
- **A wrong secret gives the same "No signatures found" error** (e.g. the Stripe CLI's secret instead of the dashboard endpoint's, or test vs live).

## What we could not test
- Real Stripe deliveries, the Stripe CLI (`stripe listen`), and test vs live secrets in a real account.
- Next.js App Router and Pages Router, Vercel serverless body handling, and other frameworks.
- Proxies that rewrite the body.

## Full fix (paid)
The step-by-step fix, commands and test record are paid content and are not in this file. Price: $4 per fix (planned launch price; checkout not open yet). SHA-256 of the full fix: 98c0a7ca9438f66cda5333522ad33df53745e32d329bca4099576de67479542a. How to buy: https://stucktoshipped.com/pricing/ and https://stucktoshipped.com/products.json

## Sources
- [Stripe docs: resolve webhook signature verification errors](https://docs.stripe.com/webhooks/signature?lang=node)
- [Stack Overflow: No signatures found matching the expected signature for payload](https://stackoverflow.com/questions/53899365/stripe-error-no-signatures-found-matching-the-expected-signature-for-payload)
- [Stack Overflow: Webhook payload must be provided as a string or a Buffer](https://stackoverflow.com/questions/76281195/stripe-webhook-payload-must-be-provided-as-a-string-or-a-buffer)
- [Stack Overflow: webhook with Stripe and Next.js 13](https://stackoverflow.com/questions/75828724/i-am-trying-to-setup-of-a-webhook-using-stripe-and-nextjs-13-2-3)
- [Stack Overflow: Stripe webhook error on Next.js / Vercel](https://stackoverflow.com/questions/77377919/stripe-webhook-error-no-signatures-found-matching-the-expected-signature-for-p)
- [vercel/next.js#49739](https://github.com/vercel/next.js/issues/49739)

## How this page was made
Drafted by an AI agent and reproduced on our test machine on 2026-10-26. No warranty; test on a copy first.
