Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid value for stripe.confirmPayment(): elements should have a mounted Payment Element

I'm trying to integrate a Stripe payments page using the React "Elements". I'm following the tutorial from https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#web-submit-payment and I've gotten to step 5, "Submit the payment to Stripe". My code doesn't look much different from the example, but whenever I try to submit a payment this error:

Invalid value for stripe.confirmPayment(): elements should have a mounted Payment Element.

Thrown from stripe.confirmPayment. I've included the <Elements/> and <PaymentElement/> on the page, and passed the return value from useElements() so I'm really not sure what I'm missing.


Here's my checkout form:

function StripeCheckoutForm({paymentIntent,booking}: StripeCheckoutFormProps) {
    const stripe = useStripe();
    const elements = useElements();
    const [confirming,setConfirming] = useState(false)

    const handleSubmit = async (ev: FormEvent<HTMLFormElement>) => {
        ev.preventDefault();

        if (!stripe || !elements) {
            notifyWarning("Still loading. Please wait a few seconds and then try again.");
            return;
        }

        setConfirming(true)
        try {
            const {error} = await stripe.confirmPayment({
                //`Elements` instance that was used to create the Payment Element
                elements,
                confirmParams: {
                    return_url: resolveRoute('customerPaymentReceived',{key:booking.key}),
                },
            })
            if(error) {
                notifyError(error.message)
                setConfirming(false)
            }
        } catch(error) {
            setConfirming(false)
            if(error?.message) {
                notifyError(error.message)  // <-- error shown here
            } else {
                notifyError("Something went wrong");
            }
        }
    }

    return (
        <form onSubmit={handleSubmit}>
            <PaymentElement/>
            <BlockSpacer height="1rem"/>
            <ActionButton disabled={!stripe || !elements || confirming} type="submit" className="btn-phone btn-fullwidth">Pay {paymentIntent.amountFormatted}</ActionButton>
        </form>
    )
}

And that form is inside this component, similar to the example shown in step 4:

import {Elements as StripeElements} from '@stripe/react-stripe-js';
import {useStripe, useElements, PaymentElement} from '@stripe/react-stripe-js';

function StripePaymentForm({stripeAccountId,paymentIntent,booking}: StripePaymentFormProps) {
    const options = {
        clientSecret: paymentIntent.clientSecret,
        loader: 'always',
    }
    return (
        <StripeElements stripe={getStripeConnect(stripeAccountId)} options={options}>
            <StripeCheckoutForm paymentIntent={paymentIntent} booking={booking}/>
        </StripeElements>
    )
}

The only thing I can see that's different is that I'm using a Connect account, so I'm passing in account ID in when I load Stripe. getStripeConnect is basically

loadStripe(STRIPE_PUBLIC_KEY, {stripeAccount: CONNECTED_ACCOUNT_ID})

You can see the React component tree here if it helps:

enter image description here

What am I missing?


I'm guessing this stems from useElements() is not finding any elements:

enter image description here

But I still don't know why.

like image 538
mpen Avatar asked Oct 21 '25 11:10

mpen


2 Answers

In my case, the issue is that during the stripe request stripe.confirmPayment, the component that has the Elements component must be being rendered on page.

If you remove this component from the DOM to show a loading animation during the request, for example, the error will be thrown.

like image 139
Bruno Oliveira Avatar answered Oct 23 '25 02:10

Bruno Oliveira


I believe it's a recent bug in react-stripe-js:

https://github.com/stripe/react-stripe-js/issues/296

like image 44
user19183758 Avatar answered Oct 23 '25 01:10

user19183758



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!