SpikePCAPI dla partnerówUKRUENPL

API dla partnerów organizacji (klucze API)

HTTP-API, którym zewnętrzny partner właściciela klubu czyta dane jego organizacji: kasa, system lojalnościowy, strona z rezerwacją online, własna witryna sieci. Klucz wydaje właściciel w panelu (sekcja Klucze API), on też decyduje, co klucz może i do kiedy działa.

To nie protokół stanowiska do gry (ten działa po WebSocket) ani API aplikacji mobilnej klienta — to osobne kontrakty. Nie ma tu sesji klienta ani logowania człowieka: żądanie przychodzi od programu partnera i jest rozpoznawane po kluczu.

Postman. Do importu gotowe są dwa pliki:

PlikCo to
spike_api_postman_collection.jsonKolekcja: 51 żądań w 8 folderach — wszystkie akcje plus sprawdzenia odmów, z gotowymi testami
spike_api_postman_environment.jsonŚrodowisko: base_url i api_key (typ *secret*), pozostałe zmienne wypełniają się same

Zaimportuj oba (*Import* → przeciągnij pliki), wybierz środowisko w prawym górnym rogu i wpisz w nim api_key. Klucz trzymaj w środowisku, a nie w kolekcji: kolekcje się przekazuje i eksportuje, środowisko zostaje u ciebie.

Dalej całość można uruchomić Runnerem — listy pamiętają id pierwszego elementu, więc gs.get, product.get, session.get, order.get i chat.messages działają bez ręcznego wpisywania. Foldery 1–7 oczekują odpowiedzi 200, czyli liczą na klucz z pełnym dostępem; klucz z ograniczonymi uprawnieniami zgodnie z zasadami odpowiada 403 forbidden_action na niedostępne akcje — co dokładnie jest dla niego dostępne, mówi meta.actions.

---

1. Skąd wziąć klucz

Klucz wydaje właściciel klubu w swoim panelu: sekcja Klucze API → „Utwórz”. Tam też wybiera, co kluczowi wolno i do kiedy działa, dlatego o klucz proś razem z listą potrzebnych ci akcji — właściciel zaznaczy właśnie je.

Co powiedzieć właścicielowi:

Gotowy klucz przekazuje ci jak hasło. Na liście kluczy widać go w masce (pierwsze i ostatnie cztery znaki), w całości — tylko w karcie, skąd się go kopiuje.

Więcej od strony właściciela jest w podręczniku użytkownika SpikePC, w sekcji Klucze API.

Klucz nie jest przypisany do klubu: działa na całą organizację, a konkretny klub wskazujesz parametrem club_id.

---

2. Transport

POST https://spikepc.com/spike_api/
X-Api-Key: 7b2d4f9a1c3e5d7f9b0a2c4e6f8a0b1d
Content-Type: application/json
 
{ "action": "gs.list", "v": 1, "data": { "club_id": 3, "limit": 50, "offset": 0 } }

Adres podawaj z ukośnikiem na końcu (/spike_api/). Bez niego serwer odpowiada przekierowaniem na adres z ukośnikiem, a treść żądania POST przy przekierowaniu ginie — żądanie przyjdzie puste i dostanie 400 bad_request.

Ten sam handler jest dostępny też pod wewnętrznym adresem ?loc=spike_user_api_request — on nadal działa, ale w integracjach używaj /spike_api/.

ZasadaDlaczego tak
Tylko POST, treść — jeden obiekt JSONParametry w query nie dochodzą do handlera: panel przepuszcza z URL wyłącznie białą listę (id, loc, page, token, hash)
Klucz — nagłówek X-Api-KeySprawdzone: proxy go przepuszcza. Authorization: Bearer nie dochodzi do PHP wcale, więc nie można go użyć
Zapas — pole api_key w treściDla klientów, którzy nie potrafią nagłówków. To pole nigdy nie trafia do dziennika
Klucz nie jest przekazywany w URLAdresy zostają w logach proxy i serwera
Parametry biznesowe — wewnątrz dataPola systemowe (action, v, api_key) leżą obok, nie mieszając się z twoimi
org_id w żądaniu nie jest przyjmowanyOrganizacja bierze się z klucza. Inaczej partner jednego klubu czytałby obce dane
club_id jest przyjmowanyAle sprawdzany względem klubów organizacji klucza → inaczej club_foreign (403)

