Storefront integration
Most of these guides are written merchant-first (admin writes, role-gated). A
storefront is the opposite: it's mostly public reads plus public checkout
writes. Legacy storefronts place the order with POST /public/orders; M3
storefronts adopt checkout-session writes (create, reprice, bind) before
payment/confirmation. This page sequences those paths and — more importantly —
draws the one boundary that trips up every storefront: what litecommerce can
estimate today vs. what it actually persists on an order.
Tenant-resolving public calls carry the tenant header
(x-organization-slug) and no bearer token — public reads are not merchant
or customer authenticated, but they still need tenant context or their
documented token-only route. Token-only checkout handoff routes document their
own exception. Paths are under /api/v1.
The cart/checkout boundary (read this first)
Before a storefront adopts the M3 checkout-session flow, its cart total is only
an estimate. The legacy POST /public/orders path persists line items only
— its subtotalInCents is the sum of the lines, taxInCents is 0, and
totalInCents equals the subtotal. Everything else — tax, shipping,
coupons, auto-discounts, bundles — is a display-only estimate until the
server-side checkout session is repriced and bound.
| Mechanism | Estimable today (display-only) | Binding at POST /public/orders | Bound by checkout sessions (M3) |
|---|---|---|---|
| Line items + subtotal | cart state | Yes — items[], subtotalInCents | — |
| Order total | subtotal (± your own estimates) | Yes — totalInCents == subtotalInCents | total incl. provider-gated tax / discounts; shipping remains display-only |
| Shipping | GET /public/shipping/zones (rates) | No — no shipping line persisted | No — rates are display-only until the shipping-charge seam lands |
| Coupons | POST /public/cart/apply-coupon (pure preview) | No — not attached | usage counted at placement |
| Auto-discounts | POST /public/auto-discounts/calculate | No — not attached | applied at checkout |
| Bundles | check-bundles / items/:slug/bundles | No — not attached | applied at checkout |
| Tax | no public estimate endpoint; cart display estimate only | No — taxInCents is 0 on legacy orders | provider-gated tax calculation after bind |
The rule: a storefront should not treat cart-side tax, shipping, or discount previews as binding. For the legacy public order path, reconcile the final display to
subtotalInCentsor label the extras "estimated, finalized at checkout." For M3 checkout sessions, read tax-inclusive totals afterbind;repricecan still returntaxInCents=0because Stripe Tax is only computed when the session is bound with the captured address.
Stripe Tax is wired into the checkout-session bind flow (#449), but it is
provider-gated and off by default. When a tax provider is enabled, bind
computes destination-based tax from the captured address, persists an internal
tax snapshot, and returns public taxInCents / totalInCents values. Until a
storefront uses that flow, do not present client-side tax as authoritative.
The read/write sequence
A typical storefront wires these in roughly this order:
- Catalog —
/guides/catalog.GET /public/itemsand/public/items/:slugfor product + variant data (public reads returnACTIVEonly). - Collections & pages —
/guides/collections-pages.GET /public/collections,/public/collections/:slug/items, and/public/pagesfor merchandising + CMS content. - Inventory —
/guides/inventory.GET /public/inventory/:itemIdandPOST /public/availability/checkfor stock state at the PDP and cart. - Pricing —
/guides/pricing. The cart-math previews:POST /public/cart/apply-coupon,POST /public/auto-discounts/calculate,POST /public/cart/check-bundles, and the proactiveGET /public/items/:slug/bundles. All display-only (see the boundary above). - Shipping —
/guides/shipping.GET /public/shipping/zonesto show rates at the cart (also display-only today). For the M3 checkout-session path, the storefront then creates a checkout session, callsrepriceas cart/contact/address inputs change, and callsbindonce the customer is ready to hand off to payment/confirmation. - BYO checkout —
/guides/byo-checkout. Use checkout sessions for the server-authoritative total and the litecommerce Stripe Payment Element handoff. Create/read/reprice/bind calls usex-organization-slug; thepayment-sessionhandoff is token-only and does not send that header. The storefront renders checkout UI; the API owns pricing, tax, payment attempts, webhook state, and order creation. - Legacy order path —
/guides/orders. If the storefront is not using checkout sessions,POST /public/orderscan still place a line-item-only order; otherwise, use public order reads (/public/orders/:id,/number/:num) only to render confirmation + status after the checkout-session/payment flow creates the order. - Returns —
/guides/returns. The post-purchase flow, authenticated by matching the order's email.
The two reference storefronts (EKGIS Naturals + Idaho Pro Gear) consume exactly this surface — they're the working proof of the BYO-frontend model.
Related
- Tenants & context — the
x-organization-slugheader - Orders & fulfillment — the full order contract + the legacy order persistence callout
- BYO checkout API — the checkout-session and payment handoff sequence for custom storefronts
- Error envelope — the shape every failed call returns