Skip to main content

Classic design · Mid

E-commerce: catalog, cart, and checkout

Classic interview design. Key points: reservations and concurrency.

14 min read · Content reviewed on October 23, 2026

Short answer

Classic interview design. Key points: reservations and concurrency. The classic e-commerce exercise asks for a product catalog, a cart, and a checkout. This case focuses on checkout, the moment when a single customer action has to change three sets of data: the order, the inventory, and the payment. Catalog and cart appear only as context.

01 · CONTEXT

One click, three data owners

The classic e-commerce exercise asks for a product catalog, a cart, and a checkout. This case focuses on checkout, the moment when a single customer action has to change three sets of data: the order, the inventory, and the payment. Catalog and cart appear only as context.

Architectures of microservices usually give each service a dedicated database. When orders and customers live in the databases of different services, the application cannot use a simple local ACID transaction. The source illustrates the problem with an online store in which the customer has a credit limit.

02 · STARTING POINT

One database, one transaction

With a single database, life is simple. Within a single service, transactions follow ACID principles because they operate on one database, and atomicity means that all operations succeed or none do. Writing the order and decrementing inventory in the same transaction therefore guarantees that both happen or neither does.

  1. The customer confirms the purchase; the request passes through the store's API and reaches the application.

    Architecture diagram: Checkout with a single database
    CLClientconfirms the purchase
    NWStore API
    CPStore application
    DBStore's single database
  2. The application opens a local transaction on the single database.

    Architecture diagram: Checkout with a single database
    CLClient
    NWStore API
    CPStore application
    DBStore's single databaselocal transaction
  3. Within the same transaction it writes the order and decrements inventory, and both changes are committed together.

    Architecture diagram: Checkout with a single database
    CLClient
    NWStore API
    CPStore application
    DBStore's single databaseorder and inventory together
  4. If something fails midway, neither change takes effect and the database rolls everything back.

    Architecture diagram: Checkout with a single database
    CLClient
    NWStore API
    CPStore application
    DBStore's single databaseeverything undone

03 · SPLITTING

When each service has its own database

Splitting into services brings gains that Microsoft's documentation lists: each service encapsulates its data and failures in one service stay isolated from the others. The price is that guarantees like ACID do not apply directly across several independently managed databases.

  1. The customer confirms the purchase and the API forwards the order to the orders service.

    Architecture diagram: Checkout with a database per service
    CLClientconfirms the purchase
    NWStore API
    CPOrder service
    DBOrder database
    CPInventory service
    DBInventory database
    CPPayments service
    DBPayments database
  2. The orders service writes the order to its own database, in a local transaction.

    Architecture diagram: Checkout with a database per service
    CLClient
    NWStore API
    CPOrder service
    DBOrder databaseorder written
    CPInventory service
    DBInventory database
    CPPayments service
    DBPayments database
  3. Next, the orders service calls the inventory service, which decrements the quantity in its database.

    Architecture diagram: Checkout with a database per service
    CLClient
    NWStore API
    CPOrder service
    DBOrder database
    CPInventory service
    DBInventory databasedecrement confirmed
    CPPayments service
    DBPayments database
  4. Then it calls the payments service and, in this scenario, the charge does not complete.

    Architecture diagram: Checkout with a database per service
    CLClient
    NWStore API
    CPOrder service
    DBOrder database
    CPInventory service
    DBInventory database
    CPPayments servicecharge failed
    DBPayments database
  5. Order and inventory have already been committed in their databases, and there is no automatic rollback that spans the three services: what was done has to be undone explicitly.

    Architecture diagram: Checkout with a database per service
    CLClient
    NWStore API
    CPOrder service
    DBOrder databasealready committed
    CPInventory service
    DBInventory databasealready committed
    CPPayments service
    DBPayments database

04 · SAGA

Local steps and compensations

The classic answer is the saga: a sequence of local transactions coordinated reliably. If a step fails by violating a business rule, the changes of the already completed steps are undone by compensating transactions.

There are two ways to coordinate the saga. In choreography, each local transaction publishes domain events that trigger local transactions in other services. In orchestration, an orchestrator tells the participants which local transactions to run.

AspectoCoreografiaOrchestration
How it coordinatesEach service publishes events that trigger the other services' stepsAn orchestrator tells the participants what to run
When it fitsSimple flows with few servicesComplex flows or ones that gain new services
Weak pointThe flow can get confusing as steps are addedThe orchestrator is a point of failure, since it manages the whole flow