v to wersja kontraktu, opcjonalna (obecnie 1).

---

3. Odpowiedź

Ta sama koperta, co u stanowiska i aplikacji mobilnej; code powtarza się w statusie HTTP:

{
  "code": 200,
  "error_key": "",
  "error_text": "",
  "action": "gs.list",
  "data": { "items": [ … ], "total": 38, "limit": 50, "offset": 0 }
}

Kody i klucze błędów

HTTPerror_keyKiedy
400bad_requestTreść nie jest obiektem JSON albo brak pola action
401empty_keyKlucz nie został przysłany
401unknown_keyKlucza nie znaleziono
401key_expiredTermin ważności klucza minął
403forbidden_actionKlucz nie ma prawa do tej akcji
403club_foreignclub_id należy do innej organizacji
404unknown_actionNie ma takiej akcji
404not_foundObiektu nie znaleziono (klub, stanowisko)
422bad_paramsBrakuje wymaganego parametru
429rate_limitedPrzekroczona częstotliwość (patrz §7), w nagłówku Retry-After
500org_unavailableBaza organizacji jest niedostępna
500query_failedZapytanie się nie udało. Nie myl tego z pustą listą: przy awarii przychodzi błąd, a nie items: []

---

4. Akcje

Co zrobić, mówi pole action. Punkt wejścia jest jeden, więc dodanie metody nie zmienia adresu i nie wymaga zmian po twojej stronie. Uprawnienie każdej akcji to nazwa funkcji w panelu: jest podpisana w karcie klucza obok pozycji uprawnień i właśnie ją właściciel zaznacza, żeby otworzyć partnerowi akcję.

Akcje w tej sekcji tylko czytają. Te, które zmieniają dane, są w §5.

Serwisowe (bez uprawnienia)

actionPrzeznaczenie
pingKlucz przyjęty: organizacja, nazwa klucza, tryb dostępu, termin, czas serwera
meta.actionsCo jest dostępne temu kluczowi — lista akcji i ich uprawnień

Klub i sala

actionUprawnienieParametryPrzeznaczenie
club.listspike_clubs_list—Kluby: nazwa, adres, telefony, współrzędne
club.mapspike_club_maps_listclub_id*Plan sali (obiekt albo null, jeśli mapy nie narysowano)
gs_group.listspike_gs_groups_listclub_idGrupy stanowisk — na nich opierają się taryfy i abonamenty
gs.listspike_gs_listclub_id, group_id, limit, offsetStanowiska: numer, typ, IP, MAC, grupa, tryb, częstotliwość ekranu, wersja oprogramowania klienta (app_version — zgłasza ją samo stanowisko przy połączeniu; puste = nie zgłaszało)
gs.getspike_gs_listid albo macJedno stanowisko
gs.statusspike_club_maps_listclub_idStan sali na żywo (patrz niżej)
snap.listspike_gs_snaps_listclub_id*Złote obrazy klubu: który jest aktywny, kiedy zrobiony

Katalog

actionUprawnienieParametryPrzeznaczenie
game.listspike_games_listclub_id, genre_id, status, search, locale, limit, offsetGry klubu: sposób uruchomienia, ocena, gatunki
game_genre.listspike_game_genres_listlocaleGatunki organizacji (jedna lista na całą sieć)
banner.listspike_banners_listclub_idBanery: obszar na ekranie stanowiska, okres, okno czasowe
category.listspike_market_category_listlocaleGrupy towarów
product.listspike_market_products_listclub_id*, cat_id, status, search, locale, limit, offsetTowary z ceną klubu i stanem magazynu
product.getspike_market_products_listclub_id*, id albo code albo barcodeJeden towar (wygodnie ze skanera)
stock.listspike_stock_listclub_id, type, product_id, date_from, date_to, limit, offsetRuch magazynu: przyjęcie, wydanie, sprzedaż, zwrot, korekta

search w towarach szuka po nazwie, kodzie artykułu i kodzie kreskowym. locale podmienia name i description tłumaczeniem tej lokalizacji; nie ma tłumaczenia — zostaje wartość bazowa, więc odpowiedź nigdy nie przychodzi pusta.

club_id przy towarach jest wymagany: towar ma własną cenę w każdym klubie, a bez klubu trzeba by zwracać „cenę w ogóle” — partner sprzedawałby po obcej. Jeśli w tym klubie ceny nie ma, przychodzi price: null i available: false — tutaj towar nie jest sprzedawany.

Godziny dostępności towaru przychodzą w polu hours — po jednym wierszu na dzień tygodnia: [{day, from_sec, to_sec}], gdzie day to 0=pon … 6=niedz, a from_sec/to_sec — sekundy od północy. Pusta tablica oznacza sprzedaż całodobową. to_sec to ostatnia wliczona sekunda (okno „18:00–22:00” przychodzi jako 64800…79259), a to_sec mniejszy od from_sec to okno przez północ: zaznaczony dzień wyznacza początek, koniec wypada następnej doby. Obok przychodzi gotowa odpowiedź hours_open (true/false — czy towar jest w sprzedaży właśnie teraz): samodzielne wyliczenie wymagałoby naszej konwencji granic i naszej strefy czasowej. Na pole available harmonogram nie wpływa — nadal dotyczy ceny w klubie i aktywności towaru.

Taryfy i abonamenty

actionUprawnienieParametryPrzeznaczenie
tariff.listspike_tariffs_listclub_idTaryfy: cena za godzinę, kolor, czy działają rabaty, status (0 = taryfa wycofana z obiegu: nie przypisuje się jej do nowych godzin harmonogramu, ale godziny, w których już stoi, nadal liczą się po jej cenie)
tariff.schedulespike_tariffs_scheduleclub_id*Siatka tygodniowa: dzień+czas → grupa stanowisk → taryfa
ticket.listspike_tickets_listclub_idAbonamenty: czas, cena, auto_apply, status (0 = wyłączony przez klub, nie jest w sprzedaży)
ticket.schedulespike_tickets_scheduleclub_id*, kind (sale \valid)Kiedy abonament jest sprzedawany albo kiedy można go wykorzystywać
discount.listspike_discounts_liststatusLista rabatów okolicznościowych
promocode.listspike_promocodes_liststatus, search, club_id, limit, offsetKody promocyjne: zdarzenie, kwota, okno, pozostałe aktywacje
payment_method.listspike_payment_methods_listtype, status, club_idKasy organizacji z wyliczanym saldem

Granice przedziałów harmonogramu są włączne, przy czym time_end to ostatnia włączona sekunda bloku (godzina 13 → 50399 = 13:59:59). W odpowiedzi obok sekund idą gotowe from/to, żebyś nie powtarzał tej konwencji u siebie i nie tracił ostatniej godziny.

Dwie siatki abonamentu to różne rzeczy: kind=sale odpowiada „kiedy można go kupić”, kind=valid — „kiedy kupione można wykorzystać”. Pusta siatka ważności znaczy „działa zawsze”.

Przy kasie bonusowej balance przychodzi jako null, a nie zero: bonusy to nie realne pieniądze w kasie.

Klienci i pieniądze

actionUprawnienieParametryPrzeznaczenie
client.listspike_clients_listsearch, is_banned, limit, offsetKlienci organizacji
client.getspike_clients_listid albo email albo phoneKarta klienta plus jego abonamenty
client.packsspike_clients_listid \email \phoneTylko abonamenty
transaction.listspike_transactions_listclient_id, club_id, type, date_from, date_to, limit, offsetRejestr operacji
shift.listspike_cash_shifts_listclub_id, status, date_from, date_to, limit, offsetZmiany kasowe z podsumowaniem i różnicą
postpay.listspike_cashdesk_listclub_id, status, date_from, date_to, limit, offsetPłatności po grze

