Configure external analytics and consent

Availability
Beta
Last verified
Last verified Aug 18, 2026

Use this workflow when you need to send online ticket purchases to a customer-managed analytics platform, tag manager, marketing pixel, or other destination. KORONA Event supplies a consent-aware purchase-event contract; your team or agency supplies the consent manager, destination code, and any adapter or field transformation.

What is supported

RequirementKORONA Event supportWho completes the setup
External analytics or tag managerCustomer-managed HTML and JavaScript can load on KORONA Event shop, payment, and success pages, but not on an external payment provider's site.Your team or agency installs, publishes, and maintains the provider code or container.
Marketing pixel or other browser destinationAn event adapter can listen for `purchase` and call a compatible destination SDK or API after destination-specific consent.Confirm compatibility, implement any field transformations, and configure the destination's consent controls.
Successful-order or thank-you-page trackingA paid order emits `purchase` on the success page when analytics consent is already active.Do not use the page URL alone; trigger the destination from the `purchase` event.
Purchase detailsThe purchase object contains a transaction ID, gross order value, currency, tax, applied voucher numbers, and items. Its meanings may differ from a destination's schema.Read the payload contract and transform values before forwarding them when the destination uses different semantics.
Campaign attributionCampaign parameters and ad click identifiers from the shop landing URL can accompany consent-managed events.Preserve the parameters when linking into the shop, then map them only where the destination supports that use.
Worked Google setupThe documented example covers GTM, GA4, Google Ads purchase conversions, Google Consent Mode, and Google-specific attribution controls.Create and configure the Google accounts, tags, consent behavior, and required transformations.
Consent bannerCustom consent-manager HTML and JavaScript can be added to every shop page.Select, license, configure, and legally approve the consent manager. KORONA Event does not provide a built-in cookie banner.
Server-side settled-order notificationThe Order Settled webhook reports settled order facts.Build and operate the receiving service. The webhook does not include browser campaign or ad-click identifiers.

KORONA Event does not provide a native or managed connection to a specific analytics platform, tag manager, pixel, marketing destination, or consent-management platform. Custom HTML and JavaScript snippets and the purchase-event contract are extension points. Another provider can use them only when your customer-managed snippet or adapter can consume the documented contract and meet that provider's technical, consent, and data requirements.

Before you start

Prepare:

  • the destination account, SDK, container, pixel, or API documentation
  • a field map from the documented purchase contract to the destination's required meanings
  • a consent manager that can restore the visitor's current choice and call JavaScript when that choice changes
  • campaign-link and cross-domain requirements for the selected destination
  • legal approval for the consent categories, retention, and destinations
  • a paid test checkout and access to the destination platform's preview or diagnostics view

For the Google example, also prepare the GTM container ID or approved `gtag` code, the GA4 property, the Google Ads conversion action, Google Ads auto-tagging, a site-wide Google tag or Conversion Linker, and any required cross-domain linking.

Agree who owns each layer before launch: KORONA Event produces the purchase event, the consent manager decides whether optional tracking may run, your snippet or adapter transforms and routes the event, and the external destination records it. Your organization remains responsible for provider compatibility and account configuration.

1. Choose the analytics mode

  1. In the back office, open Shops and select the shop.
  2. Open Checkout.
  3. In Analytics, set Mode:
ModeWhat it doesWhen to use it
Privacy-preservingSends no KORONA Event booking or ecommerce events to `window.dataLayer`. This is the default.Use this when no customer-managed conversion tracking should receive shop events.
Consent-managedSends ecommerce events to `window.dataLayer` only while the shop has live analytics consent.Use this for GTM, GA4, Google Ads, or another consent-aware external analytics setup.
DisabledStops KORONA Event shop analytics events.Use this when all KORONA Event shop analytics must be off.
  1. Select Consent-managed for the setup in this article, then save the shop.
  1. Open Code snippets for the shop.
  2. Under Custom HTML and JavaScript snippets, add the consent bridge and consent manager with Placement set to Top of `<head>`. Make sure the bridge runs before the consent manager invokes its reporting callback. They must restore consent before a paid order reaches the success event.
  3. Add GTM or other analytics code as a separate snippet. Use Top of `<head>` when the provider requires early initialization and your consent manager blocks it correctly. Use Start of `<body>` for optional scripts that can wait until the page has loaded.
  4. Keep dependent snippets in the required order and save the shop.
