How to Integrate Stripe with a React Application

Mohammad Faisal - Nov 19 '23 - - Dev Community

To read more articles like this, visit my blog

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
Enter fullscreen mode Exit fullscreen mode

and your secret key should start with sk

sk_test_somerandomgibberish
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now install some dependencies

npm install express cors nodemon stripe
Enter fullscreen mode Exit fullscreen mode

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"
},
Enter fullscreen mode Exit fullscreen mode

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}`);
});
Enter fullscreen mode Exit fullscreen mode

Now go to the terminal and run

npm start
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now go into that project and install some dependencies

npm install --save @stripe/react-stripe-js @stripe/stripe-js
Enter fullscreen mode Exit fullscreen mode

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>;
};
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
  );
};
Enter fullscreen mode Exit fullscreen mode

Now if you go to your terminal and run the front-end by running

npm start 
Enter fullscreen mode Exit fullscreen mode

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.

Payment Form

Later you can go to https://dashboard.stripe.com/test/payments to see that the payment has been successful!

payment success!

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 or Personal Website

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .