jltraveler
jltraveler

Reputation: 3

I am building an amazon clone, i am at the step to add stripe for payment, my build has worked as expected until now this is for a final please assist

my console is giving me the non specific error "Uncaught (in promise) AxiosError" this is my checkout-session, in the terminal it seems to have a problem with the .map in the stripe session , ive verified the object format and made sure it was compliant with stripe standards, i am at a loss and hoping this may be a simple fix

import { useSession, useEffect } from 'next-auth/react' 
import React from 'react'
import Header from '../components/Header'
import Image from 'next/image'
import { useSelector } from 'react-redux'
import { selectItems, selectTotal } from '../slices/basketSlice'
import CheckoutProduct from '../components/CheckoutProduct'
import Currency from 'react-currency-formatter'
import { link, loadStripe } from '@stripe/stripe-js'
import axios from 'axios'

const stripePromise = loadStripe(`${process.env.stripe_public_key}`);

function checkout() {
    const { data: session } = useSession();
    const total = useSelector(selectTotal);
    const items = useSelector(selectItems);
    
    const createCheckoutSession = async () => {
        const stripe = await stripePromise

        const checkoutSession = await axios.post('/api/create-checkout-session', {
            items: items,
            email: session.user.email
        })
        const result = await stripe.redirectToCheckout({
            sessionId: checkoutSession.data.id
        })
        if (result.error) alert(result.error.message);
        
    };
    
    
  return (
      <div className='bg-gray-100'>
          <Header />
          <main className='lg:flex max-w-screen-2xl mx-auto'>
              {/* left */}
              <div className='flex-grow m-5 shadow-sm'>
                  <Image
                      src='https://links.papareact.com/ikj'
                      width={1020}
                      height={250}
                      objectfit='contain'
                  />
                  <div className='flex flex-col p-5 space-y-10 bg-white'>
                      <h1 className='text-3xl border-b pb-4'>{items.length === 0 ? 'Your Amazon Cart is Empty' : 'Shopping Cart'}</h1>
                      {items.map((item, i) => (
                          <CheckoutProduct
                              key={i}
                              id={item.id}
                              title={item.title}
                              rating={item.rating}
                              price={item.price}
                              description={item.description}
                              category={item.category}
                              image={item.image}
                              hasPrime={item.hasPrime}
                          />
                      ))}
                  </div>

              </div>

              {/* right */}
              <div className='flex flex-col bg-white p-10 shadow-md'>
                  {items.length > 0 && (
                      <>
                          <h2 className='whitespace-nowrap'>Subtotal({items.length} items):
                              <span className='font-bold'>
                              <Currency quantity={total} currency="USD"/>
                          </span>
                          </h2>
                          <button
                              onClick={createCheckoutSession}
                              role={link}
                              disabled={!session}
                              className={`button mt-2 ${
                              !session && 'from-gray-300 to-gray-500 border-gray-200 text-gray-300 cursor-not-allowed'}`}
                              >
                              
                              {!session ? 'Sign in to checkout' : 'Proceed to checkout'}
                          </button>
                          
                      </>
                  )}
                        </div>
          </main>
    </div>
  )
}

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

export default async(req, res) => {
    const { items, email } = req.body;

    const transformedItems = item.map((item) => ({
        quantity: 1,
        price_data: {
            currency: 'usd',
            unit_amount: item.price * 100,
            product_data: {
                name: item.title,
                description: item.description,
                images: [item.image]
            },
        },
    }));

    const session = await stripe.checkout.sessions.create({
        payment_method_types: ['card'],
        shipping_options: [`shr_1M2oWjIlRietTXvq5h1c8DDQ`],
        shipping_address_collection: {
            allowed_countries: ['USA']
        },
        items: transformedItems,
        mode: 'payment',
        success_url: `${process.env.HOST}/success`,
        cancel_url: `${process.env.HOST}/checkout`,
        metadata: {
            email,
            images: JSON.stringify(items.map((item) => item.image))
        }
    });
    res.status(200).json({ id: session.id })
}

Upvotes: 0

Views: 93

Answers (1)

toby
toby

Reputation: 622

It looks like your request to Stripe is not adhering to the expected structure, and I suspect looking at the logs in your Stripe dashboard will show a list of failed requests with detailed error messages on why they failed.

items is not a parameter when creating Checkout Sessions, line_items is what you're looking for.

shipping_address_collection.allowed_countries is expecting a two-letter country code, so you want to use US instead of USA.

Upvotes: 1

Related Questions