Sign in
An image of the Stripe logo
Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
No-code
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Overview
Online payments
Products and prices
Invoicing
Subscriptions
    Overview
    How subscriptions work
    Recurring pricing models
    Get started
    Quickstart
    Integrate a SaaS business
    Embed a pricing table
    Design an integration
    Build a subscriptions integration
    Migrate subscriptions to Stripe
    Billing resources
    Coupons
    Customers
    Subscriptions
    Subscription invoices
    Manage subscriptions
    Change subscriptions
    Usage-based billing
    Use trial periods
    Set payment methods
    Subscriptions with multiple products
    Set subscription quantities
    Subscription webhooks
    Schedule subscriptions
    Tax
    Sales-led B2B billing
    Integrate with Salesforce
    Manage recurring revenue
    Revenue recognition
    Revenue recovery
    Subscription metrics
    Customer management
    Overview
    Set up the the no-code customer portal
    Set up the customer portal with the API
    Configure the customer portal
    Testing
    Test your integration
    Test clocks
    Strong Customer Authentication (SCA)
    Invoices API updates
Quotes
In-person payments
Multiparty payments
After the payment
Add payment methods
Payment Links
Stripe Checkout
Stripe Elements
About the APIs
Regulation support
Implementation guides
Testing
Billing
·
HomePaymentsSubscriptions

Usage-based billing

Learn how to charge customers based on how much they use your product or service.

We’re developing a committed spend billing model for usage-based billing. Committed spend refers to when your customer commits to spending a minimum amount of money (one-time or on a recurring basis) with you. The commitment can be solely contractual, a pre-payment without an actual contract, or a contract with some or all upfront payment.

Email us if you want to sign up for the beta.

Read the usage-based pricing model guide to learn how to implement the model in Stripe.

Find sample implementations on GitHub:

  • Pasha sample app

More details

  • Typographic sample app

More details

Charging customers based on how much of your service they use is a common revenue model for SaaS businesses-this model is called usage-based or metered billing. As a business, you provide access to your service and bill your customer based on their usage at the end of the subscription cycle. Companies that use this model often also charge a flat monthly fee. At the end of the cycle, you report the usage to Stripe.

This guide describes the unique actions you need to take in your integration to support usage-based billing. It focuses particularly on:

  • Setting up the pricing model and collecting and reporting usage records, two common points of friction for users.
  • The simplest, lowest-effort path to implement a usage-based billing integration, preferring no-code options where available. If you need to implement usage-based billing at scale or integrate it with complex systems you can follow the same pattern but use more appropriate tools, like the Stripe API, to implement it.
ComponentDescription

Product modeling

No code

Create a product to represent your service plan and configure a tiered pricing model that offers progressive, graduated pricing based on usage.

  • In the pricing models guide, learn more about the usage-based pricing model.
  • In this guide, read more about the details of modeling your products and prices on Stripe.

Customer sign-up

No code

Use a Payment Link as an out-of-the-box sign-up page and payment form for your customers to subscribe to a recurring product.

  • In the product docs, learn more about Payment Links.
  • In this guide, read about using Payment Links as a sign-up page and payment form with usage-based billing.

Trials

No code

Offer customers a trial of your service without accruing usage.

  • In the subscription trials guide, learn more about how trials work with subscriptions.
  • In this guide, learn more about how to handle trials with usage-based billing.

Subscription management

No code

Set up the customer portal to let your customers manage their subscriptions.

  • In the integration guide, learn how to set up the customer portal.
  • In this guide, learn how to use the customer portal with usage-based billing.

Cancellations

No code

Handle unbilled usage when metered subscriptions end.

  • In the cancellation guide, read more about canceling subscriptions.
  • In this guide, learn more about how to handle cancellations and usage prorations.

Monitor subscription activity

Some code

Set up webhook endpoints to listen to event notifications and handle upgrades, downgrades, payment failures, customer updates, and other scenarios.

  • In the subscriptions and webhooks guide, learn more about relevant webhook events for subscriptions.
  • In this guide, read more about event notifications relevant to usage-based billing.

Report usage

Some code

Collect usage records and report them to Stripe.

Learn about usage records and how to collect and report them to Stripe in this guide.

Testing

Some code

Test your integration for trial periods, webhook notifications, payment failures, and other common scenarios.

  • In the testing guide, read more about how to test different billing integrations.
  • In this guide, learn how to test your usage-based billing integration.

Sample integrations

Stripe has built two sample apps that demonstrate usage-based billing, Typographic and Pasha. This section describes how those sample apps are implemented.

Typographic, Stripe’s fictional demo app, uses a good-better-best model along with usage-based billing.

ComponentDescription

Product modeling

