GLY VTU
A virtual top-up platform — wallet, transfers, airtime and bills through VTpass, Flutterwave virtual cards, KYC tiers, and admin tooling for anomalies and audit.
- 25
- Route modules
- 69
- Frontend pages
- 2
- Money providers
- KYC
- Tiered limits
- Role
- Author
- Year
- 2026
- Status
- Private
- Type
- Wallet & bill payments platform
01Overview
GLY VTU is a virtual top-up platform: users fund a wallet, pay bills, buy airtime and data, transfer to each other, and issue virtual cards. Behind it sits an Express API on MySQL and a React storefront, with VTpass handling bills and Flutterwave handling cards.
VTU is the most common software product in Nigeria and the one most often built badly, because it looks like CRUD and behaves like a ledger. Money enters from a payment gateway, sits in a wallet, and leaves through a third-party biller that may succeed slowly, fail after charging, or answer twice.
The parts I care about are the ones that protect the balance: KYC tiers with limits, admin review tooling, anomaly dashboards, retention jobs, and an audit trail that can reconstruct what happened to a transaction.
02The problem
A biller integration is not a function call. VTpass can accept a request, take the money, and time out before answering — leaving the platform unsure whether to debit the user, retry, or refund. Getting that wrong in either direction costs real money: retry and you have paid twice, refund and you have paid once for nothing.
Wallets invite the second failure. Two concurrent requests reading the same balance and both deciding it is sufficient will both spend it. A wallet without serialisation is an overdraft waiting for traffic.
The third is regulatory rather than technical. Moving money without identity tiers and limits is not a product you can operate, regardless of whether the code works.
03Architecture
- 01
Wallet and transaction history
Wallet operations, transfers and a transaction history that is the source of truth rather than a view over one. Balance is something derived and reconcilable, not a number edited in place.
- 02
Bills through VTpass
Airtime, data and utility payments go through VTpass. The integration is treated as unreliable by default — a request that does not answer cleanly leaves the transaction in a state that is resolvable rather than assumed.
- 03
Virtual cards through Flutterwave
Card issuance is Flutterwave exclusively. One provider for one capability, rather than an abstraction over two providers neither of which is fully supported.
- 04
KYC tiers and limits
Verification level determines transaction limits, with admin review tooling for documents. Limits are enforced server-side against the tier, not surfaced as a UI hint.
- 05
Admin surface built for incidents
Dashboards for users, bills, transactions, finance, anomalies and audit. The anomaly view exists because the question during an incident is never 'show me all transactions' — it is 'show me the ones that do not look right'.
- 06
Hardened by default
Rate limiting, CSRF, a CORS allowlist, hardened headers, retention jobs and Swagger docs that disable themselves in environments where they should not exist.
04Key decisions
Device verification in the onboarding flow
VTU accounts are attacked with credential stuffing because the balance is immediately spendable. Binding sessions to verified devices raises the cost of a stolen password from instant to inconvenient.
Retention jobs rather than infinite logs
A fintech audit trail grows without bound and contains exactly the data you least want to keep forever. Scheduled retention is a privacy control as much as a storage one.
One provider per capability
VTpass for bills, Flutterwave for cards, and no abstraction pretending either is swappable. A provider interface with one real implementation is indirection without benefit.
Generated audit reports
Operational scripts produce PDF audit reports rather than leaving the state of the system to be described from memory during a review.
05Stack
- Node.js
- Express
- MySQL
- React
- Vite
- Tailwind CSS
- VTpass
- Flutterwave