search w klientach szuka po mailu, telefonie, loginie, imieniu i nazwisku. Telefon w client.get jest szukany we wszystkich formatach, w jakich mógł zostać zapisany (380…, +380…, 0…, 38…) — import i rejestracja zapisywały go inaczej.

Serwisowe wpisy gościnne stanowisk (gościnna płatność po grze) nie trafiają do listy klientów. Notatki operatora i awatar nie są wydawane.

Pozostały czas abonamentu liczy się po zegarze ściennym: aktywowany abonament wypala się od momentu aktywacji, więc remaining_seconds nie pokaże czasu, który już się wypalił, gdy klienta nie było.

Sesje, zamówienia, rezerwacje, czat

actionUprawnienieParametryPrzeznaczenie
session.listspike_gs_sessions_listclub_id, gs_id, client_id, status, date_from, date_to, limit, offsetHistoria sesji
session.getspike_gs_sessions_listid*Sesja plus dziennik zdarzeń (start, uruchomienia gier, zamówienia, koniec)
order.listspike_orders_listclub_id, status, gs_id, client_id, date_from, date_to, limit, offsetZamówienia sklepu z pozycjami
order.getspike_orders_listid*Jedno zamówienie; pozycja combo nosi wybór klienta w options
reserve.listspike_gs_reserve_listclub_id, gs_id, client_id, date_from, date_to, limit, offsetRezerwacje stanowisk
chat.listspike_chats_listclub_id, date_from, date_to, limit, offsetRozmowy (jedna rozmowa = jedna sesja)
chat.messagesspike_chats_listsession_id*, limit, offsetWiadomości rozmowy

Aktywna sesja wciąż zbiera swój wynik, dlatego w odpowiedzi jest active: true — nie bierz sumy pośredniej za ostateczną.

Zamówienie nie obciąża salda klienta — płaci się je na miejscu personelowi, więc total_amount to kwota do zapłaty, a nie zrealizowana płatność.

Okres przy rezerwacjach liczy się po przecięciu, a nie po początku: rezerwacja, która zaczęła się wczoraj i trwa teraz, trafia do wyboru za dziś.

Przy rozmowach total to liczba rozmów, a nie wiadomości.

Organizacja

actionUprawnienieParametryPrzeznaczenie
org.infospike_org_config_list—Strefa czasowa, zasady magazynu, limity abonamentów i płatności po grze, kluby przyjmujące zamówienia
locale.listspike_locale_liststatusJęzyki katalogu i który jest domyślny
staff.listspike_staff_list—Pracownicy i ich kluby
event.listspike_events_listsearch, date_from, date_to, limit, offsetDziennik zmian w panelu
analytics.dailyspike_analytics_listclub_id, date_from, date_toDzienne wyliczenia: obłożenie i przychód

org.info nie wydaje danych dostępowych: ani do bazy, ani SMTP, ani tokenów Telegrama, ani gs_token stanowisk, ani salda organizacji. Uprawnienie „podgląd ustawień” dostaje pracownik wewnątrz panelu, a tutaj odpowiedź idzie do strony trzeciej.

event.list nie wydaje zrzutów „przed/po”: trafiają do nich całe pola, w tym hasła Windows klubu. Zostaje kto, kiedy, w jakiej sekcji i nad czym.

analytics.daily wylicza nocne zadanie w strefie czasowej organizacji, dlatego bieżący dzień zwykle jest pusty — to nie utrata danych: za dziś bierz żywe gs.status, transaction.list, order.list. Okres domyślny to ostatnie 30 dni.

Strony i filtry

Przykład: stan sali na żywo

→ { "action": "gs.status", "data": { "club_id": 3 } }
 
