Mobile Money processing.
Here’s a thread from DevCongress slack channel. Posted here for posterity (slack deletes our old messages, but this thread is good stuff)
Below features messages by @tonymobster (Anthony Acquah)
- merchant requests telco debits customer wallet. (1 sync operation). Telco makes first-line checks, sufficient balance, wallet exists, merchant authorized, etc. and returns an acknowlegement to the merchant
- Telco initiates ussd session with subscriber’s device, sends a ussd prompt to subscriber for authorization. (Another 1 way sync operation)
- subscriber responds to prompt (yet another 1 way sync operation from subscriber to telco)
ussd session then ends and gets cleaned up. (Although some telcos might have ussd sessions that are handled by persistent connections in which case the ussd session is sync)
- upon authorization telco debits subscriber wallet, credits merchant wallet
- telco initiates a request to merchant notifying him of transaction status. (1 way sync operation)
fun fact, initially the telcos did not send a callback to the merchant, the merchant was required to wait about 15s after initiating the debit request and then start polling the telco for the status of the transaction
of course this did not scale well as momo traffic grew and they went and implemented a callback process
I’m at a mobile money vendor, collecting my money (a transaction which is by design, should happen less than 15-60 seconds), using a sync in that case.
the process for this is same as i’ve outlined above, only difference is they send an SMS to the merchant instead of a callback
in no case is it a sync process
From 1-5, how long does (or should it) it take?
average 7-60s based on the telco
but it’s not about how long it takes
it’s about how the approval process is designed
is the approval process sync or async?
that’s the constraint
allow me to quote stripe to explain my point
Each payment method supported by the Sources API is defined by four key characteristics. The combination of these characteristics determines how a source is made chargeable, and how it is used in a charge request to complete a payment.
- Pull or push: How the funds for the method of payment are transferred from your customer
- Flow: The type of action your customer must take to authenticate the payment
- Usage: Whether the
Sourceis reusable or not
- Synchronous or asynchronous: Whether the resulting charge can be confirmed immediately, or only after a delay
the mtn momo payment method is pull based, reusable and asynchronous
the flow is the customer must approve through a ussd session
vodafone cash is pull based, pre-approval flow, reusable and synchronous
although they also now have an async ussd based approval flow
vodafone cash is like card payments, it’s sync
approval is granted beforehand , before the payment processing even begins
for card you approve by providing your card details, cvc, expiry, card no. etc.
for vodacash you approve by pregenerating a one-time token beforehand
by the time payment processing starts transaction is already approved out of band
it’s just a matter of doing the accounting(funds transfers) and returning sync response to the customer
now 3D secure card payments is async . you redirect the user’s browser to the provider, 1 request
the provider processes and possibly redirects away to the card issuer’s page for approval(another request)
after processing the redirect back to the merchant page(yet another request)
it’s not a sync response
if you’re PCI compliant so you gather the card details yourself and pass it on for processing it becomes even more clear it’s not a sync response
this is the constraint, the approval process
and it’s designed async because ussd is an old protocol, and especially newer phones don’t handle it well, 4g has bad support for ussd for e.g.
and even internet can interfere with ussd. for e.g. until about last year or so your internet would cut when you receive a call on most smartphones, i think the workaround the manufacturers did was they put 2 antennas in their devices, 1 for each
those are the constraints, of course pre-approval would allow for a better flow for the dev (sync), however customers hate it! They love their prompts cause it’s user-friendly
so those are the constraints and tradeoffs
i’m still not sure why we’d want a sync payment flow though even assuming it was feasible? I’m pretty sure even when working with cards which return a sync api response the dev still processes it on a background task
send payment request, receive response back, schedule a background task to send sms/email receipt, dispatch package for delivery etc.
again to quote stripe
Your integration should not attempt to handle order fulfillment on the client side because it is possible for customers to leave the page after payment is complete but before the fulfillment process initiates. Instead, we strongly recommend using webhooks to monitor the
payment_intent.succeededevent and handle its completion asynchronously instead of attempting to initiate fulfillment on the client side.
you should be sending a request for payment, upon response display some notice to the customer, "your payment is being processed, please be patient, monitor your phone for approval, yada yada yada. Hey have you seen this cool xx we have, maybe check that out while you wait
when you receive the callback, you use that as the trigger to kickoff your fulfillment processes in the background
this way when payment failed for stuff like connectivity reasons you can even retry again and hopefully it succeeds this time without bothering your customer to go through the whole process again
this is also a good talk on exactly this, why doing a sync checkout process might look simple (in his case 6 lines of code) but will fail you and refactoring it into an async process with background jobs, webhooks and retries to make it more resilient and give your customers a better experience
It seemed like an easy feature to implement, a checkout page to place an order. But this payment gateway has a simple API, so we added that. And this email service provider makes it possible to send an email with one line of code! Finally we can notify downstream systems via a message queue. The code looks simple, 6 little lines of distributed systems code.
But those lines hid a dark secret that we only found after launching. Customers complained they didn’t get their email. The back end system wasn’t getting updated from our messages. And by far the worst of all, customers complained they saw an error page but still got charged!Clearly it wasn’t as easy as calling a few APIs and shipping, we actually need to worry about those other systems. In this session, we’ll look at taking our 6 lines of distributed systems fail, examining the inevitable failures that arise, and possible mitigating scenarios. We’ll also look at the coupling our code contains, and the ways we can address it. Finally, we’ll refactor towards a truly resilient checkout process that embraces, instead of ignoring, the fallacies of distributed computing.