Stripe webhook using CLI fails to POST. Returns "Client.Timeout exceeded while awaiting headers"

Viewed 1742

I'm trying to implement basic stripe checkout webhook with CLI as described here: https://stripe.com/docs/payments/checkout/fulfill-orders

Only difference is instead of bodyParser.raw({type: 'application/json'}), I'm using express.json({ type: 'application/json' }).

import express from 'express'
import dotenv from 'dotenv'
import connectDB from './config/db.js'
import Order from './models/orderModel.js'
import Stripe from 'stripe'

dotenv.config()

connectDB()

const app = express()

const stripe = new Stripe(`${process.env.STRIPE_SECRET_KEY}`)

app.post('/api/create-stripe-checkout-session', async (req, res) => {
  const order = await Order.findById(req.body.orderId)

  if (order) {
    const session = await stripe.checkout.sessions.create({
      success_url: 'http://localhost:3000/success?id={CHECKOUT_SESSION_ID}',
      cancel_url: 'http://localhost:3000/cancel',
      payment_method_types: ['card'],
      mode: 'payment',
      line_items: [
        {
          price_data: {
            currency: order.currency,
            unit_amount: (order.totalPrice * 100).toFixed(0),
            product_data: {
              name: `Order ID:${req.body.orderId}`,
            },
          },
          quantity: 1,
        },
      ],
    })
    res.json({ url: session.url })
  } else {
    res.status(404)
    throw new Error('Order not found')
  }
})

app.post('/webhook', express.json({ type: 'application/json' }), (req, res) => {
const payload = req.body
console.log('Got payload: ' + payload)
res.status(200)
})

const PORT = process.env.PORT || 5000

app.listen(
  PORT,
  console.log(`server running in ${process.env.NODE_ENV} mode on port ${PORT}`)
)

Response in CLI terminal: Response I get in CLI terminal

Response in server terminal: Response in server terminal

When I add signature verification as described in above stripe doc, POST request fails with error 400. I have tried removing unrelated middleware and testing in Linux and Windows but it gives the same result.

Stripe Node version: 8.163.0

Stripe CLI version: 1.6.4

1 Answers

Adding .end() in the webhook solved the problem. Stripe should update their docs. I spent two days trying to solve this.

Correct code:

app.post('/webhook', express.json({ type: 'application/json' }), (req, res) => { 
const payload = req.body
console.log('Got payload: ' + payload)
res.status(200).end()                    //add .end() to solve the issue
})
Related