Skip to content

Cart and Checkout Model

intermediate
📜Corecommerce

A shopping cart seems simple — add items, show a total, proceed to pay. But a production cart must handle pricing resolution, promotion application, tax calculation, shipping estimation, inventory validation, and multi-currency conversion, all before the customer clicks “Place Order.” Treating the cart as a simple list leads to pricing discrepancies, sold-out items reaching checkout, and promotional logic scattered across the frontend.

Optimizely Commerce treats the cart as a server-side calculation engine. Every time the cart changes, a pipeline recalculates totals, validates inventory, applies promotions, and resolves taxes. The frontend displays the results but never computes prices. This ensures pricing integrity regardless of which channel — web, mobile, or API — initiates the change.

A cart in Commerce moves through distinct phases from creation to order.

PhaseStateWhat happens
ActiveShopping in progressItems added, removed, quantities changed. Cart recalculates after each change.
CheckoutCustomer entered checkoutShipping address captured, shipping method selected, payment method chosen.
ValidatingPre-order validationInventory confirmed, prices locked, promotions finalized, tax calculated.
SubmittedOrder createdCart converts to a purchase order. Cart is archived or cleared.
AbandonedNo activity within timeoutCart persists for recovery campaigns. Not deleted automatically.

The cart persists server-side across sessions. If a customer adds items on Tuesday and returns on Thursday, their cart is intact. This persistence enables abandoned cart recovery through email campaigns and retargeting.

Commerce supports multiple named carts per customer. Common patterns include:

  • Default cart — The primary shopping cart
  • Wishlist — Items saved for later, not intended for immediate purchase
  • Requisition list — B2B buyers who reorder the same items regularly

Named carts share the same data model and calculation pipeline as the default cart, so moving items between them preserves pricing and promotion context.

Before a cart becomes an order, it passes through a validation pipeline that catches problems early. The pipeline runs automatically during checkout and can be triggered explicitly via API.

The built-in validation steps include:

  1. Inventory check — Confirm each line item has sufficient stock. If a variant is out of stock, the pipeline flags it rather than silently allowing the order.
  2. Price validation — Verify that the prices in the cart still match the current pricing engine output. Prices may have changed since the item was added.
  3. Promotion validation — Confirm all applied promotions are still valid. A time-limited coupon may have expired during the session.
  4. Address validation — Verify the shipping address is complete and in a supported region.
  5. Shipping validation — Confirm the selected shipping method is available for the destination and cart contents.

If any step fails, the pipeline returns structured errors that the frontend can display. The customer corrects the issue and resubmits.

Checkout is the process of collecting the information needed to convert a cart into an order. Commerce does not prescribe a fixed checkout UI. Instead, it provides the backend operations that any checkout UI must invoke.

The typical checkout sequence:

  1. Cart review — Customer confirms line items and quantities
  2. Shipping address — Customer provides or selects a delivery address
  3. Shipping method — Customer chooses from available options (calculated by shipping providers)
  4. Payment method — Customer selects how to pay
  5. Order review — Final summary before submission
  6. Payment processing — Payment is authorized (not captured)
  7. Order creation — Cart converts to an order with a confirmed status

Each step updates the server-side cart, triggering recalculation. When the customer selects a shipping method, the cart total updates to include shipping costs. When they enter a US address, state tax is calculated.

Commerce abstracts payment processing behind a provider interface. The checkout flow calls generic operations — authorize, capture, void, refund — and the configured payment provider handles the specifics.

OperationWhen it happensWhat it does
AuthorizeAt checkoutReserves funds without capturing them
CaptureAt fulfillmentMoves authorized funds to the merchant
VoidBefore captureCancels an authorization
RefundAfter captureReturns captured funds to the customer

This abstraction means you can switch payment providers without rewriting your checkout logic. It also supports multiple payment methods on a single order — split payment between a gift card and a credit card, for example.

Understanding the calculation order helps when debugging unexpected totals.

  1. Line item prices — Resolved from the pricing engine per variant, quantity, and customer group
  2. Line item discounts — Applied from promotion rules that target specific items
  3. Subtotal — Sum of all line items after discounts
  4. Shipping cost — Calculated by the shipping provider based on address, weight, and method
  5. Order-level discounts — Promotions that apply to the cart total (e.g., 10% off orders over $100)
  6. Tax — Calculated on the post-discount total by the tax provider
  7. Total — Final amount the customer pays

Each step depends on the previous one. Changing the shipping address can change the tax calculation, which changes the total, which might change order-level promotion eligibility. The pipeline handles these cascading recalculations automatically.

Commerce exposes cart operations through APIs, enabling headless architectures where the frontend is decoupled from the Commerce backend. A React storefront, a mobile app, and an in-store kiosk can all manipulate the same cart through the same API, and the server-side pipeline ensures consistent pricing across all channels.