Skip to main content

create_order

Places the order using the preview_id and confirmation_token returned by a preview. On success it returns the platform order ID order_id, the order status, the payable amount payable_price, and (when payment is required) the payment_action.
Order flow: search_shops → shop_id + cart_id → get_shop_menu to pick items → quote_cart to price the cart and get quote_id → select_address to get address_id → preview_order → preview_id + confirmation_token → create_order → order_id + payment_action. The preview_id and confirmation_token must come from the same preview_order call and be passed back as-is — never fabricate or mix them.
This tool is idempotent, keyed on confirmation_token. The idempotency fingerprint compares preview_id + confirmation_token + payment_method, plus whether require_phone_verify is true (not callback_url). Repeating the call with the same confirmation_token: if those match the first call, it returns the first result; if any differs, it returns IDEMPOTENCY_CONFLICT. A token places exactly one order — to order again, run preview_order for a fresh token. Note: changing only callback_url (the other three unchanged) is not a conflict — it replays and restarts status tracking (so callbacks may be delivered more than once).

Parameters

About require_phone_verify: when true, every link for this order — the payment_action.action_url returned here, and the detail_url later returned by get_order_status / list_orders — first shows a confirmation page asking for the last 4 digits of the phone number used to place the order; the order page opens only after a correct entry. Once confirmed, the same browser is not asked again for 24 hours; after 5 wrong attempts the order’s links are locked for 24 hours. Useful when links travel through chat and may reach the wrong person. The setting is fixed at order creation and cannot be changed later; omitted or false leaves the links exactly as before. About callback_url: must be an absolute http/https URL; loopback / private / link-local hosts are rejected. When set, every status change on this order POSTs one event to that URL, until the order ends (completed / cancelled / failed / refunded). Status is checked roughly every 2 seconds while unpaid, and every 30 seconds after payment. If the order has not ended after 2 hours, a final timeout event is sent and tracking stops, so you are never left waiting. Callback body:
status enum (8 values):
Order creation itself does not get its own event — the create_order response is the receipt for that. The first event is normally pending_payment.
The payment-outcome event carries two extra fields, in exactly the previous callback format, so existing receivers need no changes:
Use seq to detect missed events: seq increments without gaps per order. If you receive 1, 2, 4, event 3 never arrived — call get_order_status to fetch the current state. Deduplication: delivery is at-least-once; the same event may arrive more than once, so dedupe on (order_id, seq). A failed delivery is retried three times (after 1 / 2 / 4 seconds) and then dropped, without affecting the order itself. Without callback_url, nothing is pushed — poll get_order_status yourself.

Returns

The payable_price field is in cents (integer), not yuan. e.g. payable_price: 1500 means ¥15.00.
status enum: created, pending_payment, paid, preparing, delivering, completed, cancelled, failed, refunded.

Error Codes

See Error Handling for the full list.

Example Call

With phone confirmation on the links: