Fintech

How to Build a Fintech App in Nigeria — From Idea to Launch

A practical, regulator-aware guide to building a fintech app in Nigeria — picking partners (Flutterwave, Smile ID, Termii), designing the wallet ledger, passing KYC, and surviving CBN-adjacent compliance.

Building a fintech app in Nigeria is no longer the moonshot it was in 2017. The rails exist, the partners are mature, and the regulator has a recognisable shape. What hasn’t changed: the cost of doing this badly is your business.

This is a builder’s guide, not a regulator’s guide. We assume you have a licence path or a sponsor bank lined up. We’re focused on the engineering and product decisions that decide whether your app survives the first 1,000 active users without ledger drift, security incidents, or the kind of bugs that end up in screenshots on Twitter.

The minimum viable fintech stack in 2026

The boring stack we keep reaching for:

  • Mobile: Flutter 3.x — one codebase, native performance, deep enough integration with platform features (biometrics, secure enclave, deep links).
  • Backend: Laravel 11 or Node.js (Express/NestJS). Both work. We default to Laravel for tighter Eloquent + queue + auth + admin (Filament) integration.
  • Database: PostgreSQL 15+ for the ledger. MySQL is fine for everything else.
  • Virtual accounts: Flutterwave or Paystack for naira virtual accounts.
  • KYC: Smile ID (BVN, NIN, biometric) or Verify Me as backup.
  • OTP/SMS: Termii for SMS, plus push for in-app.
  • Card issuance: Sudo Africa or your sponsor bank’s card programme.
  • Auth: Sanctum (Laravel) or Auth0/Cognito for managed.
  • Observability: Sentry for errors, Better Stack or UptimeRobot for uptime, structured logs to Loki or BetterStack.

You can swap any of these — but pick mature, well-documented providers. Bleeding-edge experimentation is for v2, not the launch stack.

Designing the wallet — the part nobody glamorises

This is where most amateur fintech builds break. Get this right and most other problems are tractable. Get it wrong and you’re still rebuilding it three years in.

Double-entry ledger from day one

Do not store balances as a single field on the user record. Ever.

Instead, store every money movement as two ledger entries — one debit, one credit — and derive the balance from the sum. Yes, this is more work. Yes, it’s slower. Yes, you will need a balance cache for performance. Do it anyway.

Schema sketch:

CREATE TABLE accounts (
  id UUID PRIMARY KEY,
  user_id UUID NOT NULL,
  currency CHAR(3) NOT NULL,
  type TEXT NOT NULL,  -- 'wallet', 'savings', 'pool'
  created_at TIMESTAMP NOT NULL
);

CREATE TABLE ledger_entries (
  id UUID PRIMARY KEY,
  account_id UUID NOT NULL REFERENCES accounts(id),
  transaction_id UUID NOT NULL,
  amount_minor BIGINT NOT NULL,  -- always in kobo, never naira
  direction CHAR(1) NOT NULL,    -- 'D' or 'C'
  created_at TIMESTAMP NOT NULL,
  metadata JSONB
);

CREATE TABLE transactions (
  id UUID PRIMARY KEY,
  type TEXT NOT NULL,  -- 'transfer', 'topup', 'withdrawal', 'fee'
  status TEXT NOT NULL, -- 'pending', 'success', 'failed', 'reversed'
  reference TEXT UNIQUE NOT NULL,
  created_at TIMESTAMP NOT NULL
);

Critical rules:

  • Amounts are stored in minor units (kobo for naira, cents for USD). Never as floats. Never as decimals you might forget to round.
  • Every ledger entry references a transaction_id. Sum of debits for a transaction must equal sum of credits. The database enforces this with a deferred constraint.
  • Ledger entries are append-only. Reversals are new entries, not updates.

Idempotency keys on every money-moving endpoint

Every transfer/topup/withdrawal endpoint accepts an Idempotency-Key header. The server stores (key, response) pairs and returns the cached response if the same key arrives twice — no matter how long apart.

Without this: a user double-taps the transfer button, the network is flaky, the request gets retried, money moves twice. You have a customer service incident and a ledger reconciliation problem.

Reconciliation

Every day, a job runs at 02:00 that pulls bank statements from your sponsor bank or virtual-account provider and compares them against your internal ledger. Differences trigger Slack alerts to ops.

You will have differences. Sometimes the bank’s overnight batch hasn’t run. Sometimes a transaction was credited but your callback failed. Sometimes there’s a partner-side bug. Catching them at T+1 instead of T+30 is the difference between a small fix and a regulator letter.

KYC: tiers, vendors, and the ugly UX

The CBN model for KYC tiers (in 2026 terms):

Tier Verification Limits (illustrative)
Tier 1 Phone + name ₦50k single, ₦300k cumulative/day
Tier 2 + BVN/NIN ₦200k single, ₦500k cumulative/day
Tier 3 + ID photo, address proof, biometric ₦5M+ single, no daily cap

Implementation tips:

  • KYC is asynchronous. The user uploads documents; you queue verification with Smile ID; the result comes back via webhook. Do not block the UI.
  • Show explicit status on the user’s profile: “We’re verifying your documents — usually 2-5 minutes.” Don’t leave them guessing.
  • Have a manual review queue in your admin panel for cases the automated KYC can’t decide. Real people will need to look at edge cases.
  • KYC documents are encrypted at rest with per-user keys. They are PII and they are the most sensitive thing on your servers.

