Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources

Usage-based billingLegacy

Charge customers based on how much they use your product or service.

Note

We’ve updated the way usage-based billing works. See the updated usage-based billing docs.

Learn how to migrate.

Getting started

Usage-based pricing model

Learn how to model usage-based pricing on Stripe.

Record usage

Record the usage of your users and report it to Stripe.

Usage-based billing overview

Understand the major pieces of a usage-based billing integration.

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.

Sample integration

This example walks through the implementation of a fictional font service called Typographic.

Create a product and pricing

Model your business on stripe with products and prices.

Create your products and their pricing options with the Stripe API or Dashboard. Typographic has three products, each with two tiers:

  • Standard
    • Tier one: 10 USD per month for 10,000 requests
    • Tier two: An additional $0.10 USD for each request after 10,000
  • Growth
    • Tier one: 25 USD per month for 10,000 requests
    • Tier two: An additional $0.10 USD for each request after 10,000
  • Enterprise
    • Tier one: 75 USD per month for 10,000 requests
    • Tier two: An additional $0.0075 USD for each request after 10,000

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

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.

To create a metered usage pricing model on Stripe through the Dashboard:

First, create the Standard product. To learn about all the options for creating a product, see the prices guide.

  1. Go to the Products tab.
  2. Click + Add product.
  3. Enter the Name of the product: Standard, in this case.
  4. (Optional) Add a Description. The description appears at checkout, on the customer portal, and in quotes.

Next, create the monthly price for the Standard product. Select Graduated pricing for the Pricing model, then select Recurring.

Create two graduated pricing tiers:

First unitLast unitPer unitFlat rate
For the first010,0000.00 USD10.00 USD
For the next10,001∞0.10 USD0.00 USD

Then, select Monthly for the Billing period and check Usage is metered.

Repeat the steps for the Growth and Enterprise products, filling in the appropriate values as necessary.

Read the docs to learn more about different pricing models.

Sign up customers

To let your customers sign up for your services, you need to present a payment form on your website. Use Stripe Checkout to embed the form on your site or redirect customers to a Stripe-hosted form. 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.

Stripe offers other options for setting up your payment form:

  • Pricing tables: Create a pricing table from the Stripe Dashboard and embed it on your site. When a customer selects a plan, they’re taken to your payment page. Pricing tables don’t support sub-cent pricing.
  • Web Elements: Build custom checkout flows to integrate with your site.

Create a usage record

Throughout each billing period, you need to report usage to Stripe so that customers are billed the correct amounts. You can maintain your own system for recording customer usage and provide usage information for subscriptions to Stripe.

Learn how to record and report usage.

Test your integration

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

You can use test clocks to test different scenarios, including mock usage records. When you make a usage reporting call, you need to sync 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.

OptionalFree 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.

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 you can safely provision your product for your customer. The subscription transitions automatically to active when a customer makes the first payment.
activeThe subscription is in good standing. For past_due subscriptions, paying the latest associated invoice or marking it uncollectible transitions the subscription to active. Note that active doesn’t indicate that all outstanding invoices associated with the subscription have been paid. You can leave other outstanding invoices open for payment, mark them as uncollectible, or void them as you see fit.
incompleteThe customer must make a successful payment within 23 hours to activate the subscription. Or the payment requires action, such as customer authentication. Subscriptions can also be incomplete if there’s a pending payment and the PaymentIntent status is processing.
incomplete_expiredThe initial payment on the subscription failed and the customer didn’t make a successful payment within 23 hours of subscription creation. 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 Dashboard subscription settings determine the subscription’s next status. If the invoice is still unpaid after all attempted smart retries, you can configure the subscription to move to canceled, unpaid, or leave it as past_due. To reactivate the subscription, have your customer pay the most recent invoice. The subscription status becomes active regardless of whether the payment is done before or after the latest invoice due date.
canceledThe subscription was 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 generate, but payments aren’t attempted. Revoke access to your product when the subscription is unpaid because payments were already attempted and retried while past_due. To move the subscription to active, pay the most recent invoice before its due date.
pausedThe subscription has ended its trial period without a default payment method and the trial_settings.end_behavior.missing_payment_method is set to pause. Invoices are no longer created for the subscription. After attaching a default payment method to the customer, you can resume the subscription.

Learn more about subscriptions and webhooks.

OptionalCancellations

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

When a subscription is canceled, it can’t 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. This adjustment is known as a proration. You can use the create preview invoice endpoint to display the adjusted amount to your customers.

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

script.js
function createPreviewInvoice( customerId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-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. Create a preview 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
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# 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_BQokikJOvBiI2HlWgH4olfQ2'
post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) invoice = Stripe::Invoice.create_preview( customer: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true, clear_usage: true }, { price: ENV[data['newPriceId']], deleted: false } ] } ) invoice.to_json end

OptionalBilling thresholds

Billing cycle anchor

When a threshold is reached, your code controls whether to reset the billing cycle anchor, prorating all potential licensed subscriptions accordingly.

