Using Next JS to Send a Post Request to Stripe and Add Multiple Items to Cart

Are you facing challenges with NEXT JS and trying to insert the content of a state variable "cart" into the body of a POST request to the STRIPE API? The format of the cart is [{id: 1, amount: 1}, {id: , amount: }.......]

You attempted placing items directly into the API handler (list_items), which worked. However, you're struggling to get your "cart" variable to display there. It seems like you need to include the items in the POST request itself. You tried incorporating an object and JSON.stringify as a property to a line_items variable, but it did not work. Could someone assist?

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 needs 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 });
  };

Answer №1

When establishing communication between your client and backend, there is flexibility in the structure you choose. However, it's crucial that your API request to Stripe for creating the session adheres to the expected format of the line_items API parameter (reference here).

To set pricing dynamically, you can utilize the price_data attribute for 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',
  });

Alternatively, you can opt to 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',
});

Answer №2

After some trial and error, I finally cracked the code on how to successfully create a POST request. The key is in structuring the body just right:

body: JSON.stringify({
        lineItems: props.cart.map((singleItem) => {
          return {
            price: <the_stripe_price_key_for_the_given_product>,
            quantity: <the_amount>,
          };
        }),
      })

I also made sure to include this crucial line in my API handler: const { lineItems } = req.body; and then set line_items: lineItems

As Nolan astutely pointed out, 'line_items' will indeed accept an array of objects (in my case, these are derived from mapping my 'cart' state variable).

Answer №3

To dynamically add multiple cart items to my API, I took a unique approach with my frontend implementation.

