The Engineering Behind Our Payment Collection And Reconciliation Process
Pay4Me is a cross-border solution focused on tuition payments for international students and immigrants. We began operations in 2020 and officially launched in 2022.
Pay4Me provides borderless payment solutions to students by collecting the equivalent sum of the amount a student wants to pay in their local currency and then sending the money to their destination (school).
To provide this solution, our customers will need to download and install the Pay4Me app on their smartphones, create an account, and complete our Know Your Customer (KYC) requirements before they can proceed with making payments to their schools.
Before we dive into this article, here's a disclaimer: This article will be more technical than expository in its use of terminology.
Collection
In order to effectively receive and process payments for a Pay4Me customer, we have had to partner with local payment processors and integrate their APIs.
It is necessary to note that everything about payment collection revolves around this API integration, and Pay4Me's first approach towards this was to integrate the mobile app (SDKs) from these payment processors. This might seem like a no-brainer at first, but let me explain why it's not that simple.
We built our mobile app using Google Flutter, which is a cross-platform technology that supports both Android and iOS. Therefore, integration of Flutter SDK seemed to be the right way to go, and we did. However, here's what we found out:
When a Pay4Me customer tries to make a payment to their school, they have to provide us with information about the school they're paying to. Our mobile app sends that information to the database only when the customer has paid the local equivalent using our integrated payment processor. Unfortunately, this failed to process sometimes, and we then found out that instant payment confirmation was the big problem here because the Flutter SDKs were not optimized for this task.
We learned sadly that Flutter SDK is not always supported by some payment processors, which usually leaves you with the option to build and maintain one or better still use whatever open-source options are available.
Meanwhile, the technical side of this issue presents a case where we have a bug that prevents customers from initiating our integrated payment processor. We find and fix the bug, but it still takes 12 to 48 hours for it to be reviewed and approved on the app stores. The process is so rigorous that we might be out of business before the next bug fix goes live. This is also the case when adding new payment processors.
This was how we approached it in 2021 on the first version of the Pay4Me App.
Mobile SDK vs Web SDK
After our first year of building the Pay4Me App, we discovered that payment processors are heavily optimized for web-based platforms rather than mobile. This realization led us to reevaluate our approach.
What we found was a revelation: integrating a Web SDK on a mobile app can be achieved through a mobile app webview. However, this raised another question: how do we communicate between the browser and the app?
To address this challenge, we had to rethink our strategy for sending customer data to the database. In Pay4Me v1, we sent data only after payment confirmation, which sometimes led to manual data collection when issues arose. This process slowed down our ability to efficiently process school fees.
So, we decided to send customer data to the database even before payment confirmation. This allowed us to process school fees more efficiently, We also sent customer data ID and generate a payment link that opens on mobile app Web-SDK where customer completes their payment. The second endpoint accepts customer data ID and checks for payment status.
With web-view and web SDK, we provided customers with the best possible experience without leaving the app.
On the technical side, this approach enabled us to fix any payment processor issues in minutes or hours (depending on how quickly we could resolve them) without waiting for live approval from the app stores. This also applies to going live with new payment processors.
This was our approach in the release of Pay4Me App versions 2 and 3, released in 2022 and 2023 respectively.
Reconciliation
While we had successfully addressed payment collection and instant confirmation issues, our customers were still facing challenges with payment processing. Our investigation led us back to the root cause: delayed settlement.
As a payment company, we have traditionally approached collections with caution, prioritizing bank transfers as the preferred option. However, this approach has its limitations, particularly in Nigeria's bank transfer scenario, which is heavily reliant on the infrastructure of the Central Bank of Nigeria (CBN) and offers little control to our payment processors.
One common issue arises when a customer pays via bank transfer, only for it to take longer than usual, causing them to drop off from the app. Although we eventually receive notification of the confirmed payment, manual reconciliation is required.
The second part of this problem stems from the fact that, despite having significant daily transactions, our average payment ranges from $100 to $20k, and we have a small team serving over 80k users. Pay4Me couldn't handle manual reconciliation at this scale, so we went back to the drawing board and discovered Webhook as the solution.
Webhook is a notification received from our integrated payment processor about the status of customers' payments.
Although we had earlier implemented a system for payment verification and webhook, we didn't treat it as a critical component since we focused on instant payment confirmations, which work 70% of the time. Our initial webhook implementation was based on tutorials and documentation, but we needed to overhaul our code to tailor it to our business.
Now, at Pay4Me, we ensure that every webhook data received is saved and processed using metadata. We dispatch a background job that maps the webhook to the customer who made the transaction using their email, ID, and amount paid. Finally, we verify with our provider via their verification endpoint and update the customer's payment if everything checks out. We also notify them via their provided email and mobile app.
This process has improved our payment collection by over 95%
Now you might wonder how we know that the problem has been truly solved. The answer is straightforward.
We know it's because, prior to resolving this issue, payment reconciliation was a major pain point for our customers and support team. Our app store reviews and in-house support requests showed that over 70% of our support requests were related to payment reconciliation issues. Many of our Pay4Me customers expressed their frustration directly on the app store reviews, while our support team also complained about the same problem.
However, since we overhauled our code in January 2024, it's been a smooth sailing experience for everyone involved - our engineering team, support team, and most importantly, our customers. Our Pay4Me customers are now happy with the seamless payment process, our support team is no longer overwhelmed by reconciliation issues, and our engineers are receiving well-deserved praise.