VOOZH about

URL: https://blog.logrocket.com/integrating-stripe-react-stripe-js/

⇱ Integrating Stripe in your React app with React Stripe.js - LogRocket Blog


2020-08-28
1577
#ecommerce#react
Yusuff Faruq
23939
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Nowadays, making payments through a website or mobile app in exchange for a product of some sort has become ubiquitous. As such, there are a variety of payment gateway solutions that make it simple for these websites and mobile apps to accept payment.

👁 Integrating Stripe In Your React App With React Stripe.js

Stripe is one of the leading payment gateways, and it allows businesses and individuals to accept payment through the use of their robust APIs and tools. In this article, we will discuss how to integrate Stripe in our React apps using React Stripe.js, an official library from Stripe.

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

Stripe Elements

React Stripe.js is simply a lightweight wrapper around Stripe Elements, which is a set of prebuilt UI components that allow developers to implement secure payment functionality in their applications quickly and easily. One such element is the Card Element, which is a single-line form that collects all the information required to make payments online using a debit/credit card.

Developers can also build their own custom payment forms using elements that represent the individual parts of the Card Element: the Card Number Element, the Card Expiry Element, and so on. You can learn more about Stripe Elements here.

React Stripe.js

Now that we are familiar with Stripe Elements, we will look at how React Stripe.js allows us to use Elements in our applications.

In React Stripe.js, Elements are available in the form of React components, so for each Element, we have a corresponding React component. Besides the Element components, React Stripe.js also contains some Hooks and other components, like the Elements provider and ElementsConsumer.

Before we move on to building a payment form that allows us to accept payment with Stripe and React Stripe.js, I’d like to briefly discuss some of these Hooks and components as they will be fundamental to what we will do later on in this article.

The Elements provider

The Elements provider is a component that allows any components nested in it to use the Element components and the Hooks provided by React Stripe.js. Elements has two props: stripe and options. Normally, stripe takes in a Stripe object or a promise that resolves to a Stripe object. To initialize a Stripe object, you can use the loadStripe function from the stripe-js module.

import React from "react";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";

const stripe = loadStripe(
 "{PUBLIC-KEY}"
);
const App = () => {
 return (
 <Elements stripe={stripe}>
 ...
 </Elements>
 );
};

The useStripe and useElements Hooks

The useStripe and useElements Hooks are the two React Hooks that React Stripe.js offers. useStripe returns a reference to the Stripe object instance we initially passed to the Elements provider. With this Stripe object, we can interact with Stripe. useElements returns an Elements object, which we can use for interacting with our Elements and collecting sensitive for payment.

ElementsConsumer

Since Hooks can only be used in functional components, the ElementsConsumer component is used whenever we want to access the Stripe and Element instance in class-based components. It takes a function, from whose arguments we can get our Stripe and Element instances, as a child.

