stripe.confirmPayment() 的无效值:元素应该有一个已安装的支付元素

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

我正在尝试使用 React“Elements”集成 Stripe 支付页面。我正在按照 https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#web-submit-payment 中的教程进行操作,我已经进行到第 5 步,“向 Stripe 提交付款”。我的代码看起来与示例没有太大区别,但每当我尝试提交付款时,都会出现此错误:

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

stripe.confirmPayment 抛出。我在页面上包含了 <Elements/><PaymentElement/>,并从 useElements() 传递了 return 值,所以我真的不确定我错过了什么。


这是我的结帐表格:

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>
    )
}

并且该表单位于此组件内部,类似于步骤 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>
    )
}

我唯一能看到的不同之处在于我使用的是 Connect 帐户,因此我在加载 Stripe 时传入了帐户 ID。 getStripeConnect 基本上是

loadStripe(STRIPE_PUBLIC_KEY, {stripeAccount: CONNECTED_ACCOUNT_ID})

如果有帮助,您可以在这里查看 React 组件树:

我错过了什么?


我猜这源于 useElements() 没有找到任何元素:

但我还是不知道为什么。

我相信您的 loadStripe() 承诺在传递给 Elements 提供者时并未得到解决,因此 useElements returns 为 null。提前加载它或等待它,它应该可以解决您的问题。

我认为这是 react-stripe-js 中最近的一个错误:

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