PracHub
QuestionsCoachesLearningGuidesInterview Prep
|Home/System Design/OpenAI

Design a Payment Processing System with Exactly-Once Charging

Last updated: Jul 1, 2026

Quick Overview

This question evaluates a candidate's ability to design a payment system that guarantees exactly-once charging under network failures, retries, and duplicate events. It tests system design skills around idempotency, state machines, and reconciliation between internal records and an external payment provider, commonly used to assess reasoning about correctness and fault tolerance in distributed systems.

  • hard
  • OpenAI
  • System Design
  • Software Engineer

Design a Payment Processing System with Exactly-Once Charging

Company: OpenAI

Role: Software Engineer

Category: System Design

Difficulty: hard

Interview Round: Technical Screen

# Design a Payment Processing System with Exactly-Once Charging You are designing the core payment service for a marketplace platform. When a buyer checks out, the platform must charge the buyer's card through an external payment service provider (PSP), then record the outcome so the order can be fulfilled. Your service sits between the platform's checkout flow and the PSP. The bar for this problem is correctness under failure. Cards must never be double-charged; a buyer who retries a timed-out request must not pay twice; and the system's record of what happened must always converge to the PSP's record of what happened. Walk through the end-to-end design, then go deep on idempotency and on resolving unknown outcomes. ### Constraints & Assumptions - ~5,000 checkout attempts/second at peak. A single charge takes 1-3 s end-to-end because the synchronous PSP call is the slow leg. - One PSP integration to start: a request/response HTTP API plus asynchronous webhooks that deliver the final settlement state. - Single currency to start; multi-currency and marketplace split payouts are follow-ups. - The PSP supports idempotency keys but can time out, return ambiguous errors, and deliver duplicate or out-of-order webhooks. - Money correctness is non-negotiable. Availability target is 99.95%. A charge may be slow, but it must never be silently lost or duplicated. ### Clarifying Questions to Ask - Does "exactly once" mean one charge *attempt*, or one *successful capture*? Is auth-then-capture required, or a single immediate sale? - Who is allowed to retry — the browser/app, the platform's checkout service, or our payment service — and what client retry behavior should we plan for? - What is the source of truth for "the buyer was charged" — our database or the PSP — and how quickly must the two reconcile? - Must checkout get a synchronous success/failure, or can the final result be confirmed asynchronously after a "pending" response? - Which downstream systems consume payment results (ledger, fulfillment, receipts), and do they need exactly-once, ordered delivery? - Are refunds, voids, and chargebacks in scope now or later? ### Part 1: High-level design, API, and data model Sketch the end-to-end architecture and the core charge flow. Define the API the checkout service calls, the data model for a charge, and how a request flows from checkout to your service to the PSP and back to a recorded result. Make the lifecycle of a single charge explicit. ```hint Where to start Model a charge as a state machine (`created -> pending -> succeeded` / `failed`) and persist the row *before* you ever call the PSP, so a crash can never erase the fact that a charge was attempted. ``` ```hint API shape Have the create-charge endpoint accept a client-supplied idempotency key and return the current charge state, so the same request can be replayed safely and the caller can poll for the outcome. ``` #### What This Part Should Cover ```premium-lock What This Part Should Cover ``` ### Part 2: Idempotency and exactly-once charging Go deep on idempotency. A buyer double-clicks "Pay," the network times out and the client retries, and the PSP later redelivers a webhook. None of these may produce a second charge. Design the idempotency mechanism end-to-end: how keys are generated, stored, and enforced; what concurrent duplicate requests return; and how idempotency is propagated to the PSP call itself. ```hint Key + storage Persist the idempotency key with a unique constraint, bound to a hash of the request parameters, so a duplicate is caught by a write conflict instead of a check-then-act read race. ``` ```hint Concurrency Two duplicates can arrive at the same instant. Decide what the loser returns (the in-flight or final result of the first) and how you guarantee a single PSP call: serialize on the DB row and pass the *same* idempotency key to the PSP. ``` #### Clarifying Questions for this Part - Is the idempotency key generated by the client per checkout attempt, or derived server-side from order id plus amount? - How long are keys retained, and is replaying a stored key with *different* parameters an error rather than a replay? #### What This Part Should Cover ```premium-lock What This Part Should Cover ``` ### Part 3: Resolving unknown outcomes, reconciliation, and money correctness Handle the hardest failure: you call the PSP and the call times out, so you do not know whether the card was charged. Design how the system resolves unknown outcomes, how it reconciles its records against the PSP as source of truth, and how it guarantees the recorded money movement is correct. Cover duplicate and out-of-order webhooks and how downstream consumers learn the final result exactly once. ```hint Unknown outcome Never blindly re-issue a timed-out charge. Re-drive it with the *same* idempotency key (safe to repeat) or query the PSP for that key's status before deciding anything. ``` ```hint Truth and reconciliation Treat the PSP as source of truth: make webhook handling idempotent so redelivery is a no-op, and run a reconciliation job that sweeps pending charges and pulls their real status. ``` ```hint Correctness Record money movement in an append-only ledger and publish results through an outbox so downstream consumers get exactly-once, ordered updates even if your service restarts mid-publish. ``` #### What This Part Should Cover ```premium-lock What This Part Should Cover ``` ### What a Strong Answer Covers ```premium-lock What a Strong Answer Covers ``` ### Follow-up Questions - How would you extend the design to support authorization-then-capture, voids, and partial refunds while preserving idempotency? - The PSP is down for 10 minutes. How do you degrade gracefully (queue and retry, fail closed, or fail over to a second PSP), and what are the correctness implications of each? - How do you prevent and detect double-charges caused by a buggy client that generates a fresh idempotency key on every retry? - How does the design change for multi-currency, and for splitting one buyer payment across multiple sellers (marketplace payouts)?

Quick Answer: This question evaluates a candidate's ability to design a payment system that guarantees exactly-once charging under network failures, retries, and duplicate events. It tests system design skills around idempotency, state machines, and reconciliation between internal records and an external payment provider, commonly used to assess reasoning about correctness and fault tolerance in distributed systems.

Related Interview Questions

  • Design the GPU Job Scheduler for a Text-to-Video Generation Service - OpenAI (hard)
  • Design a Payment Processing System - OpenAI (hard)
  • Design a Payment Processing Service (Merchant to Payment Provider) - OpenAI (medium)
  • Design Video Generation Orchestration - OpenAI (medium)
  • Design CI/CD Build Caching - OpenAI
|Home/System Design/OpenAI

Design a Payment Processing System with Exactly-Once Charging

OpenAI logo
OpenAI
Jun 26, 2026, 12:00 AM
hardSoftware EngineerTechnical ScreenSystem Design
0
0

Design a Payment Processing System with Exactly-Once Charging

You are designing the core payment service for a marketplace platform. When a buyer checks out, the platform must charge the buyer's card through an external payment service provider (PSP), then record the outcome so the order can be fulfilled. Your service sits between the platform's checkout flow and the PSP.

The bar for this problem is correctness under failure. Cards must never be double-charged; a buyer who retries a timed-out request must not pay twice; and the system's record of what happened must always converge to the PSP's record of what happened. Walk through the end-to-end design, then go deep on idempotency and on resolving unknown outcomes.

Constraints & Assumptions

  • ~5,000 checkout attempts/second at peak. A single charge takes 1-3 s end-to-end because the synchronous PSP call is the slow leg.
  • One PSP integration to start: a request/response HTTP API plus asynchronous webhooks that deliver the final settlement state.
  • Single currency to start; multi-currency and marketplace split payouts are follow-ups.
  • The PSP supports idempotency keys but can time out, return ambiguous errors, and deliver duplicate or out-of-order webhooks.
  • Money correctness is non-negotiable. Availability target is 99.95%. A charge may be slow, but it must never be silently lost or duplicated.

Clarifying Questions to Ask

  • Does "exactly once" mean one charge attempt , or one successful capture ? Is auth-then-capture required, or a single immediate sale?
  • Who is allowed to retry — the browser/app, the platform's checkout service, or our payment service — and what client retry behavior should we plan for?
  • What is the source of truth for "the buyer was charged" — our database or the PSP — and how quickly must the two reconcile?
  • Must checkout get a synchronous success/failure, or can the final result be confirmed asynchronously after a "pending" response?
  • Which downstream systems consume payment results (ledger, fulfillment, receipts), and do they need exactly-once, ordered delivery?
  • Are refunds, voids, and chargebacks in scope now or later?

Part 1: High-level design, API, and data model

Sketch the end-to-end architecture and the core charge flow. Define the API the checkout service calls, the data model for a charge, and how a request flows from checkout to your service to the PSP and back to a recorded result. Make the lifecycle of a single charge explicit.

What This Part Should Cover Premium

Part 2: Idempotency and exactly-once charging

Go deep on idempotency. A buyer double-clicks "Pay," the network times out and the client retries, and the PSP later redelivers a webhook. None of these may produce a second charge. Design the idempotency mechanism end-to-end: how keys are generated, stored, and enforced; what concurrent duplicate requests return; and how idempotency is propagated to the PSP call itself.

Clarifying Questions for this Part

  • Is the idempotency key generated by the client per checkout attempt, or derived server-side from order id plus amount?
  • How long are keys retained, and is replaying a stored key with different parameters an error rather than a replay?

What This Part Should Cover Premium

Part 3: Resolving unknown outcomes, reconciliation, and money correctness

Handle the hardest failure: you call the PSP and the call times out, so you do not know whether the card was charged. Design how the system resolves unknown outcomes, how it reconciles its records against the PSP as source of truth, and how it guarantees the recorded money movement is correct. Cover duplicate and out-of-order webhooks and how downstream consumers learn the final result exactly once.

What This Part Should Cover Premium

What a Strong Answer Covers Premium

Follow-up Questions

  • How would you extend the design to support authorization-then-capture, voids, and partial refunds while preserving idempotency?
  • The PSP is down for 10 minutes. How do you degrade gracefully (queue and retry, fail closed, or fail over to a second PSP), and what are the correctness implications of each?
  • How do you prevent and detect double-charges caused by a buggy client that generates a fresh idempotency key on every retry?
  • How does the design change for multi-currency, and for splitting one buyer payment across multiple sellers (marketplace payouts)?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More System Design•More OpenAI•More Software Engineer•OpenAI Software Engineer•OpenAI System Design•Software Engineer System Design

Your design canvas — auto-saved

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.