export default function PreviewPage() {
// This is just sample data that can be customized as needed
  const [formData, setFormData] = useState({
    codesToSend:[
      { price: 'price_1iasdhfwie8', quantity: 1 },
      { price: 'price_i383829wdff', quantity: 1 },
    ]
  });

const submitHandler = async(e) => {
  e.preventDefault();

  const response = await fetch('/api/checkout_sessions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({

      formData

    }),
  });

  if (!response.ok) {
    throw new Error('Network response was not ok');
  }

  const result = await response.json();
  console.log(result)

  // Redirect user to Stripe checkout session URL
  window.location.href = result.url;
};
In the backend, I send the redirect URL as a JSON response back to the frontend.
if (req.method === 'POST') {
  const { formData } = await req.body;
  console.log(formData)

  const codesToSend= formData.codesToSend
  
  try {

    const session = await stripe.checkout.sessions.create({
      line_items:
      codesToSend,
      mode: 'payment',
      success_url: `${req.headers.origin}/?success=true`,
      cancel_url: `${req.headers.origin}/?canceled=true`,
      automatic_tax: { enabled: true },
    });
    
    res.status(200).json({ url: session.url });
    } catch (err) {
    res.status(err.statusCode || 500).json(err.message);
  }
} 
else {
  res.setHeader('Allow', 'POST');
  res.status(405).end('Method Not Allowed');
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Show the text beside the textbox in ASP.NET MVC

Is there a way to display text next to a Text Box using jQuery without using validation? For example, if the Name field is left blank in a form and the Submit Button is clicked, the message should appear next to the Name Text Box. Instead of traditional ...

Tips for eliminating the space between strings after pasting them into vue2

Dealing with two input fields that require removing spaces between strings has proven to be a challenge. I initially attempted to use event.clipboardData.setData, but unfortunately, it did not yield the desired outcome. Afterward, I resorted to using this. ...

"Dynamic Addition of Textboxes to Webpages with the Help of jQuery

Currently, I am facing a challenge in adding a textbox to a webpage in ASP.NET MVC using jQuery. My goal is to have a button that, when clicked, appends a text box to the existing collection of Textboxes with a specified class. Below is the jQuery code sni ...

Tips for enhancing the efficiency of large-scale data Angular Material apps when using internet explorer

Our team is currently working on an Angular Material application that deals with a significant amount of data, ranging from 20 to 40 thousand rows. While this application performs smoothly in Chrome, we are experiencing slow performance issues in MSIE 11 ...

Having trouble with @here/maps-api-for-javascript in Next.js - it's not functioning

Can anyone help me understand why @here/maps-api-for-javascript is not functioning properly in my Next.js application and producing the following error message: import H from "@here/maps-api-for-javascript"; export default H; ^^^^^^ SyntaxErr ...

Transform JSON structure (Group data)

Here is the JSON object I am working with: [{ "name" : "cat", "value" : 17, "group" : "animal", }, { "name" : "dog", "value" : 6, "group" : "animal", }, { "name" : "snak", "value" : 2, "group" : "animal", }, { "na ...

Uploading images to an S3 bucket in base64 format using Angular 7

Within my Ionic 4 Angular 7 application, I am attempting to upload an image captured using the Cordova camera plugin. The output data from this Camera plugin is in the form of base64 image data. this.camera.getPicture(options).then((imageData) => { ...

How can you integrate jquery ajax in WordPress?

Recently, I started learning about jquery and have been following a tutorial on creating instant search using jquery. The tutorial can be found here. Now, I am trying to implement this on my WordPress site, but it seems like things work differently when d ...

Ways to showcase the accurate notification?

Within my cancelimage.php script, I have a block of PHP code that is supposed to display a cancel message: <?php $image_file_name = $_FILES['fileImage']['name'] ; echo "$image_file_name Upload was Canceled"; ?> The issue ...

Angular 2: Dynamically positioning content within a div overlay

I have made some customizations to a PrimeNg TabView and placed it inside a custom component to achieve the following: https://i.sstatic.net/mjWED.gif As you can see in the image, the tabview content is set to overflow-x: hidden to enhance the appearance ...

When the program is executed, immediately use .trigger('click')

There is a spelling game that features a grid filled with hidden words. The objective of the game is to spell out these words by clicking on the letters of the alphabet, aided by hints such as images and sounds. Players are given the word they need to spe ...

Using AJAX to send a POST request with the PHP $_FILES superglobal while preventing the default form submission with the onclick

Seeking to implement a photo upload form using an AJAX script that is currently in place. Currently, I have the html form with a file input field. Upon submission, there is an onclick event triggering "PostForm(); return false;" This action directs to a ...

Tips for transferring data from a JavaScript page to a C# page by utilizing Jquery

I am working with a dynamically created table that contains values in its selected rows. I need to extract all td.innerText values from each selected row and send them to a C# page, but I am unsure of the best approach. I attempted to use JSON, but I am ...

An easy way to ensure IE opens PDF links in an iframe in a new tab

I've encountered an issue while trying to display pdf files on an html page using an iframe. Here's my code snippet: <iframe src="testfile.pdf" width="100%" height="100%"></iframe> My problem is that the links within the pdf always ...

Encountering Problems Retrieving API Information in React.JS

Currently, I'm tackling a project involving a React web application and running into an issue while trying to display specific data retrieved from a mock API: Below is the code snippet in question: import React, { Component } from 'react'; ...

Center your attention on an AngularJS-created input element

I'm currently working on a todo list project using AngularJS and I am wondering if there is a method to automatically focus on an input box after creating it by clicking on a button. As of now, the save function in my controller looks like this: $sc ...

"Troubleshooting an Issue with Angular Modules Not Functioning Properly Alongside Dependent Modules

I understand how angular.module works quite well, but for some reason I can't seem to grasp this concept. Within my code, I have the following snippet: var app = angular.module("myApp", []) app.controller("MainCtrl", ...) However, my code only fun ...

What steps can I take to make sure a particular node is successfully loaded and ready for use using JavaScript/jQuery?

When making a reservation at a hotel using the CJS Chrome extension, I am attempting to extract information about available rooms and rates both when the page loads and when the user changes dates. My current method involves injecting JavaScript into the p ...

Can we determine if a user's operating system has disabled animations?

In my frontend project with React, I am incorporating an animation within a component. However, I want to cater to users who have disabled animations in their settings by replacing the animated content with a static image. Is there a method to detect if ...

Transferring items between different containers without using innerHTML

I've got an embedded <ul> within a (hidden) <aside id="idDetails">. How can I move the ul element from inside the aside and position it in a <div id="projectSide"> without using innerHTML? Any solutions in both plain JavaScript and j ...