Appearance
Advanced Usage
Analytics & GTM
The widget fires standard DOM CustomEvents with bubbles: true and composed: true. They cross the shadow DOM boundary and are visible at window level — no special configuration needed.
Event reference
| Event | Fires when | Detail payload |
|---|---|---|
booksea:widget-loaded | Widget data has loaded | { companySlug } |
booksea:availability-confirmed | Date and service are confirmed as available | { service, date, pax } |
booksea:checkout-started | Payment intent created (user clicked Pay Now) | { pricingUuid, total, currency } |
booksea:payment-success | Stripe confirms the payment | { bookingReference, total, currency } |
booksea:payment-failure | Payment failed or was cancelled | { errorCode } — see error codes |
Listening to events
Subscribe to any event in plain JavaScript:
js
window.addEventListener('booksea:payment-success', function (e) {
console.log('Booking confirmed:', e.detail.bookingReference);
});Error codes
Possible values for errorCode in booksea:payment-failure:
| Code | Meaning |
|---|---|
payment_cancelled | Customer closed the payment modal |
payment_declined | Card was declined by the issuer |
payment_network_error | Network or connectivity failure during payment |
payment_timeout | Payment request timed out |
payment_failed | Any other failure |
GTM bridge example
How you bridge events into dataLayer depends on your GTM setup. Here is one way to do it:
html
<script>
(function () {
window.dataLayer = window.dataLayer || [];
window.addEventListener('booksea:payment-success', function (e) {
var detail = e.detail || {};
window.dataLayer.push({
event: 'payment_success',
booksea_total: detail.total || '',
booksea_currency: detail.currency || 'EUR',
booksea_reference: detail.bookingReference || '',
});
});
window.addEventListener('booksea:checkout-started', function (e) {
var detail = e.detail || {};
window.dataLayer.push({
event: 'pay_now_click',
booksea_total: detail.total || '',
booksea_currency: detail.currency || 'EUR',
});
});
})();
</script>