Skip to main content

Ticketing widget

Setup

Note

Before starting the setup, you should have a Google Tag Manager and a Google Analytics account.

Setting up Google Analytics 4 requires executing steps in the Google Analytics application, the Google Tag Manager application, and in the webpage hosting the Ticketing widget.

When all these steps are executed correctly, data from the Ticketing widget will become available in the Google Analytics reports after 24 to 48 hours.

Setup Google Analytics 4

  1. Login to your Google Analytics account.

  2. Create a new data stream via Admin > Account > Property > Data Streams.

    3.png

    Click the Add streams dropdown, and select the source type you want to stream. Select Web as the source type.

    4.png
  3. Set up web stream.

    Fill in the URL of the website hosting the Ticketing widget and choose a stream name. Thereafter, click the Create stream button. Ignore the installation instructions by clicking the close button.

    5.png
  4. Copy the Measurement ID (identifier starting with G-)so that it can be used in the setup of Google Tag Manager. You can find it again in Admin > Data collection and modification > Data streams > your stream.

    6.png

Setup Google Tag Manager (v1)

  1. Login to your Google Tag Manager account and start by creating a new container.

    7.png
  2. Fill in a container name, select the correct target platform (Web), and click Create.

    8.png

    Ignore the ‘Install Google Tag Manager’ window for now, by clicking the OK button.

  3. On the ‘Workspace‘ page, click Tags and then click New.

    9.png
  4. Edit the Tag Configuration and choose Google Analytics: GA4 Configuration as the tag type.

    10.png
    11.png
    12.png
  5. Paste the ‘Measurement ID‘ you copied from Google Tag Manager.

    If you need to copy it again, you can find it in Google Analytics > Admin > Account > Property > Data Streams > Your stream > MEASUREMENT ID (identifier starting with ‘G-’).

    14.png
  6. Add a trigger by clicking on the Triggering tile and then the + button.

    13.png
  7. Click the Trigger Configuration tile and select Custom Event as the trigger type (under Other).

    15.png
  8. Complete the Trigger Configuration settings.

    Add the following value to the event name field:

    view_item|add_to_cart|remove_from_cart|begin_checkout|add_payment_info|purchase|refund|view_cart|select_promotion|login|signup

    Note

    Select ‘Use regex matching’.

    16.png

    Give the trigger a name (eg. ‘GA4 - Ecommerce trigger‘) and click Save.

  9. Name the tag settings.

    The tag configuration should look like this:

    17.png

    Give it a name (eg. ‘GA4 - Configuration‘) and click Save.

  10. Create another Tag by clicking on the New button in the Tags component, and choose Google Analytics: GA4 event as the tag type.

    18.png
  11. Complete the Tag Configuration settings.

    Select the tag configuration you created in the previous steps as ‘Configuration Tag'.

    19.png

    For the ‘Event Name‘, click the add event name button next to the input field and select the variable with the name ‘Event‘.

    20.png
    21.png

    This will fill in the ‘Event Name‘ field with the value {{Event}}. Expand More Settings and check Send Ecommerce data.

    22.png
  12. Set a trigger by clicking on the Triggering tile and then select the previously created trigger.

    23.png
  13. Give the Tag Configuration a name and click Save.

  14. Finally, publish the tags.

    First, click the Submit button from the workspace page.

    24.png

    Indicate Publish and Create Version, add a version name and description, and click Publish.

    25.png
  15. Copy the script tags that need to be added to the Enviso Ticketing widget webpage.

    Navigate to Admin > Container > Install Google Tag Manager.

    26.png

    Copy the code that needs to be added to the <head> tag.

    27.png

Setup webpage hosting the Enviso Ticketing widget

  1. Open the webpage where the Enviso Ticketing Widget is hosted.

  2. Paste the script code (that was copied in step 15 of setting up Google Tag Manager) within the <head> tag.

  3. Publish the webpage.

When all steps are executed correctly, data from the Ticketing widget will become available in the Google Analytics reports after 24 to 48 hours.