import React from "react";
import { ElementsConsumer, Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";

const App = () => {
 return (
 <Elements stripe={stripe}>
 <CheckoutForm />
 </Elements>
 );
};

const CheckoutForm = () => {
 return (
 <ElementsConsumer>
 {({elements, stripe}) => (
 ...
 )}
 </ElementsConsumer>
 );
};

Now that we are familiar with the toolbox React Stripe.js gives us, let’s go ahead and build a simple React component that can accept payments through a debit/credit card.

Accepting payments with React Stripe.js and Stripe

Prerequisites

  1. A Stripe account — this is necessary to integrate Stripe in your app or website. You can create one at Stripe.com
  2. Basic knowledge of React

Note: To build an actual payment flow, you will need a server where client secrets can be generated to use for payment. This is beyond the scope of this article and will not be covered.

Now that we have that covered, let’s start writing some code!

Setting up our React project

Firstly, we have to create a new React project using any preferred method. I recommend using create-react-app.


Over 200k developers use LogRocket to create better digital experiences

👁 Image
Learn more →

Once our React project has been created, we have to install some dependencies. Using npm, we can install React Stripe.js and the stripe-js module:

npm install --save @stripe/react-stripe-js @stripe/stripe-js

Accepting payments

In our App component, we will initialize our Stripe object using the loadStripe function. We will then pass this instance to the stripe prop of the Elements provider.

To do this, we will need a publishable key, which you can find on your Stripe dashboard once you create an account. Note that you should use the test version of your publishable key.

Once our Elements provider is ready, we will create a new component for our checkout form, from which we will accept the user’s card details.

We will use the CardElement component to securely collect the user’s card details and pass it to Stripe for processing. Let’s write some markup and CSS for our form.

App.js

import React, { useState } from "react";
import {
 Elements,
 CardElement,
} from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import "./App.css";
const App = () => {
 const stripe = loadStripe(
 "pk_test_*****"
 );
 return (
 <Elements stripe={stripe}>
 <CheckoutForm />
 </Elements>
 );
};
function CheckoutForm() {
 const [isPaymentLoading, setPaymentLoading] = useState(false);
 return (
 <div
 style={{
 padding: "3rem",
 }}
 >
 <div
 style={{
 maxWidth: "500px",
 margin: "0 auto",
 }}
 >
 <form
 style={{
 display: "block",
 width: "100%",
 }}
 >
 <div
 style={{
 display: "flex",
 flexDirection: "column",
 alignItems: "center",
 }}
 >
 <CardElement
 className="card"
 options={{
 style: {
 base: {
 backgroundColor: "white"
 } 
 },
 }}
 />
 <button
 className="pay-button"
 disabled={isPaymentLoading}
 >
 {isPaymentLoading ? "Loading..." : "Pay"}
 </button>
 </div>
 </form>
 </div>
 </div>
 );
}

App.css

.card {
 background-color: white;
 padding: 10px 20px 11px;
 border-radius: 5px;
 width: 100%;
 border: 1px solid #afafaf;
 box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
}
.pay-button{
 padding: 0.7rem 2rem;
 width: 100%;
 margin: 1rem 0;
 color: white;
 font-weight: bold;
 font-size: medium;
 background-color: #556cd6;
 border: 0;
 border-radius: 5px;
 box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
 transition: box-shadow 500ms;
 cursor: pointer;
}
.pay-button:disabled{
 background-color: #afafaf;
 box-shadow: none;
 cursor: default;
}
.pay-button:disabled:hover{
 box-shadow: none;
}
.pay-button:hover{
 box-shadow: 2px 5px 15px 2px rgba(0, 0, 0, 0.2);
}

Now all we need to do is create a function, which we will call payMoney, for collecting users’ details and sending them to Stripe for payment. To do that, we will have to make a request to an endpoint on our server (which, again, we won’t be covering in this tutorial) to get the client secret, which we will use to make the payment.

Since we don’t have a server to make a request to, we will just use a function to represent the process.

const clientSecret = getClientSecret();

We will now use the useStripe and useElement Hooks to get the stripe and element instance, which we will use for making payment through the confirmCardPayment method. This method takes in our client secret and an object specifying additional details about the user’s payment.


More great articles from LogRocket:




const stripe = useStripe();
const elements = useElements();

const paymentResult = await stripe.confirmCardPayment(clientSecret, {
 payment_method: {
 card: elements.getElement(CardElement),
 billing_details: {
 name: "Faruq Yusuff",
 },
 },
});

As you can see from the code block above, we used the elements instance and its getElement method, which takes in the CardElement component as an argument. We can also specify other details about this payment using the billing_details property.

If our result contains an error, we will trigger an alert with the error message, and if it is successful, we will trigger an alert with a success message. And with that, our payMoney function is complete.

const payMoney = async (e) => {
 e.preventDefault();
 const clientSecret = getClientSecret();
 const paymentResult = await stripe.confirmCardPayment(clientSecret, {
 payment_method: {
 card: elements.getElement(CardElement),
 billing_details: {
 name: "Yusuff Faruq",
 },
 },
 });
 setPaymentLoading(false);
 if (paymentResult.error) {
 alert(paymentResult.error.message);
 console.log(paymentResult.error.message);
 } else {
 if (paymentResult.paymentIntent.status === "succeeded") {
 alert("Success!");
 console.log(paymentResult);
 }
 }
 };

Now this should be our completed app.

import React, { useState } from "react";
import {
 Elements,
 CardElement,
 useStripe,
 useElements,
} from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import "./App.css";
const App = () => {
 const stripe = loadStripe(
 "pk_test_***************"
 );
 return (
 <Elements stripe={stripe}>
 <CheckoutForm />
 </Elements>
 );
};
function CheckoutForm() {
 const [isPaymentLoading, setPaymentLoading] = useState(false);
 const stripe = useStripe();
 const elements = useElements();
 const payMoney = async (e) => {
 e.preventDefault();
 if (!stripe || !elements) {
 return;
 }
 setPaymentLoading(true);
 const clientSecret = getClientSecret();
 const paymentResult = await stripe.confirmCardPayment(clientSecret, {
 payment_method: {
 card: elements.getElement(CardElement),
 billing_details: {
 name: "Faruq Yusuff",
 },
 },
 });
 setPaymentLoading(false);
 if (paymentResult.error) {
 alert(paymentResult.error.message);
 } else {
 if (paymentResult.paymentIntent.status === "succeeded") {
 alert("Success!");
 }
 }
 };

 return (
 <div
 style={{
 padding: "3rem",
 }}
 >
 <div
 style={{
 maxWidth: "500px",
 margin: "0 auto",
 }}
 >
 <form
 style={{
 display: "block",
 width: "100%",
 }}
 onSubmit = {payMoney}
 >
 <div
 style={{
 display: "flex",
 flexDirection: "column",
 alignItems: "center",
 }}
 >
 <CardElement
 className="card"
 options={{
 style: {
 base: {
 backgroundColor: "white"
 } 
 },
 }}
 />
 <button
 className="pay-button"
 disabled={isPaymentLoading}
 >
 {isPaymentLoading ? "Loading..." : "Pay"}
 </button>
 </div>
 </form>
 </div>
 </div>
 );
}

We’ve just built a simple app that can accept payment using Stripe!

A note about customization and styling

We can customize our Element components’ styles using the options prop on each Element component or applying a classname to our Element component and styling the component with CSS.

Conclusion

React Stripe.js provides a fast and secure way for us to implement payment functionality in our React Apps. You can learn more about React Stripe.js and Stripe here.

LogRocket: See the technical and UX reasons why users don’t complete a step in your ecommerce flow

👁 LogRocket ecommerce insights

LogRocket lets you replay user sessions, eliminating guesswork around why users don't convert by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.

LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.

Start proactively monitoring your ecommerce apps — try LogRocket for free.

👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Debug Next.js apps with AI agents and next-browser

Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.

👁 Image
Emmanuel John
Jun 17, 2026 ⋅ 9 min read

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

👁 Image
Chizaram Ken
Jun 16, 2026 ⋅ 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now