Typographic offers three levels of service: Starter, Growth, and Enterprise. Each level of service is represented on Stripe as a different product with associated prices. They charge a flat monthly fee for each level as part of pricing model with two graduated tiers. In the Starter plan, there is no charge for the first tier of 0-10 thousand requests. And in the second tier, there is a .01 USD charge for any request over 10 thousand. Users pay 10 USD regardless of how many requests they make.

Typographic pricing table

Pasha offers two levels of service: Basic and Premium. Each level of service is represented on Stripe as a different product with associated prices. They charge a flat monthly fee for each level as part of pricing model with two graduated tiers. In the Basic plan, there is no charge for the first tier of 0-2 thousand emails. And in the second tier, there is a .01 USD charge for any email over 2 thousand. Users pay 5 USD regardless of how many emails they send.

Pasha pricing table

Read more about pricing models:

  • Usage-based pricing
  • Tiered pricing
  • Graduated pricing

Customer sign-up

Both Typographic and Pasha use prebuilt Stripe Elements for parts of their customer experience, including collecting customers’ emails and billing details when they sign up for the service for the first time.

Typographic uses the Card Element to securely collect card details, provide real-time validation, formatting, and autofill when customers enter their card details. See the code implementation in the sample app.

Typographic’s implementation of the Card Element

Pasha also uses the Card Element to collect card details. They also use prebuilt Elements to save the payment details to a customer record, handle payment failures, subscribe customers to a pricing plan, and upgrade and downgrade plans. See the code implementation in the sample app.

Pasha’s implementation of the Card Element

Trials

Designed to be a minimal implementation, Typographic doesn’t have robust handling for trials. Pasha listens for the customer.subscription.trial_will_end event and sends a notification to the customer if they receive the event. See the code implementation in the sample app.

In a production app, they would also need to implement logic to handle the behavior of the subscription after it ends.

Read more about subscription trials and subscription webhook events.

Subscription management

Typographic built a custom page that lets customers modify their plan, update payment details, and cancel their subscription.

Typographic account management page

Pasha also built a custom account management page.

Pasha account management page

You can also use Stripe-hosted resources for account management, including the customer portal and Checkout.

Cancellations

Both Pasha and Typographic provide cancellation buttons on their sites. When users cancel their subscription in the front end, their backend calls the Subscriptions API.

Here’s the frontend and backend code for Pasha.

Learn how to handle cancellations and prorations in this guide.

Monitor subscription activity

Pasha creates a webhook endpoint and listens for events about invoice status changes, cancellations, and trials ending. See an example of their webhook implementation on GitHub.

Typographic does not have a webhook implementation.

Read about monitoring subscriptions with webhooks in this guide.

Report usage

Pasha’s implementation doesn’t include usage reporting.

Typographic’s implementation of usage aggregation is minimal.

Read about how to report usage in this guide.

Testing

Neither Pasha nor Typographic have any demonstrable testing patterns.

Read about how to test your integration in this guide.

Usage-based billing lifecycle

Here’s what the lifecycle of a usage-based billing looks like.

This diagram illustrates what happens after you’ve implemented a customer experience.

Prerequisites

To implement usage-based pricing on Stripe, you need:

  • To use Stripe Billing.
  • A mechanism to track usage of your service.
  • To decide whether you’re going to charge customers automatically or send invoices.
  • To decide if you’re going to implement usage thresholds.
    • You can use billing thresholds to cap unbilled amounts or to bill when a specified threshold is reached.
    • Make sure your integration handles these events appropriately. For example, you may want to inform customers so their service isn’t interrupted unexpectedly or they’re billed unexpectedly.

Usage-based billing compared to other pricing models

With Stripe Billing, you can set up several different pricing models. Some of the most common models are flat rate, per-seat, and tiered.

In these other pricing models, you define a specific quantity when you subscribe a customer. With usage-based billing, the amount depends on the user’s activity.

Billing in arrears

If you charge a flat fee in addition to the usage, Stripe won’t charge for the flat fee until the end of the billing cycle, along with any accrued usage.

If you want to charge customers for a flat fee up front, you can create a separate product and price to represent the flat fee. If you use this approach, you can’t use the Customer portal or Stripe Checkout as they don’t support multi-item subscriptions.

Product modeling

Model your business on stripe with products and prices.

You create your products and their pricing options with the Stripe API or Dashboard. Typographic has two products, each of which has two tiers:

  • Basic option
    • Tier one: 15 USD per month for 2,000 emails
    • Tier two: An additional .00100 USD for each email after 2,000
  • Premium option
    • Tier one: 75 USD per month for 10,000 emails
    • Tier two: An additional .00075 USD for each email after 10,000