OTP and authentication

The standard pattern:

  1. Sign-up: phone number → SMS OTP via Termii → set password → BVN/NIN tier 2.
  2. Sign-in: email/phone + password → biometric on mobile (TouchID/FaceID/Android Biometric) for repeat sessions.
  3. Sensitive actions (transfer above ₦100k, change password, change beneficiary): re-authenticate with PIN or biometric.

Cost reality: SMS OTP via Termii is roughly ₦4 per message in 2026. A growing app sends 50,000+ OTPs a month. Budget ₦200k–₦500k/month and consider voice OTP or app-based TOTP as a fallback.

Compliance you cannot skip

  • NDPR / NDPA 2023 — every user-facing form has a privacy notice. Data is encrypted at rest. You can produce, on request, all data you hold about a user. You delete data on request (subject to your statutory retention obligations).
  • Audit logs — every admin action, every state change, every money movement, every login attempt, logged and immutable. You will need this when something goes wrong.
  • Transaction limits — enforce them server-side. Never trust the client.
  • Suspicious activity reporting — for licensed entities, this is mandatory. Build the flag-and-review workflow into your admin.
  • Sanctions screening — for cross-border products, screen against OFAC and UN sanctions lists.

Performance and uptime expectations

Fintech users are unforgiving of downtime — they were trying to send rent. Operating expectations:

  • 99.9% uptime minimum. This is 8.76 hours of downtime per year. Track it explicitly.
  • API p95 latency under 300ms for any endpoint a user is waiting on.
  • Monitoring — Sentry for errors, structured logs, uptime probes from at least one Nigerian region.
  • On-call rotation — at least two engineers, rotating weekly, paged on sev-1 incidents.

Common architectural mistakes

  1. Storing balances as floats — floating-point arithmetic loses precision. Use integers in minor units.
  2. Soft-deleting transactions — never. Reversals are new entries.
  3. Trusting client clock — every server timestamp comes from the server. Clients lie or are wrong.
  4. Not signing requests — webhooks from Flutterwave, Paystack, Smile ID need signature verification. Don’t trust the source IP.
  5. Storing API keys in code — environment variables, secret managers, encrypted config. Not in .env.example. Not in Git.
  6. Skipping migrations review — every database migration in fintech needs a second engineer’s review before it touches production. Especially anything that adds NOT NULL or drops a column.
  7. No rate limits — a malicious actor will brute-force OTPs, password resets, and balance enquiries. Rate-limit by IP and by user.
  8. Over-eager retries — automatic retries on 500s sound smart until they cause double-debits. Use idempotency keys plus careful retry logic.

A reference architecture

A typical Nigerian fintech app architecture:

[Flutter app] -- HTTPS --> [Nginx / Load Balancer]
                           |
                           v
              [Laravel API]  ←-- [Redis: cache + queue]
              |        |
              v        v
       [PostgreSQL]   [Object storage: KYC docs]
              |
              v
       [Background workers: KYC, payouts, reconciliation]
              |
              v
       [Webhooks IN: Flutterwave, Paystack, Smile ID, Termii]
       [Webhooks OUT: client notifications]

Our CreditPoint case study is a real-world implementation of exactly this shape. The Laravel API is the source of truth. The Flutter app is a thin client. The admin panel (Filament) sits beside the API. Everything sensitive runs through queued workers — KYC checks, payment callbacks, reconciliation, payouts.

What it actually costs

A production-grade Nigerian fintech app in 2026:

  • MVP wallet (transfer, top-up, KYC tier 2): ₦15M–₦25M, 14–20 weeks.
  • Full wallet + cards + multi-tier KYC: ₦35M–₦60M, 20–32 weeks.
  • Multi-currency + cross-border: ₦60M–₦100M+, 6+ months.

Plus ongoing: ₦300k–₦1M/month in infrastructure and per-transaction provider fees.

The full pricing breakdown is in our Mobile App Cost Guide.

FAQ

Do I need a CBN licence?

For most consumer fintech (wallets, transfers, cards), yes — directly or via a sponsor bank / regulated partner. Talk to a Nigerian fintech lawyer before you write code. We’ll happily make introductions.

Flutterwave vs Paystack for virtual accounts?

Both work. We use Flutterwave for projects that need broader Pan-African coverage and Paystack for Nigeria-only with simpler dashboards. Pick one and integrate cleanly; switching later is painful.

Should I build my own card issuer?

No. Use Sudo Africa or your sponsor bank’s programme. Card issuance involves regulatory and BIN sponsorship work that’s outside the scope of a normal product team.

How do I handle disputes and chargebacks?

Have an explicit dispute workflow in your admin. Most Nigerian disputes resolve through the inter-bank dispute system (NIBSS). Train your support team on how to log them and chase them.

What’s the biggest mistake fintech founders make in Nigeria?

Underspending on the ledger and overspending on the marketing site. Reverse the priorities. The ledger is what the regulator audits and what determines whether your business is solvent.


Building a fintech product? Talk to us — we’ve shipped wallets, KYC, virtual cards, and lending products from Lagos. We’ll tell you what’s realistic.

#fintech#nigeria#flutter#laravel#kyc#compliance

Need help with what you just read?

Whether it's an MVP, a migration, or a production AI feature — we ship.

Talk to us
Chat with us