Meniul publicat este sursa de adevăr pentru coș. Gateway-ul verifică fiecare produs, opțiune și total față de revizia meniului pe care o trimiți.
Citește catalogul
GET /v1/connections/{connection_id}/menu întoarce tot ce poate comanda clientul în locația respectivă: categorii, produse cu opțiunile lor, modalitățile de onorare activate, taxa de livrare și o revizie.
- ID-urile sunt șiruri opace. Stochează-le și trimite-le ca atare; nu încerca să le interpretezi.
- Numele și descrierile sunt texte introduse de restaurant. Afișează-le ca text, niciodată ca HTML.
Vezi meniul demonstrativ complet Pizza + meniu burger
{
"revision": "example-menu-1",
"currency": "RON",
"accepting_orders": true,
"fulfillment": [
"pickup",
"delivery"
],
"delivery_fee": 700,
"categories": [
{
"id": "pizzas",
"name": "Pizza"
},
{
"id": "meals",
"name": "Meals"
}
],
"products": [
{
"id": "pizza-margherita",
"category_id": "pizzas",
"name": "Margherita",
"description": "Tomato, mozzarella and basil",
"image_url": "https://images.example.test/margherita.jpg",
"translations": {
"en": {
"name": "Margherita",
"description": "Tomato, mozzarella and basil"
},
"ro": {
"name": "Margherita",
"description": "Roșii, mozzarella și busuioc"
}
},
"price": 3200,
"packaging": 100,
"packaging_product_id": "pizza-box",
"modifier_groups": [
{
"id": "pizza-extras",
"name": "Extras",
"kind": "extra",
"minimum": 0,
"maximum": 1,
"options": [
{
"id": "cheese",
"name": "Extra cheese",
"price": 400
}
]
}
]
},
{
"id": "burger-meal",
"category_id": "meals",
"name": "Burger meal",
"description": "Burger, fries and your choice of drink",
"translations": {
"en": {
"name": "Burger meal",
"description": "Burger, fries and your choice of drink"
},
"ro": {
"name": "Meniu burger",
"description": "Burger, cartofi prăjiți și băutură la alegere"
}
},
"price": 2500,
"packaging": 100,
"packaging_product_id": "meal-bag",
"modifier_groups": [
{
"id": "size",
"name": "Size",
"kind": "variant",
"minimum": 1,
"maximum": 1,
"options": [
{
"id": "regular",
"name": "Regular",
"price": 0
},
{
"id": "large",
"name": "Large",
"price": 0
}
]
},
{
"id": "drink",
"name": "Drink",
"kind": "bundle",
"minimum": 1,
"maximum": 1,
"options": [
{
"id": "water",
"name": "Water",
"price": 0,
"deposit": 50
}
]
},
{
"id": "meal-extras",
"name": "Extras",
"kind": "extra",
"minimum": 0,
"maximum": 1,
"options": [
{
"id": "sauce",
"name": "Extra sauce",
"price": 200
}
]
}
],
"variants": [
{
"id": "meal-regular",
"selections": [
{
"group_id": "size",
"option_id": "regular"
}
],
"price": 2500
},
{
"id": "meal-large",
"selections": [
{
"group_id": "size",
"option_id": "large"
}
],
"price": 3000
}
]
}
]
}Descarcă meniul demonstrativ ↓ · Schema Menu →
Imagini și limbi
Produsele pot include image_url, un URL HTTP(S) absolut, sau null dacă nu au imagine configurată. Rezervă spațiu pentru imagini și afișează un înlocuitor dacă încărcarea eșuează. Gateway-ul publică URL-ul; nu descarcă și nu găzduiește imaginea.
Categoriile, produsele, grupurile de opțiuni și opțiunile includ translations, cu chei de limbă precum ro, en și hu. Fiecare intrare conține name și description. Alege limba clientului, apoi limba de bază, iar în lipsa traducerii folosește câmpurile existente name și description. Traducerile lipsă nu sunt generate automat. Afișează tot conținutul tradus ca text. Alegerea limbii nu schimbă ID-urile, opțiunile sau prețurile.
Programul produselor pentru Website se configurează în editorul produsului din Retail, separat de Bolt, pentru fiecare punct de vânzare. Promoțiile pe produs nu sunt disponibile momentan în integrarea Website din Retail; reducerile aplicate la checkout rămân acceptate.
Program, sărbători și programul produselor
opening_hours descrie fusul orar al restaurantului, intervalele săptămânale periods și excepțiile special_dates. Zilele sunt numerotate de la luni 1 la duminică 7. Intervalele săptămânale pot trece peste miezul nopții; ora de sfârșit este exclusivă, iar 24:00 înseamnă sfârșitul zilei. Când schedule_enabled este false, programul săptămânal nu restricționează comenzile.
Fiecare dată specială înlocuiește întreaga zi calendaristică locală, inclusiv intervalele prelungite din ziua precedentă. Lista periods goală înseamnă închis. Intervalele unei excepții trebuie să rămână în aceeași zi; împarte o excepție nocturnă în două date. Excepția elimină și prelungirea programului săptămânal din acea zi în ziua următoare. Datele speciale se aplică și când programul săptămânal este dezactivat. Pauza manuală are în continuare prioritate.
Câmpul schedule al unui produs folosește intervale săptămânale în același fus orar: null înseamnă fără restricție proprie; [] înseamnă indisponibil toată săptămâna. Programul produsului poate doar restricționa disponibilitatea, nu poate redeschide restaurantul sau reface stocul. Folosește accepting_orders și available pentru decizia curentă; gateway-ul verifică din nou regulile la trimiterea comenzii. Aceste setări se pot schimba fără o revizie nouă a meniului.
Procesează connection.settings_changed pentru a actualiza programul, excepțiile de sărbători, fusul orar și timpul de preparare chiar dacă restaurantul rămâne deschis.
Păstrează revizia împreună cu coșul
Salvează revision cu coșul și trimite-o drept menu_revision în comandă. O revizie nouă înseamnă că prețurile sau catalogul s-au schimbat.
Dacă trimiți o revizie învechită, gateway-ul întoarce 409 menu_changed. Preia meniul, reconstruiește coșul și cere clientului să confirme orice schimbare de preț. Reîncercarea unei comenzi deja trimise este diferită: păstrează prețurile inițiale, deci retrimite-o fără modificări (vezi protocolul de reîncercare).
Înregistrează webhook-urile pentru meniu pentru actualizare automată după publicare sau schimbarea disponibilității produselor/opțiunilor. Recitește meniul conexiunii la menu.published sau menu.availability_changed; datele evenimentului cer reîmprospătarea, nu conțin catalogul. Reverifică disponibilitatea înainte de finalizarea comenzii și după notificări pierdute.
Verifică disponibilitatea înainte de finalizare
În Retail → Disponibilitate produse, personalul poate activa sau opri produse și opțiuni separat pentru fiecare punct de vânzare Website conectat, inclusiv în masă. Salvarea trimite automat o actualizare a disponibilității în fundal; nu este necesară o nouă publicare a meniului. Setările locale și ale celorlalte platforme rămân independente. Regulile de stoc și opțiuni obligatorii se aplică în continuare. Punctul de vânzare trebuie să aibă un meniu publicat înainte de editarea produselor aici.
| Câmp | Ce trebuie să faci |
|---|---|
accepting_orders | Când este false, dezactivează finalizarea pentru momentul evaluat. Pentru comenzi programate, citește meniul cu fulfillment_at pentru ora aleasă; închiderea din prezent nu exclude un interval viitor valid. |
fulfillment | Sunt acceptate ambele modalități: pickup și delivery. |
available | Când este false pentru un produs, o variantă sau o opțiune, afișeaz-o ca epuizată și nu permite selectarea ei. |
minimum / maximum | Numărul de opțiuni diferite pe care clientul trebuie, respectiv poate să le aleagă într-un grup. |
Acești indicatori se schimbă fără o revizie nouă: disponibilitatea urmărește stocul restaurantului aproximativ o dată pe minut, iar pauzele și programul se aplică imediat. Preia din nou meniul chiar înainte de finalizare și tratează totuși un eventual conflict dacă între timp se epuizează ceva.
Calculează în bani întregi
Toate sumele sunt numere întregi în bani: 3700 înseamnă 37.00 RON. Calculează cu întregi și formatează zecimalele doar pentru afișare.
unit = base price - published discount + base deposit + packaging
+ sum(extra prices + extra deposits)
+ sum(selected bundle deposits)
order total = sum(unit × quantity) - checkout_discount.amount + tip
+ (delivery_fee if fulfillment is delivery, otherwise 0)
- Pentru un produs cu
variants, câmpurileprice,discountșidepositale variantei identificate le înlocuiesc pe cele ale produsului. - Ambalajul se taxează per unitate. Restaurantul adaugă articolul de ambalaj pe bon; nu adăuga o linie proprie pentru el.
- Taxa de livrare se aplică o singură dată pe comandă, niciodată pentru ridicare.
Câmpul total este verificat: gateway-ul îl recalculează și întoarce 409 total_mismatch dacă valorile diferă. Nu trimite prețuri pe linii. Dacă checkout_discount lipsește, reducerea este zero. Cupoanele website-ului folosesc checkout_discount, descris în ghidul coșului. Ghidul coșului conține o funcție testată care face acest calcul.
Cum se publică meniul
Restaurantul publică meniul din Nexus Retail (Retail Admin → Integrări → POS → Website), cu suport pentru ridicare și livrare. Tu doar citești meniul publicat; nu trebuie să apelezi nimic când acesta se schimbă.
- Fiecare publicare înlocuiește întregul meniu cu o revizie nouă.
- Meniul curent rămâne disponibil în timpul publicării celui nou.
- Produsele pe care restaurantul nu le poate vinde în acea locație sunt publicate cu
available: false. - Dacă
GETîntoarce404 menu_not_published, cere restaurantului să publice meniul.