System requirements


Functional:

  1. User Account Management: Allow users to create, update, and delete their accounts, as well as manage personal details and payment methods.
  2. Fund Transfers: Enable users to send and receive payments to/from other users with the ability to input amounts and confirm transactions.
  3. Payment Processing: Facilitate smooth transactions, including processing card payments, bank transfers, and various electronic payment methods.
  4. Fraud Detection: Implement mechanisms to analyze transactions for potential fraudulent activities to protect users.
  5. Buyer and Seller Protection: Ensure measures are in place to safeguard both buyers and sellers, including dispute resolution and refund policies.
  6. Multi-Currency Support: Allow transactions in different currencies with real-time conversion rates.
  7. Transaction History: Provide users with a detailed history of their transactions, including amounts, dates, and transaction status.
  8. Notifications: Send real-time notifications regarding transaction status, security alerts, or promotional offers.
  9. API Integration: Offer APIs for third-party developers to integrate payment processing into their platforms easily.
  10. Security Measures: Ensure secure transactions with encryption, two-factor authentication, and compliance with payment regulations.




Non-Functional:

  1. Scalability: The system should handle a growing number of users and transactions without performance degradation. For instance, it should support up to 1 million transactions per day initially with the capacity to scale as the user base grows.
  2. Reliability: The system should ensure high availability (e.g., 99.9% uptime) to allow users to access and transact with minimal disruptions. This may involve implementing redundancy and failover mechanisms.
  3. Performance: Transactions should be processed in a timely manner, ideally within a few seconds. The system should be able to handle concurrent transactions efficiently.
  4. Security: The system must comply with security standards (e.g., PCI DSS) to protect user data and prevent unauthorized access, ensuring encryption of sensitive information and secure APIs.
  5. Usability: The interface should be intuitive and user-friendly so that users can navigate easily and complete transactions with minimal effort.
  6. Maintainability: The system should be designed for easy updates and maintenance, allowing developers to modify components without affecting overall system performance.
  7. Compliance: The service must comply with financial regulations and data protection laws across different regions (e.g., GDPR, CCPA).
  8. Localization: The system should support multiple languages and currencies to cater to a global user base.
  9. Interoperability: The payment service should be able to integrate easily with existing banking systems and third-party applications.
  10. Monitoring and Logging: There should be mechanisms in place for comprehensive logging and monitoring of transactions and system performance for audit trails and troubleshooting.





Capacity estimation

Starting: 100000 Users/day

50000 transactions per day

10GB of transactions daily

1 server can do 1000 conections

1 server can hold 1000GB of data

Having those numbers we can estimate the resources we need:

1) RPS = 50000 RPD / 24 * 60 * 60 = 0.57 RPS

2) Connections per second = 10000 / 24 * 60 * 60 = 1.15

3) Data to store per year = 10GB * 365 = 3650GB

4) Servers to serve connections = 10000 users/day / 1000 = 10 servers

5) Servers to hold data = 3650 / 1000 = 4 servers (round up)





API design

GET /v1/account

POST /v1/account

PATCH /v1/account


POST /v1/transfer

GET /v1/payLink


GET /v1/history

GET /v1/audit/logs


Database design

User <|-- UserWallet

User : +int UserId INDEX

User : +String UserName

User : +String HashedPassword

User : +String Email INDEX

User : +DateTime CreatedAt


UserWallet <|-- User

UserWallet : +int WalletId INDEX

UserWallet : +int UserId INDEX

UserWallet : +int Balance

UserWallet : +int CurrencyCode


Transaction <|-- User

Transaction <|-- PaymentType

Transaction <|-- TransactionType

Transaction : +int TransactionId INDEX

Transaction : +int UserIdFrom INDEX

Transaction : +int UserIdTo INDEX

Transaction : +int TransactionType

Transaction : +int PaymentType

Transaction : +int Amount

Transaction : +int CurrencyCode

Transaction : +DateTime Date

Transaction : +String Message


CurrencyConversionRate <|-- Currency

CurrencyConversionRate : +int ID

CurrencyConversionRate : +int FromId

CurrencyConversionRate : +int ToId

CurrencyConversionRate : +float Multiplier

CurrencyConversionRate : +DateTime timestamp INDEX



FraudLog <|-- Transaction

FraudLog : +int ID INDEX

FraudLog : +int TransactionId INDEX

FraudLog : +DateTime TimeStamp INDEX


Paymentbackend : +int ID

Paymentbackend : +String Name


PaymentbackendDetails <|-- Paymentbackend

PaymentbackendDetails : +int ID

PaymentbackendDetails : +int PaymentBackendId

PaymentbackendDetails : +int SupportedPaymentType


PaymentType : +int ID

PaymentType : +String Name


Currency : +int ID

Currency : +String Name


TransactionType : +int ID

TransactionType : +String Name




High-level design

1) Api gateway/load balancer

2) User service

3) Payment service

4) Log infra and audti services

5) Payment backend

6) Transaction processor



Request flows

1) User issues an HTTP request to transfer funds

2) Request goes through api gateway/load balancer

3) Request goes into payment service

4) Payment service calls payemnt backedn and stores transaction in db

5) Payment service issues notification to a client




