Preskočiť na obsah

Chyby a správy

Rozdiel medzi chybou protokolu a správou v odpovedi, úplný zoznam kódov a čo má klient pri každom urobiť.

Na tejto stránke

Volanie UCP v obchode na Monokaide sa môže pokaziť dvoma veľmi odlišnými spôsobmi. Buď sa požiadavka nedala spracovať vôbec — to je chyba protokolu s chybovým stavom HTTP — alebo sa spracovala a obchod má k výsledku čo povedať — to je správa v obyčajnej odpovedi 200. Táto kapitola ukazuje, ako odpovede rozlíšiť, a uvádza každý kód, ktorý API vracia, spolu s tým, čo má pri ňom urobiť váš klient.

Príklady používajú obchod https://shop.example.com a platformu, ktorej profil je na adrese https://platform.example.com/.well-known/ucp. Kedy a ako požiadavku zopakovať, podrobne opisuje kapitola Idempotencia, súbežnosť a limity.

Tri druhy odpovedí

DruhStav HTTPTeloPríklad
Chyba protokolu400–503{"code", "content", "continue_url"?} — bez objektu ucpNečitateľná hlavička UCP-Agent, znovu použitý Idempotency-Key, limit požiadaviek
Obchodná chyba200{"ucp": {…, "status": "error"}, "messages": […], "continue_url"} — bez zdrojaNeznámy košík, schopnosť, ktorú váš profil neuvádza, košík, do ktorého sa nedalo pridať nič
Zdroj so správami200, pri novom košíku alebo checkoute 201zdroj spolu s messages[]Checkout, ktorému ešte chýba doručovacia adresa, množstvo znížené na stav skladu

Dva ďalšie druhy odpovedí vôbec nie sú JSON v tvare UCP:

  • Vlastné stránky webového servera. Webový server pred obchodom niektoré situácie vybaví sám, skôr než požiadavku uvidí API, a odpovie HTML stránkou: obyčajné http://, telo nad 1 MiB, priveľa požiadaviek za sekundu, API nedostupné alebo príliš pomalé. Pozrite Odpovede, ktoré nie sú JSON.
  • Stránka odovzdania. continue_url je stránka pre prehliadač kupujúceho. API ju podáva na doméne obchodu ako HTML. Váš klient ju nikdy volať nemusí.

Ako ich rozlíšiť

Odpoveď kontrolujte v tomto poradí:

#KontrolaPotom je toČítajte
1Stav 304nezmenené — iba ak ste poslali If-None-MatchNič; vaša kópia je aktuálna. Odpoveď 304 nemá telo ani Content-Type.
2Content-Type nie je application/jsonstránka webového servera (alebo stránka odovzdania)Iba stav HTTP. Retry-After nepríde.
3Stav 400 alebo vyššíchyba protokolucode, pri 409, 429 a 503 aj Retry-After.
4Stav 200 a ucp.status je "error"obchodná chybamessages[0].code; odpoveď nemá id ani zdroj.
5Stav 200 alebo 201, bez ucp.statuszdrojZdroj a jeho messages.

