Open to senior & lead roles · Lagos, UTC+1

I build Flutter apps that stay calm when the signal doesn't.

I'm Henry Ifebunandu, a senior mobile engineer in Lagos. Most of my work is fintech: payments, cross-border FX and KYC for users in Nigeria and Ghana, on networks that drop without warning. I've been the lead or primary engineer on two production apps, including a ground-up rewrite that replaced the live product.

9:41●●● 4G
Wallet
Live
Available balance ₦482,150.00 Synced just now

Fund with Mobile Money

Tier 1 account · limit ₦50,000 per transaction
ReadyPick an amount. Try ₦80,000 too.

Try it. Tap "Drop the network", then "Fund wallet". The app keeps your balance on screen and waits for the payment instead of failing. Pick ₦80,000 to see a payment stopped before it starts, because it's over the account's limit.

6+years building mobile apps with Flutter, since 2019
2live finance apps where I was the lead or main engineer
4ways to pay built in: cards, mobile money, direct debit and bank transfers
3currencies handled in one app: naira, cedi and dollar
Work

Two finance apps, end to end

Start with the app. Open any deep dive for the full story, from the problem to the trade-offs and the outcome. FunZ screens are from the shipped app, Ladder's come from its public App Store listing, and the FX flow is an illustrative mockup.

Live in Nigeria & Ghana
Ladder App Store screenshot: investment portfolio in cedis with a Switch to USD button Ladder App Store screenshot: home screen showing portfolio value in cedis with the naira equivalent From Ladder's App Store listing
iOSAndroidRiverpodGetItWebSocketsShorebird

Ladder

A personal-finance app for Nigeria and Ghana: save, invest, budget and get help from an AI assistant.

In shortI rebuilt the whole app from scratch and replaced the old version while people were using it. The store rating went up after launch.

Role: Mobile Engineer, primary engineer on v2.0 · Sep 2025 – present · remote from Lagos

27K+active users, per the App Store listing
2countries: Nigeria and Ghana
3currencies: naira, cedi and dollar

From the App Store listing

Deep dive Letting a Ghanaian buy a Nigerian IPO People in Ghana can invest in Nigerian IPOs in their own currency, and always pay the exact rate they agreed to. Read the full storyClose
Illustrative mockup · example rates
iOSAndroidLocked quotesTyped error codesDio

A user in Accra pays in cedis for IPO units priced in naira, at a rate that can't change under them halfway through paying.

Where: Ladder · Mobile Engineer · Nigeria & Ghana

Context

Ladder lets people in Nigeria and Ghana invest, save, budget and withdraw across three currencies: naira, cedi and dollar.

Problem

Currency conversion had been written by hand in at least five different widgets. A cross-border purchase needs one rate that the user sees, agrees to and actually pays.

Constraints

Quotes expire, sometimes while the user is mid-payment. Fees must be right before the user commits. Error messages are written for people and can change, so code can't branch on them.

What I built

  • One FX layer for naira, cedi and dollar, replacing the conversion code copied across five or more widgets.
  • Locked quotes, so the rate the user confirms is the rate they pay.
  • Fee calculation inside the same layer, shown before the user commits.
  • Quote-expiry recovery. If a quote runs out mid-payment, the user gets a fresh quote and confirms it again.
  • Typed error codes. The app branches on the error code, never on the message text.
  • Tests on FX quotes and fees, including a walkthrough test that steps through the whole lock flow.

Trade-offs

One layer, not five copies. Pulling conversion out of the widgets took a refactor across the app, but now there's one place to get fees and rounding right.

Codes over messages. A backend team can reword an error without breaking the app's recovery logic.

Re-confirm, never re-price quietly. When a quote expires, the user sees the new rate and confirms it again. It costs one extra tap, but nobody pays a rate they didn't agree to.

Outcome

A Ghanaian user can buy Nigerian IPO units at a locked cross-border rate. Conversion now lives in one tested layer instead of five widgets.

Cross-border buying is still rolling out, so there are no volume numbers to share yet.