Custom HTML and JavaScript snippets for a consent manager and analytics tags
Add the consent manager, consent bridge, and GTM or analytics snippets separately so their order and placement are clear.

Body-positioned snippets start after the initial page load, when the browser is idle. An ordered external body script that does not load within 10 seconds is skipped so later snippets can continue. Do not place the consent-restoration step only in a delayed body snippet: the paid success event may occur first.

On every full shop, payment, or success-page load, your consent manager must read its saved decision and report the current state again. It must also report later acceptance, rejection, or withdrawal. KORONA Event does not persist the visitor's consent-manager decision for you.

The shop exposes either of these equivalent controller names:

```js window.ShopBookingAnalytics; window.__SHOP_BOOKING_ANALYTICS__; ```

The following vendor-neutral bridge waits briefly for that controller. Add it near the start of the Top of `<head>` snippets, then call `window.reportKoronaEventConsent` from your consent manager's initial-state and change callbacks:

```html <script> (function () { var latestChoice = { analytics: false, marketing: false }; var retryStartedAt = 0; var retryTimer = null;

function applyChoice() { var analytics = window.ShopBookingAnalytics || window.__SHOP_BOOKING_ANALYTICS__;

if (analytics) { analytics.setConsent(latestChoice); retryTimer = null; return; }

if (Date.now() - retryStartedAt < 10000) { retryTimer = window.setTimeout(applyChoice, 50); } else { retryTimer = null; } }

window.reportKoronaEventConsent = function reportKoronaEventConsent(choice) { latestChoice = { analytics: choice.analytics === true, marketing: choice.marketing === true, }; retryStartedAt = Date.now();

if (retryTimer === null) { applyChoice(); } }; })(); </script> ```

Adapt the callback names to your consent manager. The calls themselves should follow this pattern:

```js // Restore or grant analytics and marketing consent. window.reportKoronaEventConsent({ analytics: true, marketing: true });

// Reject or withdraw optional analytics and marketing consent. window.reportKoronaEventConsent({ analytics: false, marketing: false }); ```

Use the actual categories approved for your organization. Do not copy the `true` example as a default consent choice.

The `analytics` value controls KORONA Event's consent-managed storage and data-layer events. A `purchase` can therefore reach `window.dataLayer` when `analytics` is `true` even if `marketing` is `false`. The `marketing` value does not replace the advertising-consent controls required by your consent manager, GTM, Google Consent Mode, Google Ads, or applicable law. Configure those controls separately so advertising tags do not fire with analytics-only consent.

Reporting `analytics: false` stops new consent-managed data-layer events and storage use. It does not delete analytics context already stored in the visitor's browser, remove an event already pushed to `window.dataLayer`, or recall data that a tag already forwarded to or that is held by GA4, Google Ads, or another provider. Your organization owns the CMP and tag cleanup behavior, storage lifetime, and any provider-side retention or deletion process required by its approved consent design.

Instead of the controller, an integration that runs after the shop is ready can dispatch this browser event:

```js window.dispatchEvent( new CustomEvent("shop-booking-analytics:consent-update", { detail: { analytics: true, marketing: true }, }), ); ```

The KORONA Event consent bridge and Google Consent Mode control different layers. The bridge controls when KORONA Event may store analytics context and add ecommerce events to `window.dataLayer`. Google Consent Mode controls how Google tags behave. Connect both layers to the same consent manager, using the categories and defaults approved for your organization.

If you use GTM:

  • Prefer your consent-management platform's template from the Community Template Gallery, where available.
  • Run the consent template on Consent Initialization - All Pages so it sets defaults before tags that send measurement data.
  • If you create a custom GTM template, use the Tag Manager consent APIs `setDefaultConsentState` and `updateConsentState`. Do not substitute queued `gtag('consent', ...)` commands inside that template.
  • Update all applicable consent types whenever the visitor changes a choice, and restore the saved choice on subsequent page loads.

If you use the Google tag directly without GTM, place a denied default before the Google tag loader and before any `config` or `event` command:

```html <script> window.dataLayer = window.dataLayer || []; window.gtag = window.gtag || function () { window.dataLayer.push(arguments); };

window.gtag("consent", "default", { analytics_storage: "denied", ad_storage: "denied", ad_user_data: "denied", ad_personalization: "denied", }); </script> ```

