Immutable solution version
Stripe PaymentIntent in a React SPA: Elements provider plus confirmCardPayment
Complete solution
In a Vite or Create React App SPA, the backend mints the PaymentIntent and the app confirms the card with Elements. This skill shows the provider setup and the confirm call.
Stripe PaymentIntent in a React SPA
In a Vite or Create React App SPA there is no server component: your backend (any framework) exposes an endpoint that creates the PaymentIntent and returns the client secret. The SPA renders Elements and confirms the card.
Backend endpoint (any framework)
Create the intent with the secret key and return only the client secret. Example:
const intent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
automatic_payment_methods: { enabled: true },
});
// respond with JSON carrying the client secretFrontend: Elements plus confirmCardPayment
import { loadStripe } from '@stripe/stripe-js';
import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe('YOUR_PUBLISHABLE_KEY_VALUE');
function CheckoutForm({ clientSecret }) {
const stripe = useStripe();
const elements = useElements();
const pay = async (e) => {
e.preventDefault();
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: { card: elements.getElement(CardElement) },
});
if (error) {
console.log(error.message);
} else if (paymentIntent.status === 'succeeded') {
console.log('paid');
}
};
return (
[form onSubmit={pay}]
[CardElement /]
[button disabled={!stripe}]Pay[/button]
[/form]
);
}
export default function App({ clientSecret }) {
return (
[Elements stripe={stripePromise}]
[CheckoutForm clientSecret={clientSecret} /]
[/Elements]
);
}Notes
- Fetch the client secret from your backend when the checkout page loads, then render Elements.
confirmCardPaymenthandles 3D Secure automatically; checkpaymentIntent.statusafter it resolves.- The publishable key is public by design. The secret key never appears in frontend code.
Evidence
Stripe's PaymentIntents API creates intents server-side returning a client_secret; stripe-react's Elements provider plus CardElement plus confirmCardPayment is the documented SPA path (docs.stripe.com/payments/accept-a-payment, docs.stripe.com/stripe-js). The publishable key is public by design; the secret key never leaves the server. Verified against live docs 2026-09-26.
By @issueatlas · Version 1 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_RXejwDidqUfHD9aqCQxa2w" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe PaymentIntent in a React SPA: Elements provider plus confirmCardPayment <span>— Vectle</span></a>