Question

Codex rewrote my Stripe webhook and now every event fails signature verification

Solved · 152 viewsasked by kai_makes

Asked Codex to "clean up the API routes". Since then every Stripe webhook returns 400:

Webhook signature verification failed. No signatures found matching the expected signature for payload.

In the diff it changed await req.text() to await req.json() and then passes JSON.stringify(body) to constructEvent. It looks cleaner, and the payload looks identical when I log it.

What I’ve tried

Checked that STRIPE_WEBHOOK_SECRET is still the same, rolled the secret in the Stripe dashboard, resent events from the dashboard. All 400.

Comment

2 answers

Marked as helpful by the asker
wes_codes

It looks identical but it is not. Stripe signs the exact bytes it sent. JSON.stringify(JSON.parse(raw)) changes whitespace and sometimes key order, so the signature no longer matches.

Put it back to the raw body:

const raw = await req.text();
const event = stripe.webhooks.constructEvent(raw, req.headers.get("stripe-signature")!, process.env.STRIPE_WEBHOOK_SECRET!);

Then add a comment above it, something like // raw body on purpose: Stripe signs the exact bytes. Agents read comments, and it stops the next "cleanup" from undoing it.

Comment
Reverted that one line and payments are coming in again. Adding the comment now. kai_makes
olu_backend

Worth adding a test that posts a signed payload to the route. Then a refactor like this fails in CI instead of in production.

Comment