javascriptpostnext.jsstripe-payments

Next JS : Make a Post Request to Stripe in Order to Add Multiple Items to Cart


NEXT JS: I am trying to put the content of a state variable "cart" into the body of the POST request to the STRIPE API. Cart has the format [{id: 1, amount: 1}, {id: , amount: }.......]

I tried putting items directly into the API handler (list_items) and that works. But I cannot get my "cart" variable to show up there, so I guess I have to include the items in the POST request itself. Have tried getting that to run (including an object there and JSON.stringify as property to a line_items - variable, but to no avail. Maybe somebody could help me out?

API handler:

import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

export default async function handler(req, res) {

  if (req.method !== 'POST') {
    return res.send({
      error: 'Method need to be POST',
    });
  }
  const domainURL = 'http://localhost:3000';

  // const { quantity, mode, productKey } = req.body;

  const pmTypes = ['card'];
  const session = await stripe.checkout.sessions.create({
    payment_method_types: pmTypes,
    mode: 'payment',
    locale: 'en',
    line_items: the_variable????,

    success_url: `${domainURL}/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${domainURL}/cart`,
  });

  res.send({
    sessionId: session.id,
  });
}

POST request :

 const stripeLoader = loadStripe(props.pk);
  const redirectToCheckout = async () => {
    const stripeClient = await stripeLoader;

    const { sessionId } = await fetch('api/checkout_sessions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body : {????}
    }).then((res) => res.json());

    stripeClient.redirectToCheckout({ sessionId });
  };


Solution

  • You can use any structure you like to communicate between your client and backend, but your API request to Stripe to create the session must conform to the line_items API parameter expected shape (docs).

    You can either define pricing on the fly with price_data on each item:

    const session = await stripe.checkout.sessions.create({
        payment_method_types: ['card'],
        line_items: [
          {
            price_data: {
              currency: 'usd',
              product_data: {
                name: 'T-shirt',
              },
              unit_amount: 2000,
            },
            quantity: 1,
          },
        ],
        mode: 'payment',
        success_url: 'https://example.com/success',
        cancel_url: 'https://example.com/cancel',
      });
    

    Or you can use predefined prices:

    const session = await stripe.checkout.sessions.create({
      payment_method_types: ['card'],
      line_items: [{
        price: 'price_123',
        quantity: 1,
      },{
        price: 'price_456',
        quantity: 3,
      }],
      mode: 'payment',
      success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
      cancel_url: 'https://example.com/cancel',
    });