#paulocoronado
1 messages ยท Page 1 of 1 (latest)
Can you share your webhook endpoint code?
Sure! It is almost like the example code provided. This is the controller:
export async function webhook(req?: any, res?: any): Promise<void> {
const stripe = require('stripe')(process.env.STRIPE_API_KEY);
const sig = req.headers['stripe-signature'];
console.log('Webhook received!');
console.log(req.headers['content-type']); // This logs "application/json; charset=utf-8"
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_ENDPOINT_SECRET);
} catch (error) {
console.log(error);
res.status(400).send(`Webhook Error: ${error.message}`);
return;
}
console.log(`Event type ${event.type}`);
// Handle the event
switch (event.type) {
case 'customer.subscription.updated':
const subscription = event.data.object;
if (subscription.status === 'canceled') {
console.log(`Subscription canceled: ${subscription.id}`);
} else if (subscription.status === 'paused') {
console.log(`Subscription paused: ${subscription.id}`);
}
if (
subscription.status === 'active' &&
subscription.items &&
subscription.items.data.length > 0
) {
const subscriptionItem = subscription.items.data[0];
console.log(`Subscription upgraded to ${subscriptionItem.quantity} units/volume`);
}
break;
default:
console.log(`Unhandled event type ${event.type}`);
}
// Return a 200 response to acknowledge receipt of the event
return res.status(200).send();
}
And this is the router:
import { Router, text } from 'express';
import * as StripeController from '@controllers/stripe';
const router = Router();
router.route('/').post(text({ type: '*/*' }), StripeController.webhook); // <= This is the webhook
export default router;
Looking through your code. To knock out the other two bulletpoints, can you print out your stripe-signature header and confirm that it has a format like this:
Being t={some_time_stamp},v1={some_hex},v0={some_other_hex}```
And that your webhook secret starts with `whsec_` and **not** `we_`?
Yes! The stripe signature is a string like t=123456, v1=123456, v0=123456 and the webhook secret starts with whsec ๐ (knocked out)
I am using the StripeCLI and running: stripe trigger customer.subscription.updated
And the webhook secret I got from the dashboard "Test in a local environment" and then in the example code there is endpointSecret
Awesome, as long as you aren't doing a stripe listen webhook endpoint that should be the right secret
Express is pretty well known here for slightly modifying the request body. I haven't worked with it personally much but there are a couple of solutions that users have found for getting the raw request bodies. I know this GitHub issue has a couple of solutions that users found https://github.com/stripe/stripe-node/issues/341 I can look in to other solutions that have been found if you have already tried those
I found one issue, but I think it is not the only one. I was using the dev STRIPE_API_KEY, I updated to the prod ("sk_live..."), but the error persists
I'll try these!
Nice catch, I actually think the constructEvent function doesn't rely on your secret key but that is definitely something you would have run in to immediately in test mode
Pompey, just to know what I shoud expect:
console.log(req.headers['content-type']); // This log should not return "application/json; charset=utf-8", right?
Do you know what should be the expected output?
That should be the expected header. I see Content-Type: application/json; charset=utf-8 as the header that was sent for the events on my account as well
Hum, okk
Yes! We made it @keen lance! Thank you so much for your help!
I follow one of these solutions you shared and it worked perfectly! Thanks for helping me!
You were 10/10 ๐
Awesome! Glad I could help. Getting the raw request body in express can definitely be tricky