Deep dive Replacing a live fintech app Rebuilding Ladder from the ground up while v1 was live and holding real users' money. Read the full storyClose

Context

Ladder is a personal-finance app for Nigeria and Ghana covering investments, savings, budgeting, withdrawals and an AI assistant. v1 was live and holding users' money.

Problem

Build a v2.0 that replaces v1 in production instead of running beside it, across auth, KYC, savings, investments, budgeting and chat.

Constraints

Unreliable mobile networks. Two countries with different rails, rules and rollout timing. Tiered KYC limits. A codebase that grew to about 556 Dart files.

What I built

  • Architecture on Riverpod + GetIt, with separate development, staging and production builds, each on its own Firebase project.
  • WebSocket layer with heartbeat and exponential backoff, so balances stay live on bad networks instead of failing silently.
  • Payments: Flutterwave card checkout with redirect and callback handling, Mobile Money with polled verification and manual retry, and NGN bank mandates with OTP for direct debit and auto-invest.
  • One funding and withdrawal flow shared by savings and investments, with KYC tier limits checked before a transaction starts.
  • Compile-time feature flags so a feature can ship in one country before the other.
  • Networking on Dio, with interceptors for auth, cURL logging and error reporting.
  • Release tooling: a makefile for builds and Shorebird over-the-air patches, plus git hooks that bump the version automatically.

Outcome

v2 replaced v1 in production, is live in both countries, and the app's store rating went up after launch. I wrote most of v2's code, about 78% of the commits. Ladder's store listing now reports 27K+ active users and $2M+ saved.

Deep dive More from Ladder An AI assistant, selfie ID checks, security, analytics and a two-country rollout. See allClose
AI

An AI assistant inside a finance app

"Lady" streams replies over Server-Sent Events into an animated streaming-text view, with file attachments and chat history. A consent screen asks the user before any financial data is sent to the AI.

Ladder App Store screenshot introducing Lady, the personal financial assistant
Identity

Selfie capture that checks itself

On-device identity capture with Google ML Kit. It checks face size, centring, open eyes and detection confidence, with adjustable strictness and exposure correction for dim rooms.

Security

Security for a finance app

Face ID, fingerprint and PIN login, secure storage, decryption of sensitive payloads from the backend, and automatic logout after inactivity or when the app goes to the background.

Analytics

Attribution without the mess

Kochava install attribution on iOS (with the tracking-permission prompt) and Android, plus Mixpanel, behind one analytics interface with an event map and onboarding-funnel tracking. Deep links cover universal links, app links and push notifications.

Rollout

Two countries, one codebase

Compile-time feature flags decide what ships in Nigeria and what ships in Ghana. Development, staging and production each build against their own Firebase project.

2 years as technical owner
FunZ Business introduction screen with an Explore FunZ Business button
FunZ home screen showing the wallet balance, Add Money and Send actions, and Quick Pay for airtime, electricity, cable TV and data
FunZ app · personal details blurred
iOSAndroidRiverpodFastlaneGitHub Actions

FunZ

A Nigerian payments app for people and businesses: transfers, bill pay, airtime and electricity.

In shortI was the main engineer for two years. I built the business version of the app and Scan-to-Pay, and made every release build the same way.

Role: Lead Mobile Engineer · Aug 2024 – Jul 2026 · Lagos

140+screens across iOS and Android
2 yrsas the app's main engineer
~15ssaved on every account number with Scan-to-Pay
Deep dive Scan-to-Pay: from a handwritten note to a filled-in transfer Users photograph a handwritten account number instead of typing it, which cuts about 15 seconds off every transfer. Read the full storyClose
FunZ Send Money screen with the account number, account name and Zenith Bank filled in from the scan
FunZ Scan account number screen extracting a handwritten account number and bank name from a notebook page
FunZ app · scanning a handwritten note
iOSAndroidMultimodal LLMOpenRouterFuzzy matching

Point the camera at an account number scribbled on paper and the transfer form fills itself in. Money still moves only when you confirm.

Where: FunZ · Lead Mobile Engineer · Lagos

Context

