How can I get the product ID in Stripe webhook

Viewed 2005

I'm using the stripe webhook to add the purchased products to my sql database when the checkout.session.completed happens, here is my code:

router.post('/webhook', bodyParser.raw({ type: 'application/json' }), (request, response) => {
const sig = request.headers['stripe-signature'];
let event;

try {
    event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
} catch (err) {
    return response.status(400).send(`Webhook Error: ${err.message}`);
}

// Handle the checkout.session.completed event
if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
//here i want to increment the product's buy counter by 1 in the database but stripe only gives name and price, which are not unique, so i need the product id

}

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

I'm using Sequelize so i need to execute something like this when checkout.session.completed happens:

products.findOne({
   where: product_id: the purchased product id
}).then(product => {
   product.update({ buy_counter: product.buy_counter++})
}

Any way I can find the product ID of the products in the Stripe session

2 Answers

The products purchased during a given Checkout Session are available on the Session's line_items property:

https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-line_items

Note that the line_items aren't included by default and you'll need to retrieve the checkout session in a separate request and specify that you want the line_items to be included in the response. You can find an example of this in the Stripe docs here:

https://stripe.com/docs/expand#includable-properties

For example:

      // Handle the checkout.session.completed event
      if (event.type === "checkout.session.completed") {
        const session = event.data.object;
        // Note that you'll need to add an async prefix to this route handler
        const { line_items } = await stripe.checkout.sessions.retrieve(
          session.id,
          {
            expand: ["line_items"],
          }
        );

        //here i want to increment the product's buy counter by 1 in the database but stripe only gives name and price, which are not unique, so i need the product id
      }

What you need to do is to add metadata object while creating the session as below

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ['card'],
    metadata: {
        order_id: parsedOrder._id,
    },
    line_items: [
      {
        price_data: {
          currency: 'usd',
          product_data: {
            
            name: 'Stubborn Attachments',
            images: ['https://i.imgur.com/EHyR2nP.png'],
          },
          unit_amount: _orders_total_value * 100,
        },
        quantity: 1,
      },
    ],
    mode: 'payment',
    success_url: `${YOUR_DOMAIN}/success`,  // can send in the id of the order if already created with the property of the payment pending
    cancel_url: `${YOUR_DOMAIN}/cancel`, 
  });

you shall be able to recieve this metadata object in the webhook session object


    id: 'cs_test_a1e81BPpUyROiKasfagWeqWrwEwWitAggwreSW6zjtoT6PMtbHaoMZ985TLi',
    object: 'checkout.session',
    allow_promotion_codes: null,
    amount_subtotal: 4000,
    amount_total: 4000,
    billing_address_collection: null,
    cancel_url: 'http://localhost:4200/cancel',
    client_reference_id: null,
    currency: 'usd',
    customer: 'cus_JQAHHil3j2iEbc',
    customer_details: { email: 'customeremail@email.com', tax_exempt: 'none', tax_ids: [] },
    customer_email: null,
    livemode: false,
    locale: null,
    metadata: { order_id: '60910a8b62b44e8de4fe0adb' },
    mode: 'payment',
    payment_intent: 'pi_1InJwNDCa2d3q3OjcblBYNql',
    payment_method_options: {},
    payment_method_types: [ 'card' ],
    payment_status: 'paid',
    setup_intent: null,
    shipping: null,
    shipping_address_collection: null,
    submit_type: null,
    subscription: null,
    success_url: 'http://localhost:4200/success',
    total_details: { amount_discount: 0, amount_shipping: 0, amount_tax: 0 }

you can replace the order_id with your product_id or may be you can add any other useful information in the metadata.

Related