Skip to main content
Storefront API v1 to publiczne API, z którego korzysta strona sklepu w przeglądarce. Nie wymaga klucza i nie przyjmuje sekretów — sklep jest identyfikowany po shopId albo domenie. Odpowiedzi są cache’owane na CDN, a CORS pozwala na zapytania z domen sklepu i adresów podglądu.
Na stronie używaj SDK — createStorefront() sam ustawia shopId, adres API i język. Surowe endpointy przydają się w innych językach i do debugowania.

Endpointy

Adres bazowy: https://itemshop.dev/api/v2/storefront/v1

Przykład: lista produktów

Kasa

Odpowiedź
Zasady kasy:
  • Koszyk to 1–20 pozycji w items; więcej to 400 CART_TOO_LARGE. Jedna pozycja = zwykłe zamówienie. Dwie lub więcej = grupa płatności: jedna transakcja u operatora na sumę, a wewnątrz osobne zamówienie na pozycję. Odpowiedź ma wtedy groupId i orderIds[], a orderId i orderNumber wskazują grupę. Kod rabatowy liczy się raz na cały koszyk, a limity min/maks metody płatności liczą się od sumy.
  • Nick lub e-mail: w sklepie typu game wymagany jest nick (3–16 znaków a-zA-Z0-9_, inaczej NICK_REQUIRED); w sklepie ogólnym — email (inaczej EMAIL_REQUIRED). Produkt z dostawą cyfrową (deliveryKind inne niż commands) zawsze wymaga email, także w sklepie game.
  • Zgody są wymagane: terms (regulamin) i immediateDelivery (połączona zgoda na natychmiastową dostawę i utratę prawa odstąpienia) oraz legalVersion — wersja dokumentów z GET /shops/:shopIdOrDomain, które pokazałeś kupującemu. Gdy sklep zmieni regulamin, kasa zwróci LEGAL_DOCUMENTS_CHANGED — pobierz sklep ponownie i pokaż nowe dokumenty.
  • Idempotency-Key (np. UUID) jest wymagany. Ponowienie z tym samym kluczem nie utworzy drugiego zamówienia.
  • returnUrl musi wskazywać domenę sklepu lub adres podglądu (inaczej RETURN_URL_NOT_ALLOWED). Po płatności kupujący wraca na ten adres z parametrami ?itemshop_order=<numer>&itemshop_key=<klucz statusu> (fragment #… jest usuwany) — odczytaj je z location.search i pobierz status po numerze i kluczu. W produkcji adresy localhost, 127.0.0.1 i [::1] są odrzucane (także jako Origin). Bez returnUrl kupujący trafia na hostowaną stronę statusu sklepu.
  • Zamówienie darmowe (rabat 100%) ma free: true i redirectUrl prowadzący od razu do strony statusu.
  • Metoda płatności to code z /payment-methods — sklep może mieć kilka metod tego samego operatora.
  • Ochrona przed botami działa adaptacyjnie: nie blokuje zwykłych zakupów, a chronią ją też limit zapytań i blokada powtórzeń.
  • Strona nie przetwarza płatności — tylko przekierowuje na redirectUrl.

Błędy

Każdy błąd ma tę samą kopertę z maszynowym kodem code — po nim tłumacz komunikat w UI; pole error jest tylko dla dewelopera.

Realizacja vouchera

POST /shops/:shopId/vouchers/redeem z { code, nick } i opcjonalnie email (adres na treść cyfrową; także turnstileToken albo nagłówek cf-turnstile-response) zwraca { orderId, orderNumber, statusKey, status, productName, serverName, nick }. Voucher tworzy darmowe zamówienie dostarczane tak jak zwykły zakup.

Status zamówienia

GET /orders/by-number/:orderNumber/status?key=<statusKey> zwraca { orderId, orderNumber, shopId, status, productName, serverName, nick, amount, currency, createdAt, groupId, items[], delivery }. Numer może wskazywać zamówienie albo grupę; dla grupy status jest zbiorczy (może być partially_refunded), a items[] zawiera pozycje (orderId, orderNumber, status, productName, variant, quantity, serverName, amount). Zły lub brakujący klucz to 404 ORDER_NOT_FOUND. W sklepie ogólnym nick jest zamaskowanym e-mailem. statusKey (10 znaków) dostają zamówienia od 3.0 — wraca z kasy i vouchera oraz w adresie powrotu. Stary GET /orders/:orderId/status działa tylko dla zamówień sprzed 3.0.

Odbiór treści cyfrowej

Gdy delivery.ready w statusie jest true, pobierz treść: GET /orders/by-number/:orderNumber/delivery?key=<statusKey> (limit 20/min/IP, no-store). Odpowiedź to { orderNumber, items[] }, a pozycja ma kind (license_keys, download, text), state (pending, awaiting_stock, delivered, revoked), keys[], pendingUnits, text i download { url, fileName, expiresAt, maxDownloads, remaining, expired }. text wyświetlaj jako zwykły tekst, nie HTML. awaiting_stock z pendingUnits > 0 oznacza pustą pulę kluczy — klucze dojdą też e-mailem. Link download.url (GET /downloads/:token) zużywa jedno pobranie przy każdym otwarciu. Nieopłacone zamówienie to 409 ORDER_NOT_PAID, zwrot lub spór 410 DELIVERY_REVOKED. Konfiguracja po stronie sprzedawcy: Dostawa treści cyfrowych.

Widżety i prywatność

Właściciel może w ustawieniach sklepu wyłączyć dane publiczne (ostatnie zakupy, najwięksi kupujący, cel miesięczny, gracze online). Wyłączony widżet zwraca pustą listę dla wszystkich — strona powinna wtedy ukryć sekcję.

Cache i limity

  • Dane katalogu są cache’owane na CDN przez krótki czas — zmiana ceny w panelu pojawia się na stronie po chwili.
  • Kasa i vouchery mają limit zapytań na IP. Zobacz Błędy i limity.

SDK TypeScript

Wygodna warstwa nad tym API.

API z kluczem

Zarządzanie sklepem z serwera.