#florin_code

1 messages · Page 1 of 1 (latest)

sage walrusBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1318936073853866034

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.

hearty gale
#

the issue is explained better in my last thread

dusky drift
#

Hi, let me help you with this.

#

What error are you getting?

hearty gale
#

error: IntegrationError: Invalid value for stripe.confirmSetup(): elements should have a mounted Payment E…

dusky drift
hearty gale
#

the request hasn't been made

#

and I don't see any requests in the network tab

dusky drift
hearty gale
#

IntegrationError: Invalid value for stripe.confirmSetup(): elements should have a mounted Payment Element or Express Checkout Element.
at Sa (v3:1:408826)
at Ca (v3:1:410754)
at Ea (v3:1:411272)
at v3:1:505291
at async addPaymentMethodHandler (AddPaymentMethodModal.tsx:34:25)

#

const addPaymentMethodHandler = async () => {
if (!stripe || !elements) {
return;
}
console.log({ elements });

try {
  const { error } = await stripe.confirmSetup({
    elements,
    confirmParams: {
      return_url: 'https://example.com/account/payments/setup-complete',
    },
  });

  if (error) {
    setError(error.message);
  }
} catch (error) {
  console.log(error);
}

};

#

I am using the PaymentElement component from stripe
import { Elements, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js';

    <Elements stripe={stripePromise} options={options}>
      <PaymentElement />
    </Elements>
dusky drift
#

Where is addPaymentMethodHandler() called?

hearty gale
#

<Flex
onClick={handleBackdropClick}
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
>
<div className="w-96 rounded-lg bg-white p-6">
<div className="mb-4 text-lg font-semibold">{Add a payment method}</div>
<Elements stripe={stripePromise} options={options}>
<PaymentElement />
</Elements>

    <Flex className="mt-4 justify-center">
      <Button className="w-[100px]" onClick={addPaymentMethodHandler}>
        Add
      </Button>
    </Flex>

    <div className="mt-4 flex justify-end">
      <Button onClick={onClose}>Close</Button>
    </div>
    {error && <Text className="flex justify-center text-red-500">{error}</Text>}
  </div>
</Flex>
#

on a button inside that modal

dusky drift
#

I don't think the component that calls addPaymentMethodHandler is wrapped with <Elements>

#

<Elements> need to wrap a component that handles the payment, which in turn contains <PaymentElement>

hearty gale
#

I wrapped the entire modal component with elements

#

<Elements stripe={stripePromise} options={options}>
<Flex
onClick={handleBackdropClick}
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
>
<div className="w-96 rounded-lg bg-white p-6">
<div className="mb-4 text-lg font-semibold">{Add a payment method}</div>
<PaymentElement />

      <Flex className="mt-4 justify-center">
        <Button className="w-[100px]" onClick={addPaymentMethodHandler}>
          Add
        </Button>
      </Flex>

      <div className="mt-4 flex justify-end">
        <Button onClick={onClose}>Close</Button>
      </div>
      {error && <Text className="flex justify-center text-red-500">{error}</Text>}
    </div>
  </Flex>
</Elements>
#

but I wrapped it inside the modal component, not outside

#

e.g not like this

{showAddPaymentMethodModal && (
<AddPaymentMethodModal
onClose={() => {
setShowAddPaymentMethodModal(false);
}}
/>
)}

dusky drift
hearty gale
#

instead, inside AddPaymentMEthodModal I wrapped the entire jsx with elements

dusky drift
#

You need something like this:

<Elements stripe={stripePromise} options={options}>
  <CheckoutForm />
</Elements>

Where CheckoutForm is the component you shared above

hearty gale
#

yea, that seems to fix the issue

#

I see

#

Right now I have the clientSecret hardcoded like this const options: StripeElementsOptions = {
clientSecret: 'seti_1QXMdcKCK5mmw7xEvTUg0iIU_secret_RQD3r4MAbsr1tTSb2CyhllYFOh4jxZU',
};

My idea of the flow would be the following:
User clicks the Add payment method button -> HTTP Request to get a client secret for the setupIntent -> set the options object to use the client secret I got from the server -> open the modal
Is that a good approach ?