Nexus Gateway
EnglishRomână
OpenAPI

Un răspuns lent nu trebuie să producă o a doua comandă. Păstrează un ID și un corp de cerere persistente pentru fiecare achiziție și diferențiază o eroare de validare cunoscută de un rezultat incert.

Protocolul de reîncercare

Aceeași achiziție. Aceeași conexiune. Același ID. Același corp. După expirarea timpului de răspuns, un răspuns pierdut sau 503, comanda inițială poate exista deja în Retail. Un ID nou poate crea un duplicat.
  1. Înainte de prima trimitere, salvează atomic conexiunea, external_order_id și cererea completă într-o coadă persistentă de ieșire.
  2. La 200 sau 201, salvează confirmarea primirii. Folosește GET pentru starea curentă.
  3. La o eroare de rețea sau 503, păstrează cererea ca neconfirmată și reîncearcă fără modificări. Respectă Retry-After; gateway-ul trimite 5 secunde în răspunsurile 503.
  4. Folosește intervale de reîncercare exponențiale, limitate, cu variație aleatorie. Păstrează cererea după expirarea ferestrei de reîncercare și semnaleaz-o pentru reconciliere; nu o elimina tacit.
  5. Alte erori neașteptate ale serverului/proxy-ului pot avea și ele rezultate incerte. Păstrează identitatea inițială și investighează sau reîncearcă potrivit politicii tale de recuperare.
saved = persist_once(purchase, connection, external_order_id, full_request)

send saved.request to saved.connection
if response is 200 or 201:
    mark intake confirmed
    handle signed webhook updates
    reconcile with GET after gaps; poll only without webhooks
else if response is 429:
    retry saved.request after Retry-After plus jitter
else if timeout, network failure, or 503:
    keep unconfirmed
    retry saved.request after backoff
else:
    apply the error-specific recovery below

never create another purchase ID just because a response was lost

Gateway-ul rezervă persistent conținutul validat înainte de trimitere. Reîncercările identice refolosesc starea inițială chiar și după modificarea meniului sau închidere. După rezervare, ID-ul nu poate fi folosit pentru alt coș, client, referință de plată sau observație. Nu există un antet de idempotență configurabil; identitatea este external_order_id.

Răspunsuri HTTP și structura corpului

HTTPSemnificațieAcțiune
400connection_requiredSelectează o conexiune activată din lista de conexiuni și include ID-ul în rută. Nu s-a creat nicio comandă.
404connection_not_foundConexiunea selectată nu este disponibilă pentru această cheie de tenant. Actualizează lista; nu muta niciodată o comandă cu rezultat incert la alt POS.
401Cheie absentă, invalidă sau cu rol greșit.Verifică credențialele și mediul. Repetarea unei chei invalide nu ajută.
404Meniu nepublicat sau ID de comandă necunoscut acestei conexiuni.Verifică resursa și conexiunea; contactează restaurantul pentru publicarea meniului.
409Conflict cu regulile de business.Citește error și folosește tabelul de mai jos.
413Corpul depășește 4 MiB.Redu dimensiunea cererii.
422Validarea schemei sau a condițiilor a eșuat.Corectează câmpurile. Nu reîncerca o cerere invalidă fără modificări.
429Limita de cereri a fost depășită.Așteaptă secundele din Retry-After, adaugă o întârziere aleatoare și repetă ID-ul și corpul inițial. Vezi Limite de cereri mai jos.
503Retail sau stocarea nu sunt disponibile; rezultatul trimiterii este neconfirmat.Respectă Retry-After. Reîncearcă folosind ID-ul și corpul inițiale.

Citește codul din error sau detail. Autentificarea și resursele negăsite folosesc de obicei detail; conflictele de preț folosesc error. Verificările eligibilității acțiunilor pot întoarce oricare dintre forme, deci tratează-le pe ambele. Validarea include căi și tipuri de câmp fără a repeta datele clientului.

{ "error": "total_mismatch" }
{ "detail": "invalid_credentials" }
{
  "error": "invalid_request",
  "fields": [{ "path": ["body", "total"], "type": "int_type" }]
}
{ "error": "retail_unavailable", "retry_same_order_id": true }

storage_unavailable este tot un 503, cu {"error":"storage_unavailable"} și aceleași recomandări de reîncercare. Păstrează identitatea inițială chiar dacă retry_same_order_id lipsește. Proxy-urile inverse pot întoarce erori non-JSON; tratează starea HTTP și erorile de transport înainte de a interpreta corpul JSON.

Coduri de conflict

CodRecuperare
menu_not_publishedCere restaurantului să publice meniul; citirea meniului folosește 404, trimiterea comenzii folosește 409.
menu_changedActualizează meniul și reconfirmă coșul cu clientul.
restaurant_closedDezactivează finalizarea comenzilor noi. Nu ocoli închiderea folosind altă conexiune.
product_unavailableActualizează meniul și elimină/înlocuiește produsul indisponibil cu acordul clientului.
unknown_modifierFolosește ID-urile de grup și opțiune din produsul selectat.
duplicate_modifierTrimite fiecare pereche grup/opțiune o singură dată pe linie.
variant_unavailableSelectează o combinație de variantă exactă, publicată și disponibilă.
modifier_selection_invalidRespectă numărul minim și maxim de selecții al fiecărui grup.
modifier_unavailableAlege o opțiune disponibilă după actualizarea meniului.
total_mismatchRecalculează în bani întregi prețul variantei, promoțiile publicate, cuponul, garanțiile, extra, ambalajele, bacșișul și taxa de livrare.
order_id_already_usedAcest ID a fost rezervat cu alt conținut. Recuperează cererea inițială salvată; investighează înainte de a crea o achiziție cu adevărat nouă.
publication_supersededDoar pentru publicarea internă: a sosit deja o publicare mai nouă sau această generație a fost folosită cu alt conținut. Păstrează cea mai recentă publicare din coadă.
revision_already_usedDoar pentru publicare: modificarea conținutului meniului necesită o revizie nouă.

