Axire Infotech Logo

Axire Infotech

© 2026 All Rights Reserved

Stripe Billing for SaaS: Setting Up Subscriptions, Trials and Invoices

2026-10-26T06:18:36.652Z

Stripe Billing is the part of Stripe that runs recurring charges: you define products and prices, attach them to customers as subscriptions, and Stripe creates invoices, collects payment and retries failures. A working SaaS setup needs five things: clean prices, a trial rule, proration settings, the customer portal and a verified webhook handler.

Key takeaways

  • Prices are permanent: a Stripe price cannot be edited once created, so plan changes mean new prices and a migration, not an edit.
  • Webhooks decide access: your app should grant or remove paid features from webhook events, never from the browser redirect after checkout.
  • Trials need a rule: decide up front whether you collect a card, and what happens when no payment method exists on the last day.
  • SCA is a flow, not a setting: European cards can demand authentication on renewals, so failed-payment emails and a recovery link are part of the build.
  • Test with clocks: simulate renewals, trial ends and failures in test mode before a real customer is billed.

Stripe Billing setup at a glance

StepStripe object or featureDecision to makeWhat usually breaks
Model plansProduct and PriceOne product per plan, one price per currency and intervalEditing prices in the Dashboard instead of versioning them
Offer a trialSubscription trial settingsCard up front or not; what happens at trial endTrial ends with no card and access lingers
Change plansProration behaviourUpgrade now with credit, downgrade at period endCustomers surprised by a mid-cycle charge
InvoiceInvoices, tax IDs, receiptsCollect VAT numbers and company details at checkoutMissing business details on invoices
Self-serviceCustomer portalWhich plans and actions customers may usePortal allows plan switches your app cannot handle
Sync accessWebhook endpointWhich events update your databaseUnverified, non-idempotent handlers
Authenticate3D Secure and invoice recoveryHow a customer completes a bank challengeNo recovery link in failed-payment emails

1. What is Stripe Billing and when does it fit a SaaS product?

Stripe Billing is Stripe's subscription and invoicing product. It stores customers, products and prices, creates recurring invoices, and charges the saved payment method. It fits any SaaS that bills monthly or yearly, per seat or by usage. A one-off purchase needs only a simple checkout, not Billing.

Stripe describes Billing as monetization infrastructure that combines subscriptions and usage-based billing with its built-in payment system. For a startup, the practical benefit is that you do not write renewal logic, retry schedules or invoice PDFs yourself.

This guide is about the subscription layer. If you are still choosing how to take card payments at all, our separate post on payment gateway integration covers that decision. Here we assume Stripe is chosen and focus on what breaks once real customers renew.

The five objects you will work with

  • Customer: one per account in your app. Store your own user or organisation ID in its metadata.
  • Product: what you sell, such as "Team plan".
  • Price: an amount, currency and billing interval attached to a product.
  • Subscription: the link between a customer and one or more prices, with a status.
  • Invoice: the document created every cycle, which Stripe then tries to collect.

Our team builds these flows in Next.js and Node.js with Supabase as the database, and the pattern below reflects that stack. The ideas hold for any backend. If you are still weighing frameworks, our tech stack explainer for non-technical founders is a good companion.

2. How do you model products and prices so changes do not break customers?

Create one product per plan and one price per currency and billing interval, and never rely on editing a price. A Stripe price's amount is fixed once created. To change a plan's cost, create a new price, move new customers to it, and migrate existing subscribers deliberately.

This is where most early builds go wrong. Founders hard-code a price ID into the app, then want to raise a price six months later. If the old price is still attached to live subscriptions, you now have two prices for one plan and no map between them.

A naming scheme that survives price changes

Give every price a lookup key such as team_monthly_gbp_v1. Your code asks Stripe for the price by lookup key, so a later v2 can replace it without a code change. Archive old prices instead of deleting them, so existing subscribers keep working.

Decide early which currencies you will sell in. A UK and Nordic audience often wants GBP, EUR, SEK, DKK or NOK. Stripe lets one price carry several currencies, but each needs an amount you chose, not a raw conversion. Publish those amounts on your pricing page as well.

Map the pricing model to Stripe

Flat monthly plans, per-seat plans and usage-based plans each map to a different price setup. If you have not picked a model yet, read our breakdown of SaaS pricing models and how to pick one first. Billing code is expensive to rewrite after launch.

  • Flat or tiered: one recurring price per plan and interval.
  • Per seat: a recurring price with a quantity that your app updates when members join or leave.
  • Usage-based: a metered price where your app reports usage events and Stripe totals them each cycle.

Keep your own plan table in the database, with a column for the Stripe lookup key and the feature limits. Stripe knows what a customer pays. Your database should say what that payment unlocks.

3. How should you set up free trials in Stripe Billing?

Set a trial length on the subscription, decide whether to collect a card at sign-up, and choose what happens if no payment method exists when the trial ends. Collecting a card converts more trials to paid, while skipping it lowers sign-up friction. Pick one deliberately and test the final day.

Stripe lets you start a subscription with a trial period or a fixed trial end date. During the trial the invoice is zero, and the first real charge happens when the trial finishes.

Card up front or no card?

Our rule of thumb for early-stage B2B SaaS: if your product needs setup effort before it shows value, skip the card and rely on onboarding emails. If the value is visible in minutes, ask for the card. Neither choice is universally right, and your own conversion data should override our rule after a few hundred trials.

Trial end behaviour

For no-card trials, Stripe lets you set what happens at the end if there is no payment method: cancel, pause, or create an invoice. Pausing is usually friendliest, because a returning user can add a card and resume without recreating the subscription. Whatever you choose, make your app mirror it.

Stripe also sends a customer.subscription.trial_will_end event shortly before a trial ends. Use it to trigger a reminder email from your own system, with a button that opens the customer portal or a checkout session to add a card.

4. How do proration, upgrades and downgrades work?

When a customer changes plan mid-cycle, Stripe can prorate: it credits the unused time on the old price and charges for the remaining time on the new one. You control this with the proration behaviour setting. Most SaaS products upgrade immediately with proration and apply downgrades at the end of the period.

The setting has three practical modes: create prorations on the next invoice, invoice the difference immediately, or apply no proration at all. Which you choose changes when the customer sees the charge.

A worked example (hypothetical numbers)

Suppose a customer pays £30 a month on a 30-day cycle and upgrades to a £60 plan on day 10. This is an illustration, not a quote. Stripe calculates by the second, so real figures will differ slightly.

  • Unused time on the old plan: 20 of 30 days, so a credit of about £20.
  • Remaining time on the new plan: 20 of 30 days at £60, so about £40.
  • Net extra charge for the upgrade: about £20, either invoiced now or added to the next invoice.
  • From the next renewal, the customer pays £60.

If you add the difference to the next invoice, the customer gets the upgrade at once but sees a larger bill at renewal. That surprise generates support tickets. Invoicing immediately is cleaner for most small teams.

Downgrades and cancellations

For downgrades, schedule the change for the end of the current period. The customer has already paid for the higher tier, so they keep it until then. Avoid refund-style credits unless you have a clear policy. Your terms of service, not your code, should state what you refund.

The billing cycle anchor decides which day of the month renewals happen. Leave it at the sign-up date unless you have a reason, such as aligning every customer to the first of the month. Changing it later triggers proration of its own.

5. How do invoices, VAT and receipts work for European customers?

Stripe creates an invoice for every billing cycle, finalises it, and attempts payment. Each invoice has a hosted page and a PDF that customers can download. For European B2B sales, collect the customer's company name, address and VAT number at checkout so the invoice carries them from the start.

The invoice lifecycle runs from draft to open to paid, with void and uncollectible as the other end states. Your app rarely touches drafts. It reacts when an invoice is paid or fails.

Business details and tax

UK and Nordic finance teams expect an invoice that names their company and shows a VAT number. Stripe checkout can collect tax IDs, and Stripe offers a tax product that calculates tax by location. How VAT applies to your sales depends on where you and your customers are based, so confirm the setup with your accountant before launch. We build the flow; we do not give tax advice.

The regulation of the payment itself is separate. In the UK, payment services fall under the Payment Services Regulations 2017, which require the FCA to maintain a register of authorised payment institutions. Because Stripe handles the card processing, your SaaS is not the one moving the money. If you ever plan to hold or transfer funds for others, the FCA authorisation page on GOV.UK is where to begin checking your position.

Receipts and email

Stripe can email receipts and invoices on your behalf. Many teams switch this on at first, then replace it with branded emails from their own system once the product matures. Either way, show a billing history page inside your app. Customers should not need to hunt through their inbox for an invoice.

6. Set up the customer portal to cut billing support

The Stripe customer portal is a hosted page where customers update their card, view invoices, change plan or cancel. You create a portal session from your server and redirect the user to it. It removes the need to build most billing screens yourself, which saves weeks on an MVP.

Configure the portal in the Dashboard before you ship it. Decide three things:

  • Which plans can customers switch between. List only plans your app can handle. If a plan needs onboarding or custom limits, leave it out.
  • Whether cancellation is immediate or at period end. End-of-period is the common default, and it matches the access your customer has already paid for.
  • Whether to ask for a cancellation reason. A short list of reasons gives you churn data at no extra build cost.

The portal changes billing state without your app being involved, so it only works safely if webhooks are in place. A customer who cancels in the portal will not tell your app. Stripe will, through an event.

Branding matters for trust. Add your logo and colours so the redirect does not feel like a different company. Our UI/UX design team usually pairs the portal with a billing page inside the product that shows current plan, next renewal date and a clear "Manage billing" button.

Backend developer watching event logs on a monitor while building a billing webhook handler

7. Which webhooks keep your app in sync with billing?

The key events are checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted and customer.subscription.trial_will_end. Handle these, verify each signature, and treat the events as the single source of truth for who has access.

Subscription state changes outside your app all the time: renewals, failed renewals, portal cancellations and edits your team makes in the Dashboard. Webhooks are how your system finds out. Public Stripe guides from several developer teams make the same point, and so does our experience: a redirect URL is not proof of payment.

What each event should do

EventWhat your app should do
checkout.session.completedLink the Stripe customer ID to your account and store the subscription ID
invoice.paidExtend the access period and record the payment
invoice.payment_failedMark the account past due and start your recovery emails
customer.subscription.updatedSync plan, status, quantity and period end into your database
customer.subscription.deletedRevoke paid features and move the account to a free or locked state
customer.subscription.trial_will_endSend a reminder with a link to add a payment method

Rules for a safe handler

  1. Verify the signature. Use the signing secret and the raw request body. Reject anything that fails. A parsed-and-reserialised body will not verify.
  2. Be idempotent. Store each event ID in a table with a unique constraint. If the same event arrives twice, skip it.
  3. Respond fast. Return a 200 response quickly and do slow work, like emails, in a queue. Stripe retries events that time out or fail, so slow handlers create duplicates.
  4. Do not assume order. Events can arrive out of sequence. When one arrives, fetch the current subscription from Stripe and write that state, rather than trusting the event's snapshot alone.
  5. Use separate endpoints per environment. Test and live mode have different signing secrets. Mixing them is the most common launch-day bug we see.

In a Next.js app this is a route handler that reads the raw body, verifies it, writes to a Supabase table, and returns. Keep the table simple: customer ID, subscription ID, status, plan lookup key, current period end. Row-level security then lets each user read only their own billing row.

One question stays open for us on most projects: whether to gate access on status alone or on current_period_end as well. A past-due account may deserve a few days of grace. That is a product call, so write it down before you code it.

8. How do you handle SCA and failed payments on European cards?

Strong Customer Authentication (SCA) is the PSD2 rule that asks card customers in Europe to confirm many online payments with two factors, usually through a 3D Secure bank prompt. Stripe handles the prompt at sign-up. Your job is to recover renewals that need a customer to authenticate later.

PSD2 is in force across the EU, and strong customer authentication applies to electronic payments there, as the Austrian regulator and others describe in their guidance.

Where SCA bites a subscription

The first payment happens with the customer present, so the bank challenge appears in checkout. Renewals happen without them. Many renewals go through under exemptions or because the card was set up for off-session use. Some banks still demand authentication, and then the payment fails until the customer acts.

Stripe marks such an invoice as needing action and gives you a hosted invoice page where the customer can authenticate. That page is your recovery tool.

Build the recovery path

  • On invoice.payment_failed or an action-required status, email the customer a link to the hosted invoice page or the customer portal.
  • Say plainly in the email that their bank may ask for confirmation, and that nothing is wrong with their account.
  • Show a banner in the app with the same link, so a user who skips the email still sees it.
  • Turn on Stripe's automatic retries for ordinary declines, and set a grace period before access is removed.

Test this with Stripe's test cards that force authentication. Run both outcomes, a passed challenge and a failed one, and confirm your database ends up in the right state each time. UK cards fall under UK rules rather than EU ones, but in practice most UK SaaS vendors with European customers build for 3D Secure everywhere.

Mobile subscriptions add another layer. If you sell access inside a React Native app, check the app store's rules on digital purchases before wiring Stripe into the app. Our app development team can map which flows belong on the web and which in the store.

Two colleagues testing a card payment on a phone and laptop at a shared desk before launch

9. What breaks in real builds: a pre-launch checklist

Before launch, run every billing path in test mode using test clocks: sign up, trial end, renewal, upgrade, downgrade, failed payment, authentication challenge and cancellation. Confirm that your database matches Stripe after each one. Most billing bugs appear only on the second or third billing cycle.

Test clocks let you move a test customer forward in time, so you can watch a renewal or a trial ending in minutes instead of waiting a month. Use them for every scenario below.

  1. Create the plan table. Match each Stripe lookup key to your feature limits.
  2. Run a full signup. Checkout, webhook, database row, access granted.
  3. Advance the clock past the trial. Check both the card and no-card paths.
  4. Upgrade mid-cycle. Compare the proration invoice to your hand calculation.
  5. Force a failed payment. Confirm the past-due state, the email and the grace period.
  6. Force an authentication challenge. Complete it from the hosted invoice link.
  7. Cancel in the portal. Confirm your app revokes access at the right moment.
  8. Replay a webhook. Confirm nothing is applied twice.
  9. Check live-mode keys and endpoints. Separate secrets, separate endpoint, a real low-value test purchase you can refund.

A formal user acceptance pass helps here, because billing touches support, finance and product at once. Our UAT checklist for launch shows how to structure it.

What we would do first on a new project

Start with Checkout and the customer portal, two plans, a webhook handler with five events, and nothing custom. Add usage metering, multi-currency or invoicing extras only when a paying customer asks. A small billing system that is correct beats a clever one that is not. Founders with unusual needs, such as annual contracts with manual invoices, should plan for more custom work.

Stripe Billing FAQ

Do I need a developer to use Stripe Billing?

You can sell simple subscriptions with Stripe's no-code payment links and the customer portal. Once your app must unlock features based on plan, you need a developer for the webhook handler and plan table. That is a small, well-defined piece of work, not a large build.

How do I test Stripe Billing without charging real cards?

Use test mode with Stripe's test API keys and test card numbers, plus test clocks to simulate renewals and trial endings. Test mode has its own customers, prices and webhook secrets, so repeat your configuration in live mode before launch and never reuse test price IDs.

What happens if a webhook fails or arrives twice?

Stripe retries failed deliveries, so the same event can arrive more than once. Store processed event IDs and skip repeats. If your endpoint was down, you can also resend events from the Dashboard. Fetching the current subscription from Stripe on each event keeps your database correct either way.

Can I change a price after customers have subscribed?

You cannot edit an existing price amount. Create a new price, then update each subscription to it, choosing whether to prorate. Tell customers before a rise takes effect, and check your own terms for notice requirements. We do not give legal advice on contract wording.

Next steps: get your subscription billing built right

Stripe Billing saves months of work, but only if the plan model, trial rules and webhook handler are designed together. Axire Infotech is a lean studio in India working remotely with startups and businesses across Europe, with overlap on CET afternoons. We build these flows in React, Next.js, Node.js and Supabase, as part of our web development service.

See where billing sits among our full list of services and browse the projects we have built, or read more on the Axire blog. When you are ready to scope your own subscription flow, contact us with your plans and pricing. We reply to enquiries within 2 hours during business hours.

Recommended Resources

Contact

#stripe billing#saas subscriptions#stripe webhooks#SCA#proration#customer portal

Ready to Start Your Project?

Let's discuss your project and create something amazing together.

Stripe Billing for SaaS: Setting Up Subscriptions, Trials | Axire Infotech