Cancel while building
Three fixes from a developer's report. A cancel your application sends while a cart is still building is kept and honoured. A request whose placeId and restaurantName disagree is refused instead of quietly ordering from the placeId's store. And the store's address now travels with its name everywhere you and the person see it.
What changed
POST /v1/carts/:id/cancelon a cart that is still building answers202 { "cart": { "id": "crt_…", "status": "canceling" } }instead of409 cart_not_ready. Layout releases the cart the moment the build lands, never offers it to the person, and never sends Layout's cart-ready text for it.GET /v1/carts/:idreadscanceling, thencanceled. A confirm on acancelingorcanceledcart is409 cart_closed.- A cancel on a cart that was already confirmed is still
409 cart_closed, now witherror.order: the order and its state now (placing,placed,unconfirmedorrefunded). - The MCP
ordertool'scancel: truetakes the build'sidempotencyKeywhile the cart is still building, and answerscancel.status: "canceling". POST /v1/cartsand/answerwith aplaceIdand arestaurantNamethat name different stores answer409 store_mismatch. Nothing is built.error.storeis{ placeId, name, address }for the store theplaceIdnames, andcandidates, when Layout could find them, are stores matching the name. Over MCP, the build answersstoreMismatch.- The cart's
storecarries the address whenever Layout knows it, on ready, failed, answered and closed carts.GET /v1/orders/:idand every webhook payload addstore_address, null when unknown. A sandbox cart'sconfirmationCardnames the address. - Layout's cart-ready text names the store and its address, and for a cart your application built it opens with your application's name from the console:
Acme Assistant built your order at Layout test kitchen, 1 Sandbox Way, San Francisco, CA 94107:.
409 {
"error": {
"code": "store_mismatch",
"message": "placeId names Layout Test Kitchen North, which does not match restaurantName. Nothing was built. Ask the person which store they mean and send only that store's placeId, or only restaurantName with near or geo.",
"store": { "placeId": "test_place_branch_north", "name": "Layout Test Kitchen North", "address": "31 Sandbox Way, San Francisco, CA 94107" }
}
}
Why it matters
A cancel sent while a cart was building used to be refused, and the cart then landed and Layout texted the person to reply YES to an order your application had abandoned. A request carrying a placeId from one store and the name of another used to build at the placeId's store without a word, and a person nearly ordered from the wrong place. Naming the address beside the store is how the person tells two branches apart before they agree to pay.
What to do
Treat canceling as on its way to canceled, and never confirm it. On store_mismatch, ask the person which store they mean and build again with only that store's placeId. Show store.address beside the store's name. See POST /v1/carts/:id/cancel and Errors.
Breaking changes
None under the versioning policy: canceling is a new cart status, store_mismatch a new error code on a 409, and store_address a new field. One answer moves: a cancel on a building cart used to answer 409 cart_not_ready and now answers 202 canceling. A request that used to build at the placeId's store despite naming another now answers 409 store_mismatch.