Marketplaces, an interactive architecture walkthrough
E-commerce checkout and inventory: how the architecture works
How an online store turns a cart into an order: stock reservation, idempotent payment, a saga with compensation, and reliable order events.
This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate.
Interactive diagram
Overview
Checkout turns a cart into an order without selling stock that does not exist or charging a customer for an order that fails. Because inventory, payment and orders are separate services, the flow is a saga: local steps (reserve stock, take payment, create the order), each recorded, with a compensating step (release the stock, refund) when a later step fails. Stock is reserved with a conditional update and an expiry, payment calls carry idempotency keys, and order events are published through an outbox so none are lost.
Trade-offs and what changes at scale
A saga gives up the isolation of a single transaction, so other shoppers can briefly see stock as unavailable that is later released. Choosing when to reserve (at add-to-cart, at checkout, or at payment) trades abandoned-cart waste against failed checkouts after the shopper has typed their card details. Hot items concentrate writes on one stock row, so stock may be split across rows or admission controlled. An orchestrated saga is easy to follow and monitor but makes the orchestrator critical; choreography with events avoids a central service and is harder to debug. Delivery is at-least-once, so every handler (webhook, relay consumer, compensation) must be idempotent. Tax, shipping, fraud checks, returns and multi-warehouse allocation add steps not drawn here. This is a simplified teaching model based on public documentation and general design practice, not any retailer's actual architecture.
How it works, step by step
The walkthrough above, as text. Each step lights up the components named under it.
A shopper adds an item. The Cart Service checks the item and quantity against the Catalogue Service and stores the cart. Adding to a cart does not reserve stock: most carts are abandoned, and reserving on every add would let them hold inventory that others could buy.
At checkout the request carries an idempotency key, so a double click or a retry after a timeout does not place two orders. The Checkout Orchestrator loads the cart and re-prices it, because prices and availability may have changed since the item was added.
Placing an order spans inventory, payment and orders, which are separate services with separate databases, so there is no single transaction across them. The orchestrator runs it as a saga: a series of local steps, each recorded in Saga State, so a crashed orchestrator can resume where it stopped.
Step one is to reserve the stock. The Inventory Service reduces available quantity with a conditional update (only if enough remains), so two buyers cannot both take the last unit. The reservation has an expiry time. Reserving also limits the saga's weak isolation: other shoppers see the stock as taken while the order is in progress.
In a flash sale many buyers target one stock row, and updates to a single row happen one at a time. Common remedies are to split the stock into several rows or shards that each hold part of the quantity, or to admit shoppers through a queue so the row sees a bounded rate.
Step two is the charge. The Payment Service calls the provider with an idempotency key derived from the order, so a retried call does not charge the card twice. Card payments can be slow or declined, which is why stock was reserved first.
The result comes back from the provider's webhook, handled by the Payment Service and passed to the orchestrator. Order completion is driven by the webhook rather than by the shopper's browser returning to a success page, because the shopper may close the tab. Webhooks can arrive more than once and some payment methods confirm later, so the handler must be safe to run repeatedly.
If payment fails, the orchestrator runs the compensating step: release the reservation so the stock is available again. Compensations must be repeatable, since the release itself can fail and be retried. A saga cannot roll back like a database transaction; it moves forward to undo what it did.
If payment succeeds, the Order Service creates the order. It writes the order and an outbox row (the event to publish) in the same database transaction, so an order is never saved without its event also being queued for publishing. If order creation cannot be completed after payment, the orchestrator retries it and, failing that, refunds the charge.
The Outbox Relay reads new outbox rows and publishes them to Order Events. It can publish a row twice if it crashes between publishing and marking it done, so consumers must treat repeated events as normal.
The Fulfilment Service consumes order-placed events and starts picking and shipping, while the Notification Service sends the confirmation. They run after the order is recorded and off the shopper's critical path, so a slow warehouse system never delays checkout.
If a checkout dies between reserving stock and finishing, the reservation would hold stock forever. The Reservation Expiry Worker releases reservations past their expiry that no completed order claims, which also cleans up after crashed or abandoned checkouts.
Observability tracks checkout success rate, sagas stuck in a step, release backlog and payment-failure rate, plus a reconciliation check that stock, payments and orders agree. Reconciliation catches the rare cases the saga cannot.
Sequence diagram
The same walkthrough as a UML sequence diagram, one lane per layer or group (19 components in all), left to right in the order a request reaches them, numbered by step. A loop on a lane is a step that stays inside that group. Solid arrows are synchronous calls, dashed are asynchronous.
Key components
Cart and Cataloguedomain
- Cart Service: add, remove, re-price items
- Cart Store: one cart per shopper, expires when abandoned
- Catalogue Service: product data and current prices
Checkoutdomain
- Checkout Orchestrator: runs the order as a saga: reserve, pay, create order
- Saga State: progress of each checkout
Inventorydomain
- Inventory DB: stock per item; reservation rows (postgresql)
- Inventory Service: available and reserved stock, reservations with expiry
- Reservation Expiry Worker: releases reservations nobody completed
Paymentdomain
- Payment Provider: card processor or payment gateway
- Payment Service: charges with idempotency keys, handles webhooks
Ordersdomain
- Order DB: orders plus an outbox of events to publish (postgresql)
- Order Events: order placed, paid, shipped (kafka)
- Order Service: creates and tracks orders
- Outbox Relay: publishes outbox rows to the event stream
Downstreamdomain
- Fulfilment Service: pick, pack, ship
- Notification Service: order confirmation messages
Observability
- Observability: checkout success rate, stuck sagas, oversell checks
Clientslayer
- Shopper Client: web and mobile storefront
Edgelayer
- API Gateway: TLS, auth, rate limiting, idempotency keys
Sources
Public writing this explainer draws on. Read these for what the real systems actually do.
Make it yours
Copy this diagram and its walkthrough into your own workspace, then change anything: swap Postgres for DynamoDB, add a cache, rewrite the narration. Free, and it uses no AI credits.
Related walkthroughs
- Ticket booking with seat reservationHow a ticketing system sells each seat once under heavy demand: waiting room, cached seat map, time-limited holds, conditional updates and safe payment.
- Hotel booking systemHow a hotel booking system searches cached availability, books every night of a stay in one transaction, and holds rooms while payment completes.
- Ride-hailing platformHow a ride-hailing platform streams driver locations, matches a rider to a nearby driver, prices the trip with surge, and takes payment.
This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate. Real systems differ in the details. Browse the library.