One total on MCP carts

MCPBreaking

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.

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.

All changes