Using Stripe Elements in React

    Securely collect sensitive card details using Elements in a React application with the react-stripe-elements library.

    You can make use of Stripe Elements, our pre-built UI components, to create a payment form that securely collects your customer’s card information without requiring you to handle sensitive card data. The card details are then converted to a representative Token that you can safely send to your server.

    To use Stripe Elements in a React application, you can use the react-stripe-elements library. It wraps the Elements components inside of React components that you can embed in your application, directly in your JSX templates.

    This tutorial demonstrates how to build a full-stack Stripe integration with React and Node.js, using react-stripe-elements. There are five steps:

    1. Install dependencies and set up the project
    2. Create the payment form component
    3. Create a token to securely transmit card information
    4. Create the charge on your server
    5. Build and run the application

    Step 1: Install dependencies and set up the project

    You can use react-stripe-elements with the module bundler and transpiler of your choice. For the purposes of this tutorial, we are going to demonstrate how to use it with create-react-app, a popular boilerplate generator. If you prefer, you could use Parcel or your own custom webpack configuration.

    Start by creating the project with create-react-app:

    yarn create react-app elements-example
    

    Next, navigate into the elements-example directory and install the react-stripe-elements library from yarn:

    yarn add react-stripe-elements
    

    Next, open the generated public/index.html file and add a script tag that loads the Stripe.js library in the existing head tag:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="theme-color" content="#000000">
    
        <script src="https://js.stripe.com/v3/"></script>
        ...
      </head>
    
    

    This library is responsible for communicating with Stripe and performing tokenization. It must be available in the page in order for react-stripe-elements to work correctly. For PCI compliance purposes, you must load Stripe.js directly from Stripe’s servers at runtime—you can’t install it from npm or bundle it into your application like a conventional dependency.

    Step 2: Create the payment form component

    Create a src/CheckoutForm.js file and add the following:

    import React, {Component} from 'react';
    import {CardElement, injectStripe} from 'react-stripe-elements';
    
    class CheckoutForm extends Component {
      constructor(props) {
        super(props);
        this.submit = this.submit.bind(this);
      }
    
      async submit(ev) {
        // User clicked submit
      }
    
      render() {
        return (
          <div className="checkout">
            <p>Would you like to complete the purchase?</p>
            <CardElement />
            <button onClick={this.submit}>Send</button>
          </div>
        );
      }
    }
    
    export default injectStripe(CheckoutForm);
    

    The CardElement component imported from react-stripe-elements creates a “card” type element that mounts on the page when the component renders. The CardElement includes inputs for all of the major card fields: the card number, the expiration date, and the CVC. To display those inputs separately, you can use other Element components provided by the library.

    The CheckoutForm class defines a component that displays a CardElement and a button for completing the purchase. The button’s click event is wired to the submit method, which is left blank for now—the next step of this tutorial demonstrates how to make the submit method tokenize card data and send it to the server.

    The injectStripe function wraps the component, creating a new component with an injected stripe prop, which contains a Stripe object. You must use the wrapped component in your application instead of the original CheckoutForm.

    In the src/App.js file created by create-react-app, replace the current contents with the following:

    import React, {Component} from 'react';
    import {Elements, StripeProvider} from 'react-stripe-elements';
    import CheckoutForm from './CheckoutForm';
    
    class App extends Component {
      render() {
        return (
          <StripeProvider apiKey="pk_test_TYooMQauvdEDq54NiTphI7jx">
            <div className="example">
              <h1>React Stripe Elements Example</h1>
              <Elements>
                <CheckoutForm />
              </Elements>
            </div>
          </StripeProvider>
        );
      }
    }
    
    export default App;
    

    The App component is the application’s root. The JSX template in its render function is enclosed in a StripeProvider, which initializes Stripe and passes in your publishable key. It’s equivalent to creating a Stripe instance with Stripe.js.

    The Elements component, which encloses the wrapped checkout form, creates an Elements group. When you use multiple Elements components instead of the combined CardElement, the Elements group indicates which ones are related. For example, if you used separate components for the card number, expiration date, and CVC, you would put them all in the same Elements group. Note that Elements must contain the component that you wrapped with injectStripe, you cannot put Elements inside of the component that you wrap with injectStripe.

    Step 3: Create a token to securely transmit card information

    At this point, the application is capable of displaying a card entry form. The next step is adding functionality to the CheckoutForm component’s submit method so that clicking the Purchase button tokenizes the card information and sends it to your server:

    async submit(ev) {
      let {token} = await this.props.stripe.createToken({name: "Name"});
      let response = await fetch("/charge", {
        method: "POST",
        headers: {"Content-Type": "text/plain"},
        body: token.id
      });
    
      if (response.ok) console.log("Purchase Complete!")
    }
    

    In the submit method, tokenize the card information by invoking createToken on the stripe prop. The stripe prop is available inside the component due to the use of injectStripe in the previous step.

    Next, send the token to your server. This example shows how to send the token ID in the body of a POST request with the browser Fetch API. You can, however, use any approach that works for you.

    In your application, you should inform the customer that the charge completed. In the CheckoutForm.js file, add a property to the component’s state and use it to make the render function conditionally display a message when the purchase is complete:

    constructor(props) {
      super(props);
      this.state = {complete: false};
      this.submit = this.submit.bind(this);
    }
    
    ...
    
    async submit(ev) {
      ...
    
      if (response.ok) this.setState({complete: true});
    }
    
    render() {
      if (this.state.complete) return <h1>Purchase Complete</h1>;
    
      return (
        <div className="checkout">
          <p>Would you like to complete the purchase?</p>
          <CardElement />
          <button onClick={this.submit}>Send</button>
        </div>
      );
    }
    

    In a real application, you may also wish to propagate error messages from your server on failure and display them in the browser.

    Step 4: Create the charge on your server

    To create the charge on your server, create an endpoint that receives the POST request, extracts the token from the body, and creates the charge. The following code demonstrates how you can accomplish this with the Express framework in a Node.js application.

    Start by installing the necessary dependencies from npm:

    npm install express body-parser stripe
    

    Next, create a new file called server.js and add the following code:

    const app = require("express")();
    const stripe = require("stripe")("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    app.use(require("body-parser").text());
    

    This sets up an Express instance and initializes the Stripe client library, passing in the secret key. The body-parser middleware is there so that you can retrieve the payload from the POST request body. Next, add a POST request handler for the charge:

    app.post("/charge", async (req, res) => {
      try {
        let {status} = await stripe.charges.create({
          amount: 2000,
          currency: "usd",
          description: "An example charge",
          source: req.body
        });
    
        res.json({status});
      } catch (err) {
        res.status(500).end();
      }
    });
    

    The handler extracts the token from the request body and uses it to create a charge with the desired amount and currency—in this case, a $2 charge. If the charge fails and an exception is thrown, return a 500 error. You may wish to add more specialized error handling.

    Finally, make the server listen on the desired port number:

    app.listen(9000, () => console.log("Listening on port 9000"));
    

    Step 5: Build and run the application

    Use the following command to run the Node.js server:

    node server.js
    

    The create-react-app template includes a built-in webpack dev server, which you can use to build and run the frontend code. Because your Express server runs in a separate Node.js instance, you need to configure the webpack dev server to proxy the Express server. Add a proxy option to the package.json file generated by create-react-app, using the host and port where you are running the Express application:

    "proxy": "http://localhost:9000"
    

    Next, start create-react-app’s webpack dev server:

    yarn start
    

    When the webpack dev server starts, it will automatically open your web browser and load the application. You should see the credit card input form and the Purchase button. When you fill out the form with a test card and click the button, your server should create a new charge.

    For more details about the react-stripe-elements library, you can refer to its documentation on GitHub. You can also find several examples that demonstrate other features of the library in the project’s GitHub repository.

    Questions?

    We're always happy to help with code or other questions you might have! Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.