InterviewHubPRO
Section Overview
Q19

Question 19 of 50

Part 2: Real-World High-Scale Architecture Problems (11 - 25)

38%
System Design (50 Qs)•Part 2: Real-World High-Scale Architecture Problems (11 - 25)

Design an Idempotent Payment System (Stripe / Checkout).

In Simple Words: Ensure that double-clicks, network timeouts, or retried API calls NEVER charge a customer twice or corrupt bank transaction balances.

Idempotency Key Architecture:

  1. Client generates a UUIDv4 Idempotency Key in request header (Idempotency-Key: c9d721...).
  2. Payment gateway acquires a distributed lock in Redis for that key.
  3. If the key exists with a completed status, return the cached previous HTTP response immediately without touching payment processors.
  4. Execute financial transaction within a strict database transaction.
typescript
export async function processPaymentWithIdempotency(
  idempotencyKey: string,
  chargeData: { userId: string; amount: number },
  redis: any,
  db: any
): Promise<{ status: string; transactionId: string }> {
  const cacheKey = `idemp:${idempotencyKey}`;
  
  // 1. Check if already processed
  const cachedResponse = await redis.get(cacheKey);
  if (cachedResponse) {
    return JSON.parse(cachedResponse);
  }

  // 2. Acquire 30-second lock
  const locked = await redis.set(`lock:${cacheKey}`, '1', 'NX', 'EX', 30);
  if (!locked) {
    throw new Error('Concurrent request with identical idempotency key in progress');
  }

  try {
    // 3. Execute financial deduction in database
    const result = await db.executeTransaction(chargeData);
    await redis.set(cacheKey, JSON.stringify(result), 'EX', 86400 * 7); // Cache for 7 days
    return result;
  } finally {
    await redis.del(`lock:${cacheKey}`);
  }
}