create_order
Places the order using thepreview_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.
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
status enum: created, pending_payment, paid, preparing, delivering, completed, cancelled, failed, refunded.
Error Codes
See Error Handling for the full list.

