#paulocoronado

1 messages ยท Page 1 of 1 (latest)

next patioBOT
silent pawn
#

Can you share your webhook endpoint code?

next patioBOT
feral kraken
#

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;
keen lance
#

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_`?
feral kraken
#

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

keen lance
#

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

GitHub

If you use in your express app bodyParser.json() for all routes, and then have a dedicated route for stripe's webhook, then the second call to bodyParser.json({verify: ...}) as done in the exam...

feral kraken
#

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

keen lance
#

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

feral kraken
#

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?

keen lance
#

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

feral kraken
#

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 ๐Ÿ™‚

keen lance
#

Awesome! Glad I could help. Getting the raw request body in express can definitely be tricky

feral kraken
#

Yes, specially with Express ๐Ÿ˜„

#

Feel free to close this thread! Thanks so much, again!