# Checkout — spoke context

The user is checking out of a cart they built in mishopping (or any Miapp). Whoois orchestrates the payment across one or more merchants with a single passkey gesture.

If you haven't already, fetch `https://poc.whoois.app/whoois-context.md` for the root primer. For cart building / product discovery / shopping, see `https://poc.whoois.app/context/mishopping.md`.

---

## What's happening

The user has built a cart — could be a single merchant (one coffee shop) or multi-merchant (a coffee shop + bookstore + toy store all in one session). They're ready to pay. Whoois handles:

1. **Parallel authorization fan-out** — independent transactions per merchant, NOT a serial dependency chain
2. **One passkey** — user authorizes the whole cart with a single ceremony regardless of merchant count
3. **Best-rail routing** — Whoois picks the optimal payment rail per merchant (ACH/RTP, Virtual Card, Crypto) based on cost + merchant acceptance
4. **Mistamped receipts** — each merchant settlement produces a receipt that lands in the user's Mitrail

---

## Trigger phrases

- "Check out my cart"
- "Buy these"
- "Place the order"
- "Pay for everything in my cart"
- "Complete the purchase"
- "Confirm and pay"

If the user has a pending cart and mentions paying or finalizing, this is checkout intent.

---

## Tools to call

**`whoois_checkout_open`** — LLM-visible. Opens the checkout iframe. Takes a `cartId` argument (the pending cart's ID — typically retrieved from `mishopping_pending_cart_view` or returned from `mishopping_cart_build`). The iframe locks the cart (so the user can't change line items mid-checkout), displays line items, shows estimated totals per merchant, and prepares the passkey ceremony.

**`whoois_checkout_finalize`** — visibility:app (iframe-only, not directly LLM-callable). The iframe calls this when the user taps "Pay with passkey" — it fires the WebAuthn ceremony, then the server fans out parallel authorizations to each merchant's payment rail and returns settled receipts.

**`authorize_payment`** — visibility:app. Lower-level passkey-gated payment authorization. Used in single-rail scenarios.

**`whoois_cart_cancel`** — LLM-visible. Cancels a pending cart and clears the lock. Used if user says "never mind" or wants to start over.

**`whoois_receipt_open`** — LLM-visible. Re-renders the receipt iframe for a previously-completed cart.

---

## Typical flow

1. User says "check out my cart" → call `whoois_checkout_open({cartId})`
2. Iframe opens, shows cart contents + estimated totals + "Pay with passkey" button
3. User reviews, taps button → iframe internally calls `whoois_checkout_finalize` (or `authorize_payment` for single-merchant)
4. Passkey ceremony fires
5. Whoois fans out parallel authorizations: each merchant gets its own transaction on the rail Whoois selected
6. Settled receipts return — each merchant's part of the cart becomes a Mitrail entry
7. Tell the user: *"Done. {N} receipts in your Mitrail — one per merchant. You can view them anytime."*

If any merchant authorization fails (e.g., rail temporarily unavailable), the iframe surfaces the failure with retry options. The other merchants in the cart still settle independently — no all-or-nothing.

---

## State branches inside the iframe

- `loading` — cart fetch in progress
- `ready` — cart loaded, awaiting user passkey tap
- `authorizing` — passkey ceremony in progress
- `settling` — parallel auth fan-out underway
- `success` — all (or some) merchants settled, receipts displayed
- `partial-failure` — some merchants failed, others succeeded; retry CTA per failed
- `cart-locked` — another session has the cart locked; idempotency check

---

## Cart-state guards

While a cart is in checkout (locked), other tools that would mutate the cart return `cart_locked` errors:

- `mishopping_pending_cart_add`
- `mishopping_pending_cart_set_line_qty`
- `mishopping_pending_cart_clear`

This is intentional — prevents race conditions where the user adds items mid-payment. If the user wants to modify, they cancel checkout (`whoois_cart_cancel`) then modify then re-open.

---

## Payment rails (technical context)

Whoois supports three rails — selection is automatic per merchant based on cost + acceptance:

- **ACH/RTP** — cheap (~$0.05/txn), takes hours-days to settle
- **Virtual Card (SKUx)** — loss leader (~$0.90/txn), instant settlement, near-universal acceptance
- **Crypto** — network gas only, instant, limited merchant acceptance

The user doesn't pick the rail — Whoois orchestrates. Receipts show the rail used per merchant.

---

## Tone notes

Checkout is a moment of trust. The user is about to authorize real money. Be precise, not breezy. Repeat the total. Mention the passkey gate. Don't make jokes mid-checkout.

After settlement, be celebratory but brief: *"All done. Receipts in your Mitrail."*

---

*This spoke is fetched from `https://poc.whoois.app/context/checkout.md`. Pair with `https://poc.whoois.app/whoois-context.md` for the root primer and `https://poc.whoois.app/context/mishopping.md` for cart building.*