To achieve this kind of pricing, you charge a flat fee and an additional amount based on how much customers use. With graduated tiers, customers initially pay the flat fee for the first 2,000 or 10,000 emails. If they upload more than that, they reach tier two and start paying for each additional email. You could also charge solely based on usage without the flat fee.

During each billing period, you create usage records for each customer and then Stripe adds them up to determine how much to bill for. This process is explained in a subsequent step but understanding the default behavior might impact how you create prices.

Aggregate usage

By default, Stripe sums up the quantity of all usage records for a customer in a billing period and then multiplies the total by the unit_amount of the price. If you want to change this behavior, you need to set aggregate_usage when you create the price. You can read more about this in the pricing model documentation but you can choose between using:

  • The last usage record sent during a billing period
  • The last usage record sent regardless of billing period
  • The usage record with max (highest) quantity during a billing period

The default behavior is used in this guide so aggregate_usage isn’t set manually.

Customer signup

You need to create a surface to allow your customers to select a plan and enter their billing information. The easiest way to do this is with Payment Links-you don’t need to modify your site, or even use your own site. You can create a payment link configured with your product and share the link with your customers.

When a customer selects a recurring product and enters their billing information in the Payment Link, Stripe creates two records:

  • Customer
  • Subscription

These records are both stored within Stripe.

If you need more advanced options, there are several:

  • Customer portal - Configure the portal to and share the link with your customers.
  • Checkout - Add a redirect from your site to a Stripe-hosted Checkout session.
  • Elements - Use customizable React elements in your site.

Trials

You can use trial periods for subscriptions with usage-based billing. During the trial period, any usage accrued doesn’t count toward the total charged to the customer at the end of the billing cycle. After the trial period ends, usage accrues and is billed at the end of the next billing cycle.

Trials and aggregate usage

If you use the aggregate_usage parameter and set the behavior to last_ever, your customer will be billed for the last usage record if it falls within the trial period, even if the usage occurred during the trial period.

For example, if you provide file storage you might want to offer a month of free storage, but then charge for the first month if the customer continues to store files with your service.

Learn more about trial periods and subscriptions.

Webhooks and trials

Make sure that your integration properly monitors and handles web events related to changes in trial status.

A few days before a trial ends and the subscription moves from trialing to active, you receive a customer.subscription.trial_will_end event. When you receive this event, verify that you have a payment method on the customer so you can bill them. Optionally, notify the customer that they will be charged.

StatusDescription
trialingThe subscription is currently in a trial period and it’s safe to provision your product for your customer. The subscription transitions automatically to active when the first payment is made.
activeThe subscription is in good standing and the most recent payment is successful. It’s safe to provision your product for your customer.
incompleteA successful payment needs to be made within 23 hours to activate the subscription. Or the payment requires action, like customer authentication. Read more about payments that require action. Subscriptions can also be incomplete if there’s a pending payment. In that case, the invoice status would be open_payment_pending and the PaymentIntent status would be processing.
incomplete_expiredThe initial payment on the subscription failed and no successful payment was made within 23 hours of creating the subscription. These subscriptions don’t bill customers. This status exists so you can track customers that failed to activate their subscriptions.
past_duePayment on the latest finalized invoice either failed or wasn’t attempted. The subscription continues to create invoices. Your subscription settings determine the subscription’s next state. If the invoice is still unpaid after all Smart Retries have been attempted, you can configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the subscription to active, pay the most recent invoice before its due date.
canceledThe subscription has been canceled. During cancellation, automatic collection for all unpaid invoices is disabled (auto_advance=false). This is a terminal state that can’t be updated.
unpaidThe latest invoice hasn’t been paid but the subscription remains in place. The latest invoice remains open and invoices continue to be generated but payments aren’t attempted. You should revoke access to your product when the subscription is unpaid since payments were already attempted and retried when it was past_due. To move the subscription to active, pay the most recent invoice before its due date.

Learn more about subscriptions and webhooks.

Subscription management

Use the customer portal to allow your customers to modify or cancel their subscriptions. The customer portal also enables customers to view, download, and pay their invoices. Learn how to set up the customer portal.

Other options:

  • Checkout - Add a redirect from your site to a Stripe-hosted Checkout session.
  • Elements - Use customizable React elements in your site.
  • Subscriptions API - Make calls to the API from your own site.

Cancellations

With usage-based billing, the price paid by the customer varies based on consumption during the billing cycle. When changing the billing cycle results in ending a subscription interval early, you charge the customer for the usage accrued during the shortened billing cycle.

When a subscription is canceled, it cannot be reactivated. Instead, collect updated billing information from your customer, update their default payment method, and create a new subscription with their existing customer record.