Call an update from the consent manager as soon as the visitor saves or changes a choice. Use separate values so the mapping can follow your approved categories:

```html <script> window.updateGoogleConsent = function updateGoogleConsent(choice) { window.gtag("consent", "update", { analytics_storage: choice.analyticsStorage === true ? "granted" : "denied", ad_storage: choice.adStorage === true ? "granted" : "denied", ad_user_data: choice.adUserData === true ? "granted" : "denied", ad_personalization: choice.adPersonalization === true ? "granted" : "denied", }); }; </script> ```

Google Consent Mode does not save the visitor's choice for you. On every full page load, set the default first, then have the consent manager read its saved choice and call the update as soon as that choice is known. Send another update whenever the visitor changes or withdraws consent.

Do not treat the property names in this example as a universal category mapping. Your organization must decide how its legally approved CMP categories map to `analytics_storage`, `ad_storage`, `ad_user_data`, and `ad_personalization`. It must also choose between Basic Consent Mode, which blocks Google tags before consent, and Advanced Consent Mode, which can load Google tags with denied consent states. That choice does not change the KORONA Event rule: `purchase` reaches `window.dataLayer` only after the bridge receives `analytics: true`.

See Google's consent mode implementation guide and GTM consent-template guide for the provider-specific implementation details.

3. Connect an external destination

Use this provider-neutral workflow for an analytics platform, tag manager, pixel, or other browser destination:

  1. Read the purchase payload contract, including KORONA Event's meanings for value, tax, vouchers, items, and campaign fields.
  2. Create a customer-managed snippet or event adapter that listens for `purchase`, transforms the fields to the destination's semantics, and then calls the compatible destination SDK or API.
  3. Allow that destination call only after the destination-specific consent required by your approved CMP design. KORONA Event's `analytics: true` controls the purchase event, but does not grant consent to every external destination.
  4. Use the transaction ID for destination-side deduplication where supported, and define how your integration handles any lifecycle events that the purchase payload does not provide.
  5. Validate a paid purchase with accepted, rejected, and later withdrawn consent. Rejection and withdrawal must prevent future destination calls; withdrawal cannot recall data already sent.

The destination code, adapter, transformations, consent mapping, and account configuration remain customer-managed. This workflow does not imply native compatibility with a particular provider.

Worked example: GTM, GA4, and Google Ads

The following recipe uses GTM to route one purchase to GA4 and Google Ads. If you use another destination, implement the provider-neutral workflow above with that provider's supported SDK or API instead.

In your GTM container:

  1. Create a Custom Event trigger whose event name is exactly `purchase`.
  2. Create data-layer variables for the fields your destination needs:
PurposeData-layer path
Transaction ID`ecommerce.transaction_id`
Gross order value`ecommerce.value`
Currency`ecommerce.currency`
Purchased items`ecommerce.items`
Tax`ecommerce.tax`
Applied voucher number(s), comma-separated`ecommerce.coupon`
Captured Google Ads click ID, for diagnostics or custom integrations`toucantix_booking_event.gclid`
Campaign source`toucantix_booking_event.utm_source`
Campaign medium`toucantix_booking_event.utm_medium`
Campaign name`toucantix_booking_event.utm_campaign`
  1. For GA4, create a GA4 event tag for `purchase`. Transform the monetary and voucher fields as described below before mapping them to GA4.
  2. For Google Ads, create a Google Ads conversion tag for the purchase conversion action and map the transaction ID, currency, and intended conversion value. `ecommerce.value` is the gross order value; use it directly only when the Ads conversion action should report that gross value.
  3. Apply the `purchase` trigger and your consent requirements to each destination tag.
  4. Publish the GTM container only after the accepted- and rejected-consent tests pass.

A bare GA4 or Google Ads base tag does not automatically translate the KORONA Event `purchase` object into a recorded conversion. If you do not use GTM, your custom code must listen for the event, apply any destination-specific transformations, and call the destination API with the resulting values.

Transform purchase values and vouchers for GA4

The KORONA Event object is GA4-shaped, not a ready-to-send GA4 purchase. Its source values follow KORONA Event commerce semantics:

  • `ecommerce.value` is the gross order total in the currency's major unit.
  • Each item's `price` is the configured unit price, or the item's gross total divided by quantity when no configured unit price is available. It can therefore include tax.
  • `ecommerce.tax` is the separately calculated tax total.
  • The payload does not expose a separate shipping amount.

