DEV Community 👩‍💻👨‍💻

Cover image for A primer for collecting recurring payments with Stripe
CJ Avilla for Stripe

Posted on • Updated on

A primer for collecting recurring payments with Stripe

Stripe Billing is the fastest way for your business to bill customers with subscriptions and accept recurring payments. In this series, you’ll learn the fundamentals for setting up an integration to accept recurring payments. We’ll cover things like starting subscriptions, customer onboarding, collecting payment, managing the the customer lifecycle and offering ways to cancel and move between plan levels.

There are several ways to mix and match Stripe APIs and tools to set up recurring payments, some with little to no code, others with very customized flows. I’ll stick to my favorite approach when using Rails, the middle ground where we’ll write just enough code to get a customized experience while still harnessing all the power of Checkout and the customer portal.

This series won’t go into more advanced details like metered/usage-based or tiered subscriptions, but you’ll walk away with the basic building blocks and an understanding that you can build on. Checkout the official documentation to model your more complex use-case.

As a frame of reference, let’s walk through a simple web application that implements subscription billing. First, let’s define some of the common building blocks of a subscription business.

Landing page

When the customer first visits your site, they are typically greeted with a landing page. Most often, this is where we’ll ask the customer to sign up, register, or join.

Screenshot of a landing page with pricing and authentication navigation items highlighted


When a customer signs up for your service, you’ll probably collect their email address and you you might also collect other data like birthdate, shipping address, or other product preferences in order to onboard the customer to your business. We’ll refer to this step as onboarding.

Pricing page

We are all familiar with pricing pages where we learn about which products and prices are offered. In the next article in this series, we’ll talk about how to model your business with Products and Prices so that you can take advantage of all the best Checkout and Customer portal features. It turns out that configuring your products and prices correctly the first time can be very useful long term.

This is the pricing page we’ll build with Tailwind UI, a paid suite of UI components. If you prefer a no-code approach, you can now build these pricing pages with an embeddable pricing table.

Pricing table with startup, business, and enterprise levels

Payment form

The payment form collects a name and payment information. Stripe hosts this form if you use Checkout or Payment Links. Alternatively, you can host your own payment form and use the PaymentElement to collect payment details from the customer.

Each of these options vary in integration complexity:

Payment Links no-code
Checkout server-side API call and redirect
PaymentElement server-side API calls and client side integration with Stripe.js

We’ll stick with Checkout which enables us to associate a checkout session, and ultimately a subscription, with a specific Stripe Customer. Then, we’ll store a reference to the Stripe Customer in the database alongside our Devise authenticated Rails User.

Screenshot of Stripe Checkout showing the price information, promotion code interface, and payment details form

Provision access

Access provisioning is when you’ll grant access to the products and features that a customer just paid for. This happens behind the scenes using a webhook. If you’re not familiar with webhooks, there are several resources that cover webhooks in depth. If you’re using the pay gem with your Rails application, it’ll abstract away all of the work of creating or updating subscriptions in your database — super handy!

Key terms

Let’s get into the core resources you’ll want to understand.

Stripe Customer objects allow you to collect recurring charges for the same customer, and to track multiple charges.

Your customer’s payment instruments–how they pay for your service. For example, you may store a credit card on the customer object for recurring use. Stripe consistently expands support for more payment method types like bank accounts and wallets as ways to accept recurring payments. You’ll want to enable several payment method types from your Stripe dashboard — giving customers options to pay with their preferred payment method is a great way to boost conversion.

Products are what your business offers — whether that’s a good or a service. Products include the name, features, and images of the product.

Prices represent how much and how often to charge for products, including how much the product costs, what currency to use, and the interval if the price is for subscriptions.

Subscriptions are the product details associated with the plan that your customer subscribes to, which allow you to charge the customer on a recurring basis.

Invoice is a statement of amounts owed by a customer. Subscriptions automatically generate invoices for you. I like to think of Subscriptions as “engines” or “generators” for invoices. Invoices refer to another more primitive object called a PaymentIntent, but for the purposes of this tutorial, we’ll stay higher level. Just know that a PaymentIntent is something under the hood of an Invoice and the PaymentIntent is the object that moves money.

Checkout Session
A Checkout Session represents your customer's session as they start a subscription. We recommend creating a new Session each time your customer attempts to subscribe. Once payment is successful or a trial is started, the Checkout Session will contain a reference to the Customer and the customer’s related Subscription.

Customer portal
The customer portal is a Stripe page where customers can manage their billing — e.g., update payment details on file, change between plan levels, view invoice history, cancel.


Starting a Subscription with Checkout and managing billing with the customer portal is a powerful combo. This is the approach that I recommend most SaaS companies take because you’ll avoid writing a lot of billing management boilerplate, dealing with localization, and other complicated workflows.

The flow

  1. When a new user signs up for our SaaS application, we’ll create a Customer.
  2. When they attempt to access paid features, we’ll present a Pricing page built with references back to Products and Prices.
  3. When the customer chooses a plan level to subscribe to, we’ll create a Checkout Session with reference to the Customer and the Price for that level.
  4. Then, we’ll redirect the customer to the Checkout Session’s URL. On the payment form, the user will enter their payment details and click “Subscribe.” That will create a new PaymentMethod and Subscription for the Customer.
  5. Since we’re not starting the Subscription on a trial, a new Invoice is generated and payment for the first interval is attempted.
  6. Then the user is redirected back to our app and a webhook event fires, notifying our application of a newly created Subscription. The user will see a thank you page, and our webhook handler will update the database to reflect the user’s newly active status.
  7. The user accesses paid features. 🎉

Next steps

Stay tuned for the next article where you’ll learn how to model your recurring SaaS business with Products and Prices.

About the author

CJ Avilla

CJ Avilla (@cjav_dev) is a Developer Advocate at Stripe, a Ruby on Rails developer, and a YouTuber. He loves learning and teaching new programming languages and web frameworks. When he’s not at his computer, he’s spending time with his family or on a bike ride 🚲.

Top comments (0)

Create an Account!

👀 Just want to lurk?

That's fine, you can still create an account and turn on features like 🌚 dark mode.