TicketMap SDK
TicketMap SDK vam omogućava da ulaznice za svoje AnyBiz događaje prodajete direktno na sopstvenom sajtu. Prikazuje interaktivnu mapu sedenja (pomeranje, zumiranje, izbor mesta), održava dostupnost mesta ažurnom i preusmerava posetioca na hostovanu stranicu za plaćanje — sve kroz jedan script tag.
Vidžet se montira unutar Shadow DOM-a, tako da CSS vašeg sajta ne može da pokvari mapu, niti stilovi mape „cure” na vašu stranicu. Jedina globalna promenljiva koju SDK izlaže je window.TicketMap.
Preduslovi
Odeljak pod nazivom „Preduslovi“Pre integracije, vašoj organizaciji je potreban podešen SDK pristup u AnyBiz aplikaciji, u sekciji Podešavanja → SDK:
- Site key — javni ključ (npr.
sdk_pub_...) koji identifikuje vašu organizaciju. Bezbedno je uključiti ga u javni HTML. - Dozvoljeni origin-i — lista origin-a sajtova (npr.
https://www.example.com) kojima je dozvoljeno korišćenje ključa. Prazna lista dozvoljava sve origin-e; u produkciji obavezno podesite listu. - Return URL — stranica na vašem sajtu na koju posetilac stiže posle plaćanja (pogledajte Tok povratka sa plaćanja).
Biće vam potrebni i:
- SDK skripta (
ticketmap.min.js) — URL dobijate zajedno sa site key-em. - Osnovni API URL:
https://api.anybiz.rs/api/events/sdk. Uvek ga prosledite eksplicitno — ako je izostavljen, SDK pretpostavlja da se API nalazi na vašem origin-u.
Brzi početak
Odeljak pod nazivom „Brzi početak“Minimalna integracija: autentifikujte se site key-em, montirajte mapu i pokrenite checkout za izabrana mesta.
<div id="ticket-map"></div><button id="checkoutBtn" disabled>Plaćanje</button>
<script src="https://<sdk-host>/ticketmap.min.js"></script><script> (async () => { const API_BASE = 'https://api.anybiz.rs/api/events/sdk';
// 1. Zamenite javni site key za kratkotrajni auth token const auth = await TicketMap.authenticate({ siteKey: 'sdk_pub_vas_kljuc', apiBaseUrl: API_BASE, });
// 2. Montirajte mapu sedenja za jedan termin događaja const sdk = await TicketMap.init({ container: '#ticket-map', apiBaseUrl: API_BASE, eventId: 'evt_123', displayId: 'disp_456', authToken: auth.authToken, lang: 'sr', onSelectionChange: (selection) => { const btn = document.getElementById('checkoutBtn'); btn.disabled = selection.items.length === 0; btn.textContent = selection.items.length ? `Plaćanje (${selection.items.length}) — ${selection.total} ${selection.currency ?? ''}` : 'Plaćanje'; }, onError: (error) => console.error('TicketMap:', error.message), });
// 3. Rezervišite izabrana mesta i preusmerite na stranicu za plaćanje document.getElementById('checkoutBtn').addEventListener('click', () => { sdk.checkout({ customerEmail: 'kupac@example.com', // preporučeno: isporuka ulaznica + potvrda plaćanja }); }); })();</script>checkout() rezerviše izabrana mesta, kreira checkout sesiju i preusmerava pregledač na hostovanu stranicu za plaćanje. Kada se plaćanje završi, posetilac se vraća na vaš podešeni Return URL.
Učitavanje događaja i termina
Odeljak pod nazivom „Učitavanje događaja i termina“Ako ne želite da eventId/displayId upisujete ručno, izlistajte ih istim auth tokenom:
const events = await TicketMap.listEvents({ authToken, apiBaseUrl: API_BASE });// [{ id, name, description, archived, createdAt, updatedAt }, ...]
const displays = await TicketMap.listDisplays({ authToken, eventId: events[0].id, apiBaseUrl: API_BASE,});// [{ id, eventId, startTime, status: 'draft' | 'active' | 'closed', salesStartTime, salesEndTime, ... }, ...]Kroz SDK se mogu prodavati samo termini kod kojih je prodaja otvorena; na osnovu polja status i vremenskog okvira prodaje odlučite šta ćete prikazati.
Kako funkcioniše izbor mesta
Odeljak pod nazivom „Kako funkcioniše izbor mesta“SDK radi po principu lokalnog izbora: dodir na mesto menja samo vizuelni izbor u pregledaču. Ništa se ne rezerviše na serveru dok ne pozovete hold() ili checkout().
Dva stila integracije:
- U jednom koraku — posetilac izabere mesta, a vaše dugme za plaćanje pozove
sdk.checkout(). SDK rezerviše mesta i odmah preusmerava na plaćanje. Najjednostavnije, i dovoljno za većinu sajtova. - Korpa u fazama — pozovite
sdk.hold()da trenutni izbor rezervišete na serveru (podrazumevano trajanje rezervacije: 10 minuta) bez plaćanja. Posetilac može da nastavi da dodaje mesta i ponovo pozivahold(); svaki poziv dodaje nove rezervacije u korpu. Kasnijisdk.checkout()plaća sve zadržane rezervacije (i prazni korpu). PozovitereleaseHeldReservation(id)da oslobodite rezervaciju.
Boje mesta odražavaju dostupnost uživo: slobodno (siva), izabrano (plava), rezervisano za ovog posetioca (narandžasta), rezervisano od strane drugog (crvena), prodato (tamno siva). Dostupnost se automatski osvežava na svakih 10 sekundi, osim ako ne isključite polling.
Referenca za TicketMap.init(options)
Odeljak pod nazivom „Referenca za TicketMap.init(options)“Obavezno:
| Opcija | Tip | Opis |
|---|---|---|
container | string | HTMLElement | CSS selektor ili element u koji se vidžet montira. |
eventId | string | AnyBiz id događaja. |
displayId | string | Id termina koji pripada tom događaju. |
authToken | string | Token dobijen od TicketMap.authenticate({ siteKey }). |
Opciono:
| Opcija | Tip | Podrazumevano | Opis |
|---|---|---|---|
apiBaseUrl | string | trenutni origin + /api/events/sdk | Uvek postavite na https://api.anybiz.rs/api/events/sdk. |
lang | 'en' | 'sr' | 'en' | Jezik ugrađenih UI tekstova. |
labels | Partial<SdkLabels> | — | Zamena pojedinačnih UI tekstova (statusi, legenda, poruke o greškama). |
holdMinutes | number | 10 | Trajanje rezervacije na serveru za hold() / checkout() u jednom koraku. |
pollMs | number | 10000 | Interval osvežavanja dostupnosti u milisekundama. |
autoPollAvailability | boolean | true | Postavite false da isključite polling i sami pozivate refreshAvailability(). |
customerName / customerEmail / customerPhone | string | — | Podrazumevani podaci o kupcu koji se šalju uz checkout (poziv checkout() može da ih pregazi). |
promoCode | string | null | — | Podrazumevani promo kod koji se primenjuje pri checkout-u. |
reservationHolderName / reservationHolderEmail / reservationHolderPhone | string | — | Opcioni podaci o nosiocu rezervacije koji se čuvaju uz rezervacije napravljene kroz hold(). |
Callback funkcije:
| Callback | Kada se poziva |
|---|---|
onSeatClick(detail) | Samo kada posetilac dodirne mesto. detail je { seatId, action: 'select' | 'deselect', seat, selection }. |
onSelectionChange(selection) | Posle svake sinhronizacije dostupnosti — prvo učitavanje, polling i dodiri na mesta. Prima snimak izbora. |
onSeatSelect(selection) | Isti sadržaj i trenutak kao onSelectionChange (zadržano zbog kompatibilnosti; koristite bilo koji). |
onCheckoutStart(checkoutId) | Kada je checkout sesija kreirana, pre preusmeravanja na plaćanje. |
onCheckoutResult(status) | Sa početnim statusom checkout-a koji vrati API. |
onError(error) | Pri svakoj SDK grešci (neuspešan zahtev, nevažeći izbor, …). |
UI vaše korpe vodite iz onSelectionChange; onSeatClick koristite kada vam treba ponašanje vezano isključivo za dodir — na primer poziv sdk.hold() odmah pri svakom dodiru.
Snimak izbora
Odeljak pod nazivom „Snimak izbora“onSelectionChange / onSeatSelect / getSelectionSnapshot() daju:
{ seatIds: string[]; items: Array<{ seatId: string; sectionId: string; sectionTitle: string | null; seatRow: string; seatNumber: string; effectivePrice: string; // decimalni string, npr. "1200.00" currency: string; availability: 'available' | 'reserved' | 'sold'; reservationId: string | null; // id grupe rezervacija kada je mesto zadržano heldByMe: boolean; // true kada je zadržano u sesiji ovog posetioca reservedUntil: string | null; // ISO vreme isteka rezervacije }>; total: string; // zbir effectivePrice vrednosti, npr. "3600.00" currency: string | null;}Metode instance
Odeljak pod nazivom „Metode instance“TicketMap.init() vraća instancu sa metodama:
| Metoda | Opis |
|---|---|
checkout(options?) | Ako postoje zadržane rezervacije: plaća njih. U suprotnom: rezerviše trenutni izbor, pa preusmerava na plaćanje. Kroz options se po pozivu mogu pregaziti customerName, customerEmail, customerPhone, promoCode. |
hold(options?) | Rezerviše trenutni izbor na serveru i dodaje id-jeve rezervacija u korpu. Vraća sve zadržane id-jeve. Kroz options se mogu pregaziti holdMinutes i podaci o nosiocu. |
releaseHeldReservation(id) | Oslobađa jednu zadržanu grupu rezervacija. |
getHeldReservationIds() | Id-jevi rezervacija koji su trenutno u korpi. |
refreshAvailability() | Ručno osvežava dostupnost mesta. |
getSelectionSnapshot() / getSelectedItems() | Trenutni izbor (snimak / samo stavke). |
zoomIn(step?) / zoomOut(step?) / fitToScreen() | Kontrole mape, npr. za dugmad u vašoj traci sa alatkama. |
destroy() | Demontira vidžet i zaustavlja polling. Pozovite pre ponovne inicijalizacije u istom kontejneru. |
Tok povratka sa plaćanja
Odeljak pod nazivom „Tok povratka sa plaćanja“Plaćanje se obavlja na hostovanoj stranici za plaćanje (MSU), ne na vašem sajtu:
checkout()preusmerava pregledač na stranicu za plaćanje.- Posle plaćanja, platna platforma poziva AnyBiz API, koji proverava transakciju i finalizuje checkout (ulaznice se izdaju pri uspehu).
- API zatim preusmerava posetioca na Return URL iz vaših SDK podešavanja — podjednako za uspešna, odbijena i otkazana plaćanja — dodajući rezultat kao query parametre:
responseCode— kod odgovora platne platforme (00= odobreno,99= odbijeno)responseMsg— čitljiva poruka platne platformemerchantPaymentId— referenca plaćanjacheckoutId— id checkout sesijemsuAccepted—1kada je callback prepoznat i obrađen,0u suprotnom; ovo nije indikator uspešnog plaćanja — ishod čitajte izresponseCode
Isti parametri se dupliraju i u fragmentu URL-a (posle #), kao rezerva za posrednike koji uklanjaju query string.
Na toj adresi napravite stranicu sa rezultatom plaćanja koja čita parametre i prikazuje uspeh ili neuspeh. Provera plaćanja je već obavljena na serveru pre nego što posetilac stigne — parametri služe za prikaz, ne za odlučivanje o isporuci.
Da ponovo proverite rezultat iz pregledača (npr. ako posetilac osveži stranicu), pozovite POST /checkout/status sa SDK session tokenom i checkoutId; vraća proveren status: created, pending, paid, failed ili cancelled.
Autentifikacija i trajanje tokena
Odeljak pod nazivom „Autentifikacija i trajanje tokena“TicketMap.authenticate({ siteKey })menja javni site key za auth token koji važi 30 minuta. Origin pregledača iz kog zahtev stiže mora biti na listi dozvoljenih origin-a za taj ključ.TicketMap.init()menja auth token za session token po posetiocu, takođe važeći 30 minuta, ograničen na jedan termin događaja.- Po isteku, zahtevi vraćaju grešku kroz
onError— ponovo pozoviteauthenticate()iinit(). Za stranice koje dugo ostaju otvorene, autentifikujte se ponovo pre novoginit()poziva umesto keširanja tokena.
Lokalizacija
Odeljak pod nazivom „Lokalizacija“Ugrađeni tekstovi (statusna linija, legenda, uputstva, poruke o greškama) dolaze na engleskom (lang: 'en') i srpskom (lang: 'sr'). Svaki tekst se može zameniti:
await TicketMap.init({ // ... lang: 'sr', labels: { statusReady: 'Izaberite svoja mesta', errorSelectAtLeastOneSeat: 'Prvo izaberite mesto na mapi', },});API endpointi
Odeljak pod nazivom „API endpointi“SDK je tanak klijent nad javnom SDK familijom endpointa na https://api.anybiz.rs/api/events/sdk. Svi su POST sa JSON telom:
| Endpoint | Namena |
|---|---|
/auth | Zamena site key-a za auth token. |
/events, /displays | Lista događaja / termina dostupnih za prodaju. |
/session | Kreiranje sesije po posetiocu za jedan termin. |
/init | Učitavanje podataka mape sedenja. |
/availability | Dostupnost mesta uživo. |
/reserve, /release | Rezervacija / oslobađanje mesta (id-jevi su id-jevi grupe rezervacija). |
/checkout | Kreiranje checkout sesije i URL-a za preusmeravanje na plaćanje. |
/checkout/status | Proveren status plaćanja za checkout. |
Šeme zahteva i odgovora za svaki endpoint nalaze se u API referenci — potrebne su vam samo ako gradite sopstveni klijent umesto korišćenja SDK-a.
Direktno pozivanje API-ja (bez SDK-a)
Odeljak pod nazivom „Direktno pozivanje API-ja (bez SDK-a)“Za integracije na serverskoj strani — sinhronizacija događaja u vaš CMS, prikaz sopstvene liste događaja — pozivajte iste endpointe običnim HTTP zahtevima. Autentifikacija je zamena site key-a za token; ne postoji korisnički nalog, API key header niti kolačić.
1. Zamenite site key za auth token:
curl -X POST https://api.anybiz.rs/api/events/sdk/auth \ -H "Content-Type: application/json" \ -d '{"siteKey":"sdk_pub_vas_kljuc","origin":"https://www.example.com"}'{ "authToken": "eyJqdGkiOi...", "expiresAt": "2026-09-14T12:30:00.000Z" }Pravila za origin prate listu dozvoljenih origin-a vašeg ključa: ako je lista prazna, svaki origin prolazi i polje možete izostaviti; ako je lista podešena, morate poslati jedan od navedenih origin-a ili zahtev pada sa 403. Iz pregledača SDK automatski šalje origin stranice.
2. Izlistajte događaje tokenom:
curl -X POST https://api.anybiz.rs/api/events/sdk/events \ -H "Content-Type: application/json" \ -d '{"authToken":"<token-iz-koraka-1>"}'[ { "id": "evt_123", "name": "Letnji koncert", "description": null, "archived": false, "createdAt": "2026-06-01T10:00:00.000Z", "updatedAt": "2026-06-10T09:00:00.000Z" }]3. Izlistajte termine za događaj:
curl -X POST https://api.anybiz.rs/api/events/sdk/displays \ -H "Content-Type: application/json" \ -d '{"authToken":"<token>","eventId":"evt_123"}'Auth token ističe posle 30 minuta — kada dobijete grešku o isteku, ponovite korak 1 umesto dugotrajnog keširanja tokena.
Preostali endpointi (/session, /init, /availability, /reserve, /checkout) zahtevaju session token po posetiocu, vezan za jedan termin, i predviđeni su da ih SDK poziva iz pregledača kupca. Ako gradite potpuno sopstveni checkout klijent, pratite šeme u API referenci.
Rešavanje problema
Odeljak pod nazivom „Rešavanje problema“TicketMap request failed (403)priauthenticate— origin vaše stranice nije na listi dozvoljenih origin-a za site key, ili je ključ pogrešan.- Mapa se prikazuje, ali su sva mesta crvena/siva — mesta su rezervisana ili prodata, ili je prodajni period termina zatvoren. Proverite
salesStartTime/salesEndTimei status termina. Izaberite barem jedno mesto pre checkout-a—checkout()je pozvan bez izbora i bez zadržanih rezervacija.- U kontejneru se ništa ne prikazuje — element kontejnera mora postojati pre poziva
init()i mora imati širinu; mapa se prilagođava dimenzijama kontejnera.