Skip to content

ADR-014: Stage 3A guest checkout sends order requests

Status: accepted 5 October 2026 (Stage 3A, improvement-plans/Stage-3A-Plan.md). Settles decisions C01–C03, C05, C06, C09 and C15 of the Stage 3 plan for milestone 3A. Online payment (3B) is decided separately. Supersedes ADR-005.

Shops sell through the Astro storefront (ADR-013). Its cart lives behind an httpOnly cookie in the Storefront API, and customers never sign in. Ordering still happens by phone. Stage 3A makes the cart an order without online payment. The owner chose:

  • Fulfilment: pickup, flat-fee delivery, and a live Uklon courier.
  • Payment: cash or card on pickup or delivery.
  • Contact: phone and email both required.
  • Notifications: email to staff and to the customer.
  1. Guests only (C01). There are no customer accounts in 3A. The cart is owned through its cookie, and a submitted cart is closed and never reused. The login cart merge of ADR-005 does not apply, and its listener is removed.

  2. An order request, not a reservation (C03). Submitting creates a pending order with revision 1 and reserves no stock (rule B01). The customer is told the shop will confirm availability, delivery and the price. Staff confirm through the existing lifecycle, which reserves stock.

  3. Fulfilment per shop (C02). Each shop chooses, in Settings → Checkout:

    • Pickup at its address.
    • Delivery within its city for one flat fee, optionally free above an amount.
    • Uklon courier, priced live by Uklon’s API. Its contract is a separate decision.

    It also sets the lead time, the same-day cutoff, time slots and closed dates. Requests that break these are refused, not estimated. The currency is the shop’s (UAH in the pilot).

  4. The server quotes, and the quote is the agreement (C05).

    • A quote covers the items, packaging, the delivery fee and the currency, plus a fingerprint and a ten-minute expiry.
    • Submitting requires the current fingerprint. If anything changed, the customer sees the new total and confirms again.
    • Client totals, fees and prices are never accepted.
  5. Packaging is snapshotted (C06). Each order line records its packaging’s name, unit price and known cost, counted per bouquet as the cart counts it. Later catalogue edits do not change a recorded order.

  6. Offline payment, recorded by staff (C09).

    • Shops offer cash and/or card on pickup or delivery.
    • Staff with order permissions record a payment’s amount and method, with the time and actor kept in the order’s history. Customers can never mark an order paid.
    • Assembly does not wait for payment under the offline policy.
  7. One order per cart. A cart can be submitted once. A repeated submit (refresh, double click, another tab, a new retry key) returns the same order, and an injected failure leaves no orphan order and no lost cart.

  8. A private status link.

    • Each order gets a random 40-character token. Only its SHA-256 hash is stored on the order, and the token is scoped to one shop and one order.
    • Amended 6 October 2026 (PR 4): the cart’s submission row also keeps the token encrypted with the application key, so a visitor whose answer was lost and who submits again gets the same link (§7). Reissuing a link replaces it there too.
    • The link shows the status, items, totals, fulfilment and the shop’s contacts. It shows no costs, staff notes or recipient phone.
    • Links expire 60 days after the delivery date. Staff can issue a new link, which revokes the old one.
  9. Contact and messages (C15).

    • The purchaser’s phone and email are required. The recipient’s are asked only for delivery.
    • A new request emails the shop’s owner, admins and managers, and sends the customer a confirmation with the status link. Messages are transactional only, with no marketing consent bundled in.
  10. Off until switched on. Each shop’s checkout is off by default. While it is off, the Storefront API refuses quotes and submissions, and themes keep the “contact us to order” fallback.

  • One shared order-creation action serves staff and storefront orders. The staff controller and the checkout keep their own authorization.
  • New records: checkout settings, packaging snapshot columns, a checkout submission per cart, an order access token, and staff-recorded payments.
  • Abuse limits:
    • Quotes and submissions are rate-limited per visitor.
    • A shop sees at most a configured number of open requests per phone.
    • Requests reserve nothing, so no inventory can be exhausted.
  • Online payment (3B) adds payment attempts and reservations at submission without changing this request path.