Billing thresholds allow you to issue an invoice, and to (optionally) reset a subscription’s billing cycle anchor, when a customer’s accrued usage in a subscription service period reaches a specified monetary or usage threshold. Consider using billing thresholds if you want to add precautions to limit the amount owed, or to limit the products consumed, between invoices or charges.

Add a monetary threshold to a subscription

You commonly set the amount of a threshold’s value to a multiple of the cost of one unit of the product being sold.

Setting a lower amount threshold causes your customers to receive an invoice for every unit of usage, which can cause confusion.

The value is a positive integer in the smallest currency unit (for example, 100 cents to charge 1 USD; or 100 to charge 100 JPY, a zero-decimal currency). It must be at least 50 currency units.

You can also set monetary thresholds in the Dashboard, when you create or update a subscription.

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/subscriptions/sub_49ty4767H20z6a \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "billing_thresholds[amount_gte]"=10000 \ -d "billing_thresholds[reset_billing_cycle_anchor]"="false"

Add a usage threshold to a subscription item

As with monetary thresholds, usage thresholds should ideally be greater than one unit of usage, to avoid frequent invoicing. Stripe doesn’t currently support setting usage thresholds through the Dashboard.

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/subscription_items/si_CFhSgkWb0MyTWg \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "billing_thresholds[usage_gte]"=2000

Thresholds and billing cycle anchor

When a customer’s usage reaches a threshold, the subscription’s billing cycle anchor won’t change (by default). For example, if a threshold is reached in the middle of a month-long subscription, the subscription resets at the end of the month like a subscription without thresholds.

You can change this behavior so that reaching a threshold resets the billing cycle anchor. Doing this effectively treats reaching a threshold as if the subscription had reached its natural rollover point at the end of the month.

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/subscriptions/sub_49ty4767H20z6a \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "billing_thresholds[reset_billing_cycle_anchor]"="true"

Be aware that reset_billing_cycle_anchor=true isn’t allowed if a metered subscription has aggregate_usage=last_ever.

Thresholds and tiered pricing

Tiers are maintained across threshold invoices. As with a subscription without thresholds, tiers reset only at the end of the billing period, or if you configure the subscription to reset the billing cycle anchor when it reaches a threshold.

For example, let’s say you run an ad platform that has a graduated tiering structure for ad impressions:

TierAmount (unit cost)
1-10000 (up_to=10000)0.50 USD (unit_amount=50)
10000+ (up_to=inf)0.40 USD (unit_amount=40)

Because usage is billed after the fact, you set a threshold of 100 USD as a stopgap for new customers. Under this scheme, your customer is effectively billed every 200 impressions for the first 10,000 impressions (200 * 0.50 USD = 100 USD). When the customer exceeds 10,000 impressions, they’re effectively billed every 250 impressions (250 * 0.40 USD = 100 USD). This continues until the end of the billing period, at which point all un-invoiced usage are invoiced, and the subscription and tiers reset.

If you prefer that tiers reset upon reaching a threshold, you must configure the subscription to reset the billing cycle anchor when usage reaches the thresholds that you set.

Volume tiers

Volume tiers define the pricing for all units of usage, as opposed to graduated tiers, which define pricing for a specific amount of usage. Some pricing models use volume tiers that decrease the unit cost at each successive tier. You can use such models to incentivize customers to use more of a product (for example, ad impressions, or GB of storage).

When combined with thresholds, these pricing models can lead to invoices with line items for negative amounts, under the following conditions:

  1. A threshold invoice has already been issued.
  2. Subsequent usage bills at a lower unit cost.

For example, with these tiers:

TierAmount (unit cost)
1-10000 (up_to=10000)0.50 USD (unit_amount=50)
10000+ (up_to=inf)0.40 USD (unit_amount=40)

If a customer uses 10,000 units, the invoice total is 5,000 USD (10,000 * 0.50 USD = 5,000 USD). Any additional usage causes all usage to bill at the lower unit cost of 0.40 USD. So, if the customer uses just one more unit, the invoice total drops to 4,000.40 USD (10,001 * 0.40 USD = 4,000.40 USD).

If the subscription didn’t have thresholds, Stripe would issue an invoice for 4,000.40 USD at the end of the billing period.

However, to see how negative invoicing can happen, assume that we have a 5,000 USD monetary threshold in place. In this scenario, Stripe issues an invoice when the customer reaches 10,000 units of usage.

If the customer uses just one more unit, the invoice total drops to 4,000.40 USD (10,001 * 0.40 USD = 4,000.40 USD). However, if the customer consumes no more units, then they’re owed 999.60 USD (5,000 USD - 4,000.40 USD = 999.60 USD). At the end of the billing period, Stripe credits this amount to the customer’s balance, which is used to pay down future invoices.

Let’s say the customer continues to accrue usage. The cost of this usage reaches 5,000 USD again when the customer has used 12,500 units (5,000 USD / 0.40 USD = 12,500). However, the previous payment of 5,000 USD covers all of this usage, so no invoice is issued.

