# Pathrule Pattern: E-commerce Cart and Checkout (1.0.0)
# ::pathrule:package:ecommerce-cart-checkout

### [RULE] Calculate payable totals from server-owned inputs  (path: /src/commerce)
<!-- scope: folder | priority: high | strict -->

The client displays a proposal, not an authority. Product prices, eligibility, stock, tax, shipping, and exchange rules can change between cart editing and payment creation.

- Accept stable product, variant, quantity, and promotion identifiers from the client, then load current authorized commerce data on the server.
- Calculate money in integer minor units or an exact decimal representation with one documented rounding policy per currency and tax boundary.
- Return a priced checkout snapshot with version and expiry so the UI can explain changes instead of silently charging a different total.
- Store the exact line, discount, tax, shipping, currency, and total breakdown accepted for the order rather than recomputing historical orders from the current catalog.

See /src/payments for the adjacent decision or procedure that completes this constraint.

---

### [RULE] Reserve scarce inventory through one atomic transition  (path: /src/commerce)
<!-- scope: folder | priority: high | strict -->

Reading stock and decrementing later lets concurrent checkouts each observe the same unit. Holding inventory forever on abandoned payment attempts creates a different availability failure.

- Perform availability check and reservation update in one database transaction or atomic inventory service operation.
- Give the reservation a checkout or order identity, quantity, expiry, and status so retries return the same reservation.
- Commit the reservation when authoritative payment and order policy allow fulfillment; release it on terminal failure or cancellation.
- Expire abandoned reservations through idempotent scheduled work and reconcile inventory records rather than deleting evidence blindly.

See /tests/checkout for the adjacent decision or procedure that completes this constraint.

---

### [RULE] Create one order per logical checkout  (path: /src/commerce)
<!-- scope: folder | priority: high | strict -->

Browser retries, double clicks, gateway timeouts, and payment redirects can repeat checkout creation. A fresh order ID on every request turns one intent into several payable records.

- Create the logical checkout identity before external payment calls and enforce uniqueness at the server boundary.
- Persist the order and priced snapshot in a pending state, then reuse them when the same identity returns.
- Propagate the same identity into payment-provider idempotency and metadata fields without using mutable or personal values as keys.
- Disable duplicate UI submission for usability, but rely on database and provider idempotency for correctness.

See /src/payments for the adjacent decision or procedure that completes this constraint.

---

### [RULE] Advance order state from authoritative payment evidence  (path: /src/payments)
<!-- scope: folder | priority: high | strict -->

A success page, client callback, or redirect parameter can be forged, replayed, abandoned, or reached before the provider's durable result. Fulfillment needs server-verified payment state.

- Verify event signature and account context or retrieve payment state through authenticated server APIs before changing the order.
- Handle duplicate and out-of-order events idempotently and reject transitions that would move a terminal order backward.
- Store provider payment identity, amount, currency, capture state, and event identity needed for reconciliation without retaining prohibited payment data.
- Start fulfillment through a durable outbox or job after the paid transition commits, not directly inside a webhook response.

See /src/commerce for the adjacent decision or procedure that completes this constraint.

---

### [MEMORY] The cart is editable intent while the order is an immutable snapshot  (path: /src/commerce)

A cart belongs to an active shopping session and may hold stale or unavailable choices. An order is a financial and fulfillment record whose line identity and totals must remain understandable after products, names, or prices change.

- Store stable product and variant references in the cart and reprice before checkout rather than treating cached display values as current.
- Copy customer-facing description, quantity, unit price, discounts, tax, shipping, currency, and total into the accepted order.
- Append order adjustments, refunds, cancellations, and fulfillment events instead of mutating history to resemble the latest catalog.
- Merge anonymous and authenticated carts through an explicit product policy that resolves duplicates, quantities, ownership, and expired items.

See /src/payments for the rule or workflow that puts this decision into practice.

---

### [MEMORY] Checkout is a recoverable state machine  (path: /src/commerce)

Checkout spans browser navigation and external systems. Treating it as one request loses state when the user authenticates, returns from payment, closes a tab, or waits for asynchronous confirmation.

- Model pricing, reservation, order creation, payment pending, challenge, paid, failed, expired, and cancelled states with allowed transitions.
- Store only the minimum browser state needed to resume and recover authoritative status from the server by checkout identity.
- Make return routes safe to reload and revisit; they query state instead of repeating payment or order creation.
- Surface pending and recoverable failures honestly, including a path to retry payment without creating a second order or reservation.

See /tests/checkout for the rule or workflow that puts this decision into practice.

---

### [SKILL] verify-checkout-state-machine  (path: /)

---
name: verify-checkout-state-machine
description: Verify an e-commerce checkout change before accepting production payments.
---

# Verify Checkout State Machine

Run this procedure when the affected surface changes, before the result is promoted to production. Record evidence for every step instead of accepting a plausible-looking result.

1. Test stale prices, invalid promotions, tax and shipping changes, currency rounding, missing products, and quantities at inventory boundaries.
2. Run concurrent checkouts for the last units and prove reservations prevent oversell, expire safely, and remain idempotent on retry.
3. Repeat order and payment creation through double click, timeout, reload, back navigation, and duplicate client requests with the same logical key.
4. Replay valid, duplicate, out-of-order, delayed, malformed, wrong-account, wrong-amount, authorized, captured, failed, and cancelled payment evidence.
5. Verify fulfillment starts once after committed paid state, and reconcile every order against payment and inventory records after induced partial failures.

## Exit criteria

The change is complete only when the expected behavior, failure behavior, and rollback path have all been exercised with representative data. Preserve the evidence with the change so the next operator can repeat the same checks.
