#vickygiyst
1 messages ยท Page 1 of 1 (latest)
๐ happy to help
please use this thread for your messages
please move your messages here
@frank crescent ^
i m trying to integrate webhook into my NodeJS API, and when stripe calls the webhook api from my nodeJS server ,it is giving me this error
webhook error StripeSignatureVerificationError: Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the raw request body.Payload was provided as a parsed JavaScript object instead.
i tried to remove the bodyparser i have used in NodeJS , but that leads to another error
โ ๏ธ Webhook signature verification failed.
webhook error StripeSignatureVerificationError: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
can someone help me here please, its been a week, i m struggling with thie
please give me a couple of minutes to look into this
sure! thank you !
would you mind sharing your code please?
sure
server.js file
app.use(bodyParser.json({
verify: (req, res, buf, encoding) => {
// get rawBody
req.rawBody = buf.toString()
}
}))
please follow this guide https://stripe.com/docs/webhooks/signatures
router.post('/webhook',express.raw({type: 'application/json'}),paymentCtrl.webhook)
you mean like this?
yes
what webhook secret are you using?
whsec_18fbbe77fb0833c43c9777b2ce12af6bdb808eb601b168ecf572822ef392cd85
how are you testing your code?
thourgh Stripe CLI?
or do you have a webhook endpoint
no, my site is live and i gave the api url in stripe
would you mind sharing the webhook endpoint ID?
I mean when you go to your dashboard https://dashboard.stripe.com/webhooks
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
you can click on your webhook endpoint and share the ID
thanks
this is not the correct secret
okay, i clicked on reveal secret and found this -- whsec_Q3D4n3CwwiJEGOJmEsHDV2FS27lFvYAF
i have used the same on my controller file
but its still same ๐ง
issue
would you mind sharing the code for paymentCtrl.webhook
const webhook = async (req, res) =>{
console.log("called");
let data;
let eventType;
// Check if webhook signing is configured.
const webhookSecret = 'whsec_Q3D4n3CwwiJEGOJmEsHDV2FS27lFvYAF';
if (webhookSecret) {
// Retrieve the event by verifying the signature using the raw body and secret.
let event;
let signature = req.headers["stripe-signature"];
console.log(`req.body`,req.body);
console.log(`signature`,signature);
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
webhookSecret
);
} catch (err) {
console.log(`โ ๏ธ Webhook signature verification failed.`);
console.log(`webhook error`,err);
return res.sendStatus(400);
}
// Extract the object from the event.
data = event.data;
eventType = event.type;
console.log("strip webhook event",event)
} else {
// Webhook signing is recommended, but if the secret is not configured in config.js,
// retrieve the event data directly from the request body.
data = req.body.data;
eventType = req.body.type;
}
switch (eventType) {
case 'checkout.session.completed':
// Payment is successful and the subscription is created.
// You should provision the subscription and save the customer ID to your database.
break;
case 'invoice.paid':
// Continue to provision the subscription as payments continue to be made.
// Store the status in your database and check when a user accesses your service.
// This approach helps you avoid hitting rate limits.
break;
case 'invoice.payment_failed':
// The payment failed or the customer does not have a valid payment method.
// The subscription becomes past_due. Notify your customer and send them to the
// customer portal to update their payment information.
break;
default:
// Unhandled event type
}
res.sendStatus(200);
}
yes
are you receiving new events or retrying unsuccessful ones?
i tried with new events, made a purchase on my test site and then checking console on the server
ok let's try one last thing
would you mind copy-pasting the code from the link I sent you above as is
and trying that
I'm just afraid that there's a small difference that I'm unable to perceive with your code that might be causing the issue
okay, but which link you are referring to. i cant see nay link above
i didnt get that error
but got this
aah, my bad
i forget to change request to req
POST /payment/webhook 400 454 - 17.593 ms
error: Cannot read properties of undefined (reading 'type') message=Cannot read properties of undefined (reading 'type'), stack=TypeError: Cannot read properties of undefined (reading 'type')
at webhook (/usr/src/app/controllers/paymentCtrl.js:83:17)
would you mind sharing your code now?
const webhook = async (req, res) =>{
const sig = req.headers['stripe-signature'];
let event;
let endpointSecret= "whsec_Q3D4n3CwwiJEGOJmEsHDV2FS27lFvYAF";
try {
event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
console.log("event test",event)
}
catch (err) {
res.status(400).send(Webhook Error: ${err.message});
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log('PaymentIntent was successful!');
break;
case 'payment_method.attached':
const paymentMethod = event.data.object;
console.log('PaymentMethod was attached to a Customer!');
break;
// ... handle other event types
default:
console.log(Unhandled event type ${event.type});
}
// Return a response to acknowledge receipt of the event
res.json({received: true});
}
console.log("event test",event), this is not coming on server console
please copy paste the whole thing as mentioned here
app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
}
catch (err) {
response.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log('PaymentIntent was successful!');
break;
case 'payment_method.attached':
const paymentMethod = event.data.object;
console.log('PaymentMethod was attached to a Customer!');
break;
// ... handle other event types
default:
console.log(`Unhandled event type ${event.type}`);
}
// Return a response to acknowledge receipt of the event
response.json({received: true});
});
Hi! I'm taking over my colleague. Please, give me a moment to catch up.
sure. thank you
By "same error" you refer to this? โ๏ธ
error: Cannot read properties of undefined (reading 'type') message=Cannot read properties of undefined (reading 'type'), stack=TypeError: Cannot read properties of undefined (reading 'type')
at /usr/src/app/server.js:86:17
yes
this is the error
That was a different error
error: request is not defined ...
Which one are you getting now?
error: Cannot read properties of undefined (reading 'type') message=Cannot read properties of undefined (reading 'type'), stack=TypeError: Cannot read properties of undefined (reading 'type')
at /usr/src/app/server.js:86:17
yes
this is the error
this one
So the event object is empty.
I believe this is because the catch (err) {} does not return, and the execution continues, even though .constructEvent() failed.
Could you please share the event ID in this case?
where i will get the event id?
Webhook Error: stripe is not defined
this shows on stripe side
Request
{
"id": "evt_1MrJJTKGE0YlJ015pKpHzXBF",
"object": "event",
"api_version": "2022-11-15",
"created": 1680174397,
"data": {
"object": {
"id": "cus_NcYQMe9sNp5Ykg",
"object": "customer",
"address": {
"city": null,
"country": "IE",
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"balance": 0,
"created": 1680174396,
"currency": "eur",
"default_source": null,
"delinquent": false,
"description": null,
"discount": null,
"email": "vickymodi951@gmail.com",
"invoice_prefix": "F056C389",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": null,
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
},
"name": "asdasd",
"phone": null,
"preferred_locales": [
"en-GB"
],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
},
"previous_attributes": {
"currency": null
}
},
"livemode": false,
"pending_webhooks": 1,
"request": {
"id": "req_Rf67WCVdOb9bPQ",
"idempotency_key": "28b2d061-babd-4c01-bb80-07309c2daddf"
},
"type": "customer.updated"
}
It means stripe variable is not defined on this line:
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
yes, i fixed this and reran
Webhook Error: Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the raw request body.Payload was provided as a parsed JavaScript object instead.
Signature verification is impossible without access to the original signed material.
Learn more about webhook signing and explore webhook integration examples for various fra
now, the error which was coming initially appears again
to solve this problem, i copied the code of webhook from stripe doc
as it appears
but this is coming again
You need to make sure your web framework does not parse the request body into JS object.
Could you please share the code where you register your endpoints?
Are you using body-parser or smth like this?
yes, i was using , but saw the document and put express.raw, let me share the code
app.post('/payment/webhook', express.raw({type: 'application/json'}), (request, response) => {
const stripe = require('stripe')('sk_test_51MjOxxKGE0YlJ015MyhdcyHYmscoOCEjkel7GUIY2eAKJL6BhQDe7oUDKB7MVoDKAOmuXND7Mt3Zw1KoNNsfgCBR00RBvdeO7R');
const sig = request.headers['stripe-signature'];
let event;
let endpointSecret= "whsec_Q3D4n3CwwiJEGOJmEsHDV2FS27lFvYAF";
try {
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
}
catch (err) {
response.status(400).send(Webhook Error: ${err.message});
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log('PaymentIntent was successful!');
break;
case 'payment_method.attached':
const paymentMethod = event.data.object;
console.log('PaymentMethod was attached to a Customer!');
break;
// ... handle other event types
default:
console.log(Unhandled event type ${event.type});
}
// Return a response to acknowledge receipt of the event
response.json({received: true});
});
Btw, it's best to define Stripe (and other dependencies) outside of the handler, in the top of the file.
yeah, i had the code organised, but then i have to put all at once, seeing the strip doc
just to make this working
Looks alright, could you please disable the body-parser (also for other endpoints) and see if the issue persists.
I understand. We just need this to help us identify the source of the problem
yes, its working
When you define your webhook endpoints you need to register it in the following order:
if i remove body parser
app.post('/stripe_webhooks', express.raw({ type: '*/*' }), handleWebhooks) // Webhook endpoint
app.use(express.json()) // Or body-parser
app.get('/', handleHomePage) // All other endpoints
...
Webhook endpoint needs to be registered before the body-parser, then it should work. Please try and let me know if this works.
yeah ,its working now, Thank you so much
one more question i have, so though i read the docs, but just to confirm, from webhook, i can do the db operation in my APP, this is the only way to update the records of strip into my db, is that right?
It's generally advices that do respond to Stripe as soon as possible, and do the DB operations later.
But you can always access your complete Stripe data via API. Webhooks are needed to notify your app of events at a specific time.