subscription-use-cases: a Stripe Billing sample with fixed price and metered variants
Create subscriptions with fixed prices or usage based billing.
At a glance
- What is it?
- The stripe-samples/subscription-use-cases repository is a MIT licensed set of runnable samples that show how to create a customer and subscribe them to a plan with Stripe Billing, split into a fixed price variant, a usage based variant and a legacy usage based directory. It suits a developer who wants to see the API calls in context rather than read a subscription guide from scratch.
- Who is it for?
- subscription-use-cases fits a developer who needs to see Stripe Billing wired end to end, from creating a customer and a Price with a lookup key to subscribing them and handling the checkout, with two pricing tiers pre-arranged so the tiers, the coupons and the upgrade path are all visible in the code.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 175 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two pricing tiers, a checkout page and a coupon path
The purpose of this repository is narrow and stated in the first line: it shows how to create a customer and subscribe them to a plan with Stripe Billing.
The README compares four options. The first is Stripe Checkout, a hosted page, which is a separate repository. The three that live here are the fixed price subscriptions with Elements, the usage based subscriptions with Elements, and this one as the umbrella sample, with a hosted demo at checkout.stripe.dev.
The feature matrix at the top of the README is worth reading as a decision table. Defining prices in the CLI, the Dashboard or the API is supported by all three. Charging a fixed price on a recurring basis is supported by Checkout and the fixed price variant. Charging customers based on their usage, by creating a metered subscription, is supported by Checkout and the usage based variant, and the fixed price variant is explicitly not in that column. Apple Pay and Google Pay support is built into Checkout with no extra code needed, and the Elements variants do not claim it. Coupon support for subscriptions is supported by all three.
The requirement list makes the setup concrete. You need a Stripe account, you need API keys from the test dashboard, and you need two Price objects on the account with lookup_key set to sample_basic and sample_premium. The lookup key is the mechanism that lets the sample find the right price at runtime without hardcoding a price id, which is the detail that lets the same code work across test and live environments.
Two pricing tiers is the minimum for demonstrating a plan change, so the sample can show a subscriber moving from a basic tier to a premium one, which is the flow most teams need to understand first.
Two ways to install, and why the .env differs between them
The README is explicit that the sample can be installed two ways, Stripe CLI or git clone, and that the .env configuration will vary depending on which way you install.
The Stripe CLI route is described as the fastest way to clone and configure a sample to run locally, and the recommended approach, with the reason given: it will only download the code required for the server language you select. The steps are to install the CLI if you have not, link it to your account with stripe login, then run the sample installer:
stripe samples create subscription-use-casesThe CLI walks through choosing the integration type, the server and client languages, and partially configures the .env file with your Stripe API keys. Then you move into the server directory:
cd subscription-use-cases/serverThe one manual step left is the STATIC_DIR value in server/.env, which should be ../client when the sample was installed with the CLI. That is the detail that catches people out, because the directory layout differs between the two install methods and a wrong STATIC_DIR means the client assets are not served.
The alternative is to download and run directly with this repository. The .env.example file in the root shows the minimal configuration:
# Stripe keys
STRIPE_PUBLISHABLE_KEY=pk_12345
STRIPE_SECRET_KEY=sk_12345
# Optional
STRIPE_WEBHOOK_SECRET=whsec_1234The two required keys are the publishable key and the secret key, and the webhook secret is marked optional because it is only needed if you are receiving webhooks. The publishable key is safe to expose to the browser and the secret key is not, and the publishable key for the React front end is a separate variable, VITE_STRIPE_PUBLISHABLE_KEY, because the client is a Vite application.
Test cards, 3D Secure, and what you can safely try
The README explains how to exercise the samples without moving real money, and two test card numbers do most of the work.
The hosted demos run in test mode, and the instruction is to use 4242424242424242 as a test card number with any CVC and any future expiration date. That is the card that always succeeds, and it is the one to use when you want to walk the happy path of creating a customer and subscribing them.
The second number, 4000002500003155, triggers a 3D Secure challenge flow. That is the interesting one for a developer because it exercises the authentication step that a real card would go through, and it is where the failures that a simple success card would hide become visible.
The README links to the Stripe testing documentation for more about test cards, and that is where the full set of behaviours lives, including the declined and error cases that a sample cannot enumerate for you.
The wider point is that the samples give you a sandbox with the API surface of the real thing. A subscription in Stripe is not a single request, it is a sequence, with a customer, a price, a subscription and then a payment attempt, and the test cards let you walk that sequence and see the results, including the ones that end in a decline. The local server the sample runs is the same code path that would run in production, with test mode substituted for live mode.
The three directories, and why one of them says legacy
The repository layout tells you how the sample is organised, and one directory name is worth a second look.
There are three sample directories: fixed-price-subscriptions/, usage-based-subscriptions/, and usage-based-subscriptions-legacy/. The last one is named legacy, which means the current usage based implementation is the non legacy directory, and that the two exist side by side. That is a common pattern in sample repositories where a rewritten approach was added alongside the original, but it also means a reader who follows an outdated link will land on the older code. The README's own links point at the current directories, so follow those rather than a search result.
The other top-level entries describe the supporting infrastructure. There is a .cli.json file, which is the configuration the Stripe CLI reads to know the sample's name and structure. There is a .env.example, which is the template described earlier. There is a spec/ directory and a .rspec file, so the sample has RSpec tests, and a Gemfile for the Ruby tooling. There is a main.tf file, which is Terraform configuration, presumably for standing up the supporting infrastructure such as a webhook endpoint receiver. There is a .github/ directory, an .vscode/ directory, a .gitignore, and a LICENSE file.
The .env.example is notably small compared to the fuller .env shown in the README's install section. The example file has only the publishable key, the secret key and the optional webhook secret, while the README's own block also includes VITE_STRIPE_PUBLISHABLE_KEY for the React front end. That difference is a good indication of which variables are truly required and which are situational, and the file is the quicker reference.
The presence of spec/ and .rspec also tells you something about the intended workflow. These are not throwaway snippets, they are samples with tests, which means the expected way to use them is to run them and to change them.
What a sample leaves out, and the difference from the docs
It is worth being clear about what this repository is and is not, because the phrase sample carries a specific promise.
A sample demonstrates a flow. It is not a library you depend on, and it is not a starting point that is safe to ship. The code is written to be read and run, and the parts a production deployment needs that are not part of the demonstrated flow are usually the parts left out.
Concretely, that means the sample shows the sequence of API calls, the Elements integration for the fixed price case, the metered subscription for the usage based case, and the price lookup mechanism, but it does not show you how to store which customer belongs to which user of your application, how to handle a webhook that arrives twice, or how to reconcile a subscription whose state changed while your service was down. The README also does not document a subscription lifecycle policy, and there is no migration or seed script in the tree.
The relationship to the documentation is the other thing to get right. The README points at the official documentation for Stripe billing checkout overview, and the repository homepage is the Stripe Billing docs page. The samples are meant to be read alongside the docs, not instead of them. The README's own contribution to that is the feature matrix, which is a more compressed piece of guidance than the docs usually offer, since it puts the fixed price and metered cases side by side in one table.
For a developer who has read the subscription guide and wants to see it work, that is exactly the right shape of resource. For a developer who has not, the sample will get a subscription created and the flow will be visible, but the billing concepts behind it, proration on an upgrade, what happens when a payment fails, why a trial needs a payment method, will still need the documentation.
One practical note about the licences involved. The repository is MIT, so the code is reusable with attribution. The Stripe account and the API terms are separate, and this review does not interpret them.
Editorial conclusion
subscription-use-cases fits a developer who needs to see Stripe Billing wired end to end, from creating a customer and a Price with a lookup key to subscribing them and handling the checkout, with two pricing tiers pre-arranged so the tiers, the coupons and the upgrade path are all visible in the code. It is the wrong thing to adopt as a dependency, because it is a sample that expects you to bring your own Stripe account and two Price objects, and it is the wrong thing to copy wholesale into production, because the samples deliberately omit the parts a real deployment needs, such as idempotent webhook handling and a persistent customer mapping. Before you start, read the How to create Prices section in the README, and note that the usage based directory has a legacy counterpart, so check which one the documentation points at before you follow it.
Frequently asked questions
How do I run the subscription-use-cases sample locally?
The README's recommended path is the Stripe CLI: run `stripe login`, then `stripe samples create subscription-use-cases`, then `cd subscription-use-cases/server`. You can also clone and run the repository directly, and the .env configuration differs between the two methods.
What do I need before the Stripe subscription sample will work?
A Stripe account, API keys from the test dashboard, and two Price objects with lookup_key set to `sample_basic` and `sample_premium`, since the sample demonstrates two pricing tiers.
Which test card should I use with the Stripe Billing samples?
The README says the hosted demos run in test mode and to use `4242424242424242` with any CVC and a future expiration date. Use `4000002500003155` to trigger a 3D Secure challenge flow.
What is the difference between the fixed price and usage based directories?
The feature matrix in the README shows that the fixed price variant supports charging a fixed price on a recurring basis but not usage based charges, while the usage based variant supports metered subscriptions. The repository also contains a usage-based-subscriptions-legacy/ directory alongside the current one.
Is the Stripe subscription-use-cases repository still updated?
The repository is not archived and the last push was on 2026-05-01 on the main branch. The only release tag is v1.0 from 2021-04-27, and the licence is MIT.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/stripe-samples-subscription-use-cases)Was this useful?