Building financial products is no easy feat and often requires months of hard work and devotion. Yet, at the heart of everything that we do at TeamApt are our users. We innovate for business owners that rely on our product to live out their business dreams.
Sometime in 2021, we found a need that wasn’t being met as well as it could be. Our businesses were facing security challenges and so our team got to work on creating a solution for them.
The result of this effort went live in August 2022 and here’s how it’s changing the Moniepoint experience for our users.
In the beginning…
The journey of creating this solution began in 2021. We had gotten a couple of reports of fraud from our business owners. We wanted to create a system that could better protect them and their businesses.
We needed a way for them to be able to confirm who was making the transaction and this would help them verify that any transaction that they received was legitimate. The first iteration was a system that enabled you to upload the picture of the person making the transfer. This would serve as evidence that could assist with defence in court.
However, this proved to be somewhat impractical. As much as we wanted to, we couldn’t show up to defend everyone. We had to create a solution that would scale better and work effectively across the board.
We went back and decided to build a feature we called “Protected transfer”. This would give our users the ability to accept or reject transfers and hence, give them a measure of control. This idea formed the basis of what we modified to create the feature that we now have.
Innovating with empathy
TeamApt’s core values
Empathy is one of the core qualities that drive both teamwork and innovation at TeamApt. For everything that we create, we think about our users and how we can make the best experience for them.
Creating this feature with our users in mind, we had to focus on their needs. We created this feature because:
They needed better security for transfers: The primary need that made this feature important was better security. We wanted to ensure that businesses could receive transfers without the fear of being defrauded or unwittingly aiding a criminal. Hence, the solution we created needed to have a KYC feature alongside the option to receive or reject transactions.
Businesses wanted more control over inflow: With the usual transfers, business owners had no say in the kind of transactions that happened on their accounts. It was necessary that whatever we created would give them more control. They needed to be able to accept or reject transactions as necessary.
They needed more flexible payment options: Large businesses were often unable to receive direct transfers from customers. This meant that they lost business from customers who did not have their cards with them. This feature had to also expand the possibilities for POS usage beyond cards, and create an additional payment option for these businesses.
Increased transaction limits became necessary: I’ll be honest and admit that we didn’t see this use case until the feature went live, but there was a limit on the volume of transactions that people could do with their cards. Soon after we went live, we received feedback from people who could now do higher transactions than before. Transaction value was no longer constrained by card limit.
Meet the star of the show
What is the feature we created?
To solve the problems we identified above, we went through a series of iterations that resulted in the POS transfer feature.
The transfer feature on our POS is a cardless purchase or withdrawal feature that allows businesses to accept transfers from people with a proper KYC (know your customer) process. To put it simply, it enables businesses to make secure transactions by confirming the identity of the sender before accepting it on their POS.
Businesses can now accept payments from individuals without compromising the security of their business. With a proper KYC system, businesses can confirm the identity of the person making the transfer before choosing to accept or decline it. This means that businesses can receive direct transfers to their POS systems without fear of fraud. It’s a more secure transfer feature.
Let’s geek out for a bit…
How does the POS transfer feature work?
The flow of POS transfer transactions
Anytime a terminal is assigned to a business owner, we generate an account number for that POS – a special purpose account number. The first thing to note is that this inflow comes from any bank. So, we needed an inward service that would take this transfer anytime it comes from NIBSS (Nigeria Inter-bank Settlement System), look for the actual bank it is and credit the account number.
After the credit happens, we have an alert engine that picks up the transaction. The Moniepoint notification system that listens on a particular API sends a notification of the sending bank, account number, BVN number and all the details of the account.
There is a notification queue where it will publish and write the record as a transaction record. The Moniepoint notification service accepts the transaction and publishes the transaction to this queue.
The purpose of the queue is for us to be able to push the notifications to the terminal. The terminals are connected to the queue via the Advanced Message Queuing Protocol (AMQP). The number of queues is based on the number of terminals. Even if the queue goes down, we would still have the information retained. So, when the queue comes back up, the terminal consumes from it and continues.
Hence, when the transfer enters, there is a notification. If a business owner chooses to accept it, the POS terminal will make an API call to the Moniepoint front office system that this particular call is to be approved. This means that it will debit the special purpose account that has been created for this terminal and credit the business’s account with the funds. If they reject it, it debits the POS transfer account number and reverses the money back to the sending bank.
We also have redundant systems in all of this where, if the queue connection fails for any reason, the business owner could use the polling approach. They could go to the pending notification screen on the POS that makes a direct API call to the Moniepoint system and fetch all the pending notifications that they have. Here, they can accept or reject it manually. This happens in the case where they don’t get a notification on the POS directly.
Journey of a thousand steps
Here’s how we got to the current solution…
The first iteration started in the middle of last year and we called it protected transfers. We focused mainly on the security aspect then. We wanted a system where we would be able to protect businesses from crime and fraudulent practices by people. The idea was that the business owner would be able to upload an image of the customer that made the transfer. Therefore, if there was an issue, we would be able to defend them in court, etc. We finished building it but had legal constraints back then.
Were we going to always show up in court to defend everyone? We didn’t factor in practical legal constraints; so we had to pause.
After we did business banking, we talked about it again from the angle of security; the kind of people we were onboarding and their issues. So to meet up with demands, we needed a way that would be secure. Something different from the typical transfer method.
We went back and decided to build on the protected transfer feature. It didn’t have the notification feature initially. We adjusted it as we wanted people to have a window to either accept or reject transactions. Therefore, we generated single account numbers for all the POS devices.
This first model – one account number for POS transfer per business, was a start, but it didn’t scale properly either. It was the same number across all terminals so if we wanted to do notifications, a notification would go on all their terminals if all their terminals were listening on the same account number.
Imagine getting a notification on all your social media apps when you got a message on just one. Your WhatsApp would feel less intimate and the entire system would be generally less efficient.
One account number per business could only work for those who had just one terminal. We had to make amends to ensure that each terminal would have its own account number.
Our next idea was to use one socket. We placed the queue at the back of a web socket connection from the terminal. We didn’t have a direct interchange between the POS and the queue which gave us lots of issues. Things were not synchronising, notifications were not coming in, etc. So, we solved this by taking out the socket and allowing the terminals to connect directly to the queue. It helped us a lot in the end.
We understood that terminals got retrieved now and then. So, we secured the ability to also retrieve NUBAN account numbers when terminals were retrieved.
Another problem we had was that people had gotten used to a particular account number. For example, a supermarket displayed its account number on the wall and people were already used to it. What would happen if people sent money to that account number when we had already retrieved the terminal?
Our solution to that was to do it on the web. Even if the terminal was retrieved or not working, you could always go to the web to accept or decline as it showed all the transactions you’d ever had as a business owner irrespective of the terminal.
The next problem was the issue of reversal. For example, if a business owner rejected a POS transfer, it had to be reversed back to the destination bank. One of the problems with that was that there were some banks that ran services where you couldn’t reverse money to the originating account number. We were relying on the fact that the originating account number that came from that transfer was the account number we were supposed to transfer to. If someone sent money from banks with such services and the business owner rejected it, how would the money go back to the customer?
There was also the problem of banks that sent mock BVNs.
To solve these problems, we had eligibility criteria per bank, account numbers, BVNs, etc. Also, if we tried to reverse a transaction three times and we couldn’t, we would give the business owner the prompt to go ahead with a secondary choice. Here, we would state that we have tried to reverse and it didn’t go through. So, the business owner could decide to accept the transaction or initiate a manual reversal.
Sprint to the finish line
What was the development process like?
The actual development took about four months. We were a team of 7 cutting across devs, QAs, etc. and most of us had worked together before. This made collaboration easier but there was also curiosity because it was something we hadn’t worked on before or were used to. We all learned something new while creating this feature. It kept us constantly on our toes.
We started from the business objectives to a User Experience (UX) from the POS perspective and how the journey would look like on Figma. Under the business objectives, we spoke to some relationship and regional managers – people on the field, getting ideas on how we should work from them.
Then we moved to the technical deep dive level where we had a technical document on what the engineers would do, the APIs to write, the services to create, what would be the architecture of it, and more.
After that, we did sprint planning to distribute the work amongst individuals, creating tickets on Jira for timelines and work schedules. From there, our Quality Assurance team members also wrote test cases.
Then the sprint began.
People started delivering their items, testing cycles, milestones and demos in between to show what we’d done so far. There were always changes within the sprint cycle.
We had to be certain of everything. We had a one-month period where we released it to internal testers and we got feedback in that period like application crashing, applications going down, etc.
We started around April and went fully live in August.
Are we there yet?
Where we are and what’s next
So far, there has been steady growth and abduction of the product since it launched. Stories abound from our users who find increasingly diverse and specific ways that this feature makes their business transactions smoother and more secure. There have been increased transactions by businesses in terms of volume and value. We have had to even increase the limit for transactions.
For us and our users, this feature is one more way to push the boundaries of financial inclusion and easy payments for both businesses and their customers.
Empathy is one of the core values at TeamApt and by embodying this, we created a feature that is helping our users break the boundaries on what they’re capable of. We believe in creating solutions that are relevant to our users and are devoted to doing that, one feature at a time.