Preskoči na sadržaj

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.

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.

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.

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.

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 poziva hold(); svaki poziv dodaje nove rezervacije u korpu. Kasniji sdk.checkout() plaća sve zadržane rezervacije (i prazni korpu). Pozovite releaseHeldReservation(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.

Obavezno:

OpcijaTipOpis
containerstring | HTMLElementCSS selektor ili element u koji se vidžet montira.
eventIdstringAnyBiz id događaja.
displayIdstringId termina koji pripada tom događaju.
authTokenstringToken dobijen od TicketMap.authenticate({ siteKey }).

Opciono:

OpcijaTipPodrazumevanoOpis
apiBaseUrlstringtrenutni origin + /api/events/sdkUvek postavite na https://api.anybiz.rs/api/events/sdk.
lang'en' | 'sr''en'Jezik ugrađenih UI tekstova.
labelsPartial<SdkLabels>—Zamena pojedinačnih UI tekstova (statusi, legenda, poruke o greškama).
holdMinutesnumber10Trajanje rezervacije na serveru za hold() / checkout() u jednom koraku.
pollMsnumber10000Interval osvežavanja dostupnosti u milisekundama.
autoPollAvailabilitybooleantruePostavite false da isključite polling i sami pozivate refreshAvailability().
customerName / customerEmail / customerPhonestring—Podrazumevani podaci o kupcu koji se šalju uz checkout (poziv checkout() može da ih pregazi).
promoCodestring | null—Podrazumevani promo kod koji se primenjuje pri checkout-u.
reservationHolderName / reservationHolderEmail / reservationHolderPhonestring—Opcioni podaci o nosiocu rezervacije koji se čuvaju uz rezervacije napravljene kroz hold().

Callback funkcije:

CallbackKada 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.

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;
}

TicketMap.init() vraća instancu sa metodama:

MetodaOpis
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.

Plaćanje se obavlja na hostovanoj stranici za plaćanje (MSU), ne na vašem sajtu:

  1. checkout() preusmerava pregledač na stranicu za plaćanje.
  2. Posle plaćanja, platna platforma poziva AnyBiz API, koji proverava transakciju i finalizuje checkout (ulaznice se izdaju pri uspehu).
  3. 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 platforme
    • merchantPaymentId — referenca plaćanja
    • checkoutId — id checkout sesije
    • msuAccepted — 1 kada je callback prepoznat i obrađen, 0 u suprotnom; ovo nije indikator uspešnog plaćanja — ishod čitajte iz responseCode

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.

  • 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 pozovite authenticate() i init(). Za stranice koje dugo ostaju otvorene, autentifikujte se ponovo pre novog init() poziva umesto keširanja tokena.

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',
},
});

SDK je tanak klijent nad javnom SDK familijom endpointa na https://api.anybiz.rs/api/events/sdk. Svi su POST sa JSON telom:

EndpointNamena
/authZamena site key-a za auth token.
/events, /displaysLista događaja / termina dostupnih za prodaju.
/sessionKreiranje sesije po posetiocu za jedan termin.
/initUčitavanje podataka mape sedenja.
/availabilityDostupnost mesta uživo.
/reserve, /releaseRezervacija / oslobađanje mesta (id-jevi su id-jevi grupe rezervacija).
/checkoutKreiranje checkout sesije i URL-a za preusmeravanje na plaćanje.
/checkout/statusProveren 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.

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:

Terminal window
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:

Terminal window
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:

Terminal window
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.

  • TicketMap request failed (403) pri authenticate — 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/salesEndTime i 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.