Setup Google Tag Manager (v2)

Note

Before starting the setup, you should have a Google Tag Manager account and a Google Analytics 4 account.

Setting up Google Analytics 4 requires executing steps in the Google Analytics application, the Google Tag Manager application, and in the webpage hosting the Enviso Ticketing widget.

Overview

Step

Action

1

Setup Google Analytics 4

2

Setup Google Tag Manager

3

Setup webpage hosting the Enviso Ticketing widget

4

Register the custom fields in Google Analytics 4

5

Test and publish

6

Optional: Share hashed customer data with ad platforms

When all these steps are executed correctly, data from the Ticketing widget will become available in the Google Analytics reports after 24 to 48 hours.

Step 1: Setup Google Analytics 4

Refer Setup Google Analytics 4

Note

If your website already has a web data stream in Google Analytics 4, you only need its Measurement ID. Skip to Step 4: Register the custom fields in Google Analytics 4.

Step 2: Setup Google Tag Manager

Note

Instead of steps 3 to 6, you can import the ready-made container file enviso-widget-ga4-gtm.json via Admin > Import Container (choose Merge and Rename conflicting tags, triggers, and variables).

Then open the variable Const - GA4 Measurement ID, fill in your Measurement ID and continue with step 7. The file also contains a Google tag (Google Tag - GA4). If your container already has a Google tag with your Measurement ID, delete the imported one after the import, so page views are not counted twice.

  1. Login to your Google Tag Manager account and open the container used on the website hosting the Ticketing widget. If your website has no container yet, create one: fill in a container name, select Web as the target platform and click Create. Ignore the 'Install Google Tag Manager' window for now by clicking OK.

    10.png
  2. Make sure the Google tag exists. Click Tags and look for a tag of type Google Tag with your Measurement ID. If it is missing, click New, choose Google Tag as the tag type, paste your Measurement ID as the Tag ID, select the trigger Initialization - All Pages, name it (eg. 'Google Tag - GA4') and click Save.

    11.png

    Click new button.

    12.png

    Choosing a tag.

    13.png

    Click Google tag. Fill in information and save.

    14.png
  3. Create the variables. Click Variables and, under User-Defined Variables, click New. Choose Data Layer Variable as the variable type, fill in the Data Layer Variable Name from the table below and keep Data Layer Version on Version 2. Give the variable the name from the table and click Save. Repeat for each row.

    15.png

    Navigate to variables and click new on User-Defined Variables.

    16.png

    Fill in Data Layer Variable values.

    Variable name

    Data Layer Variable Name

    DLV - checkout_step

    checkout_step

    DLV - site_language

    site_language

    DLV - newsletter_optin

    newsletter_optin

    DLV - visit_date

    visit_date

    DLV - visit_timeslot

    visit_timeslot

    DLV - days_until_visit

    days_until_visit

    DLV - payment_type

    ecommerce.payment_type

    DLV - cart_discount

    cart_discount

    DLV - method

    method

    DLV - user_data.sha256_email_address

    user_data.sha256_email_address

    Result of all the Data Layer Variable values.

    17.png
  4. Create the trigger. Click Triggers and then New. Click the Trigger Configuration tile and select Custom Event as the trigger type (under Other). Add the following value to the event name field:

    ^(view_item_list|select_item|select_timeslot|add_to_cart|remove_from_cart|view_cart|apply_coupon|begin_checkout|add_shipping_info|add_payment_info|purchase|refund|login|sign_up)$

    Note

    Select 'Use regex matching'.

    Keep All Custom Events selected, give the trigger a name (eg. 'CE - Enviso widget events') and click Save.

    Navigate to Triggers and click New.

    18.png

    Fill in trigger information.

    19.png
  5. Create the GA4 event tag. Click Tags and then New, and choose Google Analytics: GA4 Event as the tag type. Paste your Measurement ID in the Measurement ID field. For the Event Name, click the add variable button next to the input field and select the variable with the name Event. This will fill in the Event Name field with the value {{Event}}.

    20.png
  6. Complete the tag configuration. Expand Event Parameters and add the rows below with Add parameter:

    Event Parameter

    Value

    checkout_step

    {{DLV - checkout_step}}

    site_language

    {{DLV - site_language}}

    newsletter_optin

    {{DLV - newsletter_optin}}

    visit_date

    {{DLV - visit_date}}

    visit_timeslot

    {{DLV - visit_timeslot}}

    days_until_visit

    {{DLV - days_until_visit}}

    payment_type

    {{DLV - payment_type}}

    cart_discount

    {{DLV - cart_discount}}

    method

    {{DLV - method}}

    Expand More Settings > Ecommerce, check Send Ecommerce data and select Data Layer as the data source. Set the trigger by clicking the Triggering tile and selecting the trigger created in step 4. Give the tag a name (eg. 'GA4 - Enviso widget events') and click Save.

    21.png
    22.png
  7. Respect your visitors' consent. If your cookie banner uses Google Consent Mode, GA4 tags follow it automatically. If it does not, ask your cookie banner provider how to block GA4 tags until the visitor accepts analytics cookies, and apply that to the new tag as well. If you share hashed customer data with ad platforms, also pass the visitor's advertising consent to the widget (see Optional: Share hashed customer data with ad platforms).

  8. If you created a new container in step 1, copy the script that needs to be added to the webpage. Navigate to Admin > Install Google Tag Manager and copy the code for the head tag.

    23.png
    24.png

    Note

    Do not publish yet. Test the setup first (see Step 5: Test and publish).

