Litestore · Operator guide

Checkout

Learn about the checkout flow, from cart and discounts through shipping, tax, and order creation.

The cart lives on your storefront, at:

/cart

That is where the shopper applies a discount code, picks a shipping rate, and sees the tax.

Payment itself happens on Stripe's hosted checkout page, and the shopper returns afterwards to:

/cart/success

Stripe is the only wired payment provider. Browsing and adding to cart work without it; starting checkout does not.

Four records carry a checkout:

Cart
CartItem
OrderIntent
Order

The path a shopper takes

  1. The shopper builds a cart, applies a code and picks a shipping rate on your storefront.
  2. Starting checkout reserves stock and the coupon slot, resolves discounts, shipping and tax, and writes the frozen quote.
  3. The shopper pays on Stripe's checkout page.
  4. Stripe's confirmation promotes that quote into an order — it is never recomputed from the live cart or catalog.

Step 2 is where nearly everything happens. It is worth reading the rest of this page as an explanation of that one step.

One server-side pricing pass

Sale prices, coupon, behavioral and loyalty discounts are all resolved on the server in a single pass.

The result of that pass is what Stripe is asked to charge.

Prices cannot be altered from the browser. The figures a shopper sees are the output of the calculation, not an input to it, so a modified page cannot produce a cheaper charge.

Doing it in one pass also settles how discounts combine. There is one calculation with one answer, rather than several discounts applied in whatever order they happened to be requested.

The frozen quote

Starting checkout writes an order intent, holding:

  • The subtotal
  • The discount
  • The tax
  • The shipping
  • The total
  • A copy of every line

The order is built from that copy when Stripe confirms payment.

What happens if someone edits a price, or deletes a variant, while a shopper is mid-checkout?

Nothing, to that shopper. A price edit or a deleted variant mid-checkout cannot change or break a paid order, because the order is assembled from the frozen copy rather than looked up again in the live catalog.

This is what lets you run the catalog during trading hours. Editing a product while people are shopping is normal, and it cannot reach into a checkout already in progress.

It also means what the shopper agreed to and what you charged them are the same numbers, recorded before payment rather than reconstructed after it.

Stock is held while the shopper pays

Stock is decremented when checkout starts.

The relevant windows are:

30 minutes to pay the quote
35 minutes of held stock
5 checkout attempts per cart per hour

The stock hold is longer than the payable window on purpose. The extra five minutes is a grace period for the payment confirmation to arrive, so a payment made at the twenty-ninth minute is not defeated by its confirmation landing a moment later.

If payment fails or the window expires, the units go back.

Holding stock at the start of checkout is the deliberate choice here. The alternative — taking stock only once payment lands — sells the last unit twice, and someone has to be told afterwards that their paid order cannot be fulfilled.

The attempt limit exists so a single cart cannot cycle through checkout endlessly, holding stock away from other shoppers.

Coupon limits at the moment of use

The coupon slot is claimed before the payment page opens.

That includes the per-customer limit.

Parallel checkouts on one account cannot all take the last use. Claiming the slot up front, rather than checking a count and trusting it to still be true a few minutes later, is what closes that gap.

Tax is its own line

Tax is charged as its own explicit line item.

Stripe's automatic tax is switched off, so the tax figure comes from your own configuration and appears as a line the shopper can see.

Guest checkout

A guest can buy without an account.

They look the order up later by order number and email.

When that person signs up with the same address, their earlier guest orders are attached to the new account. So there is no penalty for having checked out as a guest first, and nothing to migrate by hand.

Abandonment is measured

A cart that stalls is picked up by a scheduled job that sends a recovery email.

The admin also classifies why it stalled, into one of:

intent loss
checkout friction
shipping shock
price resistance

The classification is the useful part. "Abandoned carts: 340" tells you nothing you can act on; the same 340 split into shipping shock and price resistance points at two different fixes.

Where the settings live

There is no dedicated checkout page in the admin. Settings → Checkout redirects to Settings → Payments.

These are set per market, under Markets:

  • Coupons on or off
  • Loyalty on or off
  • The return window

Per market rather than store-wide, because the answers legitimately differ between the places you sell.

What to check when checkout misbehaves

If checkout will not start at all, check the Stripe connection first. It is the only wired provider, and everything before payment works without it — so a store where browsing is fine and checkout is dead is the expected symptom.

If a shopper says the price changed, remember that it cannot have. The quote was frozen when they started, and the order was built from that copy.

If stock looks wrong shortly after a failed payment, wait out the hold. Units are returned when payment fails or the window expires.

If a discount did not apply, look at the market rather than the code. Coupons and loyalty are switched on per market.

The thing to keep in mind about the whole flow:

Everything the customer is charged is decided once, on your server, before the payment page opens — and nothing after that point can change it.

On this page