Open-source billing infrastructure for Africa & beyond.
Subscriptions, usage-based metering, invoicing, and prepaid wallets — with one API.
Most billing platforms assume Stripe-only, USD-only, and card-only. NovaBilling is built for businesses that operate across multiple currencies, countries, and payment providers — especially in Africa where mobile money, bank transfers, and regional gateways are the norm.
- 6 payment providers — Stripe, Paystack, Flutterwave, DPO, PayU, PesaPal
- 40+ currencies — USD, EUR, KES, UGX, NGN, GHS, ZAR, TZS, and more
- Usage-based billing — Billable metrics with COUNT, SUM, MAX, UNIQUE_COUNT, WEIGHTED_SUM aggregations
- 5 charge models — Standard, Graduated, Volume, Package, Percentage
- Multi-tenant — Each tenant gets isolated data, custom SMTP, and their own payment provider credentials
- Self-hosted — Run it on your own infrastructure with Docker
| Category | What you get |
|---|---|
| Subscriptions | Create plans with recurring billing (monthly, yearly, weekly), upgrade/downgrade with proration |
| Usage Metering | Ingest events via API, aggregate with billable metrics, charge based on consumption |
| Invoicing | Auto-generated invoices with PDF export, email delivery, hosted checkout pages |
| Prepaid Wallets | Customer credit wallets with purchased/granted credits, auto-deduction on invoices |
| Coupons & Add-ons | Percentage or fixed-amount discounts, one-time add-on charges |
| Credit Notes | Issue refunds, void invoices, pro-rated credits on cancellation |
| Analytics | Revenue, subscriptions, customers, and payment analytics dashboards |
| Customer Portal | Self-service portal for customers to view invoices and manage subscriptions |
| Webhooks | Real-time event notifications for invoice, payment, and subscription lifecycle |
| SDKs | Auto-generated TypeScript and Python SDKs via Fern |
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Landing │ │ Dashboard │ │ Docs │ │ Portal │
│ Next.js │ │ Next.js │ │ Nuxt/Docus │ │ Next.js │
│ :4001 │ │ :4002 │ │ :4003 │ │ :4002/… │
└──────┬──────┘ └──────┬──────┘ └─────────────┘ └──────┬──────┘
│ │ │
└────────────────┼──────────────────────────────────┘
│
┌──────▼──────┐
│ NestJS │
│ API │
│ :4000 │
└──┬───┬───┬──┘
│ │ │
┌─────┘ │ └─────┐
▼ ▼ ▼
PostgreSQL Redis BullMQ
(Central + (Cache) (Workers)
Tenant DBs)
git clone https://github.com/novabilling/billing.git
cd billing
cp .env.example .env
# Edit .env — set JWT_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEY
docker compose up -d --build| Service | URL |
|---|---|
| API | http://localhost:4000 |
| Landing | http://localhost:4001 |
| Dashboard | http://localhost:4002 |
| Docs | http://localhost:4003 |
# On your server:
curl -O https://raw.githubusercontent.com/novabilling/billing/main/docker-compose.prod.yml
curl -O https://raw.githubusercontent.com/novabilling/billing/main/.env.example
cp .env.example .env
# Edit .env with real secrets and domain URLs
docker compose -f docker-compose.prod.yml up -dSee nginx.conf.example for a reverse proxy setup with custom domains.
# Start infrastructure
docker compose up -d central-db internal-tenant-db redis --wait
# Backend
cd backend
npm ci
npx prisma generate --schema=./prisma/schema-central.prisma
npx prisma generate --schema=./prisma/schema-tenant.prisma
npx prisma db push --schema=./prisma/schema-central.prisma
npm run start:dev
# Dashboard (separate terminal)
cd dashboard
npm ci
npm run devbackend/ NestJS API — TypeScript, Prisma, BullMQ, PostgreSQL
dashboard/ Next.js 16 dashboard — shadcn/ui, Tailwind v4, Zustand
landing/ Next.js 15 marketing site
docs/ Nuxt/Docus documentation site
fern/ Fern SDK generation config
sdks/ Generated TypeScript and Python SDKs
NovaBilling exposes a REST API with 107 endpoints across 18 controllers. Interactive API docs are available at /api/reference (powered by Scalar).
Authentication: Register a tenant, get a JWT, and pass it as Authorization: Bearer <token>. Alternatively, use the API key from your tenant settings as X-API-Key: <key>.
# Register
curl -X POST http://localhost:4000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@acme.com", "password": "secret", "companyName": "Acme Corp"}'
# Create a customer
curl -X POST http://localhost:4000/api/customers \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe", "email": "jane@example.com", "currency": "USD"}'import { NovaBillingClient } from "novabilling-typescript-sdk";
const client = new NovaBillingClient({
token: "your-jwt-token",
environment: "http://localhost:4000/api",
});
const customer = await client.customers.create({
name: "Jane Doe",
email: "jane@example.com",
currency: "USD",
});from novabilling import NovaBilling
client = NovaBilling(
token="your-jwt-token",
base_url="http://localhost:4000/api",
)
customer = client.customers.create(
name="Jane Doe",
email="jane@example.com",
currency="USD",
)| Provider | Regions | Methods |
|---|---|---|
| Stripe | Global | Cards, bank transfers, wallets |
| Paystack | Nigeria, Ghana, South Africa, Kenya | Cards, bank transfers, mobile money |
| Flutterwave | 30+ African countries | Cards, mobile money, bank transfers |
| DPO | 20+ African countries | Cards, mobile money |
| PayU | South Africa, Nigeria, Kenya | Cards, EFT, mobile money |
| PesaPal | Kenya, Uganda, Tanzania | M-Pesa, Airtel Money, cards |
Configure providers per-tenant in the dashboard under Settings > Payment Providers. Credentials are encrypted at rest.
We're actively looking for contributors and testers. See CONTRIBUTING.md for setup instructions and the roadmap.
Areas where help is needed:
- Taxes, net payment terms, grace periods
- Progressive billing, plan overrides, dunning
- Enhanced analytics, Helm charts, more tests
See SECURITY.md for vulnerability reporting.
NovaBilling is licensed under AGPL-3.0.