Design a payment system with holds and batching
OpenAISoftware Engineer · Technical ScreenLast updated
This question tests the ability to design a high-consistency payment processing system that handles asynchronous state transitions, authorization holds, and batch settlement workflows.
Design a Payment System with Holds and Batching
Design a payment processing service that supports two distinct flows: Immediate Charges and Authorization Holds with Delayed Settlement.
Your system must support a credit-based API where a merchant can initiate a hold on a user's funds, which is then either captured (settled) in a batch at the end of the day or released.
Requirements
- Functional:
charge(user_id, amount): Perform an immediate synchronous charge.authorize_hold(user_id, amount): Reserve funds without capturing them immediately.capture_hold(hold_id): Finalize a specific held transaction.release_hold(hold_id): Void a held transaction.
- Non-Functional:
- Idempotency: Ensure that retried requests do not result in double-charging or duplicate holds.
- Consistency: The system must accurately reflect available balance vs. held balance.
- Reliability: Payments must be auditable; handle system failures during the capture or settlement process.
- Scale: Support 1,000 requests per second and batch processing for millions of records daily.
Your Deliverables
- Data Model: Define the database schema for transactions, holds, and status tracking.
- Architecture: Describe the services and communication patterns (synchronous vs. asynchronous).
- Batch Workflow: Explain how the system handles the batch settlement process to ensure no transaction is missed or settled twice.
- Failure Handling: Describe how you handle the scenario where a network timeout occurs during an external payment gateway call.
Hints
Hint 1
Use a state machine for the hold lifecycle (e.g., PENDING, CAPTURED, VOIDED, EXPIRED) to ensure atomic state transitions.
Hint 2
Implement an idempotency key at the API level and store it in the database to prevent duplicate side effects from retried requests.
Hint 3
For batch settlement, use an idempotent 'status' update strategy or a message queue to process transactions in bulk without blocking the main request path.
Follow-up questions
- How would you handle a situation where a user's balance is sufficient during the hold, but they withdraw funds before you attempt to capture the payment?
- If the batch settlement job fails midway through, how do you ensure the system remains in a consistent state and resumes correctly?
- How would you implement a 'reconciliation' service to detect discrepancies between your internal ledger and the actual bank/gateway reports?
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.