Search code examples
reactjsstripe-paymentsfetch-apie-commerce

Error when fetching with stripe: Uncaught IntegrationError: stripe.redirectToCheckout: You must provide one of lineItems, items, or sessionId


I am currently building an Ecommerce store with React and Stripe and learning through it. Now I have reached the checkout with Stripe, but there is a problem: 'Uncaught (in promise) IntegrationError: stripe.redirectToCheckout: You must provide one of lineItems, items, or sessionId'. Also my const data is undefined.

This project is from the platform Youtube for learning to build ecommerce shops. Here is the link: Video (Section: 'Stripe')

Here are the code snippets:

Cart.jsx: `

const handleCheckout = async () => {
    const stripe = await getStripe();

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

    if(response.statusCode === 500) return;
    const data = await response.json();
    console.log("DATA", data.id);

    toast.loading('Redirecting...');
    stripe.redirectToCheckout({ sessionId: data.id }); 
  }

`

getStripe.js: `

import { loadStripe } from '@stripe/stripe-js'

let stripePromise;

const getStripe = () => {
    if(!stripePromise) {
        stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
    }

    return stripePromise;
}

export default getStripe;

`

stripe.js: `

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

export default async function handler(req, res) {
  if (req.method === 'POST') {
    console.log("Body:", req.body.cartItems);
    try {
      const params = {
        submit_type: 'pay',
        mode: 'payment',
        payment_method_types: ['card'],
        billing_address_collection: 'auto',
        shipping_options:[
            { shipping_rate: 'shr_1MD7qfEkf37UoY2b8O1odVCL' },
            { shipping_rate: 'shr_1MD7sXEkf37UoY2bSHqshySN' }
        ],
        line_items: [
          {
            //Provide the exact Price ID (for example, pr_1234) of the product you want to sell
            price: '{{PRICE_ID}}',
            quantity: 1,
          },
        ],
        success_url: `${req.headers.origin}/?success=true`,
        cancel_url: `${req.headers.origin}/?canceled=true`,
      }

      //Create Checkout Sessions from body params.
      const session = await stripe.checkout.sessions.create(params);
      res.redirect(303, session.url);
    } catch (err) {
      res.status(err.statusCode || 500).json(err.message);
    }
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}

`

The question what I ask myself: why it works in the video, but not for me, although it is the same. Already compared the code too. Is there anything I have forgotten?


Solution

  • There are 2 ways to integrate Checkout Session

    1. Redirect to Checkout Session from backend
    2. Return the Checkout Session Id from backend, and let frontend redirect using redirectToCheckout

    You are mixing up both ways by also calling res.redirect(303, session.url) on backend and stripe.redirectToCheckout({ sessionId: data.id }) on frontend.

    My suggestion is you should use 1. as it's newer and recommended integration today. Simply remove the call redirectToCheckout in frontend.