abhilashbera.dev › work › payments-billing-api
Payments & Billing API
Backend · API · Payments
The billing core behind a SaaS product — usage metering, proration, invoices and failed-payment recovery, built to be boring and correct.
- Year
- 2024
- Role
- Backend · Architecture
- Status
- In production
- Stack
- Node.js · Express
Problem
Billing logic had grown inside the product's request handlers. Plan changes mid-cycle were prorated inconsistently, webhook retries occasionally double-charged, and nobody could explain a given invoice without reading code.
Solution
Billing moved behind its own service with an append-only ledger. Every charge, credit and adjustment is an immutable entry, so an invoice is a projection rather than a computation nobody can reproduce. Webhook handlers are idempotent by event id, and dunning runs as a state machine with explicit, inspectable transitions.
Features
- 01
Usage metering
Aggregates events into billable quantities with idempotent write semantics.
- 02
Proration engine
Mid-cycle upgrades, downgrades and cancellations computed from the ledger.
- 03
Idempotent webhooks
Provider events deduplicated by id, with a replayable dead-letter queue.
- 04
Dunning state machine
Retry schedules, grace periods and downgrade paths defined as explicit states.
- 05
Audit trail
Every invoice line traces back to the entries that produced it.
Technology
Service
- Node.js
- Express
- TypeScript
- Zod
Data
- PostgreSQL
- Redis
- Ledger schema
Integrations
- Stripe
- Webhooks
- SMTP
Operations
- Docker
- OpenTelemetry
- CI checks
Architecture
01Client
Product App
Plan · Checkout
Admin Console
Invoices · Refunds
02Service
Billing API
Ledger · Proration
Dunning Worker
Retries · Notices
03Data
PostgreSQL
Append-only ledger
Redis
Idempotency keys
04External
Payment Provider
Charges · Webhooks
Invoices · Dunning
Request flow — left to right
Result
Duplicate charges went to zero, and support can now answer any billing question from the ledger without escalating to engineering.
- Duplicate charges since launch
- 0
- Invoice lines traceable
- 100%
- Failed payments recovered
- +18%