So I designed and implemented core component of UPI system for fun
Disclaimer: This article is based on my current knowledge and understanding. If you have any query or see any improvement, please mention in the comment section.
I heavily use UPI and big fan of the technology . Hence to understand it more deeply , I watched below tech talk.
tech talk link: https://www.youtube.com/watch?v=qtmDGoMD6Ck
From above screenshot, we can understand different steps happening when UPI transaction occurs. To understand each step deeply, I highly recommend to watch this talk. TL;DR of steps summary is — when person XYZ sends money to person ABC, UPI apps(Gpay, Phonepe, BHIM) basically give account details to UPI switch service/component after thorough authentication and then UPI switch service/component does the actual transaction.
Careful reader might have observed that UPI switch is core component of above entire architecture. There are many tasks UPI switch component performs but I felt that the core/ultimate task of UPI switch component is to debit money from person XYZ’s bank account and credit it to person ABC’s bank account. For this article we are going to focus on this task only.
This ultimate task can be seen as orchestrator task where UPI switch component is orchestrator and it is handling tasks like credit and debit amount across different banks account holders.
So our task is to develop API which acts as an orchestrator across different APIs and complete the end goal. To solve this problem, I am going to use azure durable functions with orchestrator pattern. Below is the code snippet.
Code is self explanatory . Two activity functions for credit and debit and one orchestrator function to coordinate and complete ultimate task.
When everything is running good, end goal is easy to achieve but let’ s see what happens when service is stopped in between .
From above screenshot, we can see debit function executed but while credit function we just stopped the service.
We reran the service and we can see only credit step(highlighted in yellow ) was executed and entire process/workflow got completed.
Isn’t this cool? This is achieved thanks to event sourcing architecture pattern. In this pattern, you maintain append only log structure(where you can only insert new records and cannot update or delete) which sounds very simple to accounting ledger or blockchain.
Due to this append only log structure , when we reran the service, service checked till which steps we have executed (in our case it was debit) and move to execute remaining step/steps(in our case it was credit).
One important point to note here is some functions can be reran even though they are executed previously if process is not able to determine via append only log structure if a function previously ran or not. To tackle this problem we need to make activity functions idempotent.
I used azure durable functions for this problem statement but you can use anything you want which exhibit this pattern and solve problem efficiently.
~ Happy coding