← { "code": 200, …, "data": { "items": [
      { "gs_id": 587, "club_id": 3, "number": "2",
        "online": true, "mode": "active",
        "busy": true, "client_id": 1402, "started_at": "2026-10-01 14:05:11",
        "time_left": { "seconds": 4260, "text": "1:11", "unlimited": false } }
    ], "total": 38, "server_time": "2026-10-01 16:10:59" } }
PoleZnaczenie
onlineStanowisko ma otwarte połączenie z serwisem. To o łączności, nie o trybie
modeactive / service (obsługa) / admin (administrowanie) / disabled (wycofane z wynajmu)
busyPrzy stanowisku gra klient. Stanowisko może być busy także przy utraconej łączności — sesję zamknie uzgadnianie
time_leftSzacunek pozostałego czasu: darmowe minuty klubu + stosowalne abonamenty + pieniądze po obowiązującej stawce. unlimited — stawki nie ma albo jest zerowa. null — przy stanowisku nikogo nie ma

time_left i online liczy ten sam kod, co mapa klubu, dlatego partner i operator widzą tę samą liczbę.

---

5. Zapis

Te akcje zmieniają dane klubu: przyjmują pieniądze, sprzedają abonament, przesuwają zamówienie, tworzą rezerwację, przyznają rabat i kredyt, wysyłają polecenie do stanowiska. Ich uprawnienia są osobne — właściciel zaznacza je w karcie klucza niezależnie od podglądu, więc „obejrzeć" i „zmienić" nigdy nie idą w jednym polu wyboru.

Zasady są te same, co u operatora w panelu: bez otwartej zmiany kasowej pieniądze nie są przyjmowane, abonament ponad limit organizacji nie jest sprzedawany, rezerwacja w zamkniętych godzinach nie powstaje. To nie „podobne sprawdzenia" — obie strony wywołują ten sam kod, więc partner nie może tego, czego nie wolno operatorowi.

actionUprawnienieParametryCo robi
client.topupspike_clients_topupclient_id*, amount*, payment_method_id*, comment, club_idDoładowuje saldo klienta przez kasę
client.sell_ticketspike_clients_sell_ticketclient_id*, ticket_id*Sprzedaje abonament, obciążając saldo klienta
transaction.refundspike_transactions_refundtx_id*Zwraca doładowanie
order.set_statusspike_orders_listorder_id*, status*Przesuwa zamówienie: new→processing→done, albo cancelled
reserve.createspike_gs_reserve_addclub_id*, gs_id*, date_start*, date_end*, client_id, descriptionTworzy rezerwację stanowiska
reserve.cancelspike_gs_reserve_delreserve_id*Anuluje rezerwację
discount.grantspike_club_maps_gs_discountgs_id*, discount_id*Przyznaje rabat okolicznościowy (0 zdejmuje)
credit.setspike_club_maps_gs_creditgs_id*, amount*Ustawia kredyt na sesję (0 zdejmuje)
postpay.enablespike_cashdesk_postpay_enablegs_id*, limit, guest, commentWłącza płatność po grze na stanowisku
postpay.limitspike_cashdesk_postpay_enablepostpay_id*, limitZmienia limit płatności po grze
postpay.stopspike_cashdesk_postpay_enablepostpay_id*Kończy płatność po grze (stanowisko dostaje session_end)
postpay.cancelspike_cashdesk_postpay_enablepostpay_id*Zdejmuje płatność po grze, która czeka na klienta
postpay.payspike_cashdesk_postpay_enablepostpay_id*, payment_method_id*, commentPrzyjmuje zapłatę za płatność po grze do kasy
gs.commandspike_club_maps_gs_commandgs_id*, action*, dataPolecenie dla stanowiska: message, poweroff, poweron, session_end

Pieniądze

Kasa jest wymagana (payment_method_id), listę podaje payment_method.list. Przy kasie bonusowej wymagany jest comment — bonusu bez wyjaśnienia nie przyjmujemy, inaczej nie ma czym odpowiedzieć na pytanie „za co naliczono". Jeśli kasa jest wspólna dla organizacji, a klubów jest kilka, potrzebny jest club_id: bez niego operacja zginęłaby dla raportów klubu.