GA4 requires purchase `value` to equal the sum of `price * quantity` across the submitted items, excluding tax and shipping. If tax or shipping makes the raw KORONA Event values inconsistent with that rule, transform the item prices and purchase value in GTM or custom code before sending the GA4 event. If a shipping amount is included in the gross order but is not otherwise available to your integration, do not send the raw gross total as GA4 purchase `value`; obtain the required value from an approved source or omit the mapping until it can be calculated correctly.

`ecommerce.coupon` contains the number of each applied or redeemed voucher, joined with commas when more than one voucher is present. If a voucher has no number, its name can be used as a fallback. Applied promotion or discount codes are not exposed in this payload. Map this value to GA4 `coupon` only when your organization intentionally reports voucher redemption as a promotion; otherwise omit or transform it.

These GA4 rules do not determine the value sent to a Google Ads conversion action. Configure the Ads value separately according to your advertising reporting and bidding requirements.

See Google's official `purchase` event specification for GA4 parameter semantics.

Preserve Google Ads click attribution

For a standard Google Ads website conversion, the conversion tag uses click information stored by the Google tag or Conversion Linker. Configure that attribution layer in addition to the `purchase` trigger:

  1. Run the Google tag on every applicable landing and conversion page, in accordance with your chosen consent mode. If your GTM container already loads a Google tag on every page, a separate Conversion Linker is not normally required.
  2. If the setup does not provide the site-wide Google tag behavior, create a Conversion Linker tag and fire it with an All Pages trigger or the applicable landing- and conversion-page triggers, subject to the same consent requirements.
  3. If the marketing site and online shop use different domains, configure cross-domain linking for both domains. The source must decorate links to the shop and the destination must accept the linker parameter. Preserving a raw `gclid` in the URL alone does not replace this setup.
  4. Keep the standard Google Ads conversion tag mapped to `ecommerce.transaction_id`, `ecommerce.currency`, and the intended conversion value. Use the raw gross `ecommerce.value` only when that is the value the Ads conversion action should report.

Do not map `toucantix_booking_event.gclid` into the standard Google Ads website conversion tag. That field is useful for diagnostics or a separately designed custom or server-side integration; the standard website tag associates the conversion through the Google tag or Conversion Linker state.

See Google's Conversion Linker guidance for the current tag and cross-domain options.

Purchase payload contract

KORONA Event clears the previous ecommerce object, then pushes the purchase. This simplified example shows the stable fields intended for customer-managed tags:

```js window.dataLayer.push({ ecommerce: null }); window.dataLayer.push({ event: "purchase", event_id: "event-id", ecommerce: { transaction_id: "INV-10042", value: 52, currency: "EUR", tax: 9, coupon: "VOUCHER-10042", payment_method: "card", items: [ { item_id: "adult-ticket", item_name: "Adult", item_category: "ticket", item_category2: "event", price: 26, quantity: 2, }, ], }, toucantix_booking_event: { event_name: "purchase", utm_source: "google", utm_medium: "cpc", utm_campaign: "summer-tickets", gclid: "example-click-id", }, }); ```

The real event can contain more fields and `null` values. Treat the documented paths above as the KORONA Event integration contract rather than copying the sample values or assuming they already meet another provider's semantics.

  • `transaction_id` uses the invoice number when available and falls back to the order number.
  • `value` is the gross amount in the currency's major unit: `52` means EUR 52.00 when `currency` is `EUR`.
  • `items` contains the purchased ticket or product rows with configured or gross-derived prices and quantities.
  • `coupon` contains applied voucher numbers, not applied promotion or discount codes. Multiple vouchers are comma-separated.
  • KORONA Event emits the browser purchase when a paid order reaches the success page with live analytics consent.
  • Repeated success-page visits are deduplicated on a best-effort basis in that browser. Clearing browser storage, using another browser or device, or a duplicate destination trigger can still create duplicates.
  • Pending or failed payments do not emit `purchase`. Refunds and cancellations do not emit a compensating ecommerce event to the customer data layer.

4. Preserve campaign attribution