Úspešná odpoveď ucp.status nikdy nemá: jeho absenciu čítajte ako úspech. Okrem 200 a 201 API žiadnu inú odpoveď 2xx nevracia a nikdy nepresmerováva (obyčajné http:// presmeruje na https:// webový server kódom 301; volajte rovno https://).

// Sort one UCP answer into the kinds above (Node 20+ fetch Response).
async function readUcp(res) {
  const retryAfter = Number(res.headers.get('retry-after')) || undefined;
  if (res.status === 304) return { kind: 'not_modified' };
  if (!(res.headers.get('content-type') ?? '').startsWith('application/json')) {
    // nginx's own HTML page: 413, 429, 502 or 504. Decide by the status alone.
    return { kind: 'web_server', status: res.status };
  }
  const body = await res.json();
  if (res.status >= 400) {
    return { kind: 'protocol_error', status: res.status, code: body.code,
             content: body.content, continueUrl: body.continue_url, retryAfter };
  }
  if (body.ucp?.status === 'error') {
    return { kind: 'business_error', code: body.messages[0].code,
             messages: body.messages, continueUrl: body.continue_url };
  }
  return { kind: 'resource', status: res.status, body, messages: body.messages ?? [] };
}

Chyby protokolu

Telo a hlavičky

Chyba protokolu má presne dva alebo tri kľúče:

KľúčTypVýznam
codereťazecJeden z kódov v tabuľkách nižšie. Rozhodujte sa podľa neho spolu so stavom HTTP.
contentreťazecAnglická veta pre vaše logy. Niektoré pomenúvajú, čo bolo odmietnuté: vety o poliach pri invalid_request a veta version_unsupported, ktorá uvádza vašu verziu. Ostatné sú pevné. content nikdy neparsujte a kupujúcemu ho neukazujte tak, ako je.
continue_urlreťazecIba pri chybách profilu platformy a pri limitoch jeho sťahovania: úvodná stránka obchodu, https://<primárna doména>/.

Každá chyba protokolu prichádza s Cache-Control: no-store. Retry-After v celých sekundách nesú tieto odpovede a žiadne iné:

OdpoveďRetry-After
409 idempotency_conflict, rovnaká požiadavka ešte beží2
429 rate_limited60
503 „Another request on this session is being processed — retry shortly“1
503 „Too many new platform profiles from this client, retry shortly“sekundy, ktoré zostávajú z aktuálneho minútového okna, aspoň 1
503 „Platform profile discovery is busy, retry shortly“10
503 „This shop is temporarily unavailable“60
JSONChyba protokolu: relácia je obsadená (503, Retry-After: 1)
{
  "code": "service_unavailable",
  "content": "Another request on this session is being processed — retry shortly"
}

Another request on the same cart or checkout is running and this one could not get its turn within 10 s, or 4 requests were already waiting (this request did not run) — or, rarely, another writer changed the session while this request ran (its result was not stored). The Idempotency-Key was released: retry the same request with the same key. Retry-After: 1. HTTP 503.

Kódy chýb protokolu sú invalid_profile_url, profile_unreachable, profile_malformed, version_unsupported, invalid_request, request_too_large, not_found, idempotency_conflict, rate_limited, service_unavailable a internal_error. Kód vyjednávania capabilities_incompatible medzi nimi nie je: prichádza ako obchodná chyba s HTTP 200.

Obchod, hostiteľ a cesta

HTTPcodecontentKedyOpakovať?Čo urobiť
404not_foundNo UCP business on this hostHostiteľ UCP neposkytuje: nie je vlastnou doménou obchodu s overeným DNS a aktívnym certifikátom, UCP je vypnuté, vstavaný obchod je vypnutý, kľúč obchodu je neaktívny alebo mu uplynula platnosť, alebo firma nemá zapnutý modul E-shop. Odpoveď zámerne nehovorí, ktorá príčina platí. Kontroluje sa pred UCP-Agent aj pred poľami tela, takže táto odpoveď príde aj na požiadavku bez UCP-Agent; skôr sa kontroluje iba limit požiadaviek a nečitateľné telo.NieOverte doménu s obchodníkom. Volajte hostiteľa z endpoint, ktorý zverejňuje profil obchodu.
404not_foundNot foundCesta alebo metóda pod /ucp/ neexistuje, napríklad POST /ucp/v1/nothing-here alebo DELETE /ucp/v1/catalog/search. Neznáma metóda je 404, nie 405.NieOpravte cestu alebo metódu.
503service_unavailableThis shop is temporarily unavailableObchod je na strane Monokaida pozastavený (firma, ktorej patrí, je deaktivovaná alebo zablokovaná) alebo sa obchod na chvíľu nepodarilo vyhľadať.Áno, po Retry-After (60 s)Skúste to niekoľkokrát. Ak to pretrváva, obchod je pozastavený: povedzte kupujúcemu, že obchod teraz nie je dostupný.

Chýbajúci košík, checkout alebo produkt nikdy nie je 404: je to obchodná chyba s HTTP 200.

Profil vašej platformy

Tieto chyby pochádzajú z hlavičky UCP-Agent a z profilu platformy, ktorý uvádza. Všetky nesú continue_url na úvodnú stránku obchodu. Každá požiadavka prechádza kontrolami v tomto poradí: hlavička, stiahnutie profilu, verzia a nakoniec vyjednávanie schopností.

HTTPcodecontentKedyOpakovať?Čo urobiť
400invalid_profile_urlThe UCP-Agent header must carry profile="https://…"Hlavička chýba, je prázdna, má viac ako 4096 znakov alebo sa nedá rozobrať, člen profile nie je reťazec v úvodzovkách, alebo jeho URL porušuje pravidlo: nie je https://, má viac ako 1000 znakov, obsahuje medzeru, používateľské meno alebo heslo, alebo chýba hostiteľ.NiePosielajte UCP-Agent: profile="https://platform.example.com/.well-known/ucp".
424profile_unreachableUnable to fetch the platform profileObchodu sa váš profil nepodarilo stiahnuť: DNS, spojenie, TLS, viac ako 3 s bez dát alebo 5 s spolu, presmerovanie, iný stav ako 200 (aj 304), viac ako 256 KiB, alebo adresa, ktorá nie je verejná. Zlyhanie si obchod pamätá 60 s.Až po oprave hostingu a nie skôr ako o 60 sProfil podávajte so stavom 200, bez presmerovania, z verejnej adresy.
422profile_malformedThe platform profile is not a valid UCP profileTelo nie je JSON, nie je objekt, nemá objekt ucp, alebo ucp.version nie je reťazec v tvare YYYY-MM-DD. Obchod si to pamätá 60 s.Až po oprave dokumentuPodávajte profil UCP; pozrite Princípy a životný cyklus.
422version_unsupportedProtocol version <version> is not supported. This business supports version 2026-04-08.Platný profil, ktorého ucp.version nie je presne 2026-04-08 (staršia aj novšia).Až po zmene profilu. Obchod si ho stiahne znova, keď vyprší platnosť jeho kópie (váš max-age, 60 sekúnd až 1 hodina); prvá požiadavka potom ešte dostane odpoveď podľa starej kópie, kým sa nová sťahuje.Uveďte "version": "2026-04-08".
503service_unavailableToo many new platform profiles from this client, retry shortlyVáš klient (jedna adresa IPv4 alebo jedna sieť IPv6 /64) už v aktuálnom minútovom okne prinútil server obchodu stiahnuť 5 adries profilu, ktoré ešte nepoznal.Áno, po Retry-AfterPoužívajte jednu stálu adresu profilu. Každý iný reťazec URL — aj s iným query stringom — je nový profil.
503service_unavailablePlatform profile discovery is busy, retry shortlyServer obchodu v aktuálnom minútovom okne stiahol 60 neznámych profilov, pre všetkých klientov spolu.Áno, po Retry-After (10 s)Zopakujte. Profil, ktorý server už pozná, na tento limit nikdy nečaká.
JSONProfil platformy sa nedal stiahnuť (424)
{
  "code": "profile_unreachable",
  "content": "Unable to fetch the platform profile",
  "continue_url": "https://shop.example.com/"
}

A network error, a timeout, a redirect, any status other than 200, a body over 256 KiB, or a host resolving to a private address. Remembered for 60 s. HTTP 424.

Požiadavka

HTTPcodecontentKedyOpakovať?Čo urobiť
400invalid_requestveta, ktorá pomenúva pole (pozrite Všetky chyby polí)Pole, ktoré API používa, má nesprávny typ JSON alebo je mimo povolených hraníc. Neznáme polia sa ignorujú, nikdy sa neodmietajú.NieOpravte pole. Nič sa nevykonalo.
400invalid_requestIdempotency-Key is not validKľúč má viac ako 255 znakov alebo obsahuje niečo iné ako tlačiteľné znaky ASCII okrem medzery — aj hlavička poslaná dvakrát, ktorá dorazí spojená cez ", ".NiePosielajte jeden kľúč s 1–255 znakmi od ! po ~, napríklad UUID.
400invalid_requestThe request is not validTelo je ohlásené ako JSON, ale nie je to platný JSON, obsahuje iba medzery, alebo je to samotný reťazec, číslo, logická hodnota či null.NiePosielajte objekt JSON.
415invalid_requestThe request is not validContent-Type uvádza inú znakovú sadu ako UTF (charset=iso-8859-2), alebo Content-Encoding nie je ani identity, ani gzip, deflate či br.NiePosielajte Content-Type: application/json v UTF-8.
403invalid_requestThe request is not validZápis, ktorý nesie session cookie Monokaida (accessToken, refreshToken, platformAccessToken, platformRefreshToken) z cudzieho webového pôvodu. Klient na serveri ich nikdy neposiela.NieNeposielajte cookies.
400request_too_largeids holds at most 20 identifiersPOST /ucp/v1/catalog/lookup s viac ako 20 hodnotami v ids. Pozor na stav: 400, nie 413.NieRozdeľte požiadavku lookup na dávky po 20 hodnotách.
413request_too_largeRequest body too largeTelo, ktoré po rozbalení prekročí limity API: 2 MiB pri JSON, alebo telo vo formáte formulára (application/x-www-form-urlencoded) nad 100 KiB alebo s viac ako 1 000 poľami. Telo, ktoré má už pri odoslaní viac ako 1 MiB, odmietne skôr webový server (vlastnou HTML odpoveďou 413), takže túto odpoveď JSON 413 dostane telo JSON iba vtedy, keď je poslané komprimované (Content-Encoding) a rozbalí sa na viac ako 2 MiB.NiePosielajte JSON a telá držte malé: 100 položiek má niekoľko kilobajtov.

Polia sa kontrolujú, až keď sa relácia nájde a je otvorená. PUT neznámej, dokončenej, zrušenej alebo odovzdanej relácie dostane odpoveď tejto relácie — not_found, checkout_completed, checkout_canceled alebo handed_off — s HTTP 200, bez toho, aby sa jej polia čítali (skôr sa odmietne iba telo, ktoré nie je objektom JSON). Taká odpoveď nehovorí nič o tom, či bolo vaše telo platné.

Každé telo posielajte s Content-Type: application/json. Telo poslané ako text/plain, ako iný typ +json alebo bez Content-Type sa nečíta: vyhľadávanie v katalógu potom prebehne ako prázdne vyhľadávanie a na lookup, detail produktu aj každé vytvorenie alebo PUT košíka či checkoutu obchod odpovie 400 request must be an object. Telo vo formáte formulára (application/x-www-form-urlencoded) sa spracuje, no každá hodnota v ňom príde ako reťazec, takže číselné pole, napríklad quantity alebo pagination.limit, sa odmietne s 400 invalid_request. Nepoužívajte ho.

Idempotencia a súbežnosť

HTTPcodecontentKedyOpakovať?Čo urobiť
409idempotency_conflictThis Idempotency-Key was used for a different requestKľúč ste už použili — v tomto obchode s touto adresou profilu — pre inú operáciu, iné id v ceste alebo iné telo.NieChyba vo vašom klientovi: každý logický zápis potrebuje nový kľúč.
409idempotency_conflictA request with this Idempotency-Key is still being processedPrvá požiadavka s týmto kľúčom a rovnakým telom ešte neskončila.Áno, po Retry-After (2 s)Pošlite tú istú požiadavku s tým istým kľúčom znova. Dostanete uloženú odpoveď.
503service_unavailableAnother request on this session is being processed — retry shortlyNa tom istom košíku alebo checkoute bežala iná požiadavka a táto sa do 10 s nedostala na rad, alebo za ňou už čakali štyri požiadavky. Nič sa nevykonalo a kľúč sa uvoľnil. Zriedkavo táto odpoveď znamená, že reláciu počas tejto požiadavky zmenil iný zapisovateľ; relácia sa potom neaktualizovala.Áno, po Retry-After (1 s)Zopakujte tú istú požiadavku s tým istým kľúčom. Na jednu reláciu posielajte naraz jednu požiadavku.

Prvé 409 má jednu zriedkavú druhú príčinu: dve kópie tej istej požiadavky sa predbiehali, prvá zlyhala a uvoľnila kľúč práve vtedy, keď ho druhá hľadala. Ak ste si istí, že obe kópie boli rovnaké, ďalší pokus s tým istým kľúčom požiadavku vykoná.

Limity a zlyhania

HTTPcodecontentKedyOpakovať?Čo urobiť
429rate_limitedToo many requestsVaša IP adresa prekročila limit operácie: 600 za minútu pri čítaní, 300 pri zápisoch, 60 pri cestách odovzdania, počítané pre každú operáciu zvlášť a naprieč všetkými obchodmi na Monokaide.Áno, po Retry-After (60 s)Spomaľte; pozrite Limity požiadaviek.
500internal_errorUnexpected server errorČokoľvek neočakávané. Podrobnosti sa zapíšu do logu na serveri a nikdy sa neposielajú. Zápis, ktorý zlyhal, uvoľnil svoj Idempotency-Key.Niekoľkokrát, s rastúcim odstupomČítanie opakujte bez zmeny, zápis s tým istým kľúčom. Ak sa to opakuje, nahláste to.
JSONLimit operácie prekročený (429)
{
  "code": "rate_limited",
  "content": "Too many requests"
}

More than the operation’s per-minute limit from your IP (600 reads, 300 writes, 60 handoff). Retry-After: 60. HTTP 429.

Všetky chyby polí

content chyby 400 invalid_request je jedna z týchto viet. <i> je index v poli, ktoré ste poslali; <field> je názov textového poľa.

contentKedy
request must be an objectTelo, ktoré nie je objekt JSON (napríklad pole), alebo telo poslané bez Content-Type: application/json (s iným typom alebo úplne bez neho) — pri operácii lookup, detaile produktu a pri každom vytvorení alebo PUT košíka či checkoutu. Prázdne telo poslané ako application/json sa prečíta ako {} a namiesto toho dostane chybu prvého poľa, ktoré mu chýba.
<path> must be an objectline_items[<i>], line_items[<i>].item, buyer, context, fulfillment, fulfillment.methods[<i>], fulfillment.methods[].destinations[<i>], fulfillment.methods[].groups[0], discounts, filters, filters.price alebo pagination s iným typom JSON. fulfillment a discounts sa čítajú iba pri vyjednanom príslušnom rozšírení; inak sa ignorujú bez ohľadu na ich tvar.
<path>.<field> must be a stringTextové pole s iným typom JSON, napríklad buyer.email must be a string, context.language must be a string, request.query must be a string, fulfillment.methods[].destinations[0].postal_code must be a string.
line_items must be an arrayVytvorenie alebo PUT košíka bez line_items (PUT košíka ich potrebuje vždy) a vytvorenie checkoutu bez použiteľného cart_id.
line_items holds at most 100 entriesViac ako 100 položiek.
line_items[<i>].item.id is requiredPoložka bez item.id, s prázdnym alebo s takým, ktoré nie je reťazec.
line_items[<i>].quantity must be a positive integer0, záporné číslo, desatinné číslo alebo reťazec ako "2". Chýbajúce množstvo znamená 1.
fulfillment.methods must be an arrayfulfillment.methods, ktoré nie je pole.
fulfillment.methods[].destinations must be an arraydestinations, ktoré nie je pole.
fulfillment.methods[].destinations[<i>].address_country is not a recognised country; send an ISO 3166-1 alpha-2 code such as "SK"Krajina zvolenej adresy nie je kód ISO alpha-2 ani alpha-3, ani názov krajiny, ktorý obchod pozná. Kontroluje sa iba zvolená adresa: tá, ktorú uvádza selected_destination_id, inak prvá.
discounts.codes must be an arraydiscounts.codes, ktoré nie je pole.
discounts.codes holds at most 10 codesViac ako 10 kódov, počítaných tak, ako ste ich poslali (pred odstránením prázdnych a duplicitných).
pagination.cursor is not validKurzor, ktorý toto API nevydalo, alebo dlhší ako 40 znakov.
pagination.limit must be a positive integer0, záporné číslo, desatinné číslo alebo reťazec.
filters.price.min must be a non-negative integer, filters.price.max must be a non-negative integerHranica ceny, ktorá nie je celé číslo v najmenších jednotkách alebo je záporná.
filters.categories must be an array of stringsfilters.categories, ktoré nie je zoznam reťazcov.
filters.categories is not supported by this shop; search by query (and filters.price) insteadFilter kategórií s akoukoľvek hodnotou vo vyhľadávaní, v operácii lookup aj v detaile produktu. Prázdny zoznam sa číta ako žiadny filter.
ids must be a non-empty arrayPožiadavka lookup bez ids alebo s prázdnym zoznamom.
id is requiredPožiadavka na produkt bez id alebo s prázdnym.
Idempotency-Key is not validPozrite Idempotencia a súbežnosť.
The request is not validPoškodený JSON, nepodporovaná znaková sada alebo kódovanie (415), odmietnutý zápis z cudzieho pôvodu (403).

Čo sa namiesto odmietnutia upraví

Niektoré hodnoty API upraví bez chyby. Porovnajte, čo ste poslali, s odpoveďou:

PošleteDostanete
Množstvo nad 999 v jednej položke999, bez správy. Viac položiek s tým istým variantom sa sčíta; súčet nad 999 sa zníži s varovaním quantity_adjusted.
pagination.limit nad 2020 výsledkov na stranu.
query dlhší ako 200 znakovHľadá sa prvých 200 znakov.
Textové pole dlhšie ako jeho limit (mená 100, e-mail 254, telefón 40, ulica 255, mesto 100, PSČ 20 znakov)Pole skrátené na túto dĺžku. Riadiace znaky sa zmenia na medzery, neviditeľné formátovacie znaky sa odstránia.
context.language, context.currency alebo context.address_country, ktorý API nevie prečítaťHodnota sa zahodí. Pre jazyk potom platí vaša hlavička Accept-Language, inak prvý jazyk obchodu.
Viac ako 10 položiek v fulfillment.methods alebo v destinations jedného spôsobuPrečíta sa iba prvých 10.
selected_option_id, ktoré nie je reťazec, alebo prázdneIgnoruje sa: uložená možnosť zostane vybraná. (null ju zruší.)
selected_destination_id, ktoré nie je reťazec alebo neurčuje žiadny cieľIgnoruje sa: použije sa prvý cieľ doručenia.
groups, ktoré nie je poleIgnoruje sa, ako keby groups chýbalo.
id položky akéhokoľvek typuIgnoruje sa: položky sa párujú podľa item.id.
Id v požiadavke lookup, ktoré nie je reťazec alebo je duplicitnéVynechá sa.
Pole, ktoré API nepoznáIgnoruje sa.

Obchodné chyby

Obchodná chyba je odpoveď HTTP 200, ktorej ucp.status je "error". Nevracia žiadny zdroj — žiadne id, žiadne položky — iba messages s jednou správou a continue_url:

JSONNeznámy, zrušený alebo vypršaný košík (HTTP 200)
{
  "ucp": {
    "version": "2026-04-08",
    "status": "error",
    "capabilities": {
      "dev.ucp.shopping.cart": [
        {
          "version": "2026-04-08"
        }
      ],
      "dev.ucp.shopping.discount": [
        {
          "version": "2026-04-08"
        }
      ]
    }
  },
  "messages": [
    {
      "type": "error",
      "code": "not_found",
      "content": "Cart not found or has expired",
      "severity": "unrecoverable"
    }
  ],
  "continue_url": "https://shop.example.com/"
}

Any cart operation on an id that is not a UUID, belongs to another shop, or names a canceled or expired cart. HTTP 200.

codecontentOperáciecontinue_urlČo urobiť
capabilities_incompatibleThe platform and this business share no version of the capability this operation needsKaždá operácia /ucp/v1, ktorej koreňovú schopnosť váš profil neuvádza vo verzii 2026-04-08. Každá operácia košíka a checkoutu v obchode v katalógovom režime. Nič sa nevykoná a žiadny Idempotency-Key sa nepoužije.Úvodná stránka obchoduDoplňte schopnosť do profilu. Pri obchode v katalógovom režime skončite pri katalógu a dajte kupujúcemu url produktu.
not_foundProduct not foundPOST /ucp/v1/catalog/product: id, ktoré obchod nezobrazuje.Úvodná stránka obchoduVyhľadajte znova.
not_foundCart not found or has expiredKaždá operácia košíka: id, ktoré nie je UUID, košík iného obchodu, zrušený alebo vypršaný košík, košík už vymazaný.Úvodná stránka obchoduVytvorte nový košík.
not_foundCheckout session not foundKaždá operácia checkoutu: id, ktoré nie je UUID, checkout iného obchodu, checkout už vymazaný; aj POST /ucp/v1/checkout-sessions s neznámym, zrušeným alebo vypršaným cart_id.Úvodná stránka obchoduVytvorte nový checkout. Zrušený alebo vypršaný checkout to nie je: naň obchod odpovie so status: "canceled".
out_of_stockAll requested items are currently out of stockVytvorenie košíka alebo checkoutu, prípadne prevod košíka, keď ste poslali položky a každá z nich je vypredaná. Relácia sa zahodí a nemá id.Úvodná stránka obchoduPonúknite iný tovar alebo katalóg prečítajte neskôr.
item_unavailableNone of the requested items can be bought in this shopTo isté, keď sa nedala pridať žiadna položka a dôvody boli rôzne: neznáme id, tovar, ktorý sa nedá objednať, vypredaný tovar — alebo iba vypredaný tovar, keď ste poslali aj zľavové kódy, ktorých odmietnutie sa počíta ako ďalší dôvod.Úvodná stránka obchoduOverte id variantov cez lookup v katalógu.
handed_offThe buyer continued on the shop: the items are in the shop’s cart — finish the purchase therePOST /ucp/v1/checkout-sessions s cart_id košíka, ktorý si kupujúci už odniesol do obchodu, alebo košíka, z ktorého si odniesol skorší checkout, ktorý už nie je otvorený. (Kým je checkout košíka ešte otvorený, odpoveďou je tento checkout, so 200.)Stránka košíka obchodu, https://<primárna doména>/cartNa tomto košíku už nestavajte. Ak kupujúci potrebuje svoj košík nájsť, dajte mu toto continue_url.

Každá obchodná chyba má závažnosť unrecoverable: tá istá požiadavka dostane tú istú odpoveď. Obchodná chyba pri zápise je výsledok ako každý iný, preto sa uloží s Idempotency-Key a pokus s tým istým kľúčom ju dostane znova — ak skúšate zmenenú požiadavku, použite nový kľúč.

Správy

Objekt správy

KľúčTypPrítomnýVýznam
type"error", "warning", "info"vždyerror: niečo blokuje alebo bolo odmietnuté. warning: niečo sa zmenilo alebo neuplatnilo a odpoveď už ukazuje výsledok. info: poznámka.
codereťazecvždyČo sa stalo. Kódy sú uvedené nižšie; kód, ktorý nepoznáte, posúďte podľa type a severity.
contentreťazecvždyPevná anglická veta; pri not_found v operácii lookup identifikátor, ktorý nič nenašiel.
pathreťazecpri niektorých kódochJSONPath do odpovede, v ktorej prišla, napríklad $.line_items[1].quantity alebo $.buyer.email. Položky odpovede idú v poradí obchodu, nie v poradí vašej požiadavky.
severity"recoverable", "requires_buyer_input", "unrecoverable"iba pri chybáchKto ju môže vyriešiť. Varovania a informačné správy závažnosť nemajú.

Kde sa messages objavuje:

Odpoveďmessages
CheckoutVždy, prípadne [].
KošíkIba keď je aspoň jedna správa.
Vyhľadávanie a lookup v katalóguIba keď je aspoň jedna správa.
Detail produktuNikdy; obchodná chyba má vlastné.
Obchodná chybaVždy jedna.

Závažnosť a čo od vás žiada

severityVýznamVáš ďalší krok
recoverableVaša platforma ju vyrieši ďalšou požiadavkou. Každá taká chyba drží checkout v stave incomplete.Pošlite v PUT to, na čo ukazuje path.
requires_buyer_inputVyriešiť ju môže iba kupujúci, na webe obchodu. Checkout v stave incomplete nedrží.Odovzdajte kupujúceho cez continue_url.
unrecoverableTáto požiadavka alebo táto relácia ďalej pokračovať nemôže.Skončite; ak chce kupujúci stále nakúpiť, začnite novú reláciu.
(žiadna — varovanie)Niečo sa upravilo alebo neuplatnilo; odpoveď ukazuje výsledok.Ukážte kupujúcemu nový stav alebo sa ho opýtajte, či to stále chce.
(žiadna — informácia)Poznámka, ktorá nič nemení.Nič, prípadne ju zapíšte do logu.

Stav checkoutu vyplýva z jeho správ: akákoľvek správa error so závažnosťou recoverable z neho robí incomplete; inak je requires_escalation a nesie payment_required. Správy checkoutu idú v tomto poradí: správy k položkám, správy k zľavovým kódom, potom to, čo checkoutu chýba, a payment_required na konci.

Správy k položkám

Objavujú sa v košíku aj checkoute pri vytvorení a pri každom zápise, ktorý posiela line_items (aj keď zmena jazyka položky nanovo nacení). Sú iba v odpovedi na zápis, ktorý ich spôsobil: v tej odpovedi je položka už odstránená alebo znížená, takže ďalšie čítanie checkoutu môže vrátiť requires_escalation bez nich.

codetype / severitypathcontentKedyČo urobiť / čo ukázať kupujúcemu
item_unavailableerror / recoverabležiadnaItem <id> is not available in this shopitem.id nie je UUID — napríklad je to SKU — alebo nie je ani aktívnym variantom zverejneného produktu firmy, ani takým produktom (id produktu zastupuje jeho aktívny variant, ktorý vznikol najskôr). Vylučovacie filtre obchodu sa tu neuplatňujú. Položka sa vynechá.Vyhľadajte tovar v katalógu a použite id variantu. Povedzte kupujúcemu, že tento tovar sa tu nepredáva.
item_unavailableerror / recoverable$.line_items[<i>], kým je položka v odpovedi, inak žiadnaItem <id> cannot be bought right nowObchod odmietol položku pridať alebo zmeniť: nedá sa objednať, nemá cenu alebo na zmenu nie je dosť tovaru na sklade.Ponúknite iný variant alebo iný tovar.
vat_mix_not_allowederror / recoverableako vyššieItem <id>: this shop does not sell zero-VAT and VAT items in one orderObchod nepredáva tovar s DPH a bez DPH v jednej objednávke.Rozdeľte nákup na dve relácie.
out_of_stockerror / recoverabležiadna (položka z relácie odíde)Item <id> is out of stockŽiadny predajný sklad a variant nie je na predobjednávku. Položka sa odstráni.Povedzte kupujúcemu, že tovar je vypredaný; ponúknite náhradu.
quantity_adjustedwarning$.line_items[<i>].quantityOnly <n> available — quantity lowered from <m>Množstvo presiahlo sklad a znížilo sa na stav skladu. Varianty na predobjednávku sa neznižujú nikdy.Ukážte nové množstvo a opýtajte sa, či ho kupujúci stále chce.
quantity_adjustedwarning$.line_items[<i>].quantityAt most 999 of one item — quantity lowered from <m>Viac položiek s tým istým variantom dalo spolu viac ako 999.Ukážte nové množstvo.

<id> je item.id tak, ako ste ho poslali (bez okrajových medzier). Správy o jednom variante — cannot be bought right now, vat_mix_not_allowed a out_of_stock — uvádzajú prvé id, ktoré ste pre daný variant poslali.

Správy k zľavovým kódom

Objavujú sa pri vyjednanom rozšírení zliav, pri každom vytvorení a PUT košíka či checkoutu vrátane prevodu košíka. Kódy sa skúšajú v poradí, v akom ste ich poslali, a uplatní sa prvý, ktorý obchod prijme.

codetypepathcontentKedyČo urobiť / čo ukázať kupujúcemu
discount_code_combination_disallowedwarning$.discounts.codes[<i>]Code '<code>' cannot be combined with '<applied code>'Kód za kódom, ktorý sa už uplatnil: na objednávku platí jeden kód.Povedzte kupujúcemu, že platí iba jeden kód.
discount_code_expiredwarning$.discounts.codes[<i>]Code '<code>' cannot be appliedObchod ako dôvod uvádza, že platnosť kódu skončila.Povedzte kupujúcemu, že kód už neplatí.
discount_code_user_ineligiblewarning$.discounts.codes[<i>]Code '<code>' cannot be appliedObjednávka nedosahuje minimálnu sumu objednávky, ktorú kód vyžaduje; porovnáva sa s medzisúčtom bez DPH pred odpočítaním zľavy.Povedzte kupujúcemu, že kód sa na túto objednávku nevzťahuje.
discount_code_invalidwarning$.discounts.codes[<i>]Code '<code>' cannot be appliedAkékoľvek iné odmietnutie: neznámy alebo vypnutý kód, kód, ktorý ešte nie je aktívny, kód s vyčerpaným počtom použití a každý kód v relácii, ktorá ešte nikdy nemala položku.Požiadajte kupujúceho, aby kód skontroloval.

V relácii, z ktorej sa odstránili všetky položky, sa kódy posudzujú voči súčtu 0: kód s minimálnou sumou objednávky dostane discount_code_user_ineligible a každý iný kód, ktorý obchod prijme, sa uplatní bez správy, no nič neodpočíta, takže discounts.applied zostane prázdne.

<i> sa počíta v zozname tak, ako ho API uchováva: bez duplicít (porovnaných bez ohľadu na veľké a malé písmená) a bez prázdnych kódov. Odmietnutý kód zostáva uložený a pri ďalšom zápise sa skúsi znova; ak ho chcete zahodiť, pošlite discounts.codes bez neho.

Pripravenosť checkoutu

Určuje sa nanovo pri každom vytvorení, PUT, GET a POST …/complete otvoreného checkoutu — keď si ho kupujúci odniesol do obchodu, opakuje sa namiesto toho posledná odpoveď pred odovzdaním. Správy k doručeniu sa objavujú iba pri vyjednanom rozšírení fulfillment.

codeseveritypathcontentKedyČo urobiť
missingrecoverable$.line_itemsThe checkout holds no itemCheckout nemá žiadnu položku.PUT s line_items.
missingrecoverable$.buyer.emailBuyer email is requiredChýba e-mail alebo to nie je e-mailová adresa.PUT celého buyer s platným email.
missingrecoverable$.fulfillment.methods[0].destinationsA shipping address is requiredEšte nie je zadaná adresa doručenia.PUT s adresou.
invalid_addressrecoverable$.fulfillment.methods[0].destinations[0]The shipping address needs street, city, postal code and countryAdrese chýba street_address, address_locality, postal_code alebo address_country.PUT s úplnou adresou.
address_undeliverablerecoverable$.fulfillment.methods[0].destinations[0]The shop does not ship to this addressAdresa je úplná, ale žiadny spôsob dopravy obchodu túto krajinu pre tento tovar neobsluhuje.Požiadajte kupujúceho o inú adresu; inak tu nakúpiť nemôže.
invalid_optionrecoverable$.fulfillment.methods[0].groups[0].selected_option_idThe selected shipping option is not offered for this checkoutZvolená možnosť sa už neponúka, napríklad po zmene krajiny. Relácia si vašu voľbu ponechá: odpoveď ukazuje selected_option_id: null a táto správa sa opakuje, kým nezvolíte ponúkanú možnosť.Zvoľte jednu z teraz ponúkaných options.
missingrecoverable$.fulfillment.methods[0].groups[0].selected_option_idChoose a shipping optionMožnosti existujú a žiadna nie je zvolená.Zvoľte možnosť.
pickup_point_requiredrequires_buyer_input$.fulfillment.methods[0].groups[0]The pickup point is chosen on the shop websiteZvolená možnosť je doručenie na výdajné miesto (Packeta). Neblokuje.Povedzte kupujúcemu, že miesto si vyberie v obchode.
payment_requiredrequires_buyer_inputžiadnaPayment is completed on the shop website — continue there to place the orderNezostala žiadna chyba recoverable: checkout je requires_escalation.Dajte kupujúcemu continue_url.

Uzavreté a odovzdané relácie

codetype / severitycontentKedyČo urobiť
checkout_completederror / unrecoverableThis checkout is already completedPUT alebo zrušenie dokončeného checkoutu. Nič sa nezmení. (GET alebo POST …/complete naň odpovie messages: [].)Skončite; objednávka je v order.
checkout_cancelederror / unrecoverableThis checkout is canceled or expired — start a new onePUT, POST …/complete alebo zrušenie zrušeného či vypršaného checkoutu. (GET naň odpovie messages: [].)Ak chce kupujúci stále nakúpiť, vytvorte nový checkout.
handed_offwarningThe buyer continued on the shop: the items are in the shop’s cart now and this session is no longer changedPUT košíka alebo checkoutu, ktorý si kupujúci už odniesol do obchodu. Odpoveď je posledná odpoveď pred odovzdaním; vaša požiadavka sa neuplatnila.Prestaňte zapisovať; zisťujte stav checkoutu, kým nepríde objednávka.

Tieto správy môžu prísť aj na zápis, ktorý sa predbiehal s objednávkou alebo s uplynutím platnosti: odpoveďou je potom relácia tak, ako je teraz — uzavretá.

JSONZápis po odovzdaní kupujúcemu
{
  "ucp": {
    "version": "2026-04-08",
    "capabilities": {
      "dev.ucp.shopping.checkout": [
        {
          "version": "2026-04-08"
        }
      ],
      "dev.ucp.shopping.fulfillment": [
        {
          "version": "2026-04-08"
        }
      ],
      "dev.ucp.shopping.discount": [
        {
          "version": "2026-04-08"
        }
      ]
    },
    "payment_handlers": {}
  },
  "id": "3d7b9e2a-6f14-4c58-9b3e-8a2f1c6d4e97",
  "buyer": {
    "email": "jana.novakova@example.com",
    "last_name": "Nováková",
    "first_name": "Jana",
    "phone_number": "+421 905 123 456"
  },
  "links": [
    {
      "url": "https://shop.example.com/obchodne-podmienky",
      "type": "terms_of_service",
      "title": "Obchodné podmienky"
    },
    {
      "url": "https://shop.example.com/ochrana-osobnych-udajov",
      "type": "privacy_policy",
      "title": "Ochrana osobných údajov"
    }
  ],
  "status": "requires_escalation",
  "totals": [
    {
      "type": "subtotal",
      "amount": 71880
    },
    {
      "type": "discount",
      "amount": -5844,
      "display_text": "JESEN10"
    },
    {
      "type": "fulfillment",
      "amount": 490
    },
    {
      "type": "total",
      "amount": 66526
    }
  ],
  "context": {
    "language": "sk",
    "address_country": "SK"
  },
  "currency": "EUR",
  "messages": [
    {
      "code": "payment_required",
      "type": "error",
      "content": "Payment is completed on the shop website — continue there to place the order",
      "severity": "requires_buyer_input"
    },
    {
      "type": "warning",
      "code": "handed_off",
      "content": "The buyer continued on the shop: the items are in the shop’s cart now and this session is no longer changed"
    }
  ],
  "discounts": {
    "codes": [
      "JESEN10"
    ],
    "applied": [
      {
        "code": "JESEN10",
        "title": "JESEN10",
        "amount": 5844,
        "method": "across"
      }
    ]
  },
  "expires_at": "2026-10-27T09:21:30.551Z",
  "line_items": [
    {
      "id": "f6a3c8e1-9d27-4b54-8e6a-2c1f7b9d3a58",
      "item": {
        "id": "1e8a6c4f-2b93-4d71-9f05-6a3c8e2b1d47",
        "price": 69900,
        "title": "Trek Marlin 5",
        "image_url": "https://shop.example.com/api/public/uploads/c4d1e5a2-8b3f-4a6c-9e07-5f2d8a1b3c40/products/trek-marlin-5-modra.webp"
      },
      "totals": [
        {
          "type": "subtotal",
          "amount": 69900
        },
        {
          "type": "total",
          "amount": 69900
        }
      ],
      "quantity": 1
    },
    {
      "id": "2e9d5b7a-4c83-4f16-a9b2-6d8e1c3f7a49",
      "item": {
        "id": "b5f81c3d-6e49-4a2b-8d73-9c0e4f1a6b25",
        "price": 990,
        "title": "Fľaša na vodu 750 ml"
      },
      "totals": [
        {
          "type": "subtotal",
          "amount": 1980
        },
        {
          "type": "total",
          "amount": 1980
        }
      ],
      "quantity": 2
    }
  ],
  "fulfillment": {
    "methods": [
      {
        "id": "shipping",
        "type": "shipping",
        "groups": [
          {
            "id": "default",
            "options": [
              {
                "id": "0c5e8a3f-7b21-4d96-8f4c-9e2a6d1b3c75",
                "title": "GLS kuriér",
                "totals": [
                  {
                    "type": "total",
                    "amount": 490
                  }
                ],
                "description": "Doručenie na adresu do 1–2 pracovných dní"
              },
              {
                "id": "6b2d9f4e-3a17-4c68-9d5b-1f8e3a7c2b40",
                "title": "Packeta – výdajné miesto",
                "totals": [
                  {
                    "type": "total",
                    "amount": 290
                  }
                ],
                "description": "Delivery in 2–3 business days"
              }
            ],
            "line_item_ids": [
              "f6a3c8e1-9d27-4b54-8e6a-2c1f7b9d3a58",
              "2e9d5b7a-4c83-4f16-a9b2-6d8e1c3f7a49"
            ],
            "selected_option_id": "0c5e8a3f-7b21-4d96-8f4c-9e2a6d1b3c75"
          }
        ],
        "destinations": [
          {
            "id": "destination",
            "last_name": "Nováková",
            "first_name": "Jana",
            "postal_code": "811 01",
            "street_address": "Hlavná 12",
            "address_country": "SK",
            "address_locality": "Bratislava"
          }
        ],
        "line_item_ids": [
          "f6a3c8e1-9d27-4b54-8e6a-2c1f7b9d3a58",
          "2e9d5b7a-4c83-4f16-a9b2-6d8e1c3f7a49"
        ],
        "selected_destination_id": "destination"
      }
    ]
  },
  "continue_url": "https://shop.example.com/ucp/continue/9bbd3dedf887f93c6287fa7f4b8de141501155714c3b2050bb83551e36ec780b"
}

A PUT after the buyer opened continue_url but before the order: the last answer, its values unchanged (served from storage, so its keys come in JSONB order), with its messages and a handed_off warning. The request was not applied. Only a PUT shows the handoff; a GET (and complete) returns the values of step 4.

Správy katalógu

codetypepathcontentKedyČo urobiť
price_filter_ignoredwarning$.filters.pricefilters.price is denominated in <currency>, prices are presented in <currency> and cannot be converted, so the price filter was not appliedVyhľadávanie alebo lookup s filters.price v mene context.currency, pre ktorú obchod nemá kurz. Vrátia sa všetky zhody.Výsledky prefiltrujte sami alebo pošlite hranice v mene odpovede.
not_foundinfožiadnasamotný identifikátor, napríklad trek-marlin-9Lookup: id, ktoré nenašlo žiadny produkt ani variant, ktorý obchod zobrazuje.Id vynechajte; ostatné výsledky platia.

Ako správy ukázať kupujúcemu

content je v angličtine a je písaný pre vývojárov. Text pre kupujúceho zostavte z code a path v jeho jazyku a content si nechajte pre logy. Každú správu pokryjú tri pravidlá:

  1. Chyby recoverable riešte sami tak, že pošlete to, na čo ukazuje path.
  2. Varovania ukážte ako zmenu, ktorú opisujú — „na sklade sú iba 2 kusy, množstvo sme znížili“ — pretože odpoveď už obsahuje zmenený stav.
  3. requires_buyer_input odovzdajte kupujúcemu spolu s continue_url.

Môžu pribudnúť ďalšie kódy. Neznámy kód posúďte podľa type a severity, nikdy kvôli nemu nezlyhajte.

Odpovede, ktoré nie sú JSON

Webový server

Webový server pred každým obchodom tieto situácie vybaví sám, skôr než požiadavku uvidí API. Telom je krátka HTML stránka, nie JSON.

HTTPKedyOpakovať?Čo urobiť
301Požiadavka na http://. Presmeruje sa na tú istú adresu s https://; klient, ktorý presmerovanie sleduje, môže z POST urobiť GET.—Volajte rovno https://.
413Telo požiadavky nad 1 MiB.NieTelá držte malé.
429Viac ako 100 požiadaviek za sekundu z vašej IP adresy, s nárazovou rezervou 200, počítané zo všetkej návštevnosti obchodov na webovom serveri. Bez Retry-After.Áno, s rastúcim odstupomRozložte požiadavky v čase; pozrite Limity požiadaviek.
502API nebeží alebo sa reštartuje.Áno, s rastúcim odstupomZápisy opakujte s tým istým Idempotency-Key.
504API neodpovedalo do 60 sekúnd. Zápis sa mohol vykonať.Áno, s rastúcim odstupomZápisy opakujte s tým istým Idempotency-Key: dostanete uloženú odpoveď, prípadne 409, kým ešte beží.
Limit webového servera (HTML)
<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>nginx</center>
</body>
</html>

nginx’s own page, above 100 requests/s per client IP (burst 200): one budget for everything that IP sends to any shop host Monokaido serves (UCP calls, pages, images) and to the storefront API. No Retry-After, not JSON. Back off and retry. The footer may carry nginx’s version.

Cesty, ktoré webový server do API neposiela — /UCP/… veľkými písmenami, /.well-known/ucp/ s lomkou na konci, /ucp bez zvyšku — skončia na webových stránkach obchodu a aj tie vrátia HTML. Používajte cesty presne tak, ako sú zverejnené.

Cesty odovzdania

continue_url (GET /ucp/continue/<token>) otvára prehliadač kupujúceho a jeho stránka sama posiela POST /ucp/continue/<token>. Váš klient nevolá ani jedno, no kupujúci vám tieto odpovede môžu nahlásiť:

CestaHTTPTeloKedy
GET200HTMLStránka odovzdania: presunie položky do košíka kupujúceho a pokračuje do obchodu.
GET410HTMLRelácia je dokončená, zrušená alebo vypršaná, alebo token nepatrí tomuto obchodu.
GET404HTML (prázdna stránka)Hostiteľ už UCP neposkytuje.
GET, POST429JSON rate_limitedViac ako 60 požiadaviek za minútu z IP adresy kupujúceho na danú cestu.
GET, POST503JSON service_unavailable, This shop is temporarily unavailableObchod je pozastavený alebo sa ho nepodarilo vyhľadať — alebo, iba pri POST, bola relácia obsadená vašimi požiadavkami.
GET, POST500JSON internal_errorNeočakávané zlyhanie.
POST200{"redirect": "/checkout"}, "/cart" alebo "/"Kam stránka prehliadač pošle ďalej.
POST400JSON invalid_request, The request is not validStránka neposlala použiteľné id košíka hosťa.
POST404JSON not_found, Not foundReláciu už nemožno odovzdať. (No UCP business on this host, keď hostiteľ UCP neposkytuje.)

Pri 5xx, 429 alebo prerušenom spojení stránka požiadavku zopakuje ešte dvakrát, po 1 a po 2 sekundách, a potom pošle prehliadač do pokladne, do košíka alebo na úvodnú stránku obchodu bez položiek. Ak vaša platforma zisťuje stav relácie, ktorú kupujúci práve otvára, majte rozpracovanú najviac jednu požiadavku, aby sa jeho požiadavka dostala na rad.

Čo zapisovať do logov

API nevracia žiadne id požiadavky. Pri každom volaní si zapíšte aspoň čas v UTC, hostiteľa, metódu a cestu, stav HTTP, code (alebo kódy správ) a vlastné korelačné id. Toto id posielajte aj ako X-Request-ID: webový server obchodu ho zapíše do svojho prístupového logu (späť ho nevracia), takže sa problém dá na strane Monokaida dohľadať. Nedávajte doň nič tajné. Id košíka a checkoutu sú prístupové údaje: nedávajte ich do logov, ktoré čítajú tretie strany — pozrite Bezpečnosť a ochrana údajov.