# One total on MCP carts

October 20, 2026 · MCP · Breaking

A build session never gets Layout's confirmation card, so the build itself now carries the one total the person pays.

## What changed

- **The fee is in the total.** On a build session, a carted build's `totalMinor`, `price` and `cart.totalMinor` are the restaurant's total plus Layout's service fee, unless the fee is waived. `cart.merchantTotalMinor` is the restaurant's own total. Over REST, the cart's `totalMinor` already worked this way.
- **`fee_not_included`.** A build session's confirm that sends the restaurant's total alone answers `confirm.error: "price_changed"` with `reason: "fee_not_included"`. Nothing is confirmed or charged.
- **Expired carts.** A confirm on a carted build more than fifteen minutes after it was ready answers `confirm_expired`, and nothing is charged. `not_confirmable_cold` now carries `reason`: `canceled`, `expired`, `closed` or `not_found`.
- **Pickup only on a build session.** A build with `fulfillment: "delivery"`, `deliverTo` or `tipPercent` builds nothing and answers `deliveryUnavailable: { reason: "not_enabled" }`. It used to build a pickup. A build session's tool list no longer shows those fields.
- **`order_status` on a build session.** With no arguments it follows this application's latest build when Layout can tell it is this application's, and otherwise answers `build.status: "not_found"`. An unknown `orderId` answers `placement.status: "not_found"`. A placed order carries `placement.pickup`, and a `challenge` carries `smsSent` when Layout knows whether the approval link was texted.

## Why it matters

The person agrees to the amount their card is charged, and on a build session the build is the only place you can read it. Showing `price` and confirming with `totalMinor` now means showing and confirming that amount.

## What to do

Show the person `price`, and confirm with the build's `totalMinor`, unchanged:

```
order {
  "action": "confirm",
  "orderId": "0b6f2a54-…",
  "expectedTotalMinor": 1890,
  "idempotencyKey": "a7c1e0d2-…"
}
```

Never add up the fee yourself, and never confirm with `cart.merchantTotalMinor` or an order's `total_minor`. See [Confirm with the person's code](https://developer.layout.link/reference/mcp#confirm-with-a-relayed-code).

## Breaking changes

Yes, in two cases. A build session that confirms with the restaurant's total alone, instead of the build's `totalMinor`, is now refused with `fee_not_included`. A build session that asks for delivery now gets no cart; build again without the delivery fields. Code that already sends `totalMinor` back as it came keeps working, and the total it shows is now the one the person pays.
