#Lucas974-webook-sig
1 messages · Page 1 of 1 (latest)
express.js
below a sample of webhook.js:
const stripe = require('stripe')(process.env.SK_STRIPE);
const signStripe = process.env.SIGNATURE
module.exports = async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, signStripe);
}
catch (err) {
res.status(400).send(`Webhook Error: ${err.message}`);
}
and app.js:
require('dotenv').config();
const webhook = require('./webhook');
const express = require('express');
const app = express();
...
app.post('/webhook', express.raw({type: 'application/json'}), webhook);
I really don't understand why this doesn't work :/
using payment link in test mode
Or do you have a HTTPS endpoint?
No that's okay
Are you using express.json anywhere?
Can you show me your whole endpoint code?
yep
app.js:
require('dotenv').config();
const webhook = require('./webhook');
const express = require('express');
const app = express();
const https = require('https');
const fs = require('fs');
const PORT = process.env.PORT;
app.post('/webhook', express.raw({type: 'application/json'}), webhook);
app.get("/", (req, res) => {
res.send(`Backend is running on port ${PORT}`);
});
const options = {
key: fs.readFileSync('/etc/ssl/private/aa.pem'),
cert: fs.readFileSync('/etc/ssl/aa.fullchain.pem')
};
https.createServer(options, app).listen(PORT, () => {
console.log(`Running backend on port ${PORT}`);
});
and webhook.js:
const stripe = require('stripe')(process.env.SK_STRIPE);
const signStripe = process.env.SIGNATURE
const { formatDate } = require('./utils');
const Payment = require('./db');
module.exports = async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, signStripe);
}
catch (err) {
res.status(400).send(`Webhook Error: ${err.message}`);
}
const id = req.body?.data?.object?.id;
if (!id) {
console.error('Invalid webhook data:', req.body);
return res.sendStatus(400);
}
res.status(200).send('Webhook received successfully');
try {
const data = await stripe.paymentIntents.retrieve(
id, { expand: ['payment_method'] }
);
const paymentData = {
pid: id,
date: formatDate(data.payment_method.created),
name: data.payment_method.billing_details.name,
email: data.payment_method.billing_details.email,
country: data.payment_method.billing_details.address.country,
type: data.payment_method.card.brand,
last4: data.payment_method.card.last4,
};
console.log(paymentData);
const payment = new Payment(paymentData);
await payment.save();
} catch(error) {
console.error('Error retrieving payment intent:', error);
}
}
Hmm okay
Right before event = stripe.webhooks.constructEvent(req.body, sig, signStripe); can you log out req.body and tell me what you see?
ok doing it
Get this:
<Buffer 7b 0a 20 20 22 69 64 22 3a 20 22 65 76 74 5f 33 4d 6c 45 53 54 47 78 62 6f 48 61 6c 4e 6f 67 30 32 33 73 42 4d 50 52 22 2c 0a 20 20 22 6f 62 6a 65 63 ... 1850 more bytes>
Invalid webhook data: <Buffer 7b 0a 20 20 22 69 64 22 3a 20 22 65 76 74 5f 33 4d 6c 45 53 54 47 78 62 6f 48 61 6c 4e 6f 67 30 32 33 73 42 4d 50 52 22 2c 0a 20 20 22 6f 62 6a 65 63 ... 1850 more bytes>
I did it like that:
try {
console.log(req.body);
event = stripe.webhooks.constructEvent(req.body, sig, signStripe);
}
Okay that is what it should look like
Can you log out your secret key and ensure it matches the one in your Dashboard for that endpoint
ok doing it...
they are same
whsec_ZV9Fh...
Really I don't understand where is the issue :/
Hmmm can you show me the full error message?
this is just:
Invalid webhook data: <Buffer 7b 0a 20 20 22 69 64 22 3a 20 22 65 76 74 5f 33 4d 6c 45 5a 54 47 78 62 6f 48 61 6c 4e 6f 67 31 66 7a 47 54 72 30 39 22 2c 0a 20 20 22 6f 62 6a 65 63 ... 1850 more bytes>
Where do you see that error exactly?
npm run dev
I proceed to a payment
then it shows up on my backend
If I remove the signing check, I can see the payment done and get the details (email.. to record in my mongodb)
"It shows up on my backend" -- what does this mean?
That error shows up?
Do you have stack trace with the line that is hitting that error?
the error comes from here:
catch (err) {
res.status(400).send(Webhook Error: ${err.message});
}
Okay can you log that whole err?
how?
console.log("err: ", err) above that res.status(400)
The other thing you can do actually is provide me an Event ID
module.exports = async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
console.log(signStripe);
event = stripe.webhooks.constructEvent(req.body, sig, signStripe);
}
catch (err) {
res.status(400).send(`Webhook Error: ${err.message}`);
}
const id = req.body?.data?.object?.id;
if (!id) {
console.error('Invalid webhook data:', req.body);
return res.sendStatus(400);
}
the error I get is not from the signing check but the code:
const id = req.body?.data?.object?.id;
if (!id) {
console.error('Invalid webhook data:', req.body);
return res.sendStatus(400);
}
are you ok with this?
Oh okay then yeah that is why
This doesnt work anymore since I use express.raw
but I don't know how I can resolve this
Well you need to find out why (!id)
But really you should be using a case statement here
Instead of checking that every object has an ID