O cerere respinsă la validarea inițială nu este rezervată. Poți corecta cererea pentru aceeași achiziție. Dacă a existat anterior o încercare cu rezultat incert, reconciliază mai întâi corpul inițial; nu presupune că un conflict ulterior a șters comanda anterioară.

Furnizează date utile pentru diagnosticare

Pentru asistență, furnizează mediul, ID-ul conexiunii din URL, ID-ul extern al comenzii, data și ora, endpointul, starea HTTP și codul erorii. Elimină cheile, antetele de autorizare, numele, telefoanele, adresele și detaliile de plată ale clienților. Nu înregistra corpuri complete de cereri sau excepții din sistemele destinație.

  • scheduled_time_unavailable: Trimite un marcaj temporal valid cu offset de fus orar explicit.
  • cancellation_not_allowed: Comanda este în afara intervalului de anulare de către client sau nu mai are o stare eligibilă. Comenzile imediate trebuie să aștepte acceptarea; cele programate acceptate trebuie să aștepte prepararea și să fie strict înaintea orei salvate de începere. Citește starea și contactează restaurantul. Existența unui bon nu blochează singură anularea unei comenzi programate altfel eligibile.
  • cancellation_conflict: A fost confirmată o altă anulare. Reconciliază folosind starea comenzii.

Actualizarea livrării

delivery_update_not_allowed: modalitate de primire sau stare incompatibilă; citește starea curentă înainte de a reîncerca. delivery_update_conflict: ID-ul cererii aparține deja altui corp. delivery_update_limit: comanda a ajuns la 100 de actualizări distincte ale livrării. Aceste erori întorc 409.

Rapoarte de rambursare

refund_report_not_allowed: comanda inițială nu era plătită online. refund_report_conflict: ID-ul cererii sau referința procesatorului a fost reutilizată. refund_amount_exceeded: suma depășește totalul comenzii sau suma rămasă rambursabilă. refund_report_limit: există deja 100 de rapoarte. Toate întorc 409; nu efectua o nouă rambursare doar pentru a rezolva o eroare de raportare.

tips_unavailable (409): meniul publicat nu permite bacșișuri pentru personal. Elimină bacșișul doar cu acordul clientului și recalculează înainte de trimiterea unei noi achiziții.

invalid_checkout_discount: Produse eligibile necunoscute sau repetate, ori sumă peste prețurile eligibile. Corectează cuponul înainte de trimiterea unei comenzi noi.

Urmărirea cererilor

Răspunsurile gateway-ului pentru cererile /v1/ procesate includ X-Request-ID. Păstrați acest antet împreună cu ID-ul conexiunii și ID-ul extern al comenzii când raportați o problemă. Fiecare încercare HTTP primește un ID nou, inclusiv reîncercările; acesta nu este o cheie de idempotență. La reîncercare, păstrați ID-ul extern și corpul original al cererii. O eroare de rețea sau un răspuns generat de proxy poate să nu conțină un ID de cerere.

Limite de cereri

Gateway-ul aplică direct limitele, pentru toate procesele care folosesc aceeași bază de date locală. Pentru fiecare tenant, citirile website (GET/HEAD/OPTIONS) se reîncarcă la 600 de cereri/minut, cu un vârf de 100; scrierile la 120/minut, cu un vârf de 30. Toate punctele de vânzare împart aceste bugete. Publicarea din Retail are un buget separat per tenant de 120/minut, cu un vârf de 30. Înlocuirea cheii nu resetează bugetele tenantului.

Toate cererile /v1/ împart și un buget de intrare de 6.000/minut, cu un vârf de 1.000, inclusiv cererile cu autentificare invalidă sau conținut incorect. Verificarea are loc înainte de citirea corpului cererii. Bugetele se reîncarcă permanent, nu la începutul fiecărui minut. Documentația, verificările de sănătate și livrările webhook nu sunt incluse. Limitele se păstrează la repornire; bazele de date independente nu împart contoarele.

Cererile peste limită primesc 429, {"error":"rate_limit_exceeded"} și Retry-After în secunde. Așteaptă cel puțin atât, adaugă o întârziere aleatoare, apoi repetă aceeași cerere cu ID-ul original al comenzii/cererii și același corp. O încercare limitată nu este trimisă către Retail. Alt client poate consuma următorul token, deci și reîncercarea poate primi 429. Folosește webhook-uri pentru actualizări și evită interogările frecvente. Dacă stocarea limitatorului nu este disponibilă, cererile sunt blocate cu 503 și Retry-After: 5.

Nexus GatewayAPI pentru comenzi website · v1.0.0

Tastează pentru a căuta în ghidurile de integrare.