Table reservations and experiences are a different app — see Table-Reservations.skill.md.
| Input | How to get it |
|---|---|
| Visitor token | STEP 1 |
Menu id, its ordered sectionIds; section ids with ordered itemIds; item id, name, description, priceInfo.price | STEP 2 (three list calls, assembled client-side) |
operationId of the ENABLED ordering operation | STEP 3 |
Fulfillment methods (name, type, fee, minOrderPrice) | STEP 3 |
Cart line ids (quantity changes) | STEP 4 response |
sectionIds order.operationId) → STEP 4 → STEP 5 (totals).minOrderPrice from STEP 3.GenerateVisitorToken once; reuse it. The cart is bound to the token.
Three visitor-readable GETs on https://www.wixapis.com/restaurants/menus/v1/:
Assemble bottom-up and keep the id order: menu.sectionIds → section, section.itemIds → item. The flat sections/items arrays are in creation order, not display order. Skip ids that don't resolve (deleted). Quote priceInfo.formattedPrice (REST includes it). labels (vegan, spicy…) are usually empty — infer dietary answers from description and say so.
onlineOrderingStatus: "ENABLED". PAUSED_UNTIL/DISABLED → say ordering is closed.enabled: true methods. fee and minOrderPrice are decimal strings in the site currency; a missing fee means 0.40 < minOrderPrice(60) → no; offer pickup (no minimum) or suggest adding items.POST https://www.wixapis.com/ecom/v1/carts/current/add-to-cart with the Restaurants Orders app id and all three of operationId, menuId, sectionId in options:
→ cart.lineItems[] with id, productName.original ("Flat White"), quantity, price.formattedAmount. Use the section the dish is shown under (from STEP 2), not any section that happens to contain it. Shop products can share the same cart (different appId).
→ priceSummary.subtotal.formattedAmount / total.formattedAmount (₪104.00 for 2 flat whites + shakshuka + cookie). Quantity and removal calls are the same as the shop recipe (update-line-items-quantity, remove-line-items).
POST https://www.wixapis.com/ecom/v1/carts/current/create-checkout { "channelType": "WEB" } → checkoutId. Then create a redirect session (POST /_api/redirects-api/v1/redirect-session with ecomCheckout.checkoutId) and give the visitor redirectSession.fullUrl. The hosted checkout is where pickup vs delivery and the time slot are chosen. The checkoutUrl from GET /ecom/v1/checkouts/{id}/checkout-url is a /checkout?checkoutId= page that headless sites don't have — don't send visitors there.
Completing a paid order needs a payment provider on the site; on a site without one, say the order can be placed but payment isn't available online yet.
options is missing operationId, menuId or sectionId, or you used the Stores app id. Restaurants dishes use 9a5d83fd-8570-482e-81ab-cfa88942ee60. There is no variantId here.
You rendered the flat list arrays. Order comes from menu.sectionIds and section.itemIds.
Those are management endpoints. The visitor path is always the eCommerce current cart with the triple above.
fee is undefined on PickupTreat a missing fee as 0; only DELIVERY carries a fee and a minimum.
Items have no dietary labels on most sites; say "based on the description" when inferring vegetarian/vegan.
ExecuteWixAPI masks failures as "Visitor token rejected (HTTP 403)"Re-run the single failing call through CallWixSiteAPI to see the real 4xx body before reacting; never mint a new token mid-cart.
| Constant | Value |
|---|---|
Restaurants Orders (New) app id (cart catalogReference.appId for dishes) | 9a5d83fd-8570-482e-81ab-cfa88942ee60 |
| Restaurants Menus app id | b278a256-2757-4f19-9313-c05c783bec92 |
| Menus base URL | https://www.wixapis.com/restaurants/menus/v1/ (menus, sections, items) |
Last updated: 17 September 2026