quote_cart
Prices the items selected in a cart: validates the shop / cart / items, calls the upstream pricing engine, and returns the price breakdown, whether checkout is allowed, and thequote_id used in the next preview step.
Order flow:
search_shops → shop_id + cart_id (carries shop & delivery coordinates) → get_shop_menu to pick items → quote_cart to price the cart and get quote_id → select_address to get address_id → preview_order (can pass quote_id back) → preview_id + confirmation_token → create_order. shop_id / cart_id / address_id and item item_id all come from upstream endpoints — pass them back as-is, do not fabricate them.Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
consent_grant_id | string | Yes | — | User consent grant ID (cg_ prefix, from verify_user_bind), identifying the consenting user |
shop_id | string | Yes | — | Shop ID (from search_shops) |
cart_id | string | Yes | — | Cart context ID (from search_shops; carries shop & delivery coordinates, so no lat/lng is needed here) |
address_id | string | Yes | — | Gateway address ID (string); use the address_id returned by select_address as-is |
items | array | Yes | — | Item list (see below, at least one) |
items[].item_id | string | Yes | — | Item ID (from get_shop_menu) |
items[].sku_id | string | No | null | SKU ID (from the menu item’s optional SKUs) |
items[].quantity | integer | Yes | — | Quantity, ≥ 1 |
items[].ingredient_option_ids | string[] | No | [] | Ingredient / option IDs (from the menu item’s options; for a non-default SKU use that SKU’s sku_options[].ingredient_options) |
items[].ingredient_quantities | array | No | [] | Portion counts for specific options, e.g. “Espresso shots x3”, shaped [{option_id, quantity}]; only options whose max_quantity exceeds 1 accept it, and exceeding it fails the order. Listing an option here counts as selecting it, so it need not repeat in ingredient_option_ids; omit and each option uses its own default_quantity (the merchant-recommended count) |
items[].remark | string | No | "" | Per-item note |
lang | string | No | — | Language for this response. One of zh / en / ja / ko / ru / ms / es; defaults to the language set at binding time (Chinese if unset) |
include_chinese | boolean | No | false | When true, the response also includes the Chinese original (<key>_zh) — see Bilingual responses |
Returns
All amount fields are in cents (integer), not yuan. e.g.
payable_price: 1200 means ¥12.00.| Field | Type | Description |
|---|---|---|
quote_id | string | Quote ID (qt_), passed to preview_order to validate the quote context |
can_checkout | boolean | Whether the cart is checkout-ready (false if any item is not checkout-able, a store-level required group is unmet, an item’s quantity is below its minimum purchase, every item in the cart is marked “cannot be ordered alone”, or upstream blocks checkout) |
blocking_reason | string | null | Why checkout is blocked (null when can_checkout is true); e.g. “pick a required item from ‘Required Soup’ before ordering (at least 1 per group)” or below the minimum order. For missing required groups see required_groups in the get_shop_menu response |
blocking_code | integer | Machine-readable failure code: 1 = the cart cannot be delivered on its own (every item is a “cannot be ordered alone” item, e.g. toppings; blocking_reason is typically “单点不配送” or “商品不可单独下单” — add a regular item and re-quote; best-effort match on upstream copy); 2 = a store-level required item group is not satisfied (add items from the required_groups in the get_shop_menu response, then re-quote; blocking_reason reads like “需从『必选好汤』补选必选项再下单”); 0 = everything else (including checkout-ready). For programmatic routing only; treat can_checkout as the source of truth |
goods_price | integer | Goods subtotal (cents) |
delivery_fee | integer | Delivery fee (cents) |
packing_fee | integer | Packing fee (cents) |
original_price | integer | Pre-discount total (cents) = payable + discount; satisfies original_price − discount = payable_price |
discount | integer | Discount amount (cents) |
payable_price | integer | Payable amount (cents) |
minimum_order_gap | integer | null | Amount short of the order minimum (cents); null when not applicable |
shop.lat | number | null | Shop latitude, same source and value as shop.lat from get_shop_menu (the shop coordinates saved with the cart_id at menu time); same coordinate system as the request lat / lng (AMap GCJ-02); null when the menu step captured no coordinates, or for a cart_id minted before this field shipped |
shop.lng | number | null | Shop longitude, otherwise same as shop.lat |
items | array | Priced item details |
items[].item_id | string | Item ID |
items[].name | string | Item name |
items[].quantity | integer | Quantity |
items[].price | integer | Item price (cents) |
items[].min_purchase | integer | null | Minimum purchase echo (≥ 1, 1 = no minimum) so you can check it against quantity; null on rare fallback paths where it can’t be resolved |
items[].available_quantity | integer | null | Remaining stock echo (units, menu-time snapshot): positive = units left, 0 = sold out, null = ample or unknown; display only — actual availability is enforced at order time |
items[].image_url | string | null | Item image URL; null if none |
items[].specs | array | Selected specs for this item, [{name, value}] (e.g. {"name":"Size","value":"Large"}); [] if none |
items[].selected_ingredients | array | Selected ingredients/options, [{group_name, name, price_delta, quantity}]; group_name may be null, price_delta is the surcharge for one portion (cents), quantity is the effective portion count (defaults to that option’s default_quantity). The line’s surcharge is NOT price_delta × quantity — see price_steps on get_item_options for the tiered price; [] if none |
Error Codes
| code | Description |
|---|---|
CONSENT_GRANT_REQUIRED | Missing consent grant (no consent_grant_id) |
CONSENT_GRANT_INVALID | Consent grant is invalid |
CONSENT_GRANT_EXPIRED | Consent grant has expired; re-authorization required |
CAP_NOT_BOUND | Capability is not enabled for this agent |
CONSENT_GRANT_WRONG_CAP | Consent grant belongs to a different capability / provider |
PUBLIC_REFERENCE_INVALID | cart_id invalid or expired, shop_id and cart_id mismatch, or item_id not part of this cart_id. address_id is only validated when the primary pricing call (cats_price) fails and falls back to the render_quote branch; an invalid address_id maps to this code there |
CART_PRICE_INVALID | items[].quantity is not an integer or is less than 1. MCP passes raw dicts that bypass pydantic, so the service validates them internally |
ELEME_ERROR | Upstream pricing call failed |
Example Call
{
"name": "quote_cart",
"arguments": {
"consent_grant_id": "cg_your_consent_grant",
"shop_id": "<from search_shops>",
"cart_id": "<from search_shops>",
"address_id": "<from select_address>",
"items": [
{"item_id": "670685166551", "sku_id": "5014584502270", "quantity": 1}
]
}
}