Step 3: Setup webpage hosting the Enviso Ticketing widget
  1. Open the webpage where the Enviso Ticketing widget is hosted.

  2. Turn on GA4 tracking in the widget. Add the line enviso.settings.gtmVersion = 'v2'; next to the other widget settings. Without it, the widget sends an older format that does not match this setup.

    <script>
        enviso.settings.apiKey = 'your-api-key';
        enviso.settings.salesPointId = 'your-sales-point';
        enviso.settings.gtmVersion = 'v2';
    </script>
  3. Make sure the Google Tag Manager code is on the page. If your website already uses Google Tag Manager, nothing changes. Otherwise, paste the script code (copied in step 8 of setting up Google Tag Manager) within the head tag, as high as possible.

  4. Publish the webpage.

    Note

    Add the setting on every page that shows the widget. If your Google Tag Manager code uses a different name than dataLayer, the widget detects it automatically.

Step 4: Register the custom fields in Google Analytics 4

Google Analytics 4 understands products, prices and orders automatically, but only shows the extra fields of the widget (like the visit date) in reports after you register them.

Note

Do this right away. Google Analytics 4 only shows these fields for data collected after you register them.

  1. In Google Analytics, navigate to Admin > Data display > Custom definitions.

  2. On the Custom dimensions tab, click Create custom dimension. Fill in the fields from one row of the table below and click Save. Repeat for each row.

    Dimension name

    Scope

    Event parameter / Item parameter

    Checkout step

    Event

    checkout_step

    Site language

    Event

    site_language

    Newsletter optin

    Event

    newsletter_optin

    Visit date

    Event

    visit_date

    Visit timeslot

    Event

    visit_timeslot

    Payment type

    Event

    payment_type

    Signin method

    Event

    method

    Item visit date

    Item

    visit_date

    Item visit timeslot

    Item

    visit_timeslot

    25.png
    26.png
  3. On the Custom metrics tab, click Create custom metric and create the two metrics below.

    Metric name

    Scope

    Event parameter

    Unit of measurement

    Days until visit

    Event

    days_until_visit

    Standard

    Cart discount

    Event

    cart_discount

    Currency

    27.png
  4. purchase is marked as a key event automatically. To count other events as key events, navigate to Admin > Data display > Events and switch on Mark as key event once the event appears in the list.

Step 5: Test and publish

