How to Integrate Stripe with a React Application
Smart people need smart solutions. And Stripe is a smart solution for accepting payments for your digital product/service.
Today, we are going to integrate Stripe with a React application. We will need a small Express backend for this purpose as well. But don’t worry. We will make everything from scratch.
Let’s get started.
Get the keys!
First, open an account on Stripe. This should be straightforward if you live in a supported country.
First, go to https://stripe.com/docs/keys and get the two API keys from there. the public one should start with pk
pk_test_somerandomgibberish
and your secret key should start with sk
sk_test_somerandomgibberish
Get these 2 keys and save them somewhere.
Important: Don’t expose your secret key! Only use the public key on the front-end
Overview of the process
The payment process looks something like the following
Step 1: The front-end makes an API call to the backend to generate a payment intent.
Step 2: The Server then uses the secret key to generate a client_secret
which is returned to the front-end
Step 3: The user fills in proper card info
Step 4: A special CardElement
will collect the info on the front-end
Step 5: Use the secret temporary key to make a payment using the stripe library.
And that’s it!
Prepare the backend
We will create an express app from scratch but if you already have a running backend that will work the same.
First, go to any directory and create an empty folder.
mkdir backend
cd backend
npm init -y
It will create a new package.json
file for you. Now we need our index.js
file.
For that run the following command
touch index.js
Now install some dependencies
npm install express cors nodemon stripe
Now go to the package.json
file and modify the start
script like the following. It will enable re-build on change automatically.
"scripts": {
"start": "nodemon index.js"
},
Now add the following starter code to that application
const express = require("express");
const app = express();
var cors = require("cors");
const PORT = 3001;
const stripe = require("stripe")("YOUR_SECRET_KEY_HERE"); // <-- change the key here
app.use(cors());
app.use(express.static("public"));
app.use(express.json());
// Create a Payment Intent (returns the client with a temporary secret)
app.post("/create-payment-intent", async (req, res) => {
const { price } = req.body;
const paymentIntent = await stripe.paymentIntents.create({
amount: price,
currency: "usd",
});
res.send({
clientSecret: paymentIntent.client_secret,
});
});
app.listen(PORT, () => {
console.log(`app is listening on port ~${PORT}`);
});
Now go to the terminal and run
npm start
And your application should be starting at port 3001
Prepare the frontend
First, create a new react project by running the following command
npx create-react-app frontend
Now go into that project and install some dependencies
npm install --save @stripe/react-stripe-js @stripe/stripe-js
Now create a new component named MyCheckoutForm.js
for now and leave it empty for now.
export const MyCheckoutForm = () => {
return <div> my checkout form</div>;
};
Let’s go to our App.js
file and load the initial stripe wrapper. Now our App.js
file should look like this
import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import { MyCheckoutForm } from "./MyCheckoutForm";
import "./App.css";
const stripePromise = loadStripe("YOUR_PUBLIC_KEY_HERE");
function App() {
return (
<Elements stripe={stripePromise}>
<MyCheckoutForm />
</Elements>
);
}
export default App;
Now let's create our checkout form to enable the payment
import React, { useState, useEffect } from "react";
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
const totalPrice = 1400; // this means 14 usd and can also be calculated at the backend
export const MyCheckoutForm = () => {
const [clientSecret, setClientSecret] = useState("");
const stripe = useStripe();
const elements = useElements();
// STEP 1: create a payment intent and getting the secret
useEffect(() => {
fetch("http://localhost:3001/create-payment-intent", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ price: totalPrice }),
})
.then(res => res.json())
.then((data) => {
setClientSecret(data.clientSecret); // <-- setting the client secret here
});
}, []);
// STEP 2: make the payment after filling the form properly
const makePayment = async () => {
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
});
}
return (
<form id="payment-form" onSubmit={makePayment}>
<CardElement id="card-element" onChange={handleChange} />
<button id="submit"> Pay Now </button>
</form>
);
};
Now if you go to your terminal and run the front-end by running
npm start
And you will see a form like the following where you can use the card number 4242 4242 4242 4242
and any future date as expiry and any number as CVC and postal code to test your payment.
Later you can go to https://dashboard.stripe.com/test/payments to see that the payment has been successful!
So that's it! Now you can take people's money without any hassle at all!
So what now?
Now you know how to accept payment from your user. Now you can customize the user experience. Check the docs!
If you want to see the full implementation and code, you can go to the following repositories.
Frontend: https://github.com/Mohammad-Faisal/stripe-react-frontend
Backend: https://github.com/Mohammad-Faisal/stripe-node-backend
Resources:
Stripe Doc: https://stripe.com/docs/stripe-js/react
Have something to say? Get in touch with me via LinkedIn