DEV Community

Cover image for Using the new Stripe Checkout in Gatsby + AWS Amplify: Redirect to checkout (client-side)
Beez Fedia
Beez Fedia

Posted on

Using the new Stripe Checkout in Gatsby + AWS Amplify: Redirect to checkout (client-side)

In the first part of this series of posts you created a Lambda function, using AWS Amplify, to create a Stripe Checkout session. In this post, you'll redirect your customer to the Stripe Checkout page using the checkout session Id.

Take a look at the code from this blog post on Github.

Step 1. Install Stripe.js

Stripe Checkout relies on Stripe's javascript library, Stripe.js. At the root of your Gatsby project, within terminal, install Stripe.js:

npm install @stripe/stripe-js
Enter fullscreen mode Exit fullscreen mode

Stripe fraud detection

Stripe includes some advanced fraud functionality that helps detect suspicious behaviour as prospective customers browse your site. The Stripe.js module inserts a <script> tag that loads Stripe.js from https://js.stripe.com as a side effect when the module is imported. For optimal fraud detection, the Stripe.js script needs to be available on every page of your website. The gatsby-browser.js API file is the perfect place to import the Stripe.js module in order to meet this requirement.

At the route of your project, create a gatsby-browser.js file:

touch gatsby-browser.js
Enter fullscreen mode Exit fullscreen mode

At the top of the gatsby-browser.js file import the Stripe.js module:

// gatsby-browser.js
import '@stripe/stripe-js'
Enter fullscreen mode Exit fullscreen mode

Step 2. Create a checkout button component

Create a CheckoutButton.js component within the /src/components/ folder

touch src/components/CheckoutButton.js
Enter fullscreen mode Exit fullscreen mode

Import React and export default an empty CheckoutButton function:

import React from "react"

const CheckoutButton = () => {}

export default CheckoutButton
Enter fullscreen mode Exit fullscreen mode

Return a <button>Continue to payment</button> from the CheckoutButton function:

import React from "react"

const CheckoutButton = () => {
  return <button>Continue to payment</button>
}

export default CheckoutButton
Enter fullscreen mode Exit fullscreen mode

Add an empty async redirectToCheckout function to the CheckoutButton component function:

import React from "react"

const CheckoutButton = () => {
  const redirectToCheckout = async () => {}

  return <button>Continue to payment</button>
}

export default CheckoutButton
Enter fullscreen mode Exit fullscreen mode

You want this function to be called when the customer clicks the Continue to payment button. Use an onClick event handler to call the redirectToCheckout function when the button is clicked.

import React from "react"

const CheckoutButton = () => {
  const redirectToCheckout = async () => {}

  return <button onClick={redirectToCheckout}>Continue to payment</button>
}

export default CheckoutButton
Enter fullscreen mode Exit fullscreen mode

Step 3. Fetch the Stripe Checkout session

The redirectToCheckout function needs to call the Lambda function you created in part 1 to retrieve the Stripe Checkout session. To interact with the Lambda you need to import API from aws-amplify. To add Amplify to your app, in terminal run:

npm install aws-amplify
Enter fullscreen mode Exit fullscreen mode

Import and configure Amplify within gatsby-browser.js:

import Amplify from "aws-amplify"
import awsconfig from "./src/aws-exports"
Amplify.configure(awsconfig)
Enter fullscreen mode Exit fullscreen mode

Import API from aws-amplify at the top of your CheckoutButton.js component file:

import { API } from 'aws-amplify'
Enter fullscreen mode Exit fullscreen mode

Add an empty async fetchSession function to your redirectToCheckout function

const redirectToCheckout = async () => {
      const fetchSession = async () => {}
  }
Enter fullscreen mode Exit fullscreen mode

Within this function send a POST request to the stripeAPI, /checkout endpoint that AWS Amplify created for you using AWS API Gateway in part 1. The Lambda function you wrote in part 1 is expecting 3 body params in this request – priceId, quantity and client_reference_id. Modify your fetchSession function to call the API endpoint to return the session Id:

const redirectToCheckout = async () => {
      const fetchSession = async () => {
        const apiName = 'stripeAPI'
        const apiEndpoint = '/checkout'
        const body = {
            quantity: 1,
            client_reference_id: 'UniqueString',
            priceId: ''
        }
        const session = await API.post(apiName, apiEndpoint, { body })
        return session
      }
  }
Enter fullscreen mode Exit fullscreen mode

As mentioned in part 1, the client_reference_id is a unique reference you can send to Stripe that will help you identify this purchase for the payment confirmation webhook later. The priceId is the priceId of the product you setup on Stripe in part 1.

To fetch the priceId of the product you created from the Stripe dashboard:

  1. Log into your Stripe dashboard
  2. Navigate to Products
  3. Select the product Pro Plan you created earlier
  4. Within the Pricing section, look for the API ID. It will look something like price_1GuxxSBwl4TwghDgsuUB0RGd. If the Id you've copied begins with prod_ this is not the right Id.

Add the priceId to the body object within the fetchSession function:

const body = {
        quantity: 1,
        client_reference_id: "UniqueString",
        priceId: "price_1GuxxSBwl4TwghDgsuUB0RGd",
      }
Enter fullscreen mode Exit fullscreen mode

Step 4. Redirect to the Stripe Checkout using the session Id

Fetch your Stripe publishable API key from Stripe Dashboard > Developers > API Keys. It will look something like pk_test_KT4KxozC6O8d3krb3FEjbBp00eruf93Bh.

At the top of the CheckoutButton.js file, Import loadStripe from @stripe/stripe-js

import { loadStripe } from '@stripe/stripe-js';
Enter fullscreen mode Exit fullscreen mode

In order to setup the stripePromise you need to call the loadStripe function using your publishable key:

const stripePromise = loadStripe('pk_test_KT4KxozC6O8d3krb3FEjbBp00eruf93Bh');
Enter fullscreen mode Exit fullscreen mode

Within the main body of the redirectToCheckout function, await the stripePromise, fetch the sessionId and call Stripe's redirectToCheckout function using the sessionId:

const session = await fetchSession()
const sessionId = session.id
const stripe = await stripePromise
stripe.redirectToCheckout({ sessionId })
Enter fullscreen mode Exit fullscreen mode

Your CheckoutButton.js component should now look like:

import React from "react"
import { API } from "aws-amplify"
import { loadStripe } from "@stripe/stripe-js"

const stripePromise = loadStripe("pk_test_KT4KxozC6O8d3krb3FEjbBp00eruf93Bh")

const CheckoutButton = () => {
  const redirectToCheckout = async () => {
    const fetchSession = async () => {
      const apiName = "stripeAPI"
      const apiEndpoint = "/checkout"
      const body = {
        quantity: 1,
        client_reference_id: "UniqueString",
        priceId: "price_1GuxxSBwl4TwghDgsuUB0RGd",
      }
      const session = await API.post(apiName, apiEndpoint, { body })
      return session
    }

    const session = await fetchSession()
    const sessionId = session.id
    const stripe = await stripePromise
    stripe.redirectToCheckout({ sessionId })
  }

  return <button onClick={redirectToCheckout}>Continue to payment</button>
}

export default CheckoutButton
Enter fullscreen mode Exit fullscreen mode

Now import the CheckoutButton into a page within your site. When your customer clicks Continue to payment they will be taken to the Stripe Checkout page:
Stripe Checkout page
In the next post, you'll implement the Stripe webhook to receive confirmation when the payment has been completed.

Latest comments (1)

Collapse
 
sbadulin profile image
Sergey Badulin

Thank you for the article! DId you managed to build it in CI system (like CircleCI)?