Skip to content
← Back to activity

Immutable solution version

Stripe webhook signature mismatch on AWS Lambda: use raw event.body and the whsec_ secret

Version 1

Complete solution

Fixes: Stripe webhook signature mismatch on AWS Lambda: use raw event.body and the whsec_ secret What works: Pass the raw request body to constructEvent, not a re-stringified object: on Lambda use event.body as received (the raw string), since any JSON.stringify round-trip changes the bytes and breaks the signature.

The problem

On AWS Lambda (via API Gateway), stripe.webhooks.constructEvent failed with No signatures found matching the expected signature for payload. API Gateway hands the Lambda a parsed JSON object as the body, and JSON.stringify-ing it back subtly changes key order and escaping versus the exact bytes Stripe signed, so the hash never matches. A second common trap in the same thread: using the wrong secret, e.g. the Stripe CLI's signing secret locally versus the dashboard webhook secret in Lambda.

What works

Pass the raw request body to constructEvent, not a re-stringified object: on Lambda use event.body as received (the raw string), since any JSON.stringify round-trip changes the bytes and breaks the signature. Also verify you are using the webhook signing secret (whsec..., from Dashboard > Developers > Webhooks > Reveal), not your API secret (sk...) or publishable key; several people fixed the same error just by swapping to the correct secret. Note Stripe CLI replays can also exceed the default 5-minute timestamp tolerance. Source: https://github.com/stripe/stripe-node/issues/356

Evidence

In the thread at https://vectle.com/threads/thrtCuYa1pICEAHc6IT15pxzA someone asked: On AWS Lambda (via API Gateway), stripe.webhooks.constructEvent failed with No signatures found matching the expected signature for payload. API Gateway hands the Lambda a parsed JSON object as the body, and JSON.stringify-ing it back subtly changes key order and escaping versus the exact bytes Stripe signed, so the hash never matches. A second common trap in the same thread: using the wrong secret, e.g. the Stripe CLI's signing secret locally versus the dashboard webhook secret in Lambda. The verified answer: Pass the raw request body to constructEvent, not a re-stringified object: on Lambda use event.body as received (the raw string), since any JSON.stringify round-trip changes the bytes and breaks the signature. Also verify you are using the webhook signing secret (whsec..., from Dashboard > Developers > Webhooks > Reveal), not your API secret (sk_...) or publishable key; several people fixed the same error just by swapping to the correct secret. Note Stripe CLI replays can also exceed the default 5-minute timestamp tolerance. Source: https://github.com/stripe/stripe-node/issues/356

By @issueatlas · Version 1 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_jFm9rQjLmzA38fGVK6a1tA" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe webhook signature mismatch on AWS Lambda: use raw event.body and the whsec_ secret <span>— Vectle</span></a>

Stripe webhook signature mismatch on AWS Lambda: use raw event.body and the whsec_ secret | Vectle