NextJS Stripe Question regarding multiple use cases of Elements

21 views Asked by At

I'm in the middle of building an ecommerce website using NextJS (Typescript) and Stripe. Everything is going really well besides this one point...

I have my entire application wrapped in an Elements component:-

return (
    <div className='main-container'>
      <Analytics />

      <GoogleReCaptchaProvider
        reCaptchaKey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY!}

      >
        <Elements stripe={stripePromise}>
          <UserProvider>

            <CartProvider>

              <ClerkProvider {...pageProps}>

                <Layout {...pageProps}>
                  <Component {...pageProps} />

                </Layout>
              </ClerkProvider>
            </CartProvider>
          </UserProvider>
        </Elements>
      </GoogleReCaptchaProvider>

      {/* <Footer /> */}
    </div>
  )
};

This worked fine for standard 'createCheckoutSession' scenarios, but I ran into some issues when trying to reutilise for express checkout (one product on a specific page). I found that I had to recreate the Elements component at a page level, otherwise it would complain it didn't exist (despite being within the scope of the provider), presumably due to lack of 'options' being passed to the parent component, which are impossible to know at a layout level.

My problems:-

ExpressCheckoutElement total doesn't take into account the shipping select, despite being provided and available.

Having to define 'Elements' twice - meaning that when I looked into the solution of:-

const onShippingRateChange = ({ resolve, shippingRate }: StripeExpressCheckoutElementShippingRateChangeEvent) => {
        console.log(shippingRate);
        console.log(price);
        const s = (price * 100) + shippingRate.amount;
        console.log(s);
        const resolveDetails = {
            lineItems: [{
                amount: s,
                name: name,
            }],

        };
        if (!elements) return;
        elements.update({ amount: s })
        setLineItems(resolveDetails.lineItems);
        resolve(resolveDetails);
    }

Using 'useElements' to update the amount - thinking this would fix the total not being accommodated, I then get the following error:-

IntegrationError: Invalid value for elements.update(): `amount` is only applicable when a `mode` is set.

This sounds like useElements is picking up my 'top level' Elements provider, which cannot have a 'mode' nor 'options' because they're specific to one item on one page, and cannot be known at top level.

Any suggestions please?

Thanks!

0

There are 0 answers