Architecture

Design a payment wallet

Involvement of money is major part in payment systems. Building a wallet service, mainly consists of money movement. When a user transfer funds to another user, the money is deducted from the one user and added in the second user. Wallet can be used to pay to purchase items for different vendors which required API integration with external services. 

Thinking Process

  1. What are the different use cases of the payment wallet
  2. Do we need distributed transactions 

Architecture

In the SOA, we have multiple services and any service can fail any time. How we can avoid the double payments or error handling in this case. We would use a sharded database to store if the payment has been done. This idempotency can be based on transaction or at the row level. This functionality can be implemented as part of a library which can be reused by other services. 

API 

Due to the sensitive nature, all the interactions between the server and the client would be secured by using https. REST API would be exposed for the applications (mobile, web) and it can be designed as below: 

  1. Login/Signup

Method: POST 
Endpoint: /v1/user

Body

Email ID: string

        Username: string

        Password: string

Server can respond with status code in conjunction with a SET-COOKIE header to set the authentication cookie.

  1. Accounting information

Method: GET

Endpoint: /v1/account

Body:

      Username: string

        Password: string

Response Fields:

  1. Balance: Integer
  2. Last transactions : List of strings 
  3. Transfering money to another user

Method: POST

Endpoint: /v1/transfer

Body:

      UserName: String

      Amount: Integer

Payment API from different vendors (e.g. Stripe) can be used to add the initial money in the account. 

Storage

Sharded Relational database:

Sharding can be used while deploying relational database. The wallet service would hash the userId to locate the database instance.  Consistent hashing can also be used to support dynamically change the number of database nodes. Two phase commit (2PC) is used to take the lock on both the rows (account A and account B). After the lock is taken on both of the rows, the leader (the node which received the client request) pass the commit message to the other node. Instead of using 2PC, distributed locks can be implemented by redis. A unique redis key

would be created by the row number and the node number. A lock needs to be taken every time a row is updated.  

NoSQL Systems 

NoSql databases can 2 phase or 3 phase commit protocol  to implement transactions in distributed environments. E.g transactions in MongoDB or Paxos for LWT (lightweight transactions in Cassandra). MongoDB ensures the ACID transaction guarantee, which is inherent requirements for financial transactions. 

Database Schema

Integration with external payment APIs:

Payment API providers (like Stripe) could be integrated for adding initial money or withdrawing money from the wallet.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button