The source describes the order like this: the orders service receives POST /orders and creates the order in PENDING state; the customers service tries to reserve credit; and the orders service's event handler approves or rejects the order.

  1. The orders service receives the purchase and creates the order in pending state; in the same local transaction it writes the message that needs to be sent.

    Architecture diagram: Checkout as a saga with an outbox
    CLClient
    CPOrder servicepending order
    DBOrders database and outboxorder and message
    CPMessage relay
    QMessage broker
    CPInventory service
    DBInventory database
    CPPayments service
    DBPayments database
  2. A separate process reads the outbox and sends the message to the broker.

    Architecture diagram: Checkout as a saga with an outbox
    CLClient
    CPOrder service
    DBOrders database and outbox
    CPMessage relaydelivers the message
    QMessage broker
    CPInventory service
    DBInventory database
    CPPayments service
    DBPayments database
  3. The inventory service receives the message and tries to reserve the items in a local transaction, just as the source's example tries to reserve credit.

    Architecture diagram: Checkout as a saga with an outbox
    CLClient
    CPOrder service
    DBOrders database and outbox
    CPMessage relay
    QMessage broker
    CPInventory servicetries to reserve
    DBInventory databaseitems reserved
    CPPayments service
    DBPayments database
  4. With the reservation made, the payments service attempts the charge; in this scenario it is declined for insufficient funds, an expected failure and not an unexpected error.

    Architecture diagram: Checkout as a saga with an outbox
    CLClient
    CPOrder service
    DBOrders database and outbox
    CPMessage relay
    QMessage broker
    CPInventory service
    DBInventory database
    CPPayments servicecharge declined
    DBPayments database
  5. The failure reaches the inventory service, which runs the compensating transaction and releases the reservation made earlier.

    Architecture diagram: Checkout as a saga with an outbox
    CLClient
    CPOrder service
    DBOrders database and outbox
    CPMessage relay
    QMessage broker
    CPInventory service
    DBInventory databasereservation released
    CPPayments service
    DBPayments database
  6. Finally the orders service receives the result and rejects the order, instead of approving it.

    Architecture diagram: Checkout as a saga with an outbox
    CLClient
    CPOrder serviceorder rejected
    DBOrders database and outbox
    CPMessage relay
    QMessage broker
    CPInventory service
    DBInventory database
    CPPayments service
    DBPayments database

The saga has costs. There is no automatic rollback, so the developer has to design the compensating transactions that undo what was done. And there is no isolation between concurrent sagas: careful analysis is needed to choose and implement countermeasures. In addition, compensations may not succeed and leave the system inconsistent.

05 · RELIABLE MESSAGING

Write and publish without losing anything

For the saga to work, the service must update the database and send the message atomically, otherwise inconsistencies appear. A distributed transaction spanning the database and the broker is not viable. Without one, sending the message in the middle of the transaction gives no guarantee that it will be committed, and sending after the commit does not guarantee the service won't crash before sending.

The way out is the transactional outbox: the service writes the message to the database, in the same transaction that updates the business entities, and a separate process sends it to the message broker.

This relay can publish the same message more than once, for example if it crashes after publishing and before recording that it published. So the consumer must be idempotente, for example by recording the identifiers of the messages already processed.

Since the saga is an asynchronous flow, whoever started the purchase through a synchronous request has to find out the result later. One of the source's options is to return the order identifier and let the client poll the state periodically.

06 · PAYMENT

Charge once, even with failures

Payment is the step where an error costs the most. The goal described by Shopify is that the charge happens exactly once despite request retries. The idempotency key finds the steps the attempt has already completed, and ensures that a single request is sent to the financial partner.

  1. The orders service requests the charge by sending a unique key for the attempt.

    Architecture diagram: Idempotent charge with reconciliation
    CPOrder servicesends the key
    CPPayments service
    DBAttempt log
    CPFinancial partner
    CPReconciliation job
  2. The payments service records the attempt in the local database, one of the steps the key allows it to find again.

    Architecture diagram: Idempotent charge with reconciliation
    CPOrder service
    CPPayments service
    DBAttempt logattempt recorded
    CPFinancial partner
    CPReconciliation job
  3. The service calls the financial partner with low timeouts so it does not wait indefinitely.

    Architecture diagram: Idempotent charge with reconciliation
    CPOrder service
    CPPayments service
    DBAttempt log
    CPFinancial partnercall with low timeout
    CPReconciliation job
  4. If the call fails due to the network, the request can be repeated with the same key, and the partner receives a single request.

    Architecture diagram: Idempotent charge with reconciliation
    CPOrder service
    CPPayments serviceretries with the same key
    DBAttempt log
    CPFinancial partner
    CPReconciliation job
  5. A reconciliation job compares the local records with the partner's and, when there is a discrepancy, records the anomaly in the database.

    Architecture diagram: Idempotent charge with reconciliation
    CPOrder service
    CPPayments service
    DBAttempt log
    CPFinancial partner
    CPReconciliation jobchecks the records

Within the saga, the Azure Architecture Center calls the point of no return the pivot transaction. After it come retryable, idempotent transactions, which help the saga reach the final state even with transient failures.

07 · PEAK LOAD AND ISOLATION

Protect checkout and close the gaps

Under peak load, Shopify uses programmable load balancers to limit the number of simultaneous checkouts. If more buyers want to pay than capacity allows, they wait in a queue before paying.

Isolation remains. There is no isolation between concurrent sagas, and Microsoft's documentation lists anomalies such as lost updates and dirty reads, the latter when one saga reads data another has modified without finishing. One of the countermeasures is to re-read the values before updating.

Frequently asked questions

What is E-commerce: catalog, cart, and checkout?

Classic interview design. Key points: reservations and concurrency.

What does the E-commerce: catalog, cart, and checkout design cover?

It is organized in these sections: One click, three data owners, One database, one transaction, When each service has its own database, Local steps and compensations, Write and publish without losing anything, and Charge once, even with failures.

How long is E-commerce: catalog, cart, and checkout and what level is it?

It takes about 14 minutes to read and is rated Mid level.

Now design it yourself

Run this case as an interview in the System Design school: you make the decisions, the tutor challenges them and you see how your design scores.