When all steps are executed correctly, data from the Ticketing widget will become available in the Google Analytics reports after 24 to 48 hours.

  1. In Google Tag Manager, click Preview, enter the address of a page with the Ticketing widget and click Connect. Your website opens in a new window and a Tag Assistant tab shows what happens. Accept analytics cookies in your cookie banner.

    28.png
  2. Go through a booking in the website window. In Tag Assistant, a new line appears for each widget event. Click an event and check that GA4 - Enviso widget events is listed under Tags Fired.

    29.png
  3. In Google Analytics, navigate to Admin > DebugView. After a few seconds your test visit appears with the events in order. Click an event to see its parameters and products.

    30.png
  4. Finally, publish the container. Click the Submit button on the workspace page, select Publish and Create Version, add a version name (eg. 'Enviso widget tracking') and click Publish.

    32.png
    31.png
Step 6: Optional: Share hashed customer data with ad platforms

Warning

Activation of customer data sharing requires a written request. Upon receipt and approval of this request, we will enable the feature, after which you may configure the applicable sharing settings.

Note

This is off by default. When you switch it on, the widget adds the buyer's hashed email address to the purchase event, so Google Ads or another ad platform can match the sale to an ad click. It is only added when the visitor gave advertising consent, and the plain email address never appears on your page. If you don't use an ad platform, skip this section.

  1. Switch it on in the widget. Add the line below next to the other widget settings (see Step 3: Setup webpage hosting the Enviso Ticketing widget).

    <script>
        enviso.analytics.optIns.customerData = true;
    </script>
  2. Pass your visitor's advertising consent to the widget. Wherever your cookie banner reports the visitor's choice, set adUserData. It matches Google Consent Mode's ad_user_data signal. If your cookie banner has no Consent Mode, use its "marketing" category. Google Consent Mode itself does not reach the widget, so this step is also needed when you use Consent Mode.

    // Visitor accepts marketing / advertising cookies
    enviso.analytics.consents.adUserData = 'granted';
    
    // Visitor refuses, or withdraws consent later
    enviso.analytics.consents.adUserData = 'denied';
    
    // Your cookie banner doesn't know yet (first visit, or consent expired)
    enviso.analytics.consents.adUserData = undefined;

    Note

    These lines work before and after the widget has loaded. Place them after the widget's loader script, like the other widget settings. Only set the field you need; don't replace the whole enviso.analytics object.

  3. Keep the consent up to date. Set the state on every page load, as soon as your cookie banner knows it, and again whenever the visitor changes it. Use undefined when the consent is unknown, so an old choice is not reused.

  4. Use the hashed email in your ad platform. For Google Ads, create a Data Layer Variable for user_data.sha256_email_address, a User-Provided Data variable of type Code that returns { sha256_email_address: ... }, and add it to your Google Ads conversion tag. Follow Google's https://support.google.com/google-ads/answer/13262500. For Meta or another platform, map the same variable to that platform's hashed email field (for Meta: em).

  5. Test it. In Preview, grant advertising consent and complete a test order: the purchase event contains user_data.sha256_email_address. Repeat with consent refused: the purchase event has no user_data.

    Note

    Keep it out of Google Analytics 4. Google's terms don't allow personal data in GA4, so don't add user_data to the GA4 event tag.

Things to know:

Point

Details

Missing, 'denied' or undefined

They all mean nothing is shared.

The consent at the moment of purchase

Consent given after the purchase is not sent afterwards.

Widget remembers the last value

The widget remembers the last value in the visitor's browser (local storage key enviso.analytics.consents).

A page reload or a payment redirect does not lose it, and all open tabs of your website use the same value. List this key in your cookie policy; it holds no personal data.

Hashing requirements

The email is trimmed and lowercased, then hashed with SHA-256. Hashing needs a secure https:// page; on a plain http:// page nothing is shared.

GDPR consideration

A hashed email is still personal data under GDPR, so your privacy policy must cover sharing it with ad platforms.

Clearing user_data

Right after the purchase event, the widget clears user_data from the dataLayer again, so later events can't read it.

Event overview
Event payloads

