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

I've been writing Flutter since 2019. Most of it touches somebody's money.

I'm Henry Ifebunandu, a senior mobile engineer in Lagos. I've been the lead or main engineer on two live finance apps, building payments, cross-border FX, business accounts and identity checks for users in Nigeria and Ghana.

9:41●●● 4G
Pocket demoLoading…

Try it. A pocket version of things I've shipped: Scan to pay fills in bank details from a photo, Buy IPO pays in cedis at a locked rate, and Business mode needs a second person to approve every payment. Try sending ₦80,000 to see a limit stop it before it starts. It's a demo, so no real money moves.

27K+active users on Ladder, across the App Store and Google Play
10K+downloads of FunZ, across the App Store and Google Play
2live finance apps where I was the lead or main engineer
4ways to pay built in: cards, mobile money, direct debit and bank transfers
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, and Ladder's come from its public store listings.

Live in Nigeria & Ghana
Ladder store screenshot: investment portfolio with a naira balance, its dollar value and an IPO spotlight Ladder store screenshot: home screen with total assets, a verification progress card and savings plans From Ladder's store listing
iOSAndroidRiverpodGetItWebSocketsShorebird

Ladder

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

In shortI was the main engineer on v2, a rebuild of the whole app that replaced the old version while people were using it.

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

27K+active users across both app stores
2countries: Nigeria and Ghana
3currencies: naira, cedi and dollar

From the store listings

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
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 · Senior 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.

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 and is live in Nigeria and Ghana. I wrote most of it: about 78% of v2's commits. Ladder's App Store and Google Play listings now report 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
10K+downloads across both app stores
Deep dive FunZ Business: a business account inside a consumer wallet People can switch between their personal wallet and a business account in the same app, and business payments need a second person to approve them. Read the full storyClose
FunZ Business introduction screen with an Explore FunZ Business button
FunZ business account home with wallet balance, Send Funds, and an Awaiting Approval card showing 15 transfers
FunZ app · personal details blurred
iOSAndroidFlutterRiverpod

I added business accounts to FunZ's personal wallet without a second app: sign-up for all three types of Nigerian business, and approval by someone else before any business payment goes out.

Where: FunZ · Lead Mobile Engineer · Lagos

Context

FunZ was a personal wallet, and the people who run businesses were already using it as individuals.

Problem

Let them run a business account from the same app, and switch between personal and business without a second download.

Constraints

Nigerian businesses register in three different ways, each with its own paperwork. Business payments need sign-off from more than one person. And business mode must never show personal-only features.

What I built

  • Personal and business in one app. One switch changes the whole app, from transfers to receipts, and business mode only shows what a business is allowed to do.
  • Sign-up for all three business types: Enterprise, Corporate and Incorporated Trustee, each with its own documents and director details.
  • Applications you can finish later. Progress saves as you go, so coming back picks up where you left off, documents included.
  • Approval before money leaves. Business transfers wait for the business's signatories, who approve or decline with an SMS code. Whoever starts a transfer can't approve it.
  • Team invites. Directors and trustees can be invited, including by FunZ tag, and join the business from their own app.

Trade-off

Safety over speed. Every business payment needs another person and an SMS code. It adds a step, but the person sending money is never the one who approves it.

Outcome

Businesses now run inside the same FunZ app as personal wallets, from sign-up to approved payments.

What I'd demo in an interview

  1. Switch to a business account, send money and open the receipt.
  2. Start a company sign-up, leave, and come back to find it filled in.
  3. Approve a waiting payment with an SMS code.
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 Secure login, links that open the right screen, privacy-safe logs and repeatable releases. See allClose
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

Face liveness checks for Flutter: free, on-device, and built to report to your backend. You pick a set of actions like blink, smile or turn left. The package guides the user through them on camera, then returns a result plus the photos or video your server needs.

  • 13 challenge actions, shuffled into a cryptographically random order each time, so a recorded attempt can't be replayed.
  • Anti-spoof checks: sensor-noise and micro-motion analysis, a colour-flash challenge, and a check that the same face stays in frame for the whole session.
  • Built for your backend. Server-bound sessions tie each check to a challenge from your server and hash the evidence into an attestation it can verify.
  • Evidence at the right moment. Photos are taken at the peak of each action, like eyes fully shut mid-blink.
  • Sessions that always finish. Timeouts mean a check can never hang, and the result arrives exactly once.
  • Fits any app: assisted mode for agents using the back camera, full theming, or your own UI and spoof detectors plugged in.
$ flutter pub add liveness_flutter
This session's challenge order
  1. Blink
  2. Turn left
  3. Smile
  4. Nod
160/160pub points
13challenge actions
MITlicense
Focus

What teams trust me with

Many ways to pay, identity checks, 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, plus paying someone from a photo of their account details.

Flutterwave checkout · polled MoMo verification · NGN mandates with OTP · Scan-to-Pay

trust

Identity & trust

Selfie checks, account limits and second-person approvals, so the right person moves the right amount.

ML Kit selfie capture · liveness_flutter · KYC tier limits · two-person approval

ownership

The person responsible

Lead or main engineer on two live finance apps, accountable for how they're built, how they ship and what happens when something breaks.

Ladder v2.0 primary engineer · 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. Senior Mobile Engineer · Ladder

    Primary engineer on Ladder v2.0 for Nigeria and Ghana. Own the app's architecture, the naira/cedi/dollar FX layer, payments, the "Lady" AI assistant, selfie KYC capture and the release tooling.

  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.

  • 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
Dart · Flutter · Jetpack Compose · Kotlin & Swift platform channels
architecture
Riverpod · BLoC · Provider · GetIt · Clean Architecture · feature-first modules
payments
Flutterwave · Paystack · Mobile Money · NGN bank mandates · multi-currency FX
data & real-time
REST · GraphQL · WebSockets · Server-Sent Events · Dio · Firebase · Hive
security & ML
Biometric & PIN auth · encrypted storage · ML Kit face detection · multimodal LLM extraction
release
Fastlane · Codemagic · GitHub Actions · Shorebird · Sentry · Crashlytics
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: several ways to pay, identity checks, and regulators who decide what each account tier can do.

Off the clock, there's always music on, anywhere from Kendrick to Don Moen. I'm usually mid-way through an anime, and I'll rewatch anything that bends reality: The Matrix, Inception, Dark.

  • EducationHND, 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:
  kyc_flows: ^handled
  payment_rails: ^4.0.0
  currencies: [NGN, GHS, USD]

dev_dependencies:   # what keeps me going
  music:            # anything that sounds good
    - Drake, Kendrick Lamar, J. Cole
    - RY X, Don Moen, anime OSTs
  anime:            # too many to list
    - Naruto, Attack on Titan, Jujutsu Kaisen
    - Kaiju No. 8, Sakamoto Days
  movies: [The Matrix trilogy, Inception]
  series: [Stranger Things, Dark]

Ready for the next adventure.

I'm looking for a senior or lead mobile role on a product team: shipping alongside designers, backend engineers and other mobile developers, and helping the people around me grow. Remote works best.

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

Inbox is open. Say hi!