Skip to content
All work
26Wallet & bill payments platform2026

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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'.

  6. 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

Decision 01

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.

Decision 02

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.

Decision 03

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.

Decision 04

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