Production-Ready Billing & Subscription Database Schema

Below is a production-grade Billing & Subscription database schema, inspired by Stripe / Chargebee / Zuora, designed for multi-tenant SaaS systems.

Iโ€™ll explain:

  1. All tables
  2. Why they exist
  3. Key relationships
  4. Design decisions (immutability, lifecycle, auditability)
Production-Ready Billing & Subscription Database Schema
ER Diagram

๐Ÿงพ SaaS Billing & Subscription Database Schema (Complete Guide)


๐Ÿง  Core Design Principles

Before schema, understand the rules:

โœ… Plans are immutable pricing units
โœ… Subscriptions are stateful lifecycles
โœ… Invoices are historical & never change
โœ… Payments are append-only records
โœ… Everything is tenant-isolated


๐Ÿงฑ High-Level Architecture

Tenant
 โ”œโ”€โ”€ Customers
 โ”œโ”€โ”€ Products
 โ”‚    โ””โ”€โ”€ Plans
 โ”‚         โ””โ”€โ”€ Subscriptions
 โ”‚              โ””โ”€โ”€ Invoices
 โ”‚                   โ””โ”€โ”€ Payments
 โ””โ”€โ”€ Usage Records (optional)

1๏ธโƒฃ tenants

๐Ÿ‘‰ Who owns the billing setup

tenants (
  id UUID PK,
  name TEXT,
  status TEXT,
  created_at TIMESTAMPTZ
)

Why?

  • Enables multi-tenant SaaS
  • Data isolation
  • Tenant-specific pricing

2๏ธโƒฃ customers

๐Ÿ‘‰ Who pays the money

customers (
  id UUID PK,
  tenant_id UUID FK,
  email TEXT,
  name TEXT,
  external_ref TEXT, -- CRM / Auth ID
  created_at TIMESTAMPTZ
)

Why?

  • A tenant can have many customers
  • Decouples auth from billing
  • Required for invoicing

3๏ธโƒฃ products

๐Ÿ‘‰ What is being sold (features)

products (
  id UUID PK,
  tenant_id UUID FK,
  name TEXT,
  description TEXT,
  active BOOLEAN
)

Why?

  • Logical grouping of plans
  • Feature-based products
  • One product โ†’ many plans

4๏ธโƒฃ plans (IMMUTABLE)

๐Ÿ‘‰ Pricing + billing rules

plans (
  id UUID PK,
  tenant_id UUID FK,
  product_id UUID FK,
  plan_key TEXT,
  billing_period INTERVAL,
  interval_count INT,
  amount_cents BIGINT,
  currency CHAR(3),
  trial_days INT,
  active BOOLEAN,
  created_at TIMESTAMPTZ,
  UNIQUE (tenant_id, plan_key)
)

Why?

  • Defines money
  • Never update price or interval
  • New price = new plan

๐Ÿ”’ Immutable after use


5๏ธโƒฃ subscriptions (STATEFUL)

๐Ÿ‘‰ Customerโ€™s active contract

subscriptions (
  id UUID PK,
  tenant_id UUID FK,
  customer_id UUID FK,
  plan_id UUID FK,
  status TEXT,
  start_date TIMESTAMPTZ,
  current_period_start TIMESTAMPTZ,
  current_period_end TIMESTAMPTZ,
  cancel_at_period_end BOOLEAN,
  canceled_at TIMESTAMPTZ
)

Why?

  • Tracks lifecycle
  • Allows upgrades/downgrades
  • Does NOT store pricing

Subscription States

INCOMPLETE
ACTIVE
PAST_DUE
CANCELED
EXPIRED

6๏ธโƒฃ invoices (HISTORICAL)

๐Ÿ‘‰ Bill generated for a period

invoices (
  id UUID PK,
  tenant_id UUID FK,
  subscription_id UUID FK,
  invoice_number TEXT,
  status TEXT,
  subtotal_cents BIGINT,
  tax_cents BIGINT,
  total_cents BIGINT,
  currency CHAR(3),
  issued_at TIMESTAMPTZ,
  due_at TIMESTAMPTZ
)

Why?

  • Legal & financial record
  • Never edited after issuance
  • Basis for payments & refunds

7๏ธโƒฃ invoice_items

๐Ÿ‘‰ Line-level billing breakdown

invoice_items (
  id UUID PK,
  invoice_id UUID FK,
  description TEXT,
  amount_cents BIGINT,
  quantity INT
)

Why?

  • Supports proration
  • Discounts
  • Add-ons
  • Usage charges

8๏ธโƒฃ payments

๐Ÿ‘‰ Money movement

payments (
  id UUID PK,
  tenant_id UUID FK,
  invoice_id UUID FK,
  provider TEXT,
  provider_payment_id TEXT,
  status TEXT,
  amount_cents BIGINT,
  currency CHAR(3),
  paid_at TIMESTAMPTZ
)

Why?

  • Append-only ledger
  • Multiple attempts per invoice
  • Gateway-agnostic

9๏ธโƒฃ payment_methods

๐Ÿ‘‰ Stored payment instruments

payment_methods (
  id UUID PK,
  customer_id UUID FK,
  provider TEXT,
  token TEXT,
  is_default BOOLEAN
)

Why?

  • PCI compliance
  • Reusable cards
  • Auto-billing support

๐Ÿ”Ÿ usage_records (Optional โ€“ Metered Billing)

๐Ÿ‘‰ Pay-as-you-go usage

usage_records (
  id UUID PK,
  subscription_id UUID FK,
  metric TEXT,
  quantity BIGINT,
  recorded_at TIMESTAMPTZ
)

Why?

  • API calls
  • Storage usage
  • Seat-based billing

๐Ÿ” Relationships Summary

EntityRelationship
Tenantowns everything
Producthas many plans
Planreferenced by subscriptions
Subscriptiongenerates invoices
Invoicehas invoice_items
Invoicepaid by payments

๐Ÿ” Critical Design Rules (Do NOT Break)

โŒ Never update plans.amount
โŒ Never delete invoices
โŒ Never modify paid invoices
โŒ Never store money in subscriptions


๐Ÿง  Mental Model (Golden Rule)

Plans define money
Subscriptions define time
Invoices define history
Payments define truth


๐Ÿ Final Thoughts

This schema:
โœ” Scales to millions of subscriptions
โœ” Supports upgrades, proration, usage billing
โœ” Is audit-safe & finance-friendly
โœ” Matches Stripe-level design


Read other awesome articles inย Medium.com or in akcoding’s posts.

OR

Join us on YouTube Channel

OR Scan the QR Code to Directly open the Channel ๐Ÿ‘‰

AK Coding YouTube Channel

Share with