Design a Payment Processor with Holds, Charges, and Network Batches
OpenAISoftware Engineer · Technical ScreenLast updated
Design a hold-and-charge payment processor with honest asynchronous results, durable deduplication, incremental network batches, and safe acknowledgment recovery.
Design a payment processor with two separate operations. A merchant first requests a hold, which the processor forwards to an upstream payment network for approval or rejection. After a successful hold, a later charge request is grouped with other charges for the same payment network, written into a batch file, and sent on a schedule.
Explain the merchant-visible results, deduplication boundaries, scaling strategy, and reliable construction and transmission of large batches.
Constraints & Assumptions
- Accepting a request into Kafka or another durable queue is not the same as receiving payment-network approval.
- Hold and charge are separate requests with different eligibility and response states.
- The source supplies no network-specific file format, schedule, settlement guarantee, amount policy, or retry protocol. Identify those dependencies explicitly.
- Batch construction should support parallel work by payment network and incremental preparation throughout the day.
Clarifying Questions to Ask
- Must the hold API wait for a network decision, or may it return pending with a later status or callback?
- Which hold states and amounts permit a charge, and can a hold expire before charge processing?
- What identities do merchants and networks support for deduplication or status lookup?
- How are batch cutoffs, acknowledgments, rejected records, and retransmission handled by each network?
Part 1 — Hold and Charge Lifecycles
Walk through request acceptance, network decisions, merchant notifications, and charge eligibility. Define what each acknowledgment means.
What This Part Should Cover
- Durable request identity and explicit pending, approved, rejected, or uncertain states.
- No claim of hold success merely because a queue write succeeded.
- Independent charge identity and validation against the relevant hold state.
Part 2 — Deduplicate and Recover
Explain merchant retries, worker crashes, lost network responses, and duplicate callbacks.
What This Part Should Cover
- Durable deduplication at logical-operation boundaries.
- Conditional state transitions and external idempotency or reconciliation.
- Separation of a processing attempt from a new financial operation.
Part 3 — Prepare and Send Network Batches
Design incremental charge collection, a stable batch cutoff, parallel construction, file validation, transmission, and acknowledgment handling.
What This Part Should Cover
- One accountable membership record per charge and a reproducible batch identity.
- Streaming or partitioned file generation with network-specific finalization.
- Transmission uncertainty and per-batch or per-record outcomes without double inclusion.
Hints
Hint 1
Name the result returned after enqueueing: A durable queue receipt can prove that the processor accepted work. It does not contain the upstream network's hold decision unless that decision has actually arrived.
Follow-up questions
- How would you recover when a network may have accepted a batch but its acknowledgment was lost?
- What happens to a charge arriving while its network's batch is being sealed?
- Why is a new filename on each retransmission not a safe deduplication strategy by itself?
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.