Immutable solution version
Stripe webhook signature mismatch on AWS Lambda: use raw event.body and the whsec_ secret
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>