Design a Payment Processing System
OpenAISoftware Engineer · OnsiteLast updated
This question tests the ability to design a distributed payment processing system that guarantees atomicity and consistency under high concurrency and partial network failures.
System Design: Payment Processing API
Design a payment processing service that allows users to pay for API credits. Your system must interact with an external third-party payment provider (like Stripe or PayPal) and update the user's credit balance internally.
Requirements
-
Functional Requirements:
- Users can initiate a payment for a specific amount.
- The system must verify successful payment with the external provider.
- User balances must be updated exactly once per successful payment.
- Provide an audit log of all transactions.
-
Non-Functional Requirements:
- Consistency: Financial data must be accurate. Double-spending or missing credits is not allowed.
- Idempotency: A user might click "Pay" multiple times, or the network might timeout. Your system must handle duplicate requests gracefully.
- Durability: Once a payment is acknowledged, it must be persisted.
- Scale: Handle 1,000 requests per second.
Design Deliverables
- API Design: Define the endpoint for initiating a payment and the webhook signature for receiving status updates from the payment provider.
- Data Model: Propose a schema that supports double-entry bookkeeping (e.g., Ledger and Accounts tables).
- High-Level Architecture: Describe how you handle retries, how you ensure idempotency, and how you prevent race conditions when updating user balances.
Constraints
- The external payment provider's API may be slow or periodically unavailable.
- Your system must handle cases where the external provider notifies you of a success, but your internal database update fails.
Hints
Hint 1
Use an idempotency key passed from the client to ensure that multiple retries of the same request result in only one transaction.
Hint 2
Implement the 'Outbox Pattern' to ensure that your internal database state and the event sent to your billing service are updated atomically.
Hint 3
Model your database using a ledger pattern where you append entries (debits/credits) rather than just updating a single 'balance' column to provide an immutable audit trail.
Follow-up questions
- How would you handle a situation where the external payment provider experiences a long-term outage?
- How would you reconcile the state between your internal ledger and the payment provider's records if a discrepancy is detected?
- What specific database isolation levels or locking strategies would you use to prevent race conditions on the user's account balance?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.