Potrzebna jest otwarta zmiana kasowa w tym klubie, inaczej 409 no_shift. Zmianę otwiera kasjer w panelu i przez API się tego nie obejdzie: pieniądze muszą należeć do czyjejś zmiany.

Zwrot (transaction.refund) jest możliwy tylko dla doładowania i tylko raz; saldo może zejść na minus — pieniądze oddano z kasy, więc schodzą z salda w całości.

Sprzedaż abonamentu obciąża saldo klienta z uwzględnieniem jego stałego rabatu (jeśli abonament rabaty dopuszcza). Abonament trafia do zapasu: zegar startuje przy aktywacji na stanowisku, a nie przy sprzedaży, inaczej kupiony z wyprzedzeniem wypaliłby się przed przyjściem klienta.

Sala

Rabat: jeśli przy stanowisku jest klient, procent idzie zrzutem do jego sesji (lista może być później zmieniona, a człowiek dogrywa na tym, co obiecano); jeśli stanowisko jest wolne, zgłoszenie czeka na tego, kto usiądzie, 30 minut.

Kredyt to dozwolona głębokość minusa do końca sesji, a nie wpłata: klient dogrywa na kredyt i spłaca go zwykłym doładowaniem. Potrzebna jest aktywna sesja klienta.

Polecenia: dozwolone są tylko message, poweroff, poweron i session_end. Tryby stanowiska, złote obrazy i reszta zarządzania salą zostają przy operatorze — to sprawa klubu, nie systemu zewnętrznego. W odpowiedzi jest delivery: done/delivered — stanowisko przyjęło, offline — nie jest połączone, timeout — nie odpowiedziało w czasie.

Klucze odmowy przy zapisie

error_keyKiedy
bad_amountKwota nie większa od zera (albo kredyt ujemny)
invalid_payment_methodKasy nie ma albo jest wyłączona
comment_requiredKasa bonusowa bez komentarza
club_requiredKasa jest wspólna, a club_id nie przekazano
no_shiftW klubie nie ma otwartej zmiany kasowej
client_not_found, ticket_not_found, order_not_found, reserve_not_found, tx_not_foundObiekt nie istnieje
no_balanceNa saldzie klienta brakuje pieniędzy na abonament
ticket_disabledAbonament jest wyłączony przez klub i nie jest w sprzedaży
pack_single_only, pack_limit_reachedLimity organizacji na abonamenty
not_a_topup, already_refundedZwrot: to nie doładowanie albo już je zwrócono
bad_status, order_finalizedZamówienie: nieznany status albo jest już zamknięte
bad_time, past_time, too_far, too_short, too_longRezerwacja: przedział nie pasuje
outside_window, gs_busy, too_many_reservesRezerwacja: poza godzinami klubu, czas zajęty, zbyt wiele rezerwacji
no_clientPrzy stanowisku nie ma grającego klienta (kredyt)
discount_not_found, credit_unavailableRabatu nie ma albo kredyt jest w organizacji niedostępny

---

6. Uprawnienia klucza

Tryb dostępu klucza wybiera właściciel:

Uprawnienie każdej akcji to nazwa funkcji w panelu i jest ona podpisana w karcie klucza obok pozycji uprawnień. Właściciel widzi więc dokładnie to, co jest sprawdzane przy żądaniu: jeśli partner dostaje forbidden_action na gs.list, w karcie klucza trzeba zaznaczyć pozycję z uprawnieniem spike_gs_list.

Termin klucza sprawdza serwer: po jego upływie każde żądanie odpowiada key_expired (401), nawet jeśli partner o tym nie wie.

---

7. Częstotliwość żądań

Limit to 120 żądań na minutę na klucz (wartość zmienia administrator systemu). Po przekroczeniu przychodzi 429 rate_limited i nagłówek Retry-After: 60.

Odpytywanie stanu sali raz na 2–5 sekund mieści się w limicie z zapasem. Jeśli trzeba częściej — poproś właściciela klubu o podniesienie limitu, a nie obchodź go kilkoma kluczami: limit liczy się na klucz właśnie po to, by jeden partner nie przeszkadzał innym.

