# System design of a payment service (Venmo) ## Functional Requirements - Users must be able to sign up to payment service - Users must be able to link/unlink a bank accounts - Users must be able to send/receive money to other payment service users - Users must be able to send/receive money to their bank account ### Non-Functional Requirements - Highly available, low latency - Have to achieve 100% accuracy <- our service will live and die based on this ## Data Models (Relational Database) Users { userId: string createTime: datetime email: string phoneNumber: string debitCardId: string balance: integer } BankAccounts { BankAcountId: string, userId: string createTime: datetime bankName: string, bankPhoneNumber: string, bankEmail: string, ... } Transactions { transactionId: timeseries key fromId: string toId: string transactionDate: datetime amount: integer status: enum (declined/accepted/waiting for verification) } ## APIs POST /whatever POST /v1/transaction { fromId: string toId: string transactionDate: datetime amount: float } 200 OK - { transactionId: timeseries key fromId: string toId: string transactionDate: datetime amount: integer status: enum (declined/accepted/waiting for verification) } 404 - Not Found { errorMessage: string } {} {} 200 GET /v1/transactions/{userId}?startTime=datetime&endtime=datetime GET /v1/bankAccuonts/{userId}?startTime=datetime&endtime=datetime GET /v1/user/{id}?startTime=datetime&endtime=datetime response: { userId: string createTime: datetime email: string phoneNumber: string debitCardId: string balance: integer bankacounts: [ bankAccount1, bankAccount2 ] } POST /v1/user/:id/accounts DELETE /v1/user/:id/accounts/:bank-id DELETE /v1/account/:bank-id PUT /v1/user/{id} request: { bankName: string, bankPhoneNumber: string, bankEmail: string bankAcountNumber: string, bankRoutingNumber: string ... } response: 200 OK PUT /v1/user/{id} request: { unlinkBankAccountId: string } response: 200 OK ## System Design Customer -> Server (through API) -> DB Customer -> Auth Layer (Active Directory) -> Server -> DB Customer 1 & 2 -> Auth Layer (Active Directory) -> Server -> DB Customer 1 ... N -> Auth Layer (Active Directory) -> Server -> DB Customer 1 ... N -> Auth Layer (Active Directory) -> Server 1..K -> DB Customer 1 ... N -> Auth Layer (Active Directory) -> LoadBalancer -> Server 1 .. K (K << N) -> DB How do we balance the load? Round Robin. Customer 1 ... N -> Auth Layer (Active Directory) -> LoadBalancer (Round Robin) -> Server 1 .. K (K << N) -> DB Customer 1 ... N -> Auth Layer (Active Directory) -> LoadBalancer 1..J (Round Robin) -> Server 1 .. K (K << N) -> DB Customer 1 ... N -> Auth Layer (Active Directory) -> LoadBalancer 1..J (Round Robin) -> Server 1 .. K (K << N) -> Redis Cache (we're going to have to a very strict expulsion property) -> DB 1..L (relational database) Customer 1 ... N -> Auth Layer (Active Directory) -> LoadBalancer 1..J (Round Robin) -> Server 1 .. K (K << N) -> Redis Cache (we're going to have to a very strict expulsion property) -> Segmented DB 1..L (relational database that are segmeneted based on the user id) Server -> Lambda Functions that can scale UniqueIdService -> Service that generates unique ids for users and bank accounts Queue ->