Link: Billpay
The Billpay monorepo powers a complete bill payment platform consisting of:
- π³ Backend Service β Handles payments, validation, reconciliation, and provider integrations (Interswitch, VTPass).
- π» Frontend Application β Modern Next.js interface for managing and completing payments (airtime, data, TV, electricity).
This repository is organized as a pnpm workspace to streamline dependency management, code sharing, and developer experience.
| Layer | Technologies |
|---|---|
| Frontend | Next.js 16 β’ TypeScript β’ Shadcn/ui β’ TailwindCSS β’ pnpm β’ Biome (Linting/Formatting) |
| Backend | NestJS β’ TypeScript β’ Prisma β’ PostgreSQL β’ Redis β’ BullMQ |
| Tooling | Docker β’ pnpm Workspaces β’ NVM (Node Version Manager) β’ Biome β’ Concurrently |
.
βββ backend # NestJS + Prisma Bill Payment Service
βββ frontend # Next.js Frontend Application
βββ package.json # Shared workspace scripts and metadata
βββ pnpm-lock.yaml
βββ pnpm-workspace.yaml# pnpm-workspace.yaml
packages:
- 'frontend'
- 'backend'- Node.js β₯ 24 (managed via
.nvmrc) - pnpm β₯ 10
- PostgreSQL
- Redis (for background jobs, queues, and reconciliation)
From the monorepo root:
pnpm installThis installs dependencies for both the frontend and backend.
pnpm devThis runs both the frontend and backend together using concurrently, with color-coded logs (like Turborepo).
pnpm --filter frontend dev
# β http://localhost:3001pnpm --filter backend dev
# β http://localhost:3000/docspnpm --filter './*' buildpnpm --filter './*' lintA Next.js 16 application using the App Router. Provides a modern UI for bill payment workflows.
Key Features:
- Modular component structure per bill category (airtime, data, TV, electricity)
- Type-safe Zod schemas
- Reusable UI components
- Integration with backend REST APIs
π Read more: Frontend README β
A NestJS service responsible for:
- Payment validation and routing to providers
- Retry & reconciliation (BullMQ + Redis)
- Provider plan synchronization (Cron jobs)
- Prisma + PostgreSQL persistence
- Auto-generated Swagger documentation
π Read more: Backend README β
Typical local setup:
# 1. Install all dependencies
pnpm install
# 2. Setup backend environment
cd backend && cp .env.example .env
# 3. Run database migrations
pnpm dlx prisma migrate dev
# 4. Run backend and frontend in separate terminals
pnpm --filter backend dev
pnpm --filter frontend devEach app defines its own .env file.
Keep sensitive credentials (DB_URL, API keys, secrets) out of version control.
Example backend .env:
NODE_ENV=development
DATABASE_URL=postgresql://user:password@localhost:5432/billpay
REDIS_URL=redis://localhost:6379
INTERSWITCH_CLIENT_ID=...
VTPASS_API_KEY=...pnpm --filter backend testpnpm --filter frontend test(Adjust for your test runner: Jest, Vitest, or Playwright.)
- Unified development β Shared tooling across backend & frontend
- Type safety β End-to-end TypeScript
- Scalability β Clear separation of concerns
- Resilience β Retry & reconciliation for payment flows
-
Create a new branch
git checkout -b feat/your-feature
-
Run linter before committing
pnpm lint
-
Follow Conventional Commits
feat: add electricity payment API
-
Open a PR with a clear, descriptive message.
Licensed under the MIT License. See LICENSE for more details.