In Nigeria, account details are often shared as a scribbled note, a document or a screenshot. Sending money meant copying them field by field.

Problem

Typing an account number and picking a bank by hand is slow, and one wrong digit can send money to the wrong person.

Constraints

Handwriting and phone photos are messy, so no reader is perfect. A 10-digit NUBAN can belong to accounts at more than one bank. And this is a payment, so a misread must never turn into a costly mistake.

What I built

  • Camera capture of just the framed region, so the model only sees the part of the page that matters.
  • Extraction of Nigerian 10-digit account numbers, and the bank name when it's written, using a multimodal LLM through OpenRouter.
  • Client-side parsing of the model's answer with confidence thresholds.
  • A candidate picker when the page holds more than one plausible account number.
  • Zoom for account details written too far from the camera to read clearly.
  • Fuzzy bank matching against the bank list, so a scrawled "Zenith" becomes Zenith Bank.
  • Prefill, not payment. The result fills the bank transfer form, and then amount, validation, confirmation and the transfer run exactly as they do for a manual transfer.

Trade-offs & safety

Assist, don't act. The scanner never starts a payment. A misread costs the user a correction, never money, and every transfer still goes through the same validation and confirmation as one typed by hand.

Ask when unsure. Confidence thresholds gate what the parser accepts, and when there are several candidates the user picks one instead of the app guessing.

A model over ML Kit. On-device ML Kit text recognition was flaky and often misread blurred digits. A multimodal LLM reads messy photos far better, in exchange for a network call on each scan.

Outcome

~20s → ~5sto enter an account number, down from typing and re-checking by hand
~90%of scans read the details correctly
Deep dive More from FunZ FunZ Business, secure login, links that open the right screen, privacy-safe logs and repeatable releases. See allClose
Business

FunZ Business, end to end

A business version of the app: corporate and enterprise onboarding, directors and signatories, and PIN-protected business transfers.

Security

Secure login

Encrypted local storage with fingerprint, Face ID and PIN unlock.

Navigation

Links that land right

App-wide routing with deep links that still open the right screen when the app starts from cold. Riverpod state across 55+ providers.

Privacy

Logs without secrets

A logging layer that strips personal data and tokens before anything is written.

Releases

Same build, every machine

App Store and Play Store releases on Fastlane and GitHub Actions, with pinned toolchains, cached dependencies and code generation in CI. Build drift between machines ended.

Open source

Something you can install today

A Flutter package on pub.dev, with every line of code public.

Flutter package · Android & iOS · MIT

liveness_flutter

Plug-and-play liveness detection for Flutter. You pick a sequence of actions like blink, smile or turn left. The package guides the user through them on camera, then returns a confidence score plus the photos or video to send to your backend.

  • 13 challenge actions, shuffled into a random order each time so a recorded attempt can't be replayed.
  • Anti-spoof checks using sensor-noise analysis and micro-motion, plus an optional colour-flash challenge against video replays.
  • Assisted mode that uses the back camera to verify someone else.
  • Fully on-device with Google ML Kit face detection. Nothing goes to a cloud service unless you send it.
  • Themeable, or replace the UI entirely.
$ flutter pub add liveness_flutter
This session's challenge order
  1. Blink
  2. Turn left
  3. Smile
  4. Nod
150/160pub points
13challenge actions
MITlicense
Focus

What teams trust me with

Patchy networks, many ways to pay, and strict rules on what each account can do. They make finance apps harder to build, and they're what I know best.

payments

Every way people pay

Cards, mobile money, direct debit and bank transfers, with account limits checked before any money moves.

Flutterwave checkout · polled MoMo verification · NGN mandates with OTP · KYC tier gating

reliability

Built for bad networks

When the connection drops, the app keeps showing what it knows, reconnects by itself and lets people retry instead of failing silently.

WebSocket heartbeat + backoff · manual retry · cold-start deep links · Shorebird patches

ownership

The person responsible

Lead or main engineer on two live finance apps. At Ladder, I rebuilt the whole app and swapped out the old version while people were using it.

Ladder v2.0 rewrite · FunZ technical owner for 2 years

