Creating your own bespoke eCommerce store with React & Stripe

E-commerce is booming, and with so many platforms to choose from it can be overwhelming to pick where to start. I’m going to walk you through how to create a completely custom experience and forgo the fees and hidden costs built into the likes of Shopify and Amazon. Let's get started.

A word on PCI Compliance

Anyone involved with the processing, transmission, or storage of card data must comply with the Payment Card Industry (PCI) Data Security Standard. A good rule of thumb, when building a PCI compliant checkout, is to not store or manage any credit card information yourself. For this reason, we’re going to use Stripe in this demonstration because they do a fantastic job of extracting away this complexity. They’re also free to use and will only take a small cut out of the price of goods sold. You should set up a stripe account and create your products before continuing onto the next steps.

Gatsby and Prismic

I am using Gatsby, a React static site generator paired with Prismic, which hosts and serves our content. These services are free to use, but you can also follow along with your preferred flavor of React application. Since we’re using Gatsby, we’re going to start by installing our stripe dependencies and adding them to the gatsby-config.js file.

Install dependencies

Adding to gatsby-config.js

{resolve: `gatsby-source-stripe`,options: {objects: ["Sku"],secretKey: process.env.STRIPE_SECRET_KEY,downloadFiles: false,},},

Your environments variables will be placed in and you process them by requiring the in gatsby-config.js like so.

require('dotenv').config({path: `.env.${process.env.NODE_ENV}`});

Next, you need to create a checkout component. Here’s my entire component for the sake of ease.

import React from 'react';import { loadStripe } from '@stripe/stripe-js';import colors from 'styles/colors';import styled from '@emotion/styled';const Header = styled.div`margin: 6rem auto;text-align: center;`;const ButtonContainer = styled.div`display: grid;grid-gap: 1.5rem;justify-content: center;`;const Button = styled.div`font-size: 1.6rem;text-align: center;background: ${colors.yellow};padding: 1.6rem;box-shadow: 2px 5px 10px rgba(0, 0, 0, 0.1);color: ${colors.grey900};border-radius: 6px;letter-spacing: 1.5px;cursor: pointer;width: 10rem;&:hover {   box-shadow: 2px 5px 10px rgba(0, 0, 0, 0.2);}`;const stripePromise = loadStripe(process.env.GATSBY_STRIPE_PUBLISHABLE_KEY)const redirectToCheckoutTwo = async event => {event.preventDefault();const stripe = await stripePromise;const { error } = await stripe.redirectToCheckout({lineItems: [{ price: process.env.GATSBY_BUTTON_PRICE_ID_TWO, quantity: 1 }],mode: 'payment',successUrl: `https://<your-redirect>`,cancelUrl: `https://<your-page>`,});if (error) {console.warn('Error:', error);
};const redirectToCheckoutFive = async event => {event.preventDefault();const stripe = await stripePromise;const { error } = await stripe.redirectToCheckout({lineItems: [{ price: process.env.GATSBY_BUTTON_PRICE_ID_FIVE, quantity: 1 }],mode: 'payment',successUrl: `https://<your-redirect>`,cancelUrl: `https://<your-page>`,});if (error) { console.warn('Error:', error); }};const redirectToCheckoutTen = async event => {event.preventDefault();const stripe = await stripePromise;const { error } = await stripe.redirectToCheckout({lineItems: [{ price: process.env.GATSBY_BUTTON_PRICE_ID_TEN, quantity: 1 }],mode: 'payment',successUrl: `https://<your-redirect>`,cancelUrl: `https://<your-page>`,});if (error) { console.warn('Error:', error); }};const Checkout = (props) => {return (<><Header><h2>Choose an amount</h2></Header><ButtonContainer><Button onClick={redirectToCheckoutTwo}>$2</Button><Button onClick={redirectToCheckoutFive}>$5</Button><Button onClick={redirectToCheckoutTen}>$10</Button></ButtonContainer></>);};export default Checkout;

I didn’t have a huge assortment of products in this case so I just created 3 separate functions with their corresponding IDs.

That’s pretty much it, it’s a super-secure and simple way to receive payment and you have all the flexibility in the world to make your customer’s journey unique. You can check out the final product here.


Stripe is relatively unknown to the general public and doesn’t give off that hue of trustworthiness that other platforms do. That’s why when I’m building out a checkout for a client I’ll typically stick with the old favorites such as Shopify or WooCommerce. I’m currently working on a React app that leverages the Shopify API, which might just be the best of both worlds. I’ll let you know how that turns out.

The author of this tutorial is Kahil Nayton, a web developer at Kworq, a creative digital agency based out of NYC.

Full stack developer based out of Brooklyn, NYC.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store