Every message the GA4 version of the widget (gtmVersion = 'v2') pushes to the dataLayer, in full, with example values. Before each event except login and sign_up, the widget first pushes { "ecommerce": null } to clear the previous ecommerce data.

Browsing
view_item_list: offer overview

One item per offer. Offers have no price yet.

{
  "event": "view_item_list",
  "checkout_step": "offer_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "item_list_id": "offer_overview",
    "item_list_name": "Offer Overview",
    "items": [
      { 
        "item_id": "12", 
        "item_name": "Museum entrance", 
        "item_category": "Museum entrance",
        "index": 0, 
        "item_list_id": "offer_overview", 
        "item_list_name": "Offer Overview" 
      },
      { "item_id": "15", 
        "item_name": "Guided tour", 
        "item_category": "Guided tour",
        "index": 1, 
        "item_list_id": "offer_overview", 
        "item_list_name": "Offer Overview" 
      }
    ]
  }
}
select_item: offer clicked
{
  "event": "select_item",
  "checkout_step": "offer_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "item_list_id": "offer_overview",
    "item_list_name": "Offer Overview",
    "items": [
      { "item_id": "12", 
        "item_name": "Museum entrance", 
        "item_category": "Museum entrance",
        "index": 0, 
        "item_list_id": "offer_overview", 
        "item_list_name": "Offer Overview" 
      }
    ]
  }
}
view_item_list: ticket selection

One item per ticket type, with its price.

{
  "event": "view_item_list",
  "checkout_step": "ticket_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "item_list_id": "ticket_selection",
    "item_list_name": "Ticket Selection",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 22.5, 
        "discount": 0, 
        "index": 0,
        "item_list_id": "ticket_selection", 
        "item_list_name": "Ticket Selection" 
      },
      { "item_id": "4712", 
        "item_name": "Child", 
        "item_category": "Museum entrance",
        "price": 12.5, 
        "discount": 0, 
        "index": 1,
        "item_list_id": "ticket_selection", 
        "item_list_name": "Ticket Selection" 
      }
    ]
  }
}
select_item: tickets chosen, Next clicked

Only the ticket types with a quantity above 0.

{
  "event": "select_item",
  "checkout_step": "ticket_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "item_list_id": "ticket_selection",
    "item_list_name": "Ticket Selection",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 22.5, 
        "discount": 0, 
        "quantity": 2, 
        "index": 0,
        "item_list_id": "ticket_selection", 
        "item_list_name": "Ticket Selection" 
      }
    ]
  }
}

Note

Extra products use the same shapes: view_item_list and select_item with list cross_sell_offers / Cross-Sell Offers (like the offer overview), then cross_sell_ticket_selection / Cross-Sell Ticket Selection (like the ticket selection, one product per select_item, without quantity).

Date selection
select_timeslot

visit_timeslot is left out when the offer has no timeslots. On each item it is that item's own timeslot, so an extra product can differ or have none.

{
  "event": "select_timeslot",
  "checkout_step": "timeslot_selection",
  "site_language": "en",
  "visit_date": "2026-10-14",
  "visit_timeslot": "10:00-10:30",
  "days_until_visit": 14,
  "ecommerce": {
    "currency": "EUR",
    "value": 45,
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 22.5, 
        "discount": 0, 
        "quantity": 2, 
        "index": 0,
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
Basket

The examples below use a basket of 2 Adult tickets (€22.50 each) and the code SUMMER10, which takes €4.50 off the whole basket.

add_to_cart

item_list_id and item_list_name are only present when the product was shown in a list earlier in the visit. Visit fields are only present once a date is known. When a quantity is raised in the basket, only the added tickets are reported, with checkout_step basket_overview.

{
  "event": "add_to_cart",
  "checkout_step": "timeslot_selection",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "value": 45,
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 22.5, 
        "discount": 0, 
        "quantity": 2, 
        "index": 0,
        "item_list_id": "ticket_selection", 
        "item_list_name": "Ticket Selection",
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
remove_from_cart

Only the removed tickets, without list or visit fields.

{
  "event": "remove_from_cart",
  "checkout_step": "basket_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "value": 22.5,
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 22.5, 
        "discount": 0, 
        "quantity": 1, 
        "index": 0 
      }
    ]
  }
}
view_cart

