# System Design Interview: Design an E-commerce Checkout System

Source: https://www.techinterview.org/post/3233463394/system-design-ecommerce-checkout-system/
Updated: 2026-04-17 · techinterview.org

## What Is an E-commerce Checkout System?

The checkout system orchestrates the final steps of an online purchase: cart validation, inventory reservation, payment processing, order creation, and fulfillment initiation. It is one of the highest-stakes flows in e-commerce: any failure or slowness directly impacts revenue. At Amazon scale: millions of checkouts per hour during peak events (Prime Day, Black Friday).

- [Coinbase Interview Guide](https://techinterview.org/coinbase-software-engineer-interview/)

- [Uber Interview Guide](https://techinterview.org/uber-software-engineer-interview/)

- [Airbnb Interview Guide](https://techinterview.org/airbnb-software-engineer-interview/)

- [DoorDash Interview Guide](https://techinterview.org/doordash-software-engineer-interview/)

- [Stripe Interview Guide](https://techinterview.org/stripe-software-engineer-interview/)

- [Shopify Interview Guide](https://techinterview.org/shopify-software-engineer-interview/)

## Checkout Flow

  - **Cart validation**: verify all items still exist, have the displayed price, and quantity is available

  - **Inventory reservation**: temporarily hold the requested quantity to prevent overselling during payment processing

  - **Payment authorization**: charge the customer's payment method

  - **Order creation**: create a confirmed order record, release the inventory reservation, deduct from inventory

  - **Fulfillment trigger**: publish order to fulfillment service (warehouse, shipping)

## Inventory Reservation (Soft Hold)

Between checkout start and payment completion, inventory must be held to prevent overselling the same item. Soft hold: reserve inventory for 10–15 minutes while customer completes payment. If payment fails or times out, the hold is released.


```
BEGIN TRANSACTION;
SELECT quantity FROM inventory WHERE sku = ? FOR UPDATE;
IF quantity < requested: ROLLBACK; return "Out of Stock";
UPDATE inventory
  SET quantity = quantity - requested,
      reserved = reserved + requested
WHERE sku = ?;
INSERT INTO holds (sku, quantity, order_id, expires_at)
VALUES (?, requested, ?, NOW() + INTERVAL 15 MINUTES);
COMMIT;
```

A scheduled cleanup job releases expired holds: UPDATE inventory SET reserved=reserved-quantity, quantity=quantity+quantity_held WHERE expired holds. This prevents inventory being stuck in hold forever if a customer abandons checkout.

## Idempotent Order Creation

Network failures during payment can leave the system in an ambiguous state: did the payment succeed? Was the order created? Use an idempotency key (checkout_session_id) to guarantee at-most-once order creation. Before creating the order, check if an order with this checkout_session_id already exists. If yes, return the existing order. This allows safe retry of the entire checkout without double-orders or double-charges.

## Order State Machine


```
PENDING → PAYMENT_AUTHORIZED → CONFIRMED → SHIPPED → DELIVERED
       → PAYMENT_FAILED → CANCELLED
       → CANCELLED (user cancels before shipment)
       → RETURN_INITIATED → RETURNED
```

Atomic state transitions via UPDATE orders SET status=? WHERE id=? AND status=expected_current_status. Optimistic locking: if the UPDATE affects 0 rows, another process already changed the state — handle accordingly.

## Preventing Oversell at Scale

At high concurrency (Black Friday surge), FOR UPDATE creates lock contention on hot items. Alternative: optimistic locking with check-and-decrement:


```
UPDATE inventory
SET quantity = quantity - requested
WHERE sku = ? AND quantity >= requested;

affected_rows = check result;
IF affected_rows == 0: return "Out of Stock";
```

No explicit lock — the WHERE clause is the check. Two concurrent updates: one succeeds, one gets affected_rows=0 (quantity already depleted). For very hot items: use a Redis atomic counter: DECRBY inventory:{sku} requested — if result < 0, INCRBY to restore and return out-of-stock. Redis single-threaded atomicity eliminates race conditions.

## Promo Codes and Discounts

Apply promo codes before payment authorization. Validate: code exists, not expired, usage limit not exceeded, applicable to items in cart. Increment usage count atomically (Redis INCR + compare to limit) before proceeding to payment — prevents race condition where two users simultaneously apply the last use of a promo code.

## Interview Tips

  - Soft hold is the central inventory design — inventory reserved but not deducted until order confirmed.

  - Idempotency key on checkout_session_id prevents double-orders on payment retry.

  - Redis for hot inventory items — contention on PostgreSQL FOR UPDATE at Black Friday scale is problematic.

  - State machine with atomic transitions prevents illegal state transitions (can't ship a cancelled order).
