Stripe Billing onboarding flow for your SaaS using NodeJS and React

Stripe Billing onboarding flow for your SaaS using NodeJS and React
In this article we will be going over the steps needed to integrate Stripe Billing with an onboarding flow using NodeJS and React. In the guide we will be:

In this article we will be going over the steps needed to integrate Stripe Billing with an onboarding flow using NodeJS and React. In the guide we will be:

  • Configuring a Stripe account with a pricing strategy we will be using in this example
  • Setting up a Route in ExpressJS which will expose the pricing strategy to the front-end
  • Setting up a React front-end which will handle the onboarding flow, utilizing Stripe Elements for checkout

In this article we assume you already have a working knowledge of Node and ExpressJS as well as the steps needed to create a React app. For some good resources on how to learn these check out:

Define your Products and Plans in Stripe

The first step is to create some products and plans in your Stripe account. If you haven’t registered for Stripe you can do so here.

For this example we are going to create a two tiered pricing strategy, with a Basic $50/month tier and a Premium at $300/month tier defined as separate Products in Stripe.

The Products we create with plans attached

If you want this automated for your specific Stripe account, feel free to edit the secret key in this RunKit to your Stripe test key.

This code will create products and plans in Stripe

const STRIPE_TEST_SECRET_KEY = "sk_test_6pewDqcB8xcSPKbV1NJxsew800veCmG5zJ"//your Stripe key here
const stripe = require('stripe')(STRIPE_TEST_SECRET_KEY);

const basicPlan = await stripe.plans.create({
    amount: 5000, 
    interval: "month", 
    product: {
        name : "AcmeBot Basic"
    currency: "USD"
const premiumPlan = await stripe.plans.create({
    amount: 30000, 
    interval: "month", 
    product: {
        name : "AcmeBot Premium"
    currency: "USD"
console.log(`Stripe Plans that were Created:`);
console.log(`AcmeBot Basic, Plan ID: ${}, Amount: $${basicPlan.amount/100}/${basicPlan.interval}, Product ID: ${basicPlan.product}`)
console.log(`AcmeBot Premium, Plan ID: ${}, Amount: $${premiumPlan.amount/100}/${premiumPlan.interval}, Product ID: ${premiumPlan.product}`)

Create a REST endpoint for getting Plans

After you have your Stripe configured, we can define a new REST endpoint in Express that our React can consume in order to render an onboarding flow using live Stripe data.

In order to render a pricing page, the front-end will need to know the plans in your Stripe account, so our code will be making an API call to Stripe using the stripe module. Here is what an example ExpressJS middleware could look like which does this.

ExpressJS middleware for getting all Stripe plans

const STRIPE_TEST_SECRET_KEY = "rk_test_3U9s3aPLquPOczvc4FVRQKdo00AhMZlMIE"; //your Stripe key here
const stripe = require('stripe')(STRIPE_TEST_SECRET_KEY);

//express middleware
async function getAllPlans(req, res, next){

    //get all plans, expand keyword will also return the contents of the product this plan is attached to
    const plans = await stripe.plans.list({expand: ["data.product"]});

//see it in action
const req = {}; // req not used
const res = {
    json : function(payload){
        console.log("All Stripe Plans:")
        for(let plan of{
            console.log(`Plan ${}, Name: ${}, Amount: ${plan.amount/100}/${plan.interval}`)
        console.log("payload:", payload);
const next = function(){};
await getAllPlans(req, res, next)

After this step is done, we can do our front-end in React in order to display a pricing page and a checkout flow

Create a Component to display pricing

In order to create a pricing page, we’ll need to define a component which renders the plan data that is gotten from the REST API we defined above.

The component will look something like this. It’ll loop through all the plans and render the relevant information such as price, name, and interval. It will also display a checkout page (which we will define in the next step) when the user presses “Get Started”.

function Pricing({pricingPlans, onPlanSelect}){
  return <div>{{id, interval, amount, product: {name}})=>{
      return <div>
        <button onClick={onPlanSelect(id)}>Get Started</button>

You see this code in action below in the CodePen. Note, for this CodePen we don’t make an API call and just statically define the payload. In your own implementation you should be pulling the payload directly from your API.

Full checkout flow

Create a Checkout Flow

For the last step, we will be creating a checkout process using Stripe Elements and tying it back to the pricing page we just set up.

In the previous example we created a callback function which would be triggered when someone picks a plan. We now need to tie that to Stripe so when they pick a plan, they are prompted with a checkout page. We do that using React Stripe Elements, the React wrapper around the Stripe Elements library.

You can see this in action below:

Now that we have a basic checkout flow, we will need to process the token generated by the form and create a subscription for the new customer, giving us a new subscription. Alternatively, you could, instead of using Stripe Elements, use Stripe Checkout which automatically creates subscriptions (but is not as flexible).

This wraps up the tutorial on creating a checkout flow with Stripe, React, and Node

What comes next?

Thanks for reading! This will get you started with billing, but we’ve only touched the tip of the iceberg of building a billing system with Stripe with this post. More advanced topics such as coupons, advanced pricing strategies, and different pricing intervals (monthly/annual for example) requires much more development to support.

If you are looking to get great looking & mobile friendly pricing pages, checkout forms, and more without having to build it all yourself, check out Servicebot - A drop-in UI toolkit built on top of Stripe, you just paste a code snippet and get a fully featured front-end powered by Stripe.


Getting Closure on React Hooks

React + TypeScript : Why and How

Page Transitions In React - React Router V6 and Framer Motion Tutorial

Learn React - Full Course for Beginners - React Tutorial 2019

React vs Vue - I Built the Same App in Both Frameworks

React Node.js MySQL Social Media App Tutorial | Full Stack Social Network App