Amazon Shopping System
E-Commerce Platform Design
Design the core of an online store: a searchable catalog, a cart, stock that is never oversold, promotions and shipping in the price, an order lifecycle, and reviews from verified buyers.
Overview
An online store lets people find products, put them in a cart, and check out. Checkout turns the cart into an order: it prices the items, takes payment, and takes the units out of stock. After that the order moves through shipping and delivery, and may be canceled or returned. This topic calls it the Amazon problem because interviewers do, but nothing here describes how Amazon itself is built.
The problem is wide, so the first skill it tests is scoping. You cannot design search ranking, recommendations, warehouses, tax and fraud in one hour. Pick the core (catalog, cart, inventory, pricing, orders), say what you left out, and go deep on the parts where bugs cost money: selling the last unit twice, charging a price the customer never saw, and an order that jumps from canceled back to shipped.
A strong answer keeps the cart cheap and forgetful (ids and quantities, no prices), makes checkout the one place where stock, price and payment meet, and writes the order lifecycle as a table of allowed moves.
Scoping the problem
- Which parts are in scope? — The store is too big for an hour — Catalog, cart, inventory, pricing, orders, reviews
- Does the cart hold stock? — Holding stock in carts locks it up for days — No; stock is reserved at checkout
- Which price does an order use? — Prices change while items sit in carts — The price at checkout, copied into the order
- Which promotions? — Each one is a pricing rule — Percent off above a subtotal, buy N get one free
- Can promotions stack? — Changes the pricing formula — Yes, but the discount never exceeds the subtotal
- One warehouse or many? — Changes where stock is taken from — One in the core; many as a follow-up
- Who may review? — Stops fake reviews — Only buyers whose order was delivered, once per product
Checkout
Checkout does four things in an order chosen so that every failure can be undone cheaply. Stock is reserved before payment, so a customer is never charged for a unit that is gone. The reservation is released if payment fails, and turned into a real deduction only after payment succeeds.
The price is worked out by a small pipeline: subtotal, then every promotion's discount (capped at the subtotal), then shipping on what is left. This is the demo's first order.
- USB-C cable — 2 × 1000 — 2000
- Desk lamp — 1 × 3000 — 3000
- Notebook — 3 × 500 — 1500
- Subtotal — 6500
- 10 percent off orders of 5000 or more — 6500 × 10 ÷ 100 — −650
- Notebooks: buy 2, get 1 free — 3 ÷ 3 = 1 free × 500 — −500
- Shipping: free at 5000 or more after discounts, else 499 — 5350 ≥ 5000 — 0
- Total — 5350
Amounts are integer cents, so there is no rounding drift. Percent discounts round down to the cent.
The order lifecycle
An order's status may only move along the arrows below. The code keeps them in one dictionary, so an illegal move (cancel after shipping, ship after cancel) raises instead of silently corrupting the order.
- u1 checks out cable, lamp, notebooks — order 1 paid, 5350 — The pricing table above
- u2 checks out the lamp — OutOfStock; stock unchanged — u1 bought the only one
- u2's card is declined for a cable — stock back to 3 — The reservation was released
- u3 clicks Place order twice with key k3 — one order, one charge — Same idempotency key
- order 1 ships, then u1 tries to cancel — InvalidTransition — Shipped orders are returned, not canceled
- u1 reviews the lamp after delivery — accepted — A verified buyer
- u3 reviews a notebook before delivery — refused — Not delivered yet
What you will be able to do
- Scope an unbounded problem to a core and name what you left out.
- Keep prices out of the cart and freeze them into order lines at checkout.
- Reserve stock all or nothing, release it on a failed payment, and prove no overselling with a thread race.
- Build the price from pluggable promotions and a shipping policy.
- Guard the order lifecycle with a transition table and make checkout safe to retry.
Functional requirements
- Catalog: add products; search by text, category and maximum price
- Cart: add, change quantity, remove; the cart shows current prices
- Checkout: freeze prices into order lines, reserve stock for every line or none, charge, then commit the stock
- Promotions (percent off above a subtotal, buy N get one free) and a shipping fee with a free threshold
- Order lifecycle: paid, shipped, delivered, canceled (before shipping), returned (after delivery); cancel and return refund and restock
- Reviews: rating 1 to 5, only by a buyer with a delivered order for the product, once per product; average rating per product
Non-functional requirements
- Stock is never oversold under concurrent checkouts
- A retried checkout with the same key never creates a second order or charge
- An order always shows the price that was charged, whatever the catalog price is later
- Promotions, shipping and the payment provider are pluggable
- Money is integer cents
Interview questions
- Many app servers sell the same product. How do you stop overselling in the database?
- Prices change while items sit in carts. What does the customer pay?
- How do promotions work, and how would you add a new one?
- Stock sits in several warehouses. How does the design change?
- Payment is slow or asynchronous. What happens to the reservation and the order status?
Sign up free to read the full topic
More Low-Level Design topics
Start free on Cariara · Coding problems · System design studio