Stripe won’t issue an invoice until either the total usage reaches 25,000 units (for a total cost of 10,000 USD), or the end of the billing period arrives—whichever occurs first. The tables below show the line items you should expect to see for the two invoices issued in the case where usage reaches 25,000 units.

Invoice 1

Line ItemQuantityAmount
Usage (0.50 USD per unit)10,0005,000 USD
Total5,000 USD

Invoice 2

Line ItemQuantityAmount
Usage (0.40 USD per unit)25,00010,000 USD
Amount previously billed (at 0.50 USD per unit)-5,000 USD
Total5,000 USD

Limitations and caveats

  • Thresholds don’t apply to trial subscriptions.
  • Monetary thresholds must be greater than the sum of any flat rates on usage-based subscription items.
  • Billing thresholds aren’t evaluated during the 24 hours leading up to the end of a subscription. This helps limit confusion for a customer who receives multiple invoices on the same date.
  • Subscriptions are only allowed a single monetary threshold.
  • Subscription items are only allowed a single usage threshold.
  • Given the real-time nature of usage reporting, invoices might not be issued at the exact moment a specified threshold is reached. Invoiced amounts or usage might be slightly higher than the specified thresholds.
  • The value used to determine whether a monetary threshold has been reached excludes taxes, but includes discounts and applicable prorations.
  • If a subscription uses the last_ever aggregation mode, you can’t enable the reset_billing_anchor option.

OptionalAggregate usage

You can apply the usage-based pricing model in situations where the unit you’re measuring isn’t strictly based on a sum.

For example, Typographic offers a copywriting service where they charge based on how many words are written. Typographic bills their customers at the end of the month based on their usage of the copywriting service, in addition to the flat monthly fee. Typographic wants to charge for the maximum number of words used per customer per month. They can configure this with the aggregate_usage parameter:

Command Line
cURL
No results
curl https://api.stripe.com/v1/prices \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d nickname="Copywriting service" \ -d product={{PRODUCT_ID}} \ -d unit_amount=10000 \ -d currency=usd \ -d "recurring[interval]"=month \ -d "recurring[usage_type]"=metered \ -d "recurring[aggregate_usage]"=max

Imagine that a customer has 2,000 words written on June 1, then has another 1,000 words written on June 15. Later, they’re credited for 1,000 of the first 2,000 words on June 20. The billed amount at the end of the month is 2.00 USD (2,000 words maximum usage during the month, charging .10 USD per word).

The aggregate_usage parameter determines how subscriptions handle usage records. Here are the options for that parameter:

  • sum—The default value (passed if you don’t specify the parameter). The total billed is based on the sum of all usage records for the billing period.
  • last_during_period—The total billed is based on the most recent usage record for the billing period. If no usage is reported for the billing period, the total billed is based on a usage quantity of 0.
  • last_ever—The total billed is based on the most recently provided usage record. If no usage is reported during the current billing period, Stripe looks for a previous usage record. If no usage record is found, the total billed is based on a usage quantity of 0.
  • max—The total billed is based on the usage record with the largest usage quantity for the billing period. If no usage is reported for the billing period, the total billed is based on a usage quantity of 0.

Which option you choose depends on how you handle usage on your end. You also set the value of the action parameter of the usage records API to reflect how you record usage.

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/prices \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "currency"="usd" \ -d "recurring[interval]"="month" \ -d "recurring[usage_type]"="metered" \ -d "product_data[name]"="Gold special" \ -d "nickname"="Gold special price" \ -d "unit_amount"=3000

When you create the subscription:

  • Don’t pass quantity.
  • Make sure to record the subscription item ID. You pass this value to the Usage Records API to report usage.

OptionalTransforming quantities

Use the transform_quantity option to aggregate usage before multiplying by unit cost. This is useful if you want to report a different quantity or usage before totaling price.

Typographic decides to expand their offerings with a custom font design service. Custom designs can be labor-intensive, so they charge an extra fee (another Product) based on the level of customization. Designers report the exact length of time it took to perform the customization, but Typographic doesn’t want to charge customers by the minute. Instead, Typographic charges for each hour spent customizing-even a partial hour.

First, create the font customization product:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/products \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d name="Font Customization Service" \ -d unit_label=Hours

Next, create a price for the font customization service product, charging 150 USD an hour and rounding up (to charge for a full hour even if only part of the hour is used):

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/prices \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d nickname="Customization Per Hour Rate" \ -d unit_amount=15000 \ -d currency=usd \ -d "recurring[interval]"=month \ -d "recurring[usage_type]"=metered \ -d product={{FONT_CUSTOMIZATION_SERVICE_PRODUCT_ID}} \ -d "transform_quantity[divide_by]"=60 \ -d "transform_quantity[round]"=up

If a designer spends 150 minutes customizing, that customer would be charged 450 USD for 3 hours of customization (2 hours and 30 minutes, rounded up).

See also

  • Sample implementation repository
  • Usage-based billing video tutorial
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Join our early access program.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc