Gatsby e-commerce Tutorial
In this advanced tutorial, you’ll learn how to use Gatsby to build the UI for a basic e-commerce site that can accept payments, with Stripe as the backend for processing payments.
Benefits of using Gatsby for e-commerce sites include the following:
- Security inherent in static sites
- Blazing fast performance when your pages are converted from React into static files
- Easy to host
You can see the working demo hosted here: https://gatsby-ecommerce-stripe.netlify.com/
- Since this is a more advanced tutorial, building a site with Gatsby before will likely make this tutorial less time-consuming (see the main tutorial here)
- Stripe account: register for an account here
Stripe is a payment processing service that allows you to securely collect and process payment information from your customers. To try out Stripe for yourself, go to Stripe’s Quick Start Guide.
There are alternatives to Stripe, like Square and Braintree, and their setup is very similar to Stripe.
Stripe offers a hosted checkout that doesn’t require any backend component. You can configure products, SKUs, and subscription plans in the Stripe Dashboard. If you’re selling a single product or subscription (like an eBook) you can hardcode the product’s SKU ID in your Gatsby site. If you’re selling multiple products, you can use the Stripe source plugin to retrieve all SKUs at build time. If you want your Gatsby site to automatically update, you can use the Stripe webhook event to trigger a redeploy when a new product or SKU is added.
Create a new Gatsby project by running the
gatsby new command in the terminal and change directories into the new project you just started:
You can extend the functionality of this default starter with plugins. One such plugin is
gatsby-plugin-stripe, which you’ll install in this project:
Open the root site directory in a text editor and navigate to
gatsby-config.js and add the StripeJS plugin to
gatsby-config.js in the plugins section. Your
gatsby-config.js should look like the following code example:
npm run develop in the terminal, which starts a development server and reloads changes you make to your site so you can preview them in the browser. Open up your browser to
http://localhost:8000/ and you should see a default homepage.
NOTE: If you have already started your Gatsby development server using
npm run develop, you will need to restart the server by pressing CTRL + C in the terminal where the command was run and running
npm run developagain to see changes in your
gatsby-plugin-stripe, will add this snippet:
to the end of the
<body> tag across all of your pages. This helps facilitate Stripe’s fraud detection.
If you want to further customize the checkout process or pull Stripe data into your site, check out Gatsby’s plugin library for more Stripe plugins.
View your API credentials by logging into your Stripe account, and then going to Developers > API Keys.
You have 2 keys in both test mode and production mode:
- a publishable key
- a secret key
While testing, you must use the key(s) that include test. For production code, you will need to use the live keys. As the names imply, your publishable key may be included in code that you share publicly (for example, on the frontend, and in GitHub), whereas your secret key should not be shared with anyone or committed to any public repo. It’s important to restrict access to this secret key because anyone who has it could potentially read or send requests from your Stripe account and see information about charges or purchases or even refund customers.
Through this tutorial you will be using the “Checkout client-only integration” from Stripe. To use this integration you need to activate it on the corresponding Checkout settings from your Stripe Dashboard.
💡 This change will also modify the interface that Stripe provides to administer your products: keep this in mind in case you have previously used this tool. If you have never used the product administrator, you don’t need to worry.
Additionally, you need to set a name for your Stripe account on your Account settings to use this integration.
To learn more about this integration you may use the Stripe docs.
You can find an implementation of these examples on GitHub.
If you’re selling a simple product, like an eBook for example, you can create a single button that will perform a redirect to the Stripe Checkout page:
To sell your products, first you need to create them on Stripe using the Stripe Dashboard or the Stripe API. This is required for Stripe to validate that the request coming from the frontend is legitimate and to charge the right amount for the selected product/SKU. Stripe requires every SKU used with Stripe Checkout to have a name: be sure to add one to all of your SKUs.
You will need to create both test and live product SKUs in the Stripe Dashboard. Make sure you toggle to “Viewing test data” and then create your products for local development.
Create a new file at
checkout.js file should look like this:
You imported React, added a button with some styles, and introduced some React functions. The
redirectToCheckout() functions are most important for the Stripe functionality. The
componentDidMount() function is a React lifecycle method that launches when the component is first mounted to the DOM, making it a good place to initialize the Stripe.js client. It looks like this:
This identifies you with the Stripe platform, validates the checkout request against your products and security settings, and processes the payment on your Stripe account.
redirectToCheckout() function validates your checkout request and either redirects to the Stripe hosted checkout page or resolves with an error object. Make sure to replace
cancelUrl with the appropriate URLs for your application.
render() function applies your styles to the button and binds the
redirectToCheckout() function to the button’s onclick event.
Now go to your
src/pages/index.js file. This is your homepage that shows at the root URL. Import your new checkout component in the file underneath the other imports and add your
<Checkout /> component within the
<Layout> element. Your
index.js file should now look similar to this:
If you go back to
http://localhost:8000/ in your browser and you have
npm run develop running, you should now see a big, enticing “BUY MY BOOK” button. C’mon and give it a click!
Instead of hardcoding the SKU IDs, you can use the gatsby-source-stripe plugin to retrieve your SKUs at build time.
Add the gatsby-source-stripe plugin which you can use to pull in the SKUs from your Stripe account.
Now you can add the plugin configuration in your
To retrieve your SKUs from your Stripe account you will need to provide your secret API key. This key needs to be kept secret and must never be shared on the frontend or on GitHub. Therefore you need to set an environment variable to store the secret key. You can read more about the usage of env variables in the Gatsby docs.
In the root directory of your project add a
To use the defined env variable you need to require it in your
gatsby-node.js like this:
Lastly, make sure that your
.gitignore file excludes all of your
In your components folder add a new
Products folder. This folder will include the components that interact with the Stripe SKUs. First, you need a component that queries and lists your SKUs:
You can validate your query and see what data is being returned in GraphiQL, which is available at
http://localhost:8000/___graphql when running
npm run develop.
Once you’re happy with your query, create a new page where you can import the newly created Sku component:
When navigating to
http://localhost:8000/advanced/ you should now see a list of paragraphs with your SKU names.
To make your SKUs more visually appealing and interactive, create a new
SkuCard component in your
This component renders a neat card for each individual SKU, with the SKU name, nicely formatted pricing, and a “BUY ME” button. The button triggers the
redirectToCheckout() function with the corresponding SKU ID.
Lastly, you need to refactor your
Skus component to initialize the Stripe.js client, and render
SkuCards while handing down the Stripe.js client in the
You can call
redirectToCheckout() providing an array of SKUs and their quantities to charge for multiple items at the same time. Instead of each “BUY ME” button redirecting to the checkout page, you can therefore provide a central “GO TO CHECKOUT” button that uses the state of a cart component. You can see the necessary changes for this example on GitHub.
In test mode (when using the API key that includes test) Stripe provides test cards for you to test different checkout scenarios.
Edit this page on GitHub