Reputation: 36391
My goal is to create a simple payment page for a product.
In the official docs it says that a generation of a token is required on the server-side in order to create a transaction, using:
stripe.paymentIntents.create({
amount: req.body.amount,
currency: 'usd'
})
and using the returned key to create a transaction.
However, some other official examples use only client-side, like this:
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement(CardElement),
})
Without the server key stripe.confirmCardPayment('{CLIENT_SECRET}', {
The docs say CLIENT_SECRET
is required but there are examples without it.
Any idea why and what is the difference?
Upvotes: 5
Views: 2313
Reputation: 3240
Unless you use Stripe's new client-only Checkout there's no way to process payments in custom Stripe integrations without some server-side code.
As you noticed, the official docs for React Stripe.js only include client-side code. However, the code samples on this page don't represent a full integration required in order to process a payment. The samples only demonstrate how you would collect and tokenize credit card details in the frontend with React Stripe.js and the createPaymentMethod function. The docs were written this way to make it easier to follow along and run the code samples in a browser without having to setup a server.
A good place to start to get an idea of what APIs are involved in end-to-end payment integrations would be:
https://stripe.com/docs/payments/accept-a-payment
(tip each code sample in the above guide has a React
version that you can tab into)
If you're interested in seeing a full working integration that builds off of those React examples, I would recommend checking out the following demo that we built for a recent developer office hours episode:
https://github.com/tmarek-stripe/demo-react-stripe-js
Specifically, I would recommend reviewing the server-side portion (here) that creates a payment intent, and the client-side portion (here) that creates a payment method and confirms the payment intent.
That's a lot to review! If you prefer, you can just watch the video where we go over how to create an (almost complete) integration with React Stripe.js:
React Stripe.js - Developer Office Hours | Youtube
Once the basics are covered I would recommend reviewing another sample for a more complete end-to-end integration:
Type-safe Payments with Next.js, TypeScript, and Stripe
When reviewing this complete integration note how you don't need to create a payment method manually when using Stripe.js. It's optional because a successful payment intent will automatically create a payment method for you.
A payment intent gets created server-side:
// Create a PaymentIntent with the specified amount.
const response = await fetchPostJSON('/api/payment_intents', {
amount: input.customDonation
});
And confirmed client-side without any createPaymentMethod
calls needed!
const cardElement = elements!.getElement(CardElement);
// Use your card Element with other Stripe.js APIs
const { error, paymentIntent } = await stripe!.confirmCardPayment(
response.client_secret,
{
payment_method: {
card: cardElement!,
billing_details: { name: input.cardholderName }
}
}
);
In a nutshell:
I hope this helps!
Upvotes: 6