Five things I learned by building my own shopping cart and checkout with Gatsby and Stripe
Tags: gatsby, stripe, react
Published: 2020-10-13 19:48:20

## TL;DR

**Don't build your own shopping cart and checkout experience unless it's a learning exercise or your client has a big budget**

- If you don't need a fully customized shopping cart and checkout experience then consider [Snipcart](https://snipcart.com/) to save on dev time
- If you're using Gatsby or React and need a customized shopping cart consider using [use-shopping-cart](https://useshoppingcart.com/) rather than building a React shopping cart from scratch
- If you need a fully customized checkout experience then you'll need to use Stripe's PaymentIntent API instead of Stripe's pre-built Checkout page. Budget more time for this

![Shopping Cart Demo](https://dev-to-uploads.s3.amazonaws.com/i/1aip3ljcfkeo20utp8oa.png)
Check out my [Muffin Plant Shop demo online store repo](https://github.com/nhuynh1/muffinsplantshop)

### 1. Gatsby makes it easy to get something up fast

For the small demo store I was working on, pulling product information from Markdown files was easy to setup by adapting [Gatsby's step-by-step tutorial](https://www.gatsbyjs.com/tutorial/).  Gatsby is built on React so there's lots of third-party components like [use-shopping-cart](https://useshoppingcart.com/) instead of building things from scratch. Gatsby sites also shield you from CMS vulnerabilities ([ahem Wordpress](https://wordpress.org/support/article/faq-my-site-was-hacked/))

### 2. No easy inventory solution with Stripe

At some point I think Stripe offered inventory management, but that doesn't seem to be the case anymore since the [Orders API has been deprecated](https://stripe.com/docs/orders)

### 3. A custom checkout experience requires using Stripe's PaymentIntent API

If you want to design your own checkout experience, then you'll have to use the PaymentIntent API and Stripe Elements. Stripe's [annotated code tutorial](https://stripe.com/docs/payments/integration-builder) covers this pretty well, you'll just have to adapt the server side code if you're using a serverless functions. For more details check out my [notes and code for my Netlify Function](https://nancyhuynh-til.netlify.app/stripe-react-notes/)

### 4. Stripe's pre-built Checkout page is easy—but you still need a little bit of server code

If you're ok with using Stripe's Checkout page (or convince your client to) then its super easy to offer card payments and digital wallets like Apple Pay. Stripe's [documentation for Checkout](https://stripe.com/docs/payments/accept-a-payment) is nicely laid out, and Netlify also has a [tutorial on setting up a Netlify Function for Stripe Checkout](https://www.netlify.com/blog/2020/04/13/learn-how-to-accept-money-on-jamstack-sites-in-38-minutes/). Just remember that customers will get redirected to Stripe to checkout

### 5. Freelancers and side-hustlers should seriously consider Snipcart

If you're building an online shop for your side hustle or a small business client Snipcart *could* be a better solution. Based on my research here are some pros:

- Snipcart offers inventory management if you don't already have a solution
- Snipcart already has a shopping cart if you don't need a fully customized cart
- Snipcart checkout does not redirect customers to another site
- If you just need a shopping cart and checkout then no server code or serverless functions are needed

I will definitely be considering Snipcart for my own online stores in the future

**References**

- [Stripe Accept a payment](https://stripe.com/docs/payments/accept-a-payment)
- [Stripe Accept a payment annotated code tutorial](https://stripe.com/docs/payments/integration-builder)
- [Gatsby.js Tutorials](https://www.gatsbyjs.com/tutorial/)
- [Learn How to Accept Money on Jamstack Sites in 38 Minutes](https://www.netlify.com/blog/2020/04/13/learn-how-to-accept-money-on-jamstack-sites-in-38-minutes/)
- [Snipcart Documentation](https://docs.snipcart.com/v3/)
- [use-shopping-cart](https://useshoppingcart.com/)