---

8. Dziennik żądań

W karcie klucza właściciel może włączyć dziennik żądań: wtedy każde wywołanie tym kluczem jest przechowywane 7 dni — akcja, kod odpowiedzi, czas trwania, IP i treść żądania (klucz jest z niej wycinany). To narzędzie do rozwiązywania „u partnera nie działa”: na stałe dziennik nie jest potrzebny.

Jeśli twoje żądanie dostaje odmowę, a powód jest niejasny, poproś właściciela o włączenie dziennika i powtórz żądanie — w dzienniku będzie widać akcję, kod i to, co dokładnie przysłałeś.

---

9. Czego w tym API nie ma

Edycji danych słownikowych. Taryfy, abonamenty, towary, kluby, stanowiska, pracownicy, uprawnienia i ustawienia organizacji nie zmieniają się przez API — to robi się w panelu. Partner ma pracować z klientami i salą, a nie przepisywać ustawienia klubu, a każda taka zmiana wymagałaby własnych sprawdzeń formularza.

Listy kluczy. Kluczem nie można odczytać tabeli kluczy: partner zobaczyłby klucze innych partnerów tej samej organizacji.

Struktury uprawnień panelu nie wydajemy: zewnętrznemu systemowi nic nie mówi, a w odpowiedzi pojawiałyby się nazwy naszych wewnętrznych funkcji.

---

10. Webhooki: zdarzenia same przychodzą do Ciebie

Aby nie odpytywać API w poszukiwaniu nowego zamówienia, podaj właścicielowi klubu swój adres — zdarzenia będą trafiać na niego same. Ustawia się to w panelu organizacji (karta „Klienci i zamówienia”): adres, wyłącznik, klucz podpisu i lista zdarzeń.

Żądanie: POST <Twój adres>, treść to JSON:

{ "event": "order.new",
  "org_id": 11,
  "sent_at": "2026-10-08T12:46:08+03:00",
  "data": { "order_id": 42, "club_id": 1, "gs_id": 11, "client_id": 35839,
            "total": 320.00, "items": 3 } }

Nagłówki: X-Spike-Event (nazwa zdarzenia), X-Spike-Org (organizacja) oraz X-Spike-Signature — podpis treści.

Zdarzenia

ZdarzenieKiedyCo jest w data
order.newklient złożył zamówienie na stanowiskuorder_id, club_id, gs_id, client_id, total, items
order.statuszmienił się status zamówieniaorder_id, club_id, gs_id, old_status, status, total, user_login
session.startklient zalogował się na stanowiskusession_id, club_id, gs_id, client_id, auth_method
session.endsesja została zamkniętato samo plus date_start, date_end, duration_seconds, time_cost, products_cost, total_cost, reason
client.topupdoładowanie salda klientaclient_id, login, amount, balance, club_id, payment_method, type, comment, source

Organizacja może zapisać się na część zdarzeń — wtedy przyjdą tylko one.

Podpis: sprawdzaj go

X-Spike-Signature: sha256=<hex> to HMAC-SHA256 z całej treści żądania na kluczu, który właściciel klubu ustawił w ustawieniach. Policz podpis samodzielnie i porównaj z nagłówkiem: bez tej weryfikacji na Twój adres będzie mógł pisać każdy, podając się za nas. Jeśli klucz nie jest ustawiony, nagłówka nie będzie; i tak warto poprosić właściciela, żeby go ustawił.

# przykład weryfikacji (bash)
calc=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
[ "sha256=$calc" = "$SIG" ] || exit 1

Dostarczanie

Wysyła kolejka, a nie żądanie operatora: panel i serwis socketowy nigdy nie czekają na Twój serwer. Stąd zasady, na które możesz liczyć:

Odpowiadaj 200 jak najszybciej i przetwarzaj zdarzenie u siebie asynchronicznie: dopóki trzymasz połączenie, zadanie kolejki jest zajęte Tobą.