Design Amazon (E-Commerce Platform)
OOP design for an e-commerce platform covering product catalog, shopping cart, order lifecycle, inventory management, payment processing, and seller marketplace with search and filtering.
The Problem
Your company runs an online marketplace that lists products from thousands of sellers. The current system is a monolithic OrderService class with 4,000 lines of if-else chains. Last week, a seller updated inventory at the exact moment two buyers checked out. Both orders confirmed, but only one unit existed. The warehouse shipped to one buyer and ghosted the other, generating a support escalation and a refund that cost more than the product itself.
E-commerce platforms are harder than simple CRUD applications because they involve competitive resource allocation: multiple buyers compete for limited inventory, multiple sellers sell the same product at different prices, and the order lifecycle has strict state transitions with side effects at every step. The system must handle cart management, price calculations with taxes and discounts, multi-seller inventory tracking, payment processing via different methods, and order state transitions from placement through delivery.
Design the core classes for an e-commerce platform that handles product catalog management, shopping cart operations, order lifecycle, inventory reservation, payment processing, and a multi-seller marketplace with search and filtering.
Requirements
Clarifying Questions
Before jumping into class design, ask questions to turn the vague prompt into a concrete specification. Cover four areas: core actions, error handling, boundaries, and future extensions.
You: "Is this a multi-seller marketplace like Amazon Marketplace, or a single-seller store?"
Interviewer: "Multi-seller. Multiple sellers can list the same product at different prices. Buyers see all offers and choose one."
That changes the data model significantly. A Product is separate from a seller's ProductListing. Each seller manages their own inventory for the same product.
You: "How does the shopping cart work? Can a buyer have items from multiple sellers in the same cart?"
Interviewer: "Yes. A single cart can hold items from different sellers. Each item tracks which seller it belongs to."
Good. The cart is seller-aware. Each CartItem must reference both the product and the specific seller offering it.
You: "What payment methods do we need to support?"
Interviewer: "Credit card, digital wallet, and cash on delivery. Make it easy to add new methods later."
Three payment methods with future extensibility. Classic Strategy pattern signal: a common interface with swappable implementations.
You: "What happens to inventory when a buyer adds something to the cart versus when they place an order?"
Interviewer: "Adding to cart does not reserve inventory. Inventory is reserved only at order placement. If stock runs out between add-to-cart and checkout, the order should fail gracefully."
This is a critical design decision. No reservation on cart-add means we must validate inventory at checkout time and handle race conditions.
You: "What is the order lifecycle? Can buyers cancel or return orders?"
Interviewer: "Orders go through PLACED, CONFIRMED, SHIPPED, DELIVERED. Buyers can cancel before shipment. Returns are allowed within a window after delivery."
Six states total: PLACED, CONFIRMED, SHIPPED, DELIVERED, CANCELLED, RETURNED. The State pattern fits well here since transitions have preconditions and side effects.
You: "Do we need product search and filtering? By what criteria?"
Interviewer: "Yes. Search by name or keyword. Filter by category, price range, and seller rating. Sort by price or relevance."
Search with filtering and sorting. The catalog needs a query interface, not just direct lookups.
You: "Do we need product reviews and ratings?"
Interviewer: "Basic reviews: a buyer can rate a product 1-5 stars and leave a comment. Show average rating on the product. Keep it simple."
Reviews are a secondary feature. A Review entity attached to a product, with an aggregate rating computed on the product.
You: "Should we handle discounts or coupon codes?"
Interviewer: "Support percentage-based and flat-amount discount coupons applied at checkout. One coupon per order."
Discount as a Strategy or simple polymorphism: percentage vs. flat amount.
Perfect. You have clarified scope and ruled out unnecessary complexity. The system is a multi-seller marketplace with cart management, inventory reservation at checkout, state-machine order lifecycle, Strategy-based payments and discounts, and basic search with filtering.
Final Requirements
Functional Requirements:
- Sellers register and list products with name, description, price, category, and stock quantity
- Buyers search products by name/keyword and filter by category, price range, and seller rating
- Buyers add/remove/update items in a shopping cart with quantity tracking
- Checkout creates an order, reserves inventory, and processes payment
- Orders follow the lifecycle: PLACED > CONFIRMED > SHIPPED > DELIVERED, with CANCELLED and RETURNED branches
- Buyers can cancel orders before shipment and return orders within a configurable window after delivery
- Buyers leave product reviews with a 1-5 star rating and text comment
- Coupon codes apply percentage or flat discounts at checkout
Non-Functional Requirements:
- Thread-safe inventory management to prevent overselling under concurrent checkouts
- Extensible payment processing for new payment methods without modifying existing code
- State machine enforcement for order transitions (no illegal state jumps)
- Price calculations must be deterministic: base price + tax + shipping, minus discounts
Out of Scope:
- UI/frontend rendering
- Database persistence and ORM
- Recommendation engine and personalization
- Shipping provider integration
- Real-time notifications (push/email)
- Multi-currency support
Example Inputs and Outputs
Scenario 1: Happy-path checkout
- Input: Buyer adds 2x "Wireless Mouse" ($25.00 each) from SellerA and 1x "USB-C Hub" ($45.00) from SellerB. Applies coupon "SAVE10" (10% off). Pays with credit card.
- Expected: Cart total = $95.00. After 10% discount = $85.50. Tax (8%) = $6.84. Shipping = $5.00. Grand total = $97.34. Order is PLACED, inventory decremented for both sellers.
- Why: Validates multi-seller cart, discount application, and tax/shipping calculation.
Scenario 2: Inventory conflict at checkout
- Input: Buyer has 3x "Mechanical Keyboard" in cart, but only 2 remain in SellerA's stock.
- Expected: Checkout fails with an insufficient-stock error. No order is created. No payment charged. Stock remains at 2.
- Why: Validates inventory check at order placement, not at cart-add time.
Scenario 3: Order cancellation
- Input: Buyer cancels an order in CONFIRMED state (not yet shipped).
- Expected: Order transitions to CANCELLED. Reserved inventory is released back to the seller's stock. Payment refund is initiated.
- Why: Validates state machine transitions and inventory release on cancellation.
Try It Yourself
Try it yourself
Before reading the solution, spend 20 minutes sketching your class diagram. Start with the entities: what "things" exist in this system? Pay special attention to the relationship between Product, Seller, and Inventory. Focus on how cart items track which seller they belong to, and how the order lifecycle enforces valid transitions. Compare your design with the walkthrough below.
Step 1: Identify Core Entities
Start by asking: what are the main "things" in this problem? Pull nouns from the requirements and ask what responsibility each one carries.
A common mistake is merging Product and Inventory into one class, or putting cart logic directly on the User. Good design means each class owns exactly one responsibility. In an e-commerce system, the boundaries are product information (catalog), stock quantities (inventory), buying actions (cart/order), and payment processing.
| Entity | Responsibility | Key attributes |
|---|---|---|
| Marketplace | Top-level orchestrator. Registers users, manages catalog, processes checkouts. | users, catalog, orders |
| User | Base for Buyer and Seller. Holds profile and address. | id, name, email, addresses |
| Buyer | Places orders, manages cart, writes reviews. | cart, orderHistory |
| Seller | Lists products, manages inventory, fulfills orders. | listings, rating |
| Product | Catalog entry. Name, description, category. Seller-agnostic. | id, name, description, category, averageRating |
| ProductCategory | Enum or class for categorization. Enables filtering. | name |
| ProductListing | A seller's offer for a specific product: price and stock. | product, seller, price, stockQuantity |
| Cart | Holds items a buyer intends to purchase. Computes subtotals. | items, buyer |
| CartItem | A line in the cart: references a listing and quantity. | listing, quantity |
| Order | A confirmed purchase with payment and state. | items, buyer, state, payment, shippingAddress |
| OrderItem | Snapshot of a purchased listing: locked price and quantity. | listing, priceAtPurchase, quantity |
| OrderState | Enum for lifecycle states. Enforces valid transitions. | PLACED, CONFIRMED, SHIPPED, DELIVERED, CANCELLED, RETURNED |
| Payment | Records how the order was paid. References method and amount. | method, amount, status |
| PaymentMethod | Strategy interface for card, wallet, COD. | pay(amount) |
| Address | Value object for shipping/billing. | street, city, state, zip, country |
| Review | Buyer's rating and comment on a product. | buyer, product, rating, comment |
| Coupon | Discount applied at checkout: percentage or flat amount. | code, discountType, value, minOrderAmount |
Notice that Product and ProductListing are separate because a product is a catalog concept (name, description, category) while a listing is a seller-specific offer (price and stock). Merging them would force every seller to share a single price and inventory pool, which breaks the multi-seller requirement.
I also want to call out that Buyer and Seller could be roles on a single User class (Amazon lets the same account buy and sell). For interview clarity, I keep them as subclasses so each has a distinct responsibility list. Mention this tradeoff to your interviewer.
Step 2: Define Relationships and Class Design
Now that we know the entities, let's map how they connect and derive each class's state and methods.
Class Diagram
Deriving the Marketplace Class
The Marketplace is the top-level orchestrator. It ties together user registration, product catalog search, and the checkout flow.
Deriving state from requirements:
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with NotesFromSDE Premium.