A self-contained, end-to-end usage-based billing platform for SaaS products. Ingest usage events, aggregate by customer and feature, rate them with configurable pricing, and generate detailed invoices -- all viewable from a built-in web dashboard.
Zero external dependencies. Runs on Python's standard library with a local SQLite database. No Stripe, no Postgres, no message queues -- just python3 backend/server.py and you're up.
- Customer Management -- Create and manage customer accounts with email and timezone support
- Usage Event Ingestion -- Batch ingest timestamped usage events (e.g., API calls, storage, compute hours)
- Usage Aggregation -- Query aggregated usage by customer and feature over any time window
- Invoice Generation -- Generate monthly invoices for all customers with configurable unit pricing
- Line Item Breakdown -- Each invoice includes per-feature quantity, unit price, and total amount
- Idempotent Billing -- Re-running billing for the same period safely overwrites previous invoices
- Web Dashboard -- Interactive UI to manage the full billing lifecycle without touching the API directly
- REST API -- Clean JSON API with versioned
/v1/endpoints - Docker Support -- Production-ready Dockerfile with non-root user and configurable environment
| Layer | Technology |
|---|---|
| Backend | Python 3.9+ (standard library only -- http.server, sqlite3, json) |
| Database | SQLite (single file, zero config) |
| Frontend | TypeScript compiled to vanilla JS, plain HTML/CSS |
| Containerization | Docker (Python 3.11-slim, non-root user) |
Browser (Dashboard)
| fetch JSON
v
Python HTTP Server ---> SQLite DB
- Serves static UI (customers, events,
- REST API endpoints invoices, line_items)
- Billing engine
# Clone the repo
git clone https://github.com/sohan-shingade/billing_platform.git
cd billing_platform
# Ensure the data directory exists
mkdir -p backend/data
# Start the server
python3 backend/server.pyOpen http://127.0.0.1:8000 in your browser.
docker build -t billing-platform .
docker run -p 8000:8000 billing-platformpython3 backend/test_demo.pyThis boots the server, creates a sample customer, ingests events, runs billing, and prints the generated invoice -- all automatically.
All endpoints are prefixed with /v1/.
POST /v1/customers
{
"name": "Acme Corp",
"email": "contact@acme.com",
"timezone": "UTC"
}Response 201 Created:
{
"id": 1,
"name": "Acme Corp",
"email": "contact@acme.com",
"timezone": "UTC"
}POST /v1/events/batch
[
{
"customer_id": 1,
"feature": "api_calls",
"quantity": 10,
"ts_event": "2025-09-16T21:15:00Z"
},
{
"customer_id": 1,
"feature": "storage",
"quantity": 1,
"ts_event": "2025-09-16T21:19:00Z"
}
]Response 201 Created:
{"inserted": 2}GET /v1/customers/{id}/usage?start=2025-09-01T00:00:00Z&end=2025-10-01T00:00:00Z
Response 200 OK:
[
{"feature": "api_calls", "quantity": 15.0},
{"feature": "storage", "quantity": 1.0}
]POST /v1/invoices/run?period=2025-09&unit_price=0.01
Generates invoices for all customers with usage in the given period.
Response 201 Created:
{"invoices_generated": 1}GET /v1/customers/{id}/invoices
Response 200 OK:
[
{
"id": 1,
"period_start": "2025-09-01T00:00:00",
"period_end": "2025-10-01T00:00:00",
"total": 0.16,
"generated_at": "2025-09-16T21:20:12.289097",
"line_items": [
{"feature": "api_calls", "quantity": 15.0, "unit_price": 0.01, "amount": 0.15},
{"feature": "storage", "quantity": 1.0, "unit_price": 0.01, "amount": 0.01}
]
}
]customers events invoices invoice_line_items
----------- -------- --------- -------------------
id (PK) id (PK) id (PK) id (PK)
name customer_id (FK) customer_id (FK) invoice_id (FK)
email (UNIQUE) feature period_start feature
timezone quantity period_end quantity
ts_event total unit_price
ts_ingested generated_at amountThe built-in web dashboard at http://localhost:8000 provides five sections:
- Create Customer -- Register new customers with name, email, and timezone
- Ingest Event -- Submit individual usage events with feature name, quantity, and timestamp
- Get Usage -- Query aggregated usage for a customer over a date range
- Run Invoicing -- Generate invoices for a billing period (YYYY-MM) with configurable unit price
- List Invoices -- View all invoices for a customer with full line item breakdown
billing_platform/
├── backend/
│ ├── server.py # HTTP server, API routes, DB init, billing engine
│ ├── test_demo.py # End-to-end scripted demo
│ ├── requirements.txt # Dependencies (for future migration to FastAPI)
│ └── data/ # SQLite database (created at runtime)
├── frontend/
│ ├── index.html # Dashboard UI
│ ├── main.ts # TypeScript source
│ ├── main.js # Compiled JavaScript
│ └── tsconfig.json # TypeScript config
├── dockerfile # Production Docker image
└── README.md
| Environment Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Server bind address |
PORT |
8000 |
Server port |
BILLING_DB |
backend/data/billing.db |
SQLite database file path |
rm backend/data/billing.db
# Restart the server -- tables are recreated automatically- Ingest -- Usage events are recorded with a customer ID, feature name, quantity, and timestamp
- Aggregate -- Events are grouped by customer and feature using
SUM(quantity)over the billing period - Rate -- Each aggregated feature is multiplied by the configured unit price
- Invoice -- An invoice is created per customer with line items for each feature
- Idempotent -- Running billing again for the same period replaces the previous invoice (no duplicates)
- Pricing Engine -- Tiered, volume, and graduated pricing models
- Credits & Commitments -- Prepaid usage credits with overage billing
- Late Event Handling -- Watermarks and grace windows for delayed events
- Invoice PDFs -- Downloadable invoice documents
- Webhook Notifications -- Event-driven alerts for invoice generation
- Production Stack -- FastAPI + PostgreSQL + background workers
- "What-If" Estimator -- Preview billing impact before committing usage
MIT