In Nigeria's mobile-money economy, phone numbers have pulled off a neat little coup: they've become a second identity for bank accounts. Ask most people in Nigeria for their account details these days, and there's a decent chance they'll just say “use my phone number.” It's simpler, and everyone's already got it saved anyway.
The catch is that in an ecosystem where several fintechs allow phone numbers to double as account numbers, a single number can lead to multiple destinations. A notable source of erroneous transfers, as we’ve come to see, traces back to phone numbers being registered across multiple fintechs simultaneously, rather than to fraud or a mistyped digit in an account number.
To understand how we’ve eliminated this problem at Moniepoint, I had a virtual sit-down with Timilehin, who leads our Inbound and Outbound Account Payments team; Mofoluwake, Lead Product Manager on the Outbound Payments team; and Backend Engineer Obumneme.
One phone number, multiple destinations
For me, the outsider looking in, phone number wallets were the problem. A regular bank account number belongs to one bank, full stop. But a phone number, as we've established, can be registered with several fintechs at once. And because sending money, as Mofoluwake puts it, has become pure muscle memory, the way you can walk into your own house in the dark and still find your way around without thinking twice, most people don't stop to double-check the bank name that pops up. Pick the wrong bank, and the customer ends up at the wrong destination. All we needed, I figured, was something that caught that risk without slowing the app down. Pretty straightforward and simple.
But Timilehin, Mofoluwake, and Obumneme, the people who actually built this, saw it differently. To them, this wasn't one problem to fix. It was three separate things that all had to be right at once, for the whole customer experience to feel seamless:
When a single phone number could be linked to more than one fintech at once, could the system tell which one you actually meant?
Could the system correctly recognise which bank an external account number belonged to?
Could it just as reliably recognise Moniepoint's own account numbers, including new ones, not just those customers had used before?
Getting bank detection right means looking at the big picture every time a user types in an account number. By checking our network records alongside our own internal accounts, the app instantly recognises whether a number belongs to an external bank, a Moniepoint account, or both.
If there's only one possible match, the app selects the bank for you and gets out of your way. If the number exists across two institutions, the app displays both options so you can explicitly choose your intended destination without surprises.
For new numbers, you pick the bank manually just once. The platform learns from that selection, eliminating the manual step for the next person who sends money to that number. As new accounts and connections emerge over time, the system continuously updates its records to keep every account accurately mapped.
One logic, multiple possibilities
Early in testing, the team hit a case where an earlier version of that logic fell apart. The first time someone sent money to a particular phone number, the system matched it to a specific fintech and cached the answer, just as it would for a regular bank account. So later, when the customer wanted that same number's wallet but from another fintech instead, the app kept surfacing the other fintech, because that was the only answer the cache had ever stored.
The root of it, the team realised, was a wrong assumption baked into that first version: phone-number lookups had been designed to behave like bank-account lookups: one number, one fixed answer. That's true for a bank account. It isn't true for a phone number, which can sit in several wallets at once.
So we rebuilt the logic into what the app runs today: when a phone number is linked to more than one bank, the system clears the old cached answer and saves both matches side by side, rather than letting one silently block the other. It took a lot of test cases, switching a single number between banks over and over, to make sure a new match never quietly erased an old one.
The result is the behaviour described earlier in this piece, rather than an app that locks onto one answer and never reconsiders; today's app is willing to hold several possibilities at once and let the customer choose.
One system, multiple defences
Getting the matching right was only half the job. It also had to be fast.
To make the experience feel instantaneous, the team implemented smart caching technology to enable faster lookups. Once a number’s bank match is confirmed, the system safely remembers it for 30 days. That means the next time someone sends money to that same number, the app pulls the answer in a fraction of a second instead of checking the database all over again.
We also treated the two account types differently because they don't carry the same risk. A regular bank account number is almost always tied to one bank, so once it's found, it's returned right away, no extra checks needed. A phone number, because it can be tied to more than one fintech, goes through the fuller check first. This way, we move fast where it's safe to do so and take the extra time only where accuracy actually depends on it.
From there, we moved through implementation, then a genuinely heavy round of QA (bank accounts, Moniepoint accounts, and the trickier phone-number scenarios, tested and retested), and finally into rollout.
As of this writing, among customers who've already updated to the latest version of the Moniepoint app, the feature is live in their hands, making their transfers safer without requiring any changes. You still type the phone number the way you always have. The difference is that now, somewhere underneath that autopilot, the system is paying closer attention than you are: cross-checking and remembering what it learned last time.
━━━━━━━━━━
If you're looking to build the next cool thing at Moniepoint, you can start here.