I am trying create a custom Stripe Checkout according to the docs here. (Web/React/Node) https://stripe.com/docs/payments/quickstart
Following the docs I am successful in creating a paymentIntent and charging.
The problem is when I add a connected account to the stripe instance, the <PaymentElement>
refuses to show. I can confirm on the Stripe dashboard that indeed a payment intent is created successfully in the connected account for the correct customer existing in said connected account, I am successfully passing back the payment intent id, but the element just won’t show. Just as a sanity check, when I remove the connected account, it works as expected.
I am following here https://stripe.com/docs/connect/enable-payment-acceptance-guide?elements-or-checkout=elements&html-or-react=react on how to add the connected account.
import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component's render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_NTv6FvtshDhM7cWcoiIvFk1w', { stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}' }); function App() { return ( <Elements stripe={stripePromise}> <CheckoutForm /> </Elements> ); }; ReactDOM.render(<App />, document.getElementById('root'));
Here is my implementation
import React, { useState, useEffect } from "react"; import { loadStripe } from "@stripe/stripe-js"; import { Elements } from "@stripe/react-stripe-js"; import CheckoutForm from "./CheckoutForm"; export default function Checkout({ stripeAccount, amount, firstName, lastName, email, }) { // Make sure to call loadStripe outside of a component’s render to avoid // recreating the Stripe object on every render. // This is your test publishable API key. const stripePromise = loadStripe( "pk_test_1234", stripeAccount ); const [clientSecret, setClientSecret] = useState(""); useEffect(async () => { // Create PaymentIntent as soon as the page loads fetch("http://localhost:3000/api/app/createPaymentIntent", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ stripeAccount, amount, firstName, lastName, email, }), }) .then((res) => res.json()) .then((data) => setClientSecret(data.clientSecret)); }, []); const appearance = { theme: "stripe", labels: "floating", variables: { fontLineHeight: "50px", borderStyle: "solid", borderWidth: "2px", borderColor: "#efefef", backgroundColor: "#000", boxShadow: "0px 16px 32px 0px rgb(0 0 0 / 6%)", borderRadius: "30px", padding: "0 25px", marginBottom: "20px", }, }; const options = { clientSecret, appearance, }; return ( <div className="Checkout"> {clientSecret && ( <Elements options={options} stripe={stripePromise}> <CheckoutForm /> </Elements> )} </div> ); }
//node
// Create a PaymentIntent with the order amount and currency const paymentIntent = await stripe.paymentIntents.create( { customer: stripeCustomer.id, amount: amount * 100, currency: "usd", automatic_payment_methods: { enabled: true, }, }, { stripeAccount, } );
//node NOTE: if I comment out the connected account like below, then it works fine.
// Create a PaymentIntent with the order amount and currency const paymentIntent = await stripe.paymentIntents.create( { // customer: stripeCustomer.id, amount: amount * 100, currency: "usd", automatic_payment_methods: { enabled: true, }, }, // { // stripeAccount, // } );
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Thanks for sharing the additional context. It appears that you’re not initialising Stripe.js correctly, specifically when trying to pass the stripeAccount
parameter:
const stripePromise = loadStripe("pk_test_1234", {
stripeAccount
});
See here.
Method 2
Looks like you aren’t passing the options
prop the the <Elements />
provider component (which needs the client_secret
from your Payment Intent).
function App() {
return (
<Elements stripe={stripePromise} options={{ clientSecret: 'pi_xxx_secret_yyy' }}>
<CheckoutForm />
</Elements>
);
};
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0