System requirements


Functional:

List functional requirements for the system (Ask the chat bot for hints if stuck.)...

  • Users should be able to transfer money from bank account into payment system and vice versa, as transaction.
  • Users should be able to send money to other users in the payment system and vice versa, as transaction.
  • Users should be able to add/edit their profile
  • Users should be able to add and remove bank account.
  • Users should be able to view historical transactions.
  • The account will be highly secure: user identity can't be faked.
  • The system will detect suspicious transactions and alert users, and may withhold the transaction until user approve.
  • The transaction is highly consistent, user won't lose and get money out of nothing.
  • Transaction will be denied if sender has insufficient fund.
  • Receivers and senders of transactions can use different currency.
  • How currency exchange rate is determined, is out of the scope.


Non-Functional:

List non-functional requirements for the system...

  • The system should support billions of users worldwide, with acceptable performance.
  • The system should be able to process tens of billions of transactions each day with acceptable performance.
  • All user data should be retained lifelong.
  • The system is highly consistent, no data will be lost.


Capacity estimation

Estimate the scale of the system you are going to design...

  • Data for Transactions
    • Assume 10Billion transactions per day, and each transaction comprised of 100 byte of data; the estimation covers capacity for the next five years.
    • Storage = 10 billion * 100 * 5 * 365 byte, which is roughly 2 Pera Bytes
  • Data for User Profile:
    • Assume 1 billion users, and each user consists of 1000 bytes of data(profile, contact, bank account, setting)
    • Storage = 1 billion * 1000 byte, which is roughly 1 tera bytes.




API design

Define what APIs are expected from the system...

  • Api Send Money : (send money to user in the system)
    • Parameters:
      • sender id
      • receiver id
      • amount
      • time
      • location
    • Response:
      • success or fail
      • error message
  • Api Transfer Money(move money into or out of the system):
    • Parameters:
      • type: move out or move in
      • user id
      • account id
      • amount
    • Response:
      • success or fail
      • error message
  • Api add bank account:
    • Parameters:
      • user id
      • bank account number
      • bank routing number
    • Response:
      • success or fail
      • error message
  • Api remove bank account
    • Parameters:
      • user id
      • bank account id
    • Response:
      • success or fail
      • error message
  • Api: get transaction history
    • Parameters:
      • user id
      • time range
    • Response
      • List<transaction info >




Database design

Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...

  • User Profile - relational db, shard by user id
    • Schema
      • user id
      • first name
      • last
      • phone
      • email
      • address
      • social security number - encrypted
      • password - encrypted
  • User Account - relational db, shard by user id
    • Schema
      • user id
      • transaction id
      • start
      • end
      • amount
      • timestamp
      • currency
  • Bank Account - relational db, shard by user id
    • Schema
      • user id
      • account id
      • bank account number - encrypted
      • routing number - encrypted
      • currency
  • Transaction - relational db, shard by transaction id
    • Schema
      • transaction id
      • sender id
      • receiver id
      • location
      • time
      • amount
      • type - user to user; user to bank; bank to user
      • state




High-level design

You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...







Request flows

Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...

  • Send money (assume that the application already validates that sender id and receiver id is correct): user make request to the api server -> service sender user account has sufficient fund deduct the amount (through transaction) -> service adds the amount to receiver id -> server adds a record in transaction db -> server return success to user (or failure if account has insufficient fund





Detailed component design

Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...

  • Concurrency in Send money api: the service creates an entry in transaction db and get the transaction id back -> service . The execution of transaction is handled by transaction processor.
  • Transaction processor checks user account making sure sender has enough fund before deducting the amount. However, the user might be sending current requests. Without any handling, the operations may interleave, an error could occur that would bring the amount to negative. The service instead, put the check funding and deduct from funding into one transaction. Hence making the request sequential. Similarly, when adding the amount to the receiver, it's also in a transaction.
  • Once the update is done, notification service will pick up the change and send update to user with frequency based on their selection.





Trade offs/Tech choices

Explain any trade offs you have made and why you made certain tech choices...

  • To mitigate concurrency issue in send money service, the system chooses transactions over other mechanisms for the ease of development.
  • Instead of using a single value represent the balance of user account, we use an entry of account changes imposed by each transactions. This ensures the idempotency of the system.
  • Instead of having the api service update account, we dedicate the work to an offline transaction processor, this enables more complex functionalities like performing fraud detection before executing the transaction.





Failure scenarios/bottlenecks

  • There could be dead lock in send money service, where two users might be sending money to each other concurrently.
  • Data could be in inconsistent state, if one of the operation in a transaction fails to execute. For example, receiver account fail to increment, while the money already gets deducted from user account. In this case, the get money service will issue an refund transaction. In case of refund transaction failing, this would trigger manual handling.




Future improvements

What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?

  • For deadlock in send money service, the system could potentially add a timeout.