value is the total after the basket discount. coupon and cart_discount are only present when they apply: coupon when a code is used, cart_discount when part of the discount is on the basket as a whole rather than on single tickets. Unlike the checkout events, the item prices here do not include the basket discount.

{
  "event": "view_cart",
  "checkout_step": "basket_overview",
  "site_language": "en",
  "cart_discount": 4.5,
  "ecommerce": {
    "currency": "EUR",
    "value": 40.5,
    "coupon": "SUMMER10",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 22.5, 
        "discount": 0, 
        "quantity": 2, 
        "index": 0,
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
apply_coupon

The basket discount is spread over the items: here €2.25 per ticket.

{
  "event": "apply_coupon",
  "checkout_step": "basket_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "value": 40.5,
    "coupon": "SUMMER10",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 20.25, 
        "discount": 2.25, 
        "quantity": 2, 
        "index": 0 
      }
    ]
  }
}
Checkout

Same basket as above. In all three events the basket discount is spread over the item prices, and coupon is only present when a code is used.

begin_checkout
{
  "event": "begin_checkout",
  "checkout_step": "basket_overview",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "value": 40.5,
    "coupon": "SUMMER10",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 20.25, 
        "discount": 2.25, 
        "quantity": 2, 
        "index": 0,
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
add_shipping_info
{
  "event": "add_shipping_info",
  "checkout_step": "personal_information",
  "site_language": "en",
  "newsletter_optin": true,
  "ecommerce": {
    "currency": "EUR",
    "value": 40.5,
    "coupon": "SUMMER10",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 20.25, 
        "discount": 2.25, 
        "quantity": 2, 
        "index": 0,
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
add_payment_info

For a free order, value is 0 and payment_type is free.

{
  "event": "add_payment_info",
  "checkout_step": "payment",
  "site_language": "en",
  "ecommerce": {
    "currency": "EUR",
    "value": 40.5,
    "payment_type": "ideal",
    "coupon": "SUMMER10",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 20.25, 
        "discount": 2.25, 
        "quantity": 2, 
        "index": 0,
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
Order
purchase

transaction_id is the Enviso order number and value the amount paid. The event-level visit fields come from the first ticket and are left out when no date is known. payment_type and coupon are only present when known.

{
  "event": "purchase",
  "checkout_step": "purchase",
  "site_language": "en",
  "newsletter_optin": true,
  "visit_date": "2026-10-14",
  "visit_timeslot": "10:00-10:30",
  "days_until_visit": 14,
  "ecommerce": {
    "transaction_id": "100234",
    "value": 40.5,
    "currency": "EUR",
    "payment_type": "ideal",
    "coupon": "SUMMER10",
    "items": [
      { "item_id": "4711", 
        "item_name": "Adult", 
        "item_category": "Museum entrance",
        "price": 20.25, 
        "discount": 2.25, 
        "quantity": 2, 
        "index": 0,
        "visit_date": "2026-10-14", 
        "visit_timeslot": "10:00-10:30", 
        "days_until_visit": 14 
      }
    ]
  }
}
purchase with hashed customer data

Only when you switched on customer data and the visitor granted advertising consent (see Optional: Enhanced Conversions with hashed customer data). The event is the same as above plus user_data. Right after it, the widget pushes a message without an event that clears user_data again, so later events can't read it. In order, the dataLayer then receives:

[
  { "ecommerce": null },
  {
    "event": "purchase",
    "checkout_step": "purchase",
    "site_language": "en",
    "newsletter_optin": true,
    "visit_date": "2026-10-14",
    "visit_timeslot": "10:00-10:30",
    "days_until_visit": 14,
    "ecommerce": { 
      "transaction_id": "100234", 
      "value": 40.5, 
      "currency": "EUR", 
      "items": [ … ] 
    },
    "user_data": {
      "sha256_email_address": "86e0b9e56c17cc4d12387e1949b85053fbe73bc3ce5a1188713a9d300cc6133d"
    }
  },
  { "user_data": null }
]
refund

Sent once a visitor's cancellation has gone through. transaction_id is the same order number as on purchase, and value is the full order total. checkout_step holds the last step the visitor was on in this visit.

{
  "event": "refund",
  "checkout_step": "offer_overview",
  "site_language": "en",
  "ecommerce": {
    "transaction_id": "100234",
    "currency": "EUR",
    "value": 40.5
  }
}
Account

These two have no ecommerce reset before them, no checkout_step or site_language, and no personal data.

login
{ "event" : "login", "method": "login" }
sign_up

Sent right after login the first time a visitor signs in after creating an account, so that sign-in sends both events.

{ "event": "sign_up", "method": "sign_up" }
When events are sent

Event

Variation (list)

Sent when

view_item_list

Offer overview

(offer_overview)

The list of offers has loaded.

view_item_list

Ticket selection

(ticket_selection)

The ticket types and prices of the chosen offer have loaded.

view_item_list

Cross-sell carousel on the date step

(cross_sell_offers)

The cross-sell offers for the chosen date have loaded, in the sales and the redeem flow. Sent again only when the set of offers changes.

view_item_list

Highlighted cross-sell offers on the date step

(cross_sell_offers)

The highlighted cross-sell offers have loaded.

view_item_list

Cross-sell carousel in the basket

(cross_sell_offers)

The basket's cross-sell offers have loaded. Sent again only when the set of offers changes.

view_item_list

Cross-sell ticket selection

(cross_sell_ticket_selection)

A cross-sell dialog has loaded the ticket types of its offer.

view_item

-

Not sent today: no part of the widget reports it.

select_item

Offer overview

(offer_overview)

The visitor clicks an offer, also on the voucher redeem overview.

select_item

Ticket selection

(ticket_selection)

The visitor clicks Next on ticket selection with at least one ticket chosen.

select_item

Cross-sell offer

(cross_sell_offers)

The visitor clicks the add button on a cross-sell card, in a carousel or the highlighted offers.

select_item

Cross-sell ticket

(cross_sell_ticket_selection)

A ticket type in the cross-sell dialog goes from 0 to 1 or more for the first time.

select_item

-

The visitor clicks Next on date &amp; time in the sales flow.

add_to_cart

Sales flow

The reservation is created: the main tickets plus any cross-sell picked along the way.

add_to_cart

Redeem flow

The voucher reservation is created, plus any cross-sell picked along the way.

add_to_cart

Cross-sell from the basket

A cross-sell offer from the basket carousel is reserved.

add_to_cart

Plus button on a basket line

The higher quantity is saved; only the added units are sent.

remove_from_cart

Remove a basket line

The reservation is removed; items linked to it are sent too.

remove_from_cart

Remove one product from a line

That product's reservation is removed.

remove_from_cart

Minus button on a basket line

The lower quantity is saved; only the removed units are sent.

view_cart

-

The basket overview opens.

apply_coupon

-

A discount code is accepted as valid.

begin_checkout

-

The visitor clicks Next on the basket overview and every membership has a visitor assigned.

add_shipping_info

-

The visitor clicks Next on personal details and the form is valid.

add_payment_info

Adyen

The visitor submits a payment method in the Adyen payment form.

add_payment_info

Free order

An order of 0 is completed without a payment step (payment_type: free).

purchase

-

The order-complete page shows after a successful payment, also after a redirect such as iDEAL or 3-D Secure. Not sent when paying an existing pay-later order.

refund

-

A signed-in visitor cancels an order and the cancellation succeeds.

login

Sign-in pop-up

The visitor finishes signing in through the pop-up.

login

Sign-in redirect

The visitor returns to the page after signing in through a redirect.

sign_up

-

Right after login, the first time the visitor signs in after creating an account.