When a subscription has been scheduled for cancellation using cancel_at_period_end, you can reactivate it at any point up to the end of the period by updating cancel_at_period_end to false. The final invoice includes any metered usage when the subscription cancels at the end of the billing period.

Prorations

When your customer changes their subscription, there’s often an adjustment to the amount they owe known as a proration. You can use the upcoming invoice endpoint to display the adjusted amount to your customers.

On the frontend, pass the upcoming invoice details to a backend endpoint.

script.js
View full sample
function retrieveUpcomingInvoice( customerId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/retrieve-upcoming-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerId: customerId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then(invoice => { return invoice; }); }

On the backend, define the endpoint for your frontend to call. Retrieve the upcoming invoice and pass in the changes you want to preview. For this example, you need to delete the subscription item for the old price ID, clear the usage, and then add the new price ID. These changes aren’t actually applied, they just define what the preview looks like.

server.rb
View full sample
# Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key =
'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
post '/retrieve-upcoming-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) invoice = Stripe::Invoice.upcoming( customer: data['customerId'], subscription: data['subscriptionId'], subscription_items: [ { id: subscription.items.data[0].id, deleted: true, clear_usage: true }, { price: ENV[data['newPriceId']], deleted: false } ] ) invoice.to_json end

Monitor subscription activity

Monitor subscriptions in the Dashboard or set up webhook endpoints and listen for events. Learn more about subscriptions and webhooks.

Report usage

Throughout each billing period, you need to report usage to Stripe so that customers are billed the correct amounts. You do this by creating usage records with a subscription item, quantity used, and a timestamp. How often you report usage is up to you, but this example uses a daily schedule. It’s best to send usage records in batches to reduce the number of API calls you need to make.

You also have the option of calculating usage yourself or having Stripe do it. In this example, Stripe does the calculations so the action is set. When reporting usage, use idempotency keys to ensure usage isn’t reported more than once in case of latency or other issues.

report_usage.rb
View full sample
# Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key =
'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
# This code can be run on an interval (for example, every 24 hours) for each active # metered subscription. # You need to write some of your own business logic before creating the # usage record. Pull a record of a customer from your database # and extract the customer's Stripe Subscription Item ID and usage for # the day. If you aren't storing subscription item IDs, # you can retrieve the subscription and check for subscription items # https://stripe.com/docs/api/subscriptions/object#subscription_object-items. subscription_item_id = '{{SUBSCRIPTION_ITEM_ID}}' # The usage number you've been keeping track of in your database for # the last 24 hours. usage_quantity = 100 timestamp = Time.now.to_i # The idempotency key allows you to retry this usage record call if it fails. idempotency_key = Opus::Crypto::Random.uuid begin Stripe::SubscriptionItem.create_usage_record( subscription_item_id, { quantity: usage_quantity, timestamp: timestamp, action: 'set' }, { idempotency_key: idempotency_key } ) rescue Stripe::StripeError => e puts "Usage report failed for item #{subscription_item_id}:" puts "#{e.error.message} (idempotency key: #{idempotency_key})" end

When you report usage, the timestamp has to be within the current billing period, otherwise the call fails. If aggregate_usage is set to sum on the price, there’s an additional five minutes after the end of a billing period when you can report usage (this is to accommodate for clock drift). For all other aggregate_usage values, the timestamp has to be within the billing period.

If you need to see the usage for a customer during a current period, you can retrieve the upcoming invoice and check the quantity for each subscription_item.

Testing

Test your integration to make sure it behaves as you expect. Learn more about testing subscriptions integrations.

You can use to test clocks to test different scenarios, including mock usage records. When you use make a usage reporting call, you need to synch the timestamp of the test clock with the usage records. Make a note of the test clock timestamp so that your usage records fall within the same time window. Learn more about test clocks.

Was this page helpful?
Need help? Contact Support.
Watch our developer tutorials.
Check out our product changelog.
Questions? Contact Sales.
Powered by Markdoc
You can unsubscribe at any time. Read our privacy policy.
On this page
Sample integrations
Usage-based billing lifecycle
Prerequisites
Usage-based billing compared to other pricing models
Product modeling
Customer signup
Trials
Subscription management
Cancellations
Monitor subscription activity
Report usage
Testing
Related Guides
Design your integration
Usage-based pricing model
Billing quickstart
Stripe Shell
Test mode
Welcome to the Stripe Shell! Stripe Shell is a browser-based shell with the Stripe CLI pre-installed. Login to your Stripe account and press Control + Backtick on your keyboard to start managing your Stripe resources in test mode. - View supported Stripe commands: - Find webhook events: - Listen for webhook events: - Call Stripe APIs: stripe [api resource] [operation] (e.g. )
The Stripe Shell is best experienced on desktop.
$