#moez - webhook
1 messages · Page 1 of 1 (latest)
Hey there, can we chat in this thread?
Would you mind moving the snippet in here please? I'll get back to you as soon as i can
ok
exports.getCheckoutStripe = async(req, res, next) => {
const travel = await Travel.findById(req.params.travelId);
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
success_url: `${req.protocol}://${req.get('host')}/my-booked-travels`,
cancel_url: `${req.protocol}://${req.get('host')}/travel/${travel.slug}`,
customer_email: req.user.email,
client_reference_id: req.params.travelId,
line_items: [
{
name: `${travel.name} Travel`,
description: travel.summary,
images[
`${req.protocol}://${req.get('host')}/img/travels/${travel.imageCover}`
],
amount: travel.price * 100,
currency: 'usd',
quantity: 1
}
]
});
res.status(200).json({
status: 'success',
session
});
});
const bookingBasedCheckout = async (session) => {
try {
const travel = session.client_reference_id;
const user = (await User.findOne(
{ email: session.customer_email })
).id;
const price = session.line_items[0].amount / 100;
await Booking.create({ travel, user, price });
} catch (error) {
console.log(error.message)
}
}
exports.webhookCheckout = (req, res) => {
const signature = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
process.env.STRIPE_WEBHOOKS_SECRET
);
} catch(error) {
return res.status(400).send(`error: ${error.message}`)
}
if (event.type === 'checkout.session.completed') {
bookingBasedCheckout(event.data.object);
}
res.status(200).json({ recieved: true })
}
My issue is I'm able to create a new booking with every successful payment
so I'm already in prod mode
I print my logs in terminal to see what is going on and I find that the response to the webhooks was with 400 status code
2022-02-15T20:29:24.843700+00:00 heroku[router]: at=info method=POST path="/webhook-checkout" host=goaheadtravel.herokuapp.com request_id=a1092076-de76-4a05-be25-c48c5f5a792d fwd="54.187.174.169" dyno=web.1 connect=0ms service=3ms status=400 bytes=814 protocol=https
Was this endpoint working in testmode?
the webhook handler endpoint i mean, with the signature verification
Do you have any example event IDs I can review?
I used the test mode already
Ok, and was it working there?
the payment passed successfully but the when the webhook url hited there's no booking created
"cs_test_a1gYZnIzXd6cML1EFcJq3Cmc7QzjR4Qe7oLAoN9NY3GHa38Bex6TgXY1DK",
I grab the id above from a failed log
I mean was this webhook endpoint working in test mode like you expected?
Were you able to create the booking from the events in test mode?
Can you share some specific failed event delivery IDs like evt_1234? or successful ones form test mode?
Can you copy one of those event IDs here?
It looks like the delivery is still pending in test mode, too
Which likely means this was not working in test either
ok
I'd suggest exploring further in test mode to understand what is failing, and where
{
"object": {
"id": "cs_test_a1bCZIN7IPMQWMA4A6XbtyL1Jb3DePqmoWojlKyGAKdMnkhHemUFYBQJNV",
"object": "checkout.session",
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": 39700,
"amount_total": 39700,
"automatic_tax": {
"enabled": false,
"status": null
},
"billing_address_collection": null,
"cancel_url": "https://goaheadtravel.herokuapp.com/travel/venice-by-night",
"client_reference_id": "5c88fa8cf4afda39709c2951",
"consent": null,
"consent_collection": null,
"currency": "usd",
"customer": "cus_L9rwYNwkJjGLGs",
"customer_creation": "always",
"customer_details": {
"email": "eliana@example.com",
"phone": null,
"tax_exempt": "none",
"tax_ids": [
]
},
"customer_email": "eliana@example.com",
"expires_at": 1645045439,
"livemode": false,
"locale": null,
"metadata": {
},
"mode": "payment",
"payment_intent": "pi_3KTYBnA1H3VpG3Rz1RGzUSHH",
"payment_link": null,
"payment_method_options": {
},
"payment_method_types": [
"card"
],
"payment_status": "paid",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": null,
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [
],
"shipping_rate": null,
"status": "complete",
"submit_type": null,
"subscription": null,
"success_url": "https://goaheadtravel.herokuapp.com/my-booked-travels",
"total_details": {
"amount_discount": 0,
"amount_shipping": 0,
"amount_tax": 0
},
"url": null
}
}
Usually in Node a common issue is modification of the raw request body before verifying signature
Those event lines you see with the "Pending" message
Click in to one of them, and you should be able to see your server response body shown
error: 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
Is your server using express for serving the endpoints, and do you have json body parsing enabled?
yes, but I used the express.raw in post request before json body parsing enabeling
// use the stripe webhook in order to create a new booking travel
app.post(
'/webhook-checkout',
express.raw({ type: 'application / json' }),
bookingController.webhookCheckout
);
// Body parser, reading data from body into req.body
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ extended: true, limit: '10kb' }));
app.use(cookieParser());
Hmm ok, then you'll need to confirm all the inputs to constructEvent with some additional logging.
Making sure you have the raw request body (it should contain extra whitespace), the signature, and the signing secret
It's also easy to mix up signing secrets if you're testing multiple endpoints or live and test, as those secrets are specific to each endpoint
Looking at your account, you only have a test mode endpoint configured
So in test mode you'd expect the signing secret to be whsec_T7...Cgrf
but in order to support live mode you'd need to create a live mode endpoint in your dashboard, which will have a new/unique signing secret