Katkat

Design a Payment Processing System

OpenAISoftware Engineer · Onsite

Last 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

  1. 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.
  2. 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?