Litestore · Operator guide
Commerce

Checkout

Understand what happens between a shopper's cart and a paid order, and what to check when checkout goes wrong.

Checkout is how a shopper's cart becomes a paid order. Read this page to understand how Litestore prices the cart, holds stock while the shopper pays, and builds the order once payment arrives.

The cart is on your storefront, at:

/cart

On this page the shopper applies a discount code, picks a shipping rate and sees the tax.

The shopper pays on Stripe's hosted checkout page. Afterwards, Stripe sends them back to:

/cart/success

Stripe is the only payment provider Litestore is wired to. Shoppers can browse and add to the cart without it, but they can't start checkout.

Litestore uses four records for a checkout:

Cart
CartItem
OrderIntent
Order

The path a shopper takes

  1. The shopper fills a cart. On your storefront they add items, apply a code and pick a shipping rate.
  2. The shopper starts checkout. Litestore reserves the stock and the coupon slot. It works out the discounts, shipping and tax, and saves a frozen quote.
  3. The shopper pays on Stripe's checkout page.
  4. Stripe confirms the payment. Litestore turns the frozen quote into an order. It never recalculates the order from the live cart or catalog.

Almost everything happens in step 2. The rest of this page explains that step.

One server-side pricing pass

Litestore works out sale prices and coupon, behavioral and loyalty discounts on the server, in a single pass.

Litestore then asks Stripe to charge the result of that pass.

Nobody can change prices from the browser. The figures a shopper sees come out of the calculation. They don't go into it, so a modified page can't produce a cheaper charge.

The single pass also settles how discounts combine. There is one calculation with one answer. Litestore doesn't apply discounts one after another in whatever order they were requested.

The frozen quote

When the shopper starts checkout, Litestore writes an order intent. It records:

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

When Stripe confirms the payment, Litestore builds the order from that copy.

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

Nothing changes for that shopper. A price edit or a deleted variant can't change or break a paid order, because Litestore builds the order from the frozen copy. It doesn't look the items up again in the live catalog.

This is why you can work on the catalog while people are shopping. Editing a product during trading hours is normal, and the edit can't affect a checkout that has already started.

It also means the shopper agreed to the same numbers you charged them. Litestore records those numbers before payment instead of piecing them together afterwards.

Stock is held while the shopper pays

Litestore takes the stock off when checkout starts.

These time limits apply:

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

The stock hold is deliberately longer than the time the shopper has to pay. The extra five minutes give the payment confirmation time to arrive. If a shopper pays in the twenty-ninth minute and the confirmation comes a moment later, the payment still counts.

If the payment fails or the time runs out, Litestore puts the units back.

Litestore holds stock at the start of checkout on purpose. If it only took stock once payment arrived, it could sell the last unit twice. Someone would then have to tell a customer that their paid order can't be fulfilled.

The attempt limit stops a single cart from cycling through checkout endlessly and keeping stock away from other shoppers.

Coupon limits at the moment of use

Litestore claims the coupon slot before the payment page opens. This includes the per-customer limit.

If one account runs several checkouts at once, only one of them can take the last use. Litestore claims the slot up front. It doesn't check a count and assume the count is still right a few minutes later.

Tax is its own line

Litestore charges tax as its own line item.

Stripe's automatic tax is switched off. The tax figure comes from your own configuration, and the shopper sees it as a separate line.

Guest checkout

A guest can buy without an account.

To find the order later, they look it up by order number and email.

If that person later signs up with the same address, Litestore attaches their earlier guest orders to the new account. Checking out as a guest first costs them nothing, and you don't have to move anything by hand.

Abandonment is measured

When a cart stalls, a scheduled job picks it up and sends a recovery email.

The admin also sorts each stalled cart by why it stalled:

intent loss
checkout friction
shipping shock
price resistance

The reason is what makes this useful. Knowing you have 340 abandoned carts doesn't tell you what to do. If you know some stalled on shipping shock and others on price resistance, you can see two different problems to fix.

Where the settings are

The admin has no separate checkout settings page. Settings → Checkout redirects to Settings → Payments.

You set these per market, under Markets:

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

They are set per market rather than for the whole store, because the right answer can differ between the places you sell.

What to check when checkout misbehaves

Checkout won't start at all. Check the Stripe connection first. Stripe is the only wired provider, and everything before payment works without it. So if browsing works but checkout doesn't, Stripe is the likely cause.

A shopper says the price changed. It can't have. Litestore froze the quote when they started checkout and built the order from that copy.

Stock looks wrong just after a failed payment. Wait for the hold to end. Litestore returns the units when the payment fails or the time runs out.

A discount didn't apply. Check the market before the code. Coupons and loyalty are switched on per market.

Remember

Litestore decides everything the customer pays once, on your server, before the payment page opens. Nothing after that point can change it.

On this page