Vishal.dev
Back
•••• •••• •••• 4242
Backend

NexPay — Multi-Tenant Payment Infrastructure

Production-grade payment platform implementing the full payment lifecycle, double-entry accounting ledger, wallet balances, fraud scoring, subscription billing, webhooks, disputes, payouts, and daily reconciliation.

Node.js 20Express 4TypeScriptPostgreSQL 16PrismaRedis 7BullMQNext.js 14ZodJWT + TOTP MFAVitestDocker Compose
60+
DB models
6
Async workers
34
Feature modules
22
Test files

Domain Knowledge

What problem this project solves

Payments are a distributed-consistency problem: money must never be lost or double-spent, even when networks fail mid-transaction. NexPay treats every movement of money as a state transition in a strict state machine with idempotent operations. The double-entry ledger guarantees accounting invariants hold, the outbox pattern guarantees webhook delivery, and daily reconciliation catches drift between payment records and ledger balances.

Architecture

How the system is structured

A Turbo monorepo with three apps — an Express REST API, a merchant portal, and an admin portal — plus shared packages and a TypeScript SDK. The API is organized into 34 feature modules backed by 6 BullMQ workers (billing, fraud-unblock, outbox, payout, reconciliation, webhook). Middleware enforces JWT auth with RBAC, idempotency keys (Redis lock + Prisma), Prometheus metrics, per-endpoint rate limiting, and request tracing.

Data Model

Schema design and data flow

60+ Prisma models covering merchants, customers, payment methods, payment state machines, ledger accounts and entries, wallets, invoices, subscriptions, disputes, fraud rules, webhooks, payouts, and reconciliation runs. Account types follow double-entry conventions: Asset, Liability, Revenue, Expense, Reserve.

Key Challenges

Hardest problems encountered

The hardest problems were payment state consistency (a payment can be captured, refunded, disputed, won, or lost — each transition must be atomic and idempotent), preventing double-charging under retries via idempotency keys, fraud scoring that adapts per merchant, and keeping the ledger balanced under high concurrency using advisory locks.

Scaling Strategy

How the system grows

BullMQ distributes background work across 6 workers with retry and dead-letter queues. Redis caches hot paths and backs rate limiting. The reconciliation worker runs daily and the outbox worker guarantees event delivery. Docker Compose supports dev, production (with Nginx, Prometheus, Grafana), and e2e environments.

Security

Defense-in-depth approach

JWT authentication with RBAC, TOTP MFA, sandbox mode for testing, idempotency enforcement, per-endpoint rate limiting, HMAC-signed webhooks, tenant-scoped data access, and full audit logging.

Failure Handling

Resilience and recovery

Webhook delivery uses exponential backoff with a dead-letter queue. Payments are idempotent so duplicate requests never double-charge. The fraud-unblock worker resolves time-based flags automatically. Reconciliation detects ledger drift daily.

Observability

Monitoring and debugging

Prometheus metrics, Pino structured logging with request IDs, and a metrics module. 22 test files cover ledger invariants, tenant isolation, payment state transitions, refunds, reconciliation, and webhook delivery.

Trade-offs

Engineering decisions and alternatives

PostgreSQL + Prisma for relational integrity over NoSQL. BullMQ over in-process queues for durability and observability. A monolith API over microservices at this scale. Gateway adapters (Mock, Stripe, Razorpay) over a single vendor.

Architecture Decisions

Key choices and what was rejected

Decision
Chosen
Rejected
Ledger consistency
Double-entry + advisory locks
Single-entry (no integrity guarantee)
Event publishing
Outbox pattern with BullMQ
Fire-and-forget (silent loss)
Payment safety
Idempotency keys
Client dedupe only
Tenancy
Shared schema with tenant scope
Schema-per-tenant

Senior-Level Topics

Concepts this project explores

Payment State MachinesDouble-Entry AccountingIdempotency PatternsOutbox PatternFraud ScoringMulti-TenancyWebhook ReliabilityDaily Reconciliation