01Platform — Product & Engineering

Trile

Subscription billing for Nepal

A complete payment platform for a market with no recurring-card rail: wallet-funded subscriptions, a paisa-precise double-entry ledger, hosted checkout, a merchant dashboard, and a regulator-grade admin console — six applications on one API.

Visit trile.app Beta / sandbox
Trile — subscription payments for Nepal: hosted checkout, merchant dashboard, and wallet top-ups via eSewa, Khalti, IME Pay and ConnectIPS.
Role
Product strategy · Product design · Design system · Frontend engineering · Backend engineering · Compliance UX
Stack
NestJS · PostgreSQL + Drizzle · BullMQ · React 19 · TanStack Router / Query · Tailwind v4 · Better Auth · Zod + OpenAPI · Astro
Year
2026
Discipline
Payments Infrastructure
ApplicationsSix surfaces, one API
Codebase~2,200 TypeScript files
Money typeInteger paisa, never floats
ShippedAdmin v1.0 · Directory v1.1
01

The problem is the rail, not the software

Cards issued in Nepal do not support merchant-initiated recurring charges. There is no card-on-file rail, which means the entire international subscription stack — the one every SaaS founder assumes — simply does not land here. Merchants end up chasing customers by hand every month, reconciling screenshots of wallet transfers against a spreadsheet.

Porting Stripe's model was never the answer. The constraint is structural, so the model had to change: instead of pulling from a card that can decline, the customer funds a wallet once — from eSewa, Khalti, IME Pay, or a bank — and every billing cycle deducts from a balance that is already there. A renewal stops being a network call to a card scheme and becomes an internal ledger movement.

02

Four objects, one wallet

The whole domain model fits in a sentence: a subscription draws an invoice from the customer's wallet each cycle. Everything else is scaffolding around that.

product → price → subscription → invoice
The billing spine. Prefixed ULIDs throughout, so every ID is sortable and self-describing at a glance in a log.
customer → wallet
The funding side. Top-ups arrive from Nepali wallet providers and banks; the balance is what the subscription draws against.
Hosted checkout or the raw /v1 API
Bilingual EN / नेपाली checkout for merchants who want a drop-in, and a typed REST surface for merchants who want to build their own.
03

Built for correctness, because it is money

Financial software fails differently from other software: a bug is not a bad experience, it is someone's money in the wrong place. The invariants were fixed before the first endpoint was written, and the architecture enforces them rather than trusting callers to be careful.

Integer paisa as strings
No floating-point currency anywhere in the system — not in the database, not on the wire, not in the UI formatter.
Mandatory idempotency keys
Every write is safe to retry. A dropped connection at the wrong moment cannot double-charge a wallet.
Append-only double-entry ledger
Entries are immutable. Corrections happen by posting a reversal, never by editing history — so the books can always be replayed.
Signed webhooks + event log
A durable, ordered event stream merchants can verify and replay to rebuild their own state after an outage.
Daily reconciliation
Ledger and balances are reconciled every day, so drift is caught in hours rather than at quarter close.
04

The admin console is the hard part

Most of the engineering weight sits where users never look. Trile staff need cross-tenant visibility over every merchant, wallet, and ledger entry — which is exactly the surface a regulator worries about. The console was designed so that an operator cannot move money or read personal data without it being authorised, re-authenticated, and permanently recorded.

That meant separation of duties between compliance, support, and finance-ops roles; maker-checker approval on every money-movement action; mandatory TOTP with step-up re-auth before sensitive operations; and a tamper-evident audit trail that logs reads of personal data, not just writes. KYC tiers are enforced against wallet caps at the API boundary rather than in the interface, and PII exports are generated and audited server-side — never assembled in a browser.

05

Nepali-first, not translated

The product is bilingual end to end, but the localisation goes past strings. Dates render in Bikram Sambat alongside Gregorian, because that is the calendar the compliance context actually runs on. Amounts format in रु with paisa precision. NEPALPAY QR acceptance and cross-border settlement to India are first-class parts of the model, not adapters bolted on afterwards.

Alongside the core platform, the same system powers a public editorial directory of Trile-powered businesses — discovery only, with no funds moving through it — built as a static Astro site against a read-only projection of the merchant data.

A case study is a summary. The site is the argument.

Trile is live — go and use it, then tell us what you want built.