System should allow to add/edit and delete users
System should allow login of the users
System should allow users to link bank accounts/cards
System should be able to verify the identity of account holder
A verified user should be able to send money from or receive payment to pay account
User should be able to see the total balance and the transaction history
Able to send the payment
User should be able to receive payment
User should be able to select the payment mode
User should be able to select the currency
User should be able to get the notification of the transaction
User should be able to receive the fraud alert if any transaction happens that is not used initiated
Lets suppose system has total 100 million users
10% of the capacity interact with the system on a daily basis
DAU -> 10 M
10% of DAU actually makes the transaction and rest just check their account
write ops -> 1 M
read ops -> 9 M
read/write = 9:1
Given 1M users actually does the transaction and each transaction makes entry for transactionid, sender, receiver , transactiontime, status etc. on an avg. total 1-2KB of data will be stored per transaction. Lets suppose each user may do 2-3 transactions and hence averaging to 1.5 of 1M would be total transactions
Per day storage requirement :
1M* 2KB * 1.5 = 3GB / Day
Per year storage requirement :
3GB * 365 = 1.1TB
Given the data retention of 7 years
Total Capacity requirement of trx data is
7.7 ~ 8 TB
For Ledger entries, capacity requirement would be 2* Transaction requirement = 16TB
TPS :
1M * 1.5 ~ 18 TPS avg
Peak = 2* 18 = 36
QPS:
9M * 3 = 27 Million reads/Day = 1500
Peak = 3000 QPS
Users API
An api to register user to the system
Signature : {baseuri}/api/v1/register
Method : POST
Request Body :
{firstname, lastname, email, mobile, country, address}
Once user is registered an email is send to validate the email
Validate API
Signature : {baseuri}/api/v1/validate
Once validated user is allowed to enter the password & confirmpassword
Set Password API
Signature : {baseuri}/api/v1/login
method : POST
Request Payload : { username : encrypted, password : encrypted }
Add card details API
Signature : /api/v1/addpay
POST
Request Payload : send payload of card details or payment data in encrypted format.
Q - which encrypted format to use?
Fetch Balance API
Signature : /api/v1/transaction?page=x&limit=100
Get
Response : list of transaction
Initiate payment
Signature : /api/v1/pay
POST
requestpayload : {
senderid, receiverid, amount, currency, paymentmethodid, idempotencykey
}
For Storing The User Details
User Table
id
firstName
lastName
emailAddress
mobileNum
isKycConfirmed
isEmailValidated
isActive
createdDate
UpdatedDate
DeletedDate
Address Table
id
streetName
addressLine1
addressLine2
addressLine3
city
zip
state
country
createdDate
updatedDate
userId
PaymentMethods Table
id
userid
paymentMethod
cardtype
cardNum
validDate
cvv
upiid
transaction Table
trxId
senderId
receiverId
amount
isTrxSuccess
payMethodId
Since, its a payment system it is important that ACID principle is followed. Since relational database support ACID properties, choosing SQL would be a better approach. SQL database also supports in managing the concurrency and transactions are better handler in SQL database.
In order to design or build such a system we will take the help of 2 approach mentioned below
a ) Client-Server architecture - This helps in letting client interact with the platform. It will support different APIs that a client need in order to interact or make calls with the system.
This again is broken into 2 piece
1) UI -> Since I am familiar with Angular, I will choose this to build my UI. UI is deployed on an S3 storage in AWS. Couple of advantage that we get out of this is its very low cost to deploy the UI on S3. Also, we can place CDN in front to improve the overall load time and hence improving the user experience.
2) Backend - We deploy our containerized backend into EKS cluster. Again, since its a EKS, we can define the maximum number of replicas that should be spawned in case load comes. Also, we can configure our K8S to define the threshold that EKS engine will use to spawn the new pod.
b) Microservice architecture - This offloads the task that a user is not dependent upon . For ex - Notification service. Whenever any transaction happens, an event is pushed to a queue which is then listened by listener or consumer for sending the notification.
We will use Kubernetes as a platform to manage our containerized application. We can easily provision horizontal scaling in case of load shoot.