Skip to content

TicketMap SDK Integration

Use the TicketMap SDK to render event seat maps and run checkout from external websites.

The SDK uses a local selection first model: tapping a seat only updates UI selection (selectedSeatIds); nothing is reserved on the server until your code calls sdk.hold() or sdk.checkout(). If hold() was used, checkout(...) only pays for accumulated holds.

Use onSeatClick when you want a hook that runs only on user taps (not during polling updates). onSeatSelect / onSelectionChange run after availability sync — see below.

<div id="ticket-map"></div>
<button id="checkoutBtn" disabled>Checkout (0)</button>
<div id="summary">No seats selected</div>
<ul id="items"></ul>
<script src="https://cdn.yourapp.com/ticketmap.min.js"></script>
<script>
;(async () => {
const auth = await TicketMap.authenticate({
siteKey: 'sdk_pub_demo_12345678'
})
const sdk = await TicketMap.init({
container: '#ticket-map',
eventId: 'evt_123',
displayId: 'disp_456',
authToken: auth.authToken,
onSelectionChange: (selection) => {
const checkoutBtn = document.getElementById('checkoutBtn')
const summary = document.getElementById('summary')
const items = document.getElementById('items')
checkoutBtn.disabled = selection.items.length === 0
checkoutBtn.textContent = `Checkout (${selection.items.length})`
summary.textContent =
selection.items.length === 0
? 'No seats selected'
: `${selection.items.length} seat(s) • ${selection.total} ${selection.currency ?? ''}`.trim()
items.innerHTML = ''
selection.items.forEach((item) => {
const li = document.createElement('li')
li.textContent = `Row ${item.seatRow} Seat ${item.seatNumber} - ${item.effectivePrice} ${item.currency}`
items.appendChild(li)
})
}
})
document.getElementById('checkoutBtn').addEventListener('click', async () => {
await sdk.checkout()
})
})()
</script>
  • container: CSS selector or HTMLElement where widget mounts.
  • eventId: AnyBiz event id.
  • displayId: AnyBiz display id that belongs to the given event.
  • authToken: token from TicketMap.authenticate({ siteKey }).
  • apiBaseUrl: defaults to /api/events/sdk on current origin.
  • holdMinutes: hold TTL before checkout.
  • pollMs: availability polling interval in milliseconds.
  • customerName, customerEmail, customerPhone: optional customer details forwarded to /sdk/checkout (recommended for MSU).
  • onSeatSelect(selection): full SdkSelectionSnapshot after every sync (first load, polling, seat taps). Use selection.seatIds / selection.items (includes row, section title, price, currency, hold metadata).
  • onSeatClick(detail): tap-only{ seatId, action: 'select' | 'deselect', seat, selection }. Call await sdk.hold() here if you want immediate server holds per tap.
  • onSelectionChange(selection): same snapshot as onSeatSelect; use either or both depending on whether you need deduplication.
  • onCheckoutStart, onCheckoutResult, onError.

TicketMap.init(...) resolves to an SDK instance with:

  • hold(options?): POST /reserve for current selection; merges reservation ids for a later checkout().
  • checkout(options?): if hold() added ids, runs POST /checkout for those only; otherwise reserves current selection then checks out (legacy one-shot).
  • releaseHeldReservation(id), getHeldReservationIds().
  • refreshAvailability(): manually reloads seat availability.
  • getSelectedItems(): currently selected ticket items.
  • getSelectionSnapshot(): full selection payload (seatIds, items, total, currency).
  • destroy(): unmount SDK and cleanup listeners.

onSelectionChange receives:

  • seatIds: string[]
  • items: Array<{ seatId, sectionId, sectionTitle, seatRow, seatNumber, effectivePrice, currency, availability, reservationId, heldByMe, reservedUntil, reservationHolderName?, reservationHolderEmail?, reservationHolderPhone? }>
  • total: string
  • currency: string | null

reservationId is the parent reservation group id (ev_reservation.id) when the seat is currently held.

SDK APIs now treat reservation ids as group ids:

  • POST /api/events/sdk/reserve returns one row per seat and includes reservationId (parent id).
  • id may still be present in reserve response as a temporary compatibility alias; prefer reservationId.
  • POST /api/events/sdk/release expects parent reservationId.
  • POST /api/events/sdk/checkout expects reservationIds as parent group ids.

SDK mounts using Shadow DOM so host CSS does not break the seat map.

  • Styles are injected in shadow root.
  • Konva rendering stays inside SDK container.
  • Public surface is only window.TicketMap.

SDK uses these routes:

  • POST /api/events/sdk/auth
  • POST /api/events/sdk/events
  • POST /api/events/sdk/displays
  • POST /api/events/sdk/session
  • POST /api/events/sdk/init
  • POST /api/events/sdk/availability
  • POST /api/events/sdk/reserve
  • POST /api/events/sdk/release
  • POST /api/events/sdk/checkout
  • POST /api/events/sdk/checkout/status

For MSU checkout, keep callback processing on the API domain, then redirect users to a friendly website page:

  1. Browser is redirected to MSU HPP.
  2. MSU returns to fixed callback endpoint: /api/events/sdk/msu/return.
  3. Backend verifies payment (QUERYTRANSACTION) and finalizes checkout.
  4. Backend redirects user to organization-specific friendly page from SDK settings (sdk_settings.returnUrl), forwarding callback fields like:
    • msuAccepted
    • responseCode
    • responseMsg
    • merchantPaymentId
    • checkoutId

Recommended website result page examples:

  • Production: https://merchant-a.com/payment-result

Configure these values in AnyBiz Settings -> SDK for your organization:

  • siteKey (string): publishable key passed to TicketMap.authenticate({ siteKey })
  • allowedOrigins (string[]): parent origins allowed for that key (empty array = allow any)
  • sessionSecret (optional string): optional per-organization HMAC secret for SDK session tokens
  • returnUrl (optional string): friendly page URL where user lands after backend processed MSU callback

siteKey must be unique across organizations.