I want to use Stripe PaymentElement(form) with ExpressCheckoutElement(apple pay, google pay) in the same page. They integrate with each other well. With ExpressCheckoutElement the PaymentElement shows the express options instead of it's own (apple pay, google pay).
Library: React Stripe. js
const stripe = loadStripe(key);
const options = {
clientSecret: 'xxxx',
};
const App = () => (
<Elements stripe={stripe} options={options}>
<StripeExpressCheckoutElementWithPaymentElementComponent />
</Elements>
);
const StripeExpressCheckoutElementWithPaymentElementComponent = ({...}) => {
const stripe = useStripe();
const elements = useElements();
const onConfirm = async () => {
...
const { error } = await stripe.confirmPayment({
elements,
confirmParams: { return_url: '' }
});
...
}
const onSubmit = async (e) => {
e.preventDefault();
...
const { error } = await stripe.confirmPayment({
elements,
confirmParams: { return_url: '' }
});
...
}
...
return (
<>
<ExpressCheckoutElement onConfirm={onConfirm} />
<form onSubmit={onSubmit}>
<PaymentElement />
</form>
</>
)
}
The problem: Error response from ExpressCheckoutElement (apple pay, for example) triggers the PaymentElement validation and errors are displayed on the form. The received error is a card error and thus shows on the PaymentElement. I'd like to not trigger PaymentElement validation.
The solution: Use 2 Elements providers
const stripe = loadStripe(key);
const options = {
clientSecret: 'xxxx',
};
const App = () => (
<>
<Elements stripe={stripe} options={options}>
<StripeExpressCheckoutElementComponent />
</Elements>
<Elements stripe={stripe} options={options}>
<StripePaymentElementComponent />
</Elements>
</>
);
Disable google / apple pay for PaymentElement
<PaymentElement
options={{
paymentMethodOrder: ['card'],
wallets: { applePay: 'never', googlePay: 'never' },
}}
/>
Is using 2 Elements a valid option or I'm doing this wrong in the first place?
Your approach seems valid to me. It is a bit unusual to have two Elements providers on the same page like this, so there's a slightly-increased risk of running into edge-case bugs surrounding that, but other than that I think this is perfectly fine.
If you haven't already you should contact Stripe support and make a feature request to improve this behavior, or at least have more control over it.