release

Boring, repeatable releases

Updates reach the App Store and Google Play the same way every time, and urgent fixes can go out without waiting for store review.

Fastlane · GitHub Actions · Codemagic · pinned toolchains · cached dependencies

Experience

Where I've shipped

  1. Mobile Engineer · Ladder

    Primary engineer on the v2.0 rewrite that replaced the live v1. Built the naira/cedi/dollar FX layer, the payments experience, the "Lady" AI assistant, selfie KYC capture and the release tooling for an app serving Nigeria and Ghana.

  2. Lead Mobile Engineer · FunZ

    Primary technical owner of a consumer and business fintech app for two years. Built Scan-to-Pay and the FunZ Business vertical, and automated releases to both stores.

  3. Mobile Engineer · GetEquity

    Refactored legacy Flutter modules into modular Provider-based packages, added Shorebird OTA updates for critical patches, and built release workflows on Codemagic. The platform served 10K+ daily active investors.

  4. Mobile Engineer · Traverse Apps

    Cross-platform products for finance and accounting clients in Flutter and Jetpack Compose, with Firebase and Ably real-time features. Shipped Floatr, a loan-disbursement app that reached 5,000+ installs in 5 months, and AACSL, a mobile client that automates payroll and bookkeeping work for a UK/Nigerian chartered-accounting firm.

  • Drugstore.ng 2021 – 22

    Nigeria's online pharmacy app, with personalised drug requests and dynamic pricing across pharmacies. Shipped in 3 months against a 4-month plan.

  • Whipik 2022

    Launched "Become a Writer", cutting publishing-rights approval from days to near-instant. Analytics via Firebase, Mixpanel and Branch.io.

  • PureMatch 2023

    Flutter contract work.

  • WePrototype 2019 – 20

    Flutter, GraphQL and AWS Rekognition. My first professional Flutter work.

Stack

Tools I use in production

Dart and Flutter every day. Kotlin and Swift when a platform channel needs them.

mobile

DartFlutterJetpack ComposeKotlin & Swift platform channels

architecture

RiverpodBLoCProviderGetItInjectableClean ArchitectureDesign tokensMVVMFeature-first modules

payments

FlutterwavePaystackMobile MoneyMulti-currency FXNGN bank mandatesDirect debitOTP flows

data & real-time

RESTGraphQLWebSocketsServer-Sent EventsDioFirebase AuthFirestoreCloud FunctionsHive

security & ML

Biometric & PIN authKeychainEncrypted storagePayload decryptionPII-safe loggingML Kit face detectionMultimodal LLM extraction

release & observability

FastlaneCodemagicGitHub ActionsShorebirdApp Store ConnectPlay ConsoleCompile-time feature flagsSentryCrashlyticsMixpanelKochava
Henry Ifebunandu sitting on a wooden boardwalk among trees, chin resting on his hand
About

Mechanical engineer by training

I studied Mechanical Engineering at Yaba College of Technology and wrote my first professional Flutter code in 2019. Since then I've worked mostly on apps that move money: lending, investing, savings, transfers and bill pay.

I build for the conditions my users actually have: patchy networks, several ways to pay, and regulators who decide what each account tier can do.

  • EducationND & HND, Mechanical Engineering · Yaba College of Technology
  • AwardGrand Prize, SMFEST Hackathon (Silicon Africa), 2022
# pubspec.yaml
name: henry_ifebunandu
description: Senior mobile engineer. Flutter, fintech, African markets.
version: 6.0.0+2019   # years of Flutter, first commit in 2019

environment:
  location: Lagos, Nigeria
  timezone: UTC+1   # full UK/EU overlap, afternoons with US East
  remote: true

dependencies:
  flaky_networks: ^handled
  payment_rails: ^4.0.0
  currencies: [NGN, GHS, USD]

Ready for the next adventure.

I'm looking for a senior or lead mobile role where I can own a product end to end. Remote works best.

Lagos · UTC+1 · full overlap with UK & EU hours · afternoons with US East

Signal's good over here. Say hi!