'how to fix stripe webhook 503 error in nodejs

I developed and deployed a web app on Heroku and I really need help with the stripe webhook. So in short, I created a webhook in order to grab data from successful checkout session payment to create a new travel booking in my DB, and send email to users (this is the purpose), before sharing with you my code snippets, I have to tell you that I grab the code from stripe DOCS and the 2nd second the payment event was successful but when the "success_url" is hited the RESPONSE is an error 503, check the log from Heroku logs:

2022-02-19T23:20:31.394781+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/my-booked-travels" host=goaheadtravel.herokuapp.com request_id=982c4872-db8b-4360-ae23-14506b3465df fwd="***" dyno= connect= service= status=503 bytes= protocol=https

I used nodejs so in order to parse the req.body as a row I implement the post method on my path like so:

// In order to parse the req.body as a raw
app.post(
  '/webhook-checkout',
  express.raw({ type: "*/*", limit: "50mb" }),
  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());

the remain snippet is creating a 'session' and 'webhookcheckout' handlers like so:

exports.getCheckoutStripe = catchAsyncHandler( async(req, res, next) => {
    const travel = await Travel.findById(req.params.travelId);

    // 2) Create checkout session as request
  const session = await stripe.checkout.sessions.create({
        // Information about the checkout session
    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,

        // Information about the travel
    line_items: [
      {
        name: `${travel.name} Travel`,
        description: travel.summary,
        images: [`${req.protocol}://${req.get('host')}/img/travels/${travel.imageCover}`],
        amount: travel.price * 100, // the amount is expected to be in cent 1.00$
        currency: 'usd',
        quantity: 1
      }
    ]
  });

  // render the checkout session as response
  res.status(200).json({
    status: 'success',
    session
  });
});
const createBookingCheckout = async session => {
  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 });
}

exports.webhookCheckout = (req, res, next) => {
  const sig = req.headers['stripe-signature'];

  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      process.env.STRIPE_WEBHOOKS_SECRET
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle the event
  switch (event.type) {
    case 'checkout.session.completed':
      const session = event.data.object;
      createBookingCheckout(session);
      // Then define and call a function to handle the event checkout.session.completed
      break;
    // ... handle other event types
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  // Return a 200 response to acknowledge receipt of the event
  res.status(200).json({ received: true });
};


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source