Skip to main content
For most storefronts, use Hosted Checkout. It includes a production cart drawer, item updates, discounts, authentication, addresses, fulfilment, payment, and confirmation. Build a custom cart only when the product requires full control over the cart and checkout UI.

Cart invariants

These rules apply whether the UI is custom or Hosted Checkout:
  1. Every cart belongs to an anonymous or logged-in session.
  2. Commerce Engine does not create an empty cart.
  3. The first item creates the cart.
  4. Later item changes mutate the existing cart.
  5. variant_id is always present in item operations; use null for a simple product.
  6. A mutation returns the full updated cart.
  7. Login merges the active anonymous cart into the account session.
  8. to_be_paid is the final amount to show after loyalty and credit deductions.
  9. Carts can expire and must be recovered gracefully.

Hosted Checkout cart

When the application also uses @commercengine/storefront, use provided auth mode and two-way token synchronization. See the framework-specific Hosted Checkout guide.

Custom cart setup

Use the session accessor:
For first-party SSR wrappers, use the browser or request-bound session accessor appropriate to the component or mutation boundary.

Retrieve the active cart

A missing cart is an empty state, not necessarily an application error.

First Add to Cart

Create the cart with at least one item:
For a product with variants, variantId must be the resolved purchasable variant ID. For a simple product it must be null.

Creating the cart on first add

Add, update, and remove items

Use the same operation for subsequent item changes. quantity is the desired total quantity, not a delta.
Remove the line by setting quantity to zero:
Always replace local cart state with the updated cart returned by the latest valid mutation.

Serialize cart mutations

Rapid clicks or quantity changes can start multiple mutations concurrently. Because every response contains a complete cart snapshot, an older response can overwrite a newer state. Queue cart mutations with concurrency 1:
A mutation library with an async queue or mutex is preferable for larger applications.

Serialized cart mutations

Optimistic UI

Optimistic updates can improve perceived speed, but they do not remove the need to serialize server mutations. A safe pattern:
  1. calculate and render an optimistic local state
  2. enqueue the server operation
  3. replace local state with the returned cart
  4. roll back or refetch on failure
  5. announce the result for assistive technology
Do not calculate authoritative discounts, tax, shipping, or to_be_paid solely on the client.

Persist and recover cart state

The active cart is tied to the session, so getUserCart() is the preferred recovery path. A custom cart can also persist the last cart_id to reduce lookup ambiguity. On startup or cart open:
  1. read the persisted cart ID if present
  2. fetch that cart
  3. check expires_at
  4. if missing/expired, clear the stored ID
  5. fall back to getUserCart()
  6. create a new cart only when the next item is added
Persist the order number after order creation as well, so the payment-return page can recover after navigation or reload.

Restoring the active cart

Login and logout transitions

Login

Commerce Engine merges the active anonymous cart into the logged-in session. After verification:
  • invalidate/refetch the cart query
  • do not copy items manually
  • do not create another cart
If the returning account had a previous active cart, Commerce Engine resolves the active-cart transition server-side.

Logout

Logout returns a new anonymous token pair. Preserve those tokens through managed SDK storage, then refetch cart state. Do not call clearTokens() after a successful logout.

Cart structure

Important fields include:
Display to_be_paid as the final payable amount. grand_total can be higher when loyalty points or credit balance have been applied.
Render money using the currency information returned by the cart; do not assume one currency symbol.

Coupons and promotions

Automatic promotions are reflected in the returned cart. For a custom coupon UI:
Remove the coupon:
Some coupons depend on logged-in customer history or groups. An anonymous session can receive an error requiring login. Show the API’s user-safe message or map it to a clear login prompt. Do not assume every available coupon is valid for the current cart until the API applies or evaluates it.

Loyalty and credit balance

Loyalty and credit operations require the appropriate logged-in customer state. After every redemption/removal:
  • use the returned cart
  • update to_be_paid
  • handle the zero-payment case during order creation
  • do not subtract values twice in the UI

Addresses and fulfilment

Addresses, serviceability, and fulfilment selection change cart totals. Keep them in the custom checkout flow rather than treating the cart shown on the PLP/PDP as final. See Checkout for:
  • saved address linking
  • pincode lookup and deliverability
  • multiple shipments
  • delivery versus collect-in-store
  • payment and retry

Cart deletion

Use the exact SDK method contract for deleting a cart and confirm its response semantics. After successful deletion:
  • clear persisted cart ID
  • set local cart state to empty
  • invalidate cart badge/query state
Do not assume a deleted cart remains as an editable empty shell unless the operation contract explicitly says so.

Error handling

Treat errors by operation and status: Do not retry cart mutations blindly because the first attempt may have succeeded server-side.

Accessibility

  • cart count should use aria-live="polite"
  • quantity controls need accessible names including the product
  • disable controls while their queued mutation is active
  • return focus appropriately after removing an item
  • announce errors and successful updates
  • maintain keyboard focus when a drawer opens/closes
Hosted Checkout supplies the cart UI; validate its integration and surrounding buttons in the host application.

Production checklist

Cart skills and starter patterns

Use the cart/checkout skill for exact edge cases and the production starters for integrated query, session, and Hosted Checkout patterns.