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

Time:10-16

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,
  });
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

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 });
  };
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I figured out how to make the POST request. The body has to look like this:

body: JSON.stringify({
        lineItems: props.cart.map((singleItem) => {
          return {
            price: <the_stripe_price_key_for_the_given_product>,
            quantity: <the_amount>,
          };
        }),
      })
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

included the following line in the API handler: const { lineItems } = req.body; and set line_items: lineItems

So, just as Nolan pointed out, line_items will accept an array of objects (in my case generated through mapping of my 'cart' state variable).

CodePudding user response:

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',
});
  • Related