The online shop reads these values from the landing-page address while analytics consent is active:

  • `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, and `utm_content`
  • `gclid` and `fbclid`
  • `campaign_id` and `placement_id`

For a direct Google Ads link into the shop, keep Google Ads auto-tagging enabled if your approved setup uses `gclid`, or add the UTM parameters required by your reporting. For a campaign that first lands on another website, that website must preserve the required parameters when it links or redirects into the shop. KORONA Event cannot recover a click identifier that is removed before the visitor reaches the shop.

Campaign context is stored and added to rich booking events only after the visitor grants analytics consent. If the visitor navigates away from the original campaign URL before granting consent, the original parameters may not be available for the later purchase.

For a friendly campaign URL or direct offer link, see Add deep links from a marketing page.

5. Test the complete setup

Use a test conversion action or analytics property when your provider supports one.

  1. Open the exact campaign link in a clean browser session.
  2. In GTM Preview or an equivalent debug view, confirm that the consent manager sets Google consent defaults before measurement and that the KORONA Event bridge reports the current choice before checkout events.
  3. Reject optional consent. Using your approved test-payment process, complete a paid checkout and confirm that no KORONA Event `purchase` appears in `window.dataLayer`. Confirm that Google tags follow the basic or advanced consent behavior your organization selected and do not use consent-dependent storage or advertising features while the relevant states are denied.
  4. Start a new clean session, accept the approved analytics and marketing choices, and complete a paid test checkout.
  5. On the success page, confirm one `purchase` event with the expected transaction ID, gross value, currency, and items.
  6. Confirm that the GA4 and Google Ads tags fire once and that the destination diagnostics receive the test event. Verify that GA4 receives a value equal to the transformed item total excluding tax and shipping, while Google Ads receives the separately configured conversion value.
  7. Use Tag Assistant or the equivalent preview to confirm that the Google tag or applicable Conversion Linker is active on the campaign landing page and success page. When domains differ, confirm that cross-domain links carry the linker parameter and the shop accepts it.
  8. Repeat the accepted-consent checkout on a mobile viewport and after a payment-provider redirect when that provider leaves and returns to the shop.

The paid order in KORONA Event and the destination event should use the same invoice number as `transaction_id`. Do not configure a separate page-view conversion on the success URL; it can count refreshes without the ecommerce payload.

Server-side alternative

Use the Order Settled webhook when an external system needs an authoritative notification that an order became settled. Its payload includes the order number, payment state and method, currency, gross values, and line items.

The webhook is not a ready-made Google Ads or GA4 integration. It does not contain browser UTM parameters, `gclid`, or `fbclid`, so it cannot by itself distinguish purchases from advertising campaigns or upload Google offline conversions. A customer-owned server-side integration must capture the legally permitted click or session identifier separately, join it to the settled order, deduplicate deliveries, and send the destination request.

Troubleshooting

ProblemWhat to check
No `purchase` in `window.dataLayer`Mode is Consent-managed, the success page has a paid order, and the consent bridge reported `analytics: true` before the purchase event.
`purchase` exists but GA4 or Google Ads receives nothingGTM container publication, the exact `purchase` Custom Event trigger, destination tag configuration, field mappings, Google consent states, and destination consent requirements.
GA4 revenue does not match the intended item revenueThe GA4 tag transforms gross/configured KORONA Event values so `value` equals the submitted item `price * quantity` total and excludes tax and shipping. Check that applied voucher numbers were not treated as GA4 promotion codes unintentionally.
GTM loads before consentConsent-manager blocking rules, snippet order, and whether the GTM tag has the required consent checks. Analytics mode alone does not block the GTM snippet.
Campaign or `gclid` is missingThe parameter reached the shop landing URL and analytics consent was active before the campaign context needed to be stored.
Google Ads records a conversion without campaign attributionThe site-wide Google tag or applicable Conversion Linker runs on landing and conversion pages, has the required consent, and uses cross-domain linking when the marketing site and shop use different domains. Do not pass the diagnostic `toucantix_booking_event.gclid` field to the standard website conversion tag.
Conversion fires twiceA second page-view trigger, more than one destination tag, repeated GTM containers, cleared browser storage, or testing from another browser or device.
Tracking works in the shop but not after paymentThe consent manager restored its current choice on the payment or success-page load and reported it through the consent bridge before `purchase`.
Consent banner covers checkout controlsAdjust the consent-manager layout for small screens without using custom CSS that hides checkout actions.

Ready to Get Started?

Book a free demo or reach out — we’d love to hear from you.