# Domain: Orders, Checkout, Fulfillment, Freight ## Lifecycle ``` cart → checkout (one tx) → order per shop shipment flow ───────────────────────── ───────────────────────── pending_payment ──pay──► paid ──first shipment──► fulfilling ──all shipped──► shipped │ │ └──cancel──► cancelled delivered (all shipments) ──► completed ``` Every arrow is a guarded `UPDATE … WHERE status = …`; stale actions → 409. ## Checkout invariants (`modules/order/service.rs`) One transaction per checkout: lock SKUs (`FOR UPDATE` in id order) → resolve flash-sale activity pricing → per-shop coupon discount (server-computed, client sends only coupon ids) → per-shop freight fee → insert order + items + stock decrements → commit → clear cart. Orders are split per shop; each order carries `total_minor = subtotal − discount + shipping_fee_minor`. Snapshots make history immutable: order items keep `unit_price_minor`, `product_name`, `flash_sale_item_id`, and the freight `freight_template_id`/`freight_pricing_method` resolved at checkout. Later template edits never touch past orders. ## Freight (`modules/freight/`) Templates are shop-scoped (`own_shop`): by_piece or by_weight (grams on `skus.weight_grams`), first-unit + additional-unit fees with part-unit round-up, `always_free`, `free_threshold_minor`, and region rules overriding default fees by case-insensitive match against address region/city/country. Resolution per line: product template → shop default → zero fee. Fees merge per template group within a shop order and convert from the group's SKU currency to the order currency. `POST /orders/shipping-quote` is the read-only quote (normal prices only); checkout recomputes authoritatively in the order transaction. Client-supplied fees are never read. Shipping companies are a dictionary (`shipping_companies`); shipments record `shipping_company_code` validated against it. ## Key files See `docs/code_index/order.md`.