stripe-node: Webhook validate signing error: No signature found matching the expected signature for payload. | express
Another ‘Webhook validate signing’ issue! Whoooohooo 🥳
Hi there! I am trying to built a Backend Server for a Web project with Google Cloud App Engine.
What do I want to achieve:
I want to verify all my received WebHooks from Stripe.
What is my Problem:
Currently I always get the same error message.
❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
I tried lot’s of ways getting the raw body from the request and passing it to the stripe.webhooks.constructEvent
Method.
But all failed…
My Code to reproduce
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
const raw = Buffer.from(JSON.stringify(req.body), 'base64').toString('utf8');
console.log(raw);
const sig = req.headers['stripe-signature'];
const endpointSecret = 'whsec_*********';
let event;
try {
event = stripe.webhooks.constructEvent(raw, sig, endpointSecret);
} catch (err) {
// On error, log and return the error message
console.log(`❌ Error message: ${err.message}`);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Successfully constructed event
console.log('✅ Success:', event.id);
// Return a response to acknowledge receipt of the event
res.json({received: true});
});
As you can see it is nearly identical to the code from the Stripe Docs.
I am not sure if App Engine, from Google Cloud, is parsing the request body before I can even touch it.
My only reference point is that if I console.log
out the complete request, the body
part is always already parsed as a JSON, at least it seems like it.
This is what I get when I do console.log(req)
:
{ ... },
body: {
id: 'evt_1JcW8OKBPpELGMIU63zjXLPM',
object: 'event',
api_version: '2020-08-27',
created: 1632319755,
data: { object: [Object] },
livemode: false,
pending_webhooks: 1,
request: { id: 'req_mjJqRWVdi4t0Hb', idempotency_key: null },
type: 'invoice.paid'
},
{ ... }
What I have tried so far
I tried many things.
JSON.stringify(req.body)
Result:
❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
Buffer.from(req.body, 'base64').toString('utf8');
Result:
❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
Buffer.from(JSON.stringify(req.body), 'base64').toString('utf8');
(same as in ‘My Code to reproduce’) Result:
❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
- I have also tried the ‘simple middleware’ idea from jlomas-stripe. But still: Result:
❌ Error message: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
req.body.raw
Result:
undefined
req.body.rawBody
Result:
undefined
req.rawBody
Result:
undefined
…
At the end, as you can see, I got very frustrated ☹️ …
Is this a Bug or is there a solution to fix it?
I have only tested it with the Stripe CLI.
Name | Version |
---|---|
NodeJS | v. 14 |
express | v. 4.17.1 |
stripe | v. 8.176.0 |
Thank you in advance for helping 😄 Greetings from Hamburg, Germany
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 20 (1 by maintainers)
Hi, @MNorgren !
After a long debugging session with one very nice Stripe Discord Admin from the Stripe Dev Server the problem was actually very simple.
I did use a bodyParser like this:
app.use(express.json())
and this middleware did converted the body into a JSON format before I could get the raw body.And Stripe needs the raw body to verify the WebHook.
And so now what I have done is the following:
Hope this helps! Greetings from Hamburg.
@Jonathan-Hofmann - Thank you, that also looks like it would work!
I also found a work-around by using the
express.raw({type: 'application/json'})
as specified in the docs, but rather than usingrequest.body
, I had to userequest.rawBody
.My express route ended up looking like this:
I love you, sincerely
HI all! I have a NestJS app and I am obtaning raw body at application level like this:
It works when I use my own credentials at test mode. But when I deploy the code to the production where I use another stripe account credentials with live mode, it throw this error when a payment is received: No signatures found matching the expected signature for payload
I couldn’t find any solution for days. Can you please help me?
Another alternative solution. Since we need to access only the raw request body we can alter the request object to have a raw body property. Since we are using json body parser we can set this in the middleware like this:
u saved my life, thanks!!