简体   繁体   中英

having problems with stripe/ redirecttocheckout

i have been trying to understand stripe for quite a while now. the major problem i am having is that i am a front end developer (with about a year of experience) and while i have some node.js/backend experience it is simply not enough to handle server processing of payments. i am going for the JAMstack serverless function approach using netlify. and thus far everything seems to be working out EXCEPT right at redirect to checkout i am getting the error "stripe.redirectToCheckout is not a function"

here is some of my code:

const inventory = require('./data/products.json');

exports.handler = async (event) => {
  const { sku, quantity } = JSON.parse(event.body);
  const product = inventory.find((p) => p.sku === sku);
  const validatedQuantity = quantity > 0 && quantity < 2 ? quantity : 1;

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ['card'],
    billing_address_collection: 'auto',
    shipping_address_collection: {
      allowed_countries: ['US'],
    },
    success_url: `${process.env.URL}/success`,
    cancel_url: process.env.URL,
    line_items: [
      {
        name: 'bitch',
        currency:'USD',
        amount: 299,
        quantity: validatedQuantity,
      },
    ],
  });

  return {
    statusCode: 200,
    body: JSON.stringify({
      sessionId: session.id,
      publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
    }),
  };
};

^^^^this is where i create the checkout through a serverless function although it took some time i have been able to create a lambda function through netlify, hide my public and private keys, create a stripe element, but i am just so confused as to why i am getting this error...

blow is where the error seems to be

//client sides
import Stripe from 'stripe'

export async function handleFormSubmission(event) {
  event.preventDefault();

  const form = new FormData(event.target);

  const data = {
    sku: form.get('sku'),
    quantity: Number(form.get('quantity')),
  };


  const response = await fetch('/.netlify/functions/create-checkout', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  }).then((res) => res.json());

  const stripe=Stripe(response.publishableKey);
  const {err}=await stripe.redirectToCheckout({
    sessionId:response.sessionId
  })


  if(err){
    console.log(err)
  }
}

also if it is any help here is where i am calling the function (handleformsubmit or whatever)

import React from 'react'
import {loadStripe} from "@stripe/stripe-js"
import './Checkout.css'
import {useState} from 'react'
import {Elements,
CardElement,
useStripe,
useElements} from '@stripe/react-stripe-js'
import axios from 'axios'
import {loadProducts} from './load-products'
import {handleFormSubmission} from './stripe-purchase'



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

const CheckoutForm=()=>{

  const stripe=useStripe()
  const elements=useElements()
  const handleSubmit=async(e)=>{

    e.preventDefault()
    if (!stripe || !elements) {
    // Stripe.js has not loaded yet. Make sure to disable
    // form submission until Stripe.js has loaded.
    return;
  }
  // Get a reference to a mounted CardElement. Elements knows how
   // to find your CardElement because there can only ever be one of
   // each type of element.
  const cardElement = elements.getElement(CardElement);

    const {error, paymentMethod}=await stripe.createPaymentMethod({
      type:'card',
      card:cardElement
    })

    loadProducts();

  }

  return (
    <form onSubmit={handleFormSubmission} method='POST'>
      <img className='checkoutImage' src='./logo2.png' />
      <label  class="ml-2  font-bold text-blue-700 text-md">
Enter card details below:
                        </label>
      <fieldset className="my-2 FormGroup">

         <div className="FormRow">
         <CardElement options={{
     style: {
       base: {
         fontSmoothing: 'antialiased',
         fontWeight: 900,
         iconColor: '#60A5FA',
         fontSize: '30px',
         color: '#374151',
         '::placeholder': {
           color: '#3182ce',
         },
       },
       invalid: {
         iconColor: '#EF4444',
         color: '#DC2626',
       },
       complete:{
         iconColor:'green',
         color: 'green',
       }
     },
   }}/>
         </div>
       </fieldset>


<div className='checkoutbuttonContainer'>
            <button type="submit" className="scoreButtons scoreButtonGrey flex justify-center rounded-md border border-gray-300 bg-pink-600 shadow-sm px-4 py-2 bg-white text-base font-medium text-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 hover:bg-pink-500 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                Submit Payment <span className='priceLine'></span> <span className='price'> </span>
                </button>
                </div>
                </form>

  )
}

const StripeSetup = () => {
  return (
    <div><Elements stripe={stripePromise}><CheckoutForm /></Elements></div>
  )
}

export default StripeSetup

this is the first time in a while i have felt really overwhelmed by new material. im not even sure if i'm learning at a proper pace anymore nor even learning as much as just copying in code i find online lol... but this did take a good amount of work on my end nonetheless. would really love if someone could help. BTW i am now realizing that i created stripe elements etc which i don't even know if are necessary when using redirect to checkout as this is supposed to lead the client to a stripe checkout? can someone clarify all this for me. and please help if they can! thanks so much in advance

ONE last thing i wanted to say. i do not need a cart, products listing or anything. this is a one time payment for 2.99 and it will lead to the next page is the user submits the payment. not sure if that changes anything but figured the more details the better

Problem was in AWFUL documentation as well as netlify's instructions.

i needed to call loadstripe again first:

  const stripe=await loadStripe(response.publishableKey);
  const {err}=await stripe.redirectToCheckout({
    sessionId:response.sessionId
  })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM