SaaS Billing Architecture: Subscriptions, Usage and Entitlements
SaaS2026-09-23Agentixly Team

SaaS Billing Architecture: Subscriptions, Usage and Entitlements

SaaS billing architecture explained: pricing models, metering, entitlements, dunning and tax, with a vendor build vs buy guide and a working code example.

A SaaS billing architecture is the set of systems, pricing catalog, subscription state, usage metering, invoicing, entitlements and dunning, that turns a customer's plan into an accurate bill and the right product access every period, with no human in the loop. Get one piece wrong and it rarely fails loudly: a customer gets billed twice, usage silently drops during a traffic spike, or a downgraded account keeps enterprise features for months. This guide breaks the architecture into its real components, shows a concrete pattern for the part most teams get wrong, idempotent usage and webhook handling, and maps a vendor landscape that shifted substantially in 2026.

What Pricing Model Fits Your SaaS Product?

Most SaaS companies do not choose one pricing model so much as accumulate one: a simple flat plan gets usage limits, add-ons and enterprise tiers bolted on as the product grows. That works until the billing code encodes five special cases for five customers signed under five different verbal agreements. Picking a small number of explicit pricing primitives early, even if you only use one or two at launch, keeps the architecture able to support the others later.

| Pricing model | How it works | Best fit | Watch for | | --- | --- | --- | --- | | Flat rate | One price per billing period, no usage dimension | Simple products, easy to sell and forecast | Leaves value on the table as usage grows | | Per seat | Price scales with named or active users | Collaboration and internal tools | Seat sharing; disputes over what counts as active | | Usage-based | Price scales with a metered quantity: API calls, records, compute, tokens | Infrastructure, data and AI products where value tracks consumption | Revenue is less predictable; needs real-time metering | | Hybrid | A base platform fee plus usage on top, or per seat plus overage | Products with a clear floor and a variable cost driver | Two pricing engines to reconcile instead of one | | Credits or prepaid | Customers buy a credit balance; features and usage draw it down | AI features, multi-product platforms, usage that is hard to price per unit | Breakage and refund policy need deciding upfront |

The right model follows your cost structure and your buyer's mental model of value, not a competitor's pricing page. If your marginal cost per customer is close to zero, seat or flat pricing is simplest to sell. If cost scales with consumption, usage-based or credit pricing keeps margin intact as customers grow; our guide to SaaS development cost breaks down how infrastructure and AI usage show up in your own cost base before you set prices against it.

What Are the Components of a SaaS Billing Architecture?

Treat billing as a pipeline, not a database table. Each stage below takes an input, applies one job, and hands a clean output to the next stage, which makes every stage independently testable and independently replaceable if you later change vendors.

  1. Catalog. Defines products, plans, prices and currencies. This is the source of truth for what can be sold, and it should be versioned so a price change never rewrites what an existing customer agreed to.
  2. Subscription state. Tracks what each customer currently subscribes to: plan, quantity, trial status, renewal date and any scheduled changes. Every other stage reads from this system.
  3. Metering. Ingests usage events from your product (API calls, active seats, rows processed, tokens consumed) and aggregates them into a billable quantity per customer per period.
  4. Rating. Applies pricing rules to the aggregated quantity, tiered pricing, volume discounts, minimum commitments, to produce a price.
  5. Invoicing. Assembles subscription charges, usage charges, credits, taxes and discounts into an invoice, and drives payment collection.
  6. Entitlements. Translates the customer's paid plan into what the product allows right now: feature flags, limits and access, checked on nearly every request.
  7. Dunning. Handles failed payments: retry schedules, card-update prompts, grace periods, and eventual suspension or downgrade.
  8. Tax. Determines the right jurisdiction and rate for each sale and keeps records for remittance and audits.

Most billing outages trace back to two stages being merged that should have stayed separate: entitlements checked by calling the billing provider's API live, or metering written directly against the invoicing system instead of an append-only event log. Keep the stages apart and each one degrades independently instead of taking the whole product down with it. For how this pipeline sits inside the rest of your platform, see our guides to multi-tenant SaaS architecture and designing modern SaaS architecture for scale.

How Does Usage-Based Billing Work?

A usage-based system starts with an event: "customer X made an API call" or "customer Y processed 4 records." Your application emits that event immediately, carrying a stable identifier your own system generated, not one assigned later by a billing vendor. A meter definition tells the billing layer how to turn a stream of events into a billable quantity, for example by summing a numeric value across the billing period, and which customer each event belongs to. Stripe's Meters API, for example, separates the meter definition from the individual meter events you send, so you can change how usage aggregates without touching the event stream itself.

Two problems show up the first time usage crosses a billing boundary. Late events happen when a client buffers usage offline and reports it after the period closed, so your rating logic needs an explicit policy: bill it next period, reopen the invoice, or drop it past a cutoff. Out-of-order events happen because delivery order is not guaranteed, so your aggregation must be commutative (sums and counts are safe; anything that depends on sequence, such as "last value wins," is not, unless you add your own sequencing).

Example: an API product charges 2 dollars per 1,000 requests above a 50,000 request monthly allowance. Assumptions: a customer on the standard plan makes 180,000 requests in a month, with the allowance included in the base fee. Billable usage is 180,000 minus 50,000, or 130,000 requests, which is 130 billable units of 1,000. At 2 dollars per unit, usage charges are 260 dollars for the period, on top of the flat plan fee. The rating engine, not the metering pipeline, owns this allowance-and-overage math, so the same raw usage events can support a pricing change without re-ingesting a single event.

Metering pipelines drift from reality if nothing checks them. Run a daily reconciliation job that compares your internal usage ledger against what your billing provider recorded, and alert on any gap past a small tolerance. Drift usually means a webhook was missed, a deploy dropped an event, or a customer integration is double-sending, and catching it in hours instead of at month-end invoicing saves the awkward call explaining a surprise bill.

Building an Idempotent Usage and Webhook Pipeline

Idempotency is the property that processing the same event twice has the same effect as processing it once. Billing is one of the few places in a SaaS product where getting this wrong has a dollar amount attached, so it deserves more rigor than a typical webhook handler.

The pattern is the same whether you are ingesting your own usage events or handling webhooks from a billing provider: verify authenticity first, extract a stable event identifier, and use that identifier as a database-level uniqueness constraint before any side effect runs. Providers that guarantee at-least-once delivery, Stripe's webhook system retries failed deliveries with exponential backoff for up to three days, will send the same event more than once during network issues or deploys, and they do not guarantee delivery order. Code that assumes an event fires exactly once, in order, will eventually double-charge or double-grant access.

import type { Request, Response } from "express";
import Stripe from "stripe";
import { db } from "./db";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET as string;

// Mount this route with the raw body parser only; parsing JSON before
// this handler runs corrupts the payload used for signature verification.
export async function handleStripeWebhook(req: Request, res: Response) {
  let event: Stripe.Event;

  try {
    const signature = req.headers["stripe-signature"] as string;
    event = stripe.webhooks.constructEvent(req.body, signature, webhookSecret);
  } catch (err) {
    console.error("Webhook signature verification failed", err);
    return res.status(400).send("Invalid signature");
  }

  // Dedupe on Stripe's event id, not on event.created: delivery order is
  // not guaranteed, and retried deliveries reuse the same event id.
  const alreadyProcessed = await db.processedEvents.findUnique({
    where: { eventId: event.id },
  });

  if (alreadyProcessed) {
    return res.status(200).send("Already processed");
  }

  // Record the event and enqueue the real work in one transaction, so a
  // crash between the two steps cannot cause a silent double-run.
  await db.$transaction(async (tx) => {
    await tx.processedEvents.create({
      data: { eventId: event.id, type: event.type, receivedAt: new Date() },
    });
    await tx.billingJobs.create({
      data: { eventId: event.id, payload: event as unknown as object },
    });
  });

  // Return 2xx immediately; a background worker processes billingJobs.
  // Stripe expects a response within 10 seconds and retries on timeout.
  return res.status(200).send("Queued");
}

Three details make this reliable in production. First, the uniqueness constraint on eventId lives in the database, not in application logic, because two concurrent requests can both pass an in-memory check before either writes. Second, recording the event and enqueueing the job happen in the same transaction, so a crash between them cannot leave the event marked processed while the work never ran. Third, the handler does no slow work itself, invoice updates, emails, downstream API calls, so a slow dependency cannot cause the provider to time out and retry an event you already accepted.

Entitlements and Feature Gating: The Layer Billing Forgets

Billing answers "what does this customer owe." Entitlements answer "what can this customer do right now," and the two questions have very different latency and availability requirements. A checkout flow can tolerate a few hundred milliseconds and the occasional retry. A feature-gate check that runs on every page load or every API request cannot: if it calls your billing provider synchronously, a billing provider outage becomes a product outage.

The fix is an entitlements service that sits inside your own infrastructure, fed by webhooks from subscription state changes, and queried locally (in-memory cache, Redis, or a fast local table) on the request path. When a plan changes, a webhook updates the local entitlement record; the request path never waits on an external call. This also gives you one place to answer questions billing was never designed for: feature flags by plan, usage limits that need a soft warning before a hard block, and sales-negotiated overrides for a single enterprise account.

Purpose-built entitlement platforms, Stigg and Schematic are two current examples, exist specifically to manage this layer: they let you define plans and limits once, enforce them at runtime through an SDK, and let sales override a single customer's limits without a code deploy. That is worth evaluating before you build a bespoke entitlements table, especially once you support both self-serve and sales-led deals with different override needs. Enterprise buyers add another layer on top of entitlements, role-based access rather than plan-based access, which we cover in enterprise-ready SaaS: SSO, SCIM, RBAC and audit logs.

Build vs Buy: Choosing a Billing Platform in 2026

The usage-based billing vendor landscape consolidated hard in 2026, which matters if you are choosing a platform today, because you are also choosing which acquirer's roadmap you inherit. Stripe completed its acquisition of Metronome in January 2026, folding real-time metering and enterprise contract management into Stripe Billing, and Adyen closed its acquisition of Orb on July 1, 2026. Stripe had already acquired merchant-of-record platform Lemon Squeezy in 2024 and, by early 2026, was migrating merchants onto Stripe's own Stripe Managed Payments. Lago remains an independent, open-source, self-hostable billing engine, and Maxio, the 2022 merger of Chargify (now sold as Advanced Billing) and SaaSOptics (now Maxio Core), continues to operate as a standalone subscription platform, alongside longer-standing players Zuora, Chargebee, Recurly and Paddle.

| Decision | Build in-house | Buy a platform | | --- | --- | --- | | Core subscription billing | Rarely worth it below a dedicated billing team | Default for most: Stripe Billing, Chargebee, Recurly, Maxio, Zuora | | Usage metering | Workable with an event log and scheduled aggregation | Lago for open-source, self-hosted control at scale | | Entitlements and feature gating | Common to build since it touches product logic closely | Stigg or Schematic for sales-negotiated overrides without a deploy | | Global sales tax and VAT | Rarely worth building; jurisdiction rules change constantly | Paddle as merchant of record, or Anrok layered on your billing stack | | Dunning and payment retries | Skip building it; a solved problem | Your billing platform's built-in retry and card-update flows |

Two questions cut through most build vs buy debates faster than a feature checklist. First, does your pricing model fit the platform's data model without workarounds, since every workaround becomes a migration cost later. Second, given 2026's acquisitions, who owns the platform's roadmap now, and does their incentive still align with yours as a standalone billing vendor, or has the product been folded into a payments or checkout business with different priorities.

Why Do Tax and Dunning Break at Scale?

Selling software across borders means collecting the right tax in the right jurisdiction, and getting it wrong is a compliance problem, not just a billing bug. Two structurally different approaches exist. A merchant of record, such as Paddle or Stripe Managed Payments, becomes the legal seller of record, calculates and remits tax on your behalf, and takes a larger cut of revenue for absorbing that liability. Alternatively, you stay the seller of record and use a calculation specialist, such as Anrok, layered on your existing billing platform, which costs less but leaves registration and remittance to your finance team.

Inside the EU, the VAT One Stop Shop lets a business register once and file a single return for cross-border business-to-consumer digital sales instead of registering in every member state where it has customers. This is not legal or tax advice, and thresholds and rules vary by jurisdiction and change over time, so confirm your specific obligations with a tax advisor before you launch in a new market.

Dunning, the process of recovering failed payments, is worth taking seriously: involuntary churn from expired cards and failed charges is often a larger revenue leak than voluntary cancellations, and most of it is recoverable with process rather than more sales effort. A solid dunning flow retries failed charges on a schedule spread over one to two weeks rather than immediately, since many failures are temporary, prompts customers to update expired cards before they lapse, and applies a grace period with in-product warnings before suspending access. Configure this once in your billing platform, then revisit the retry schedule and messaging quarterly against your own recovery rate.

Pricing Migrations, Grandfathering and AI Credits

Pricing changes are inevitable, and how you migrate existing customers onto a new price matters as much as the new price itself. Treat every price as versioned and immutable: a price change creates a new price object and, usually, a new plan, rather than mutating the number on an existing one. Existing subscriptions keep referencing their original price, grandfathering, until you explicitly migrate them, either automatically after a notice period or by customer choice.

  1. Version the price, do not edit it. Create a new price or plan ID for the new terms; never change the amount on a price ID customers are already subscribed to.
  2. Segment affected customers. Query subscriptions by current price ID so you know exactly who is affected before you announce anything.
  3. Decide a grandfather window. Common patterns are indefinite grandfathering for existing customers, or a fixed notice period of 30 to 90 days before migration.
  4. Notify before you migrate. Email and in-product messaging, with the specific date, the specific new price, and what happens if the customer does nothing.
  5. Migrate in batches. Move a small cohort first, watch support volume and payment failure rates, then proceed to the rest.
  6. Keep the old price queryable. Finance and support need to see historical pricing on old invoices long after the price itself is retired.

Credit-based pricing has become the default for AI features because the underlying cost per request is volatile and hard to attach to a flat fee. The common pattern meters raw usage (tokens, requests, minutes of compute) at the infrastructure layer, applies a margin over the actual cost from the model provider, and exposes the result to customers as simple credits rather than raw token counts they have no intuition for. Keep that margin configurable and out of customer-facing contracts as a fixed number, since model provider pricing changes faster than most sales contracts get renegotiated. Our guide to adding AI features to your SaaS goes deeper on the unit economics behind this margin.

Illustrative scenario: a SaaS product sells AI summarization credits. Assumptions: the underlying model call costs the vendor 0.4 cents per summary on average, the product targets a 70 percent gross margin on AI usage, and credits are sold in bundles. Cost-plus pricing at that margin means charging roughly 1.3 cents of credit value per summary (0.4 cents divided by 0.3, since a 70 percent margin means cost is 30 percent of price). A bundle representing 1,000 summaries would list at roughly 13 dollars. The product displays "1,000 credits" to the customer, not a cents-per-summary calculation, which is the entitlements layer hiding the rating math from the buyer.

How Agentixly Approaches SaaS Billing Architecture

Agentixly designs and builds billing architecture as part of its SaaS development work, for startups moving from a single flat price to usage-based or hybrid models, and for scale-ups replacing a billing system they have outgrown. The approach stays consistent across engagements, without promising a specific outcome before we have seen your pricing model and existing data.

  1. Pricing and data model discovery. Map your actual pricing rules, including the verbal exceptions and grandfathered deals nobody wrote down, before writing a line of migration code.
  2. Architecture. Design the catalog, subscription state, metering and entitlements boundaries as separable services, and choose which stages to build versus buy against the table above.
  3. Build. Implement the metering pipeline, idempotent event and webhook handling, and the entitlements service, with the same code review and testing standards as the rest of the product.
  4. Reconciliation and monitoring. Stand up the internal usage ledger, the drift-detection job against your billing provider, and alerting before launch, not after the first disputed invoice.
  5. Handover. Documentation of the pricing model, the schema and the migration runbook, owned by your team from day one.

Where billing touches security, access to the customer ledger, payment data handling, audit logging, our cybersecurity discipline reviews the design alongside the SaaS team rather than after the fact.

Next Steps

A SaaS billing architecture earns its complexity only when it matches how you actually price your product, not before. Start with the pipeline: get catalog, subscription state and invoicing right using a platform rather than custom code, add metering and entitlements as separate services once usage-based or hybrid pricing is real, and treat idempotency as a requirement from the first event you ingest, not a fix you add after the first duplicate charge.

If you are designing or rebuilding billing for a usage-based or enterprise pricing model, explore Agentixly's SaaS development services or get in touch to talk through your pricing model and current architecture. Every inquiry gets a response within 24 hours.