Detailed component design

1) Payment service: accepts payment requests from client and coordinates payment processros to execute payment backends. Performs risk checks for transations using FraudService and records transactions in durable manner into Transaction DB. ALso notifies client about success using Notification Service

2) User service. Manages user accounts. Stores relevant user info in database and provides API to manage an account

3) Log service. Samples health logs from all system components (except self) and stores them in a log database. Also allows to perform a fulltext search on the logs and sends notification when a new log is encountered

4) Audit infra. Monitors the health of underlying services and sends notifications using Notification Service if health parameters drop with limit

5) Transaction read replica. Responsible for serving transaction writes to the user. Used to optimize read-heavy path of retrieving transaction info.







Trade offs/Tech choices

Predominance of Reads

  1. User Account Information:
    • PathGET /v1/account
    • Expected Reads: The user profile and balance check are common operations. Users may frequently access their account details without triggering many updates.
    • Optimization: Use caching for user profiles and balances (e.g., Redis) to reduce database load.
  2. Transaction History:
    • PathGET /v1/history
    • Expected Reads: Users will query their transaction history often to verify payments and balances.
    • Optimization: Implement pagination and caching strategies to improve response times and reduce database querying overhead.
  3. Payment Links:
    • PathGET /v1/payLink
    • Expected Reads: Many users may request payment links for different transactions.
    • Optimization: Cache frequently generated links or store them temporarily in a quick-access database.
  4. Currency Conversion Rates:
    • Path: Could be an endpoint like GET /v1/currency/rates.
    • Expected Reads: Currency rates are often read for each transaction and may not change frequently.
    • Optimization: Store rates in a high-speed cache and limit updates perhaps hourly or daily.

Predominance of Writes

  1. User Account Creation/Updates:
    • PathPOST /v1/account and PATCH /v1/account
    • Expected Writes: These paths involve high write operations for user creation and metadata updates.
    • Optimization: Validate inputs at the application layer to ensure that only necessary data modifications are made.
  2. Fund Transfers:
    • PathPOST /v1/transfer
    • Expected Writes: This is a critical path where each transaction results in multiple writes, including creating transaction records and updating user wallet balances.
    • Optimization: Use an asynchronous processing model (e.g., message queues) to manage transactional writes to the database and ensure transactional integrity.
  3. Logging Transactions:
    • Path: Writing logs to Log Infrastructure
    • Expected Writes: Each transaction may generate multiple log entries for security and auditing. This creates a significant amount of write operations.
    • Optimization: Batch log entries to write in groups to reduce write frequency and thus improve performance.
  4. Fraud Detection Logs:
    • Path: Writing to TransactionFraudLog
    • Expected Writes: When an unusual transaction is detected, it would lead to numerous write operations.
    • Optimization: Ensure that the fraud detection system is efficient at batching operations to avoid overwhelming the logging infrastructure.

Handling failed transactions

Handling failed transactions in a payment system is crucial for ensuring reliability and fault tolerance. Here's how we can tackle these challenges based on the provided information:

Tracking Payment State:

  • Definitive Payment State: Maintaining a definitive payment state at every stage of the payment cycle enables us to determine the current state of a transaction in case of failure.
  • Persistence: Persisting payment states in an append-only database table ensures that transaction status can be accurately tracked and managed.


1) Transaction log is a read heavy system that prioritize availability thus we choose some no-sql solution for easy scaling like cassandra or amazon dynamo db

2) Logging system is write heavy with strong avaialbilty a thus we prioritize sharding our log database based on service (user service, payment service, etc) For reading when the amount of logs is too big we use pagination to retrieve only latest logs. For DB with use some NoSQL solution optimized for high writes

3) User management system is not read or write heavy and case use classic SQL solution and be sharded by user ID when the amount of users get too big

4) To insure durability of our transaction log we maintain a write ahead log that records all action applications before flushing them to db.

5) To scala the payment processros we use queu technology like apache kafka.





Failure scenarios/bottlenecks


Retry Queue and Dead Letter Queue:

  • Retry Queue: Retryable errors, such as transient network issues, are routed to a retry queue for subsequent retry attempts.
  • Dead Letter Queue: Messages that fail repeatedly end up in the dead letter queue, facilitating debugging and isolation of problematic messages for inspection.


Retry Strategies:

  • Immediate Retry: Resending the request immediately upon failure.
  • Fixed Intervals: Waiting a fixed amount of time between the failed payment and subsequent retry attempts.
  • Incremental Intervals: Gradually increasing the time between retry attempts.
  • Exponential Backoff: Doubling the waiting time between retries after each failed attempt to prevent overwhelming the system with retry attempts.
  • Cancellation: Canceling the request if the failure is deemed permanent or if repeated attempts are unlikely to succeed.


Example of Retry:

  • Scenario: A client attempts to make a $10 payment, but the request fails due to a poor network connection.
  • Retry Attempts: The client retries the payment request multiple times until the network connection eventually recovers, ensuring the transaction's successful completion.
  • Retry Interval Decision: Deciding appropriate time intervals between retries is crucial to balance between ensuring transaction success and avoiding overwhelming the system with retry attempts.






Future improvements

Use ML for fraud detection