Where can I find it? Company >>> Components/Integrations >>> Google Tag Manager
Google Tag Manager is a tag management system that lets you manage, deploy and administer marketing tags (code snippets or tracking pixels) without changing your website code each time.
With this integration, you can track purchase conversions in Google Analytics 4 (GA4) and Google Ads, whether you use TuriTop's default thank-you page or your own custom thank-you page. The setup depends on which page you use, so this article provides separate instructions for each option.
Warning: To set up this tool correctly, we strongly recommend getting assistance from a marketing and GTM specialist, especially if you have advanced requirements or need to track events we do not support. Please note that you are responsible for:
- Creating your GTM account.
- Setting up and installing the container on your website.
- Configuring the container tags and triggers.
- Testing your triggers and tags.
- Publishing/deploying changes to your live website.
If you have questions after reading this article, please contact our support team so we can advise you based on your TuriTop account configuration.
Which thank-you page am I using?
- Default page: after checkout, the buyer sees TuriTop's confirmation page (on the turitop.com domain).
- Custom page: after checkout, TuriTop redirects the buyer to a page on your website (the one configured as your Custom Success URL).
Using the TuriTop Plugin for WooCommerce? The WordPress/WooCommerce setup is explained in this article.
How this integration works
The booking widget is embedded as an <iframe> on your website, but checkout ends on the TuriTop domain. This integration allows conversions to be measured on your domain, within the same session that brought the campaign visitor.
In broad terms:
- The widget reads attribution data from your page (the parent page):
gclid,gbraid,wbraid,gad_source, parametersutm_*and cookies_ga/_gcl_aw, and carries them through the checkout flow. This data is transmitted live and is never stored in our database. - The widget sends a standardized funnel of events to your page:
widget_loaded(fires when the widget loads),add_to_cart(fires when theticket_type_count),checkout_started(fires when the customer reaches the form and payment step),purchase(fires when the purchase is confirmed) andpayment_error(fires when payment fails or is declined). - When the purchase is confirmed, the conversion fires on your domain through one of two automatic methods:
- If you use the default thank-you page of TuriTop: sent via
postMessageto the page embedding the widget (without redirecting). - If you use the custom thank-you page: a top-level redirect to your thank-you page with parameters in the URL.
- If you use the default thank-you page of TuriTop: sent via
In both cases, conversions are deduplicated by transaction_id: the booking ID, cart code (cart_hash), or multi-client purchase code (multi_client_hash), so the same sale is never counted twice. On a custom page, reloading or returning to the page does not send the purchase again, provided the browser allows local storage (localStorage).
What you can measure
-
Purchases (
purchase): attributed to your Google Ads campaigns and GA4, including value and currency. -
Breakdown by company (
company_short_id), product (product_short_id) and originating domain (site_url): useful if you manage multiple companies or websites. -
Payment methods:
stripe,paypal,sis,promo, etc. -
Earlier funnel events (
widget_loaded,add_to_cart,checkout_started): to optimize your campaigns. -
Session tracking: Attribution via
gclid/gbraid/wbraid/gad_source,utm_*and cookies_ga/_gcl_aw.
Payments using the classic Redsys gateway or PayPal navigate at the top level, so the bank return reaches your custom success page (or the page embedding the widget) and the conversion fires there. No additional configuration is required.
The containers we provide measure purchases. Funnel events reach your page but do not trigger any tags. To measure those events, you must create your own tags.
Data sent
Default page: widget events (postMessage)
Fields/payload of the purchase:
| booking_id | Booking ID = transaction_id (deduplication key). For cart bookings, the transaction_id is the cart cart_hash code. For multi-client bookings, it is the multi_client_hash multi-client code. |
| total | Amount paid |
| currency | Currency code (EUR, USD…) |
| product_short_id | Product ID |
| product_name | Product name |
| quantity |
1 for a single booking. Number of bookings in a cart or multi-client purchase |
| company_short_id | Company ID |
| site_url | Page where the booking started: domain and path |
| payment_method | stripe, paypal, sis, promo, etc. |
| attribution | gclid, gbraid, wbraid, gad_source, utm_*, _ga, _gcl_aw (whichever were present) |
Purchases without an online payment gateway (discounts, free bookings, etc.) are recorded with payment_method = promo and total may be 0. A deferred payment (payment link) does not trigger purchase (it is not a new purchase).
Fields/payload of the widget_loaded:
| company_short_id | Company ID |
| product_short_id | Product ID |
| product_name | Product name |
| currency | Currency code (EUR, USD…) |
| site_url | Page where the booking started: domain and path |
Fields/payload of the add_to_cart:
| product_short_id | Product ID |
| product_name | Product name |
| quantity | Units. Sum of ticket_type_count
|
| value | Total price based on the selected units |
Fields/payload of the checkout_started:
| company_short_id | Company ID |
| product_short_id | Product ID |
| currency | Currency code (EUR, USD…) |
| total | Amount to pay |
| quantity | Units. Sum of ticket_type_count
|
Fields/payload of the payment_error:
| booking_id | Booking ID = transaction_id (deduplication key). For cart bookings, the transaction_id is the cart cart_hash code. For multi-client bookings, it is the multi_client_hash multi-client code. |
| company_short_id | Company ID |
| product_short_id | Product ID |
| payment_method | stripe, paypal, sis, promo, etc. |
| error_context | "payment_declined" |
How are TuriTop payment gateways recorded?
| Stripe | stripe |
| PayPal (classic) | paypal |
| PayPal Express Checkout | paypalEC |
| PayPal Wallet (Commerce) | paypalPPCP |
| PayPal Card (Commerce) | paypalPPCPCard |
| Redsys (redirect) | sis |
| Redsys inSite (embedded) | redsysinsite |
| Bizum (Redsys) | bizum |
| MercadoPago | mercadopago2 |
| iDEAL | ideal |
| Sofort | sofort |
| myPOS | mypos |
| Realex (Global Payments) | realex |
| Ecomm365 | ecomm365 |
| Paygate | paygate |
| Free · Pay on arrival · Bank transfer · Cheque · Prepaid · Gift voucher · Card (manual/back office) · Optional payment · Other · Custom method · Empty/unknown | promo |
Custom page: URL parameters
When the buyer completes checkout, TuriTop redirects them to your Custom Success URL and appends the purchase details as parameters. For example:
https://yourwebsite.com/thank-you/?currency=EUR&total=120.50&product_short_id=P123&product_name=Boat+tour&booking_id=ABC123&link=...&d=...&csid=C456&company_name=My+Company&lang=en&tt_attr=eyJnY2xpZCI6Ii4uLiJ9Parameter format
- Read parameters by name, not by position. Their order may vary depending on the purchase type.
- Text values are URL-encoded (a space is represented as
+). Inproduct_nameandcompany_name, the character&is replaced by-. - Parameters ending in
[]are lists. They appear repeatedly, once per booking (for example,booking_id[]=A1&booking_id[]=A2). - Amounts are numbers with a decimal point (
120.50).
In the following table, booking means an individual booking, cart means a shopping-cart purchase, and multi-client means a multi-client purchase.
| Parameter | Format | When it is included |
|---|---|---|
booking_id
|
Text | Individual booking: booking reference. |
shopping_cart_id
|
Text | Cart: cart reference. |
multiclient_hash
|
Text | Multi-client: purchase reference. |
booking_id[]
|
List of strings | Cart and multi-client: one reference per booking. |
total
|
Number (120.50)
|
Always. Amount paid (may be 0). For cart and multi-client purchases, the total amount. |
price[]
|
List of numbers | Cart and multi-client: amount for each booking. |
currency
|
Currency code (EUR)
|
Whenever the booking has a currency. |
product_short_id
|
Text | Product code. For carts and multi-client purchases with multiple products, repeated once per booking. |
product_name
|
Text | Product name in the default language of your company's website. For carts and multi-client purchases with multiple products, repeated once per booking. |
product_description
|
Base64 text | Redsys only: product summary. |
csid
|
Text | Always. Company code (for resales, the supplier company). |
company_name
|
Text |
Always. Company name corresponding to csid.
|
lang
|
Language code (es)
|
Always. |
link / link[]
|
{booking}/{code}/{language}/0/{hide_prices}/1
|
Ticket link. link for individual bookings;
link[] one per booking for carts and multi-client
purchases.
|
d
|
Ticket base URL |
Always. The full link is d + link.
|
client_name / client_name[]
|
Text | Only if you enabled "Include name and email in the URL". |
client_email / client_email[]
|
Only if you enabled "Include name and email in the URL". | |
buyer_email
|
Multi-client only, if you enabled "Include name and email in the URL". | |
fbpixel
|
Text | If your company has a Facebook Pixel ID. |
payment_link
|
1
|
Only when payment comes from a payment link. Not a new purchase: the container does not count it. |
tt_attr
Base64url text
|
Always: payment method, origin page and visit attribution. | Always: payment method, origin page and visit attribution. |
Ds_SignatureVersionValues sent by Redsys, unchanged
Ds_MerchantParameters,
Ds_Signature
|
Values sent by Redsys, unchanged | Only with Redsys and "Parameters in URLs" enabled on the terminal. Used to display or verify the payment, not to measure the purchase. |
The tt_attr
tt_attr is a JSON object encoded as unpadded base64url (+ becomes -, / becomes _, with no trailing = ).
It contains only letters, numbers, hyphens and underscores, so redirects cannot break it. It is not encrypted: anyone who sees the URL can read it.
| Key | When | Value |
|---|---|---|
gclid, gbraid, wbraid,
gad_source, utm_source,
utm_medium, utm_campaign,
utm_term, utm_content, _ga,
_gcl_aw
|
If present during the visit | Marketing attribution for the visit. |
payment_method
|
Always |
Payment gateway (stripe, paypal,
sis…) or promo.
|
site_url
|
If the originating page is known | Page where the booking started: domain and path, without query string or fragment. For carts, the first booking that has one. |
reseller_csid
|
Resales only | Reseller company code. |
reseller_name
|
Resales only | Reseller company name. |
To read it with your own JavaScript code:
function decodeTtAttr(value) {
var s = value.replace(/-/g, '+').replace(/_/g, '/');
while (s.length % 4) { s += '='; }
return JSON.parse(atob(s));
}
var tt = new URLSearchParams(location.search).get('tt_attr');
var attr = tt ? decodeTtAttr(tt) : {};
Resales
In a resold booking, csid and company_name belong to the supplier (product owner), whereas on the default page company_short_id belongs to the reseller.
To link the two, tt_attr contains reseller_csid and reseller_name for the reseller.
What happens if the URL is too long?
Removable parameters are subject to a combined limit of 1023 characters (configured URL + parameters). If the URL is too long, TuriTop removes parameter groups in this order and stops as soon as the URL fits:
product_description-
tt_attr(removing it also removes payment method, origin page and attribution). -
link/link[], and with themprice[],client_name[]andclient_email[]. dproduct_namefbpixel-
buyer_email(multi-client) andclient_name/client_email(individual booking)
Important:
- A parameter is removed entirely or not at all: it is never truncated.
- The purchase reference (
booking_id,booking_id[],shopping_cart_id,multiclient_hash),total,currency,csid,company_name,product_short_id,langnorpayment_link) is never removed, nor are the essential parameters. Therefore, the purchase is always measured, although payment method, origin page or product name may be missing if removed. A purchase containing many bookings may exceed 1023 characters using only these parameters. - With Redsys (and Bizum), the buyer first visits a short TuriTop URL and is then redirected to your page. On that final redirect, there is no length limit: nothing is removed.
- To avoid dropped parameters, use a short Custom Success URL.
Prerequisites
- Have GA4 installed on your domain and Google Ads auto-tagging enabled, so the cookies
_ga/_gcl_awandgclidreach your page. - Have an account and a Google Tag Manager web container.
- Have your GTM container ID (
GTM-XXXXXXX), your GA4 Measurement ID (G-XXXXXXXXXX), your Google Ads Conversion ID (AW-XXXXXXXXXX) and the conversion label for your purchase conversion action.
Instructions
Follow these steps to connect your TuriTop dashboard to GTM:
Step 1: Access your Google Tag Manager account
Go to the Google Tag Manager website (https://tagmanager.google.com/) and sign in with your Google account or create a new one if you do not have one (tutorial).
Once signed in, open Workspace and copy the ID shown at the top right of the page. It will look like: GTM-XXXXX.
Step 2: Connect Google Tag Manager to your TuriTop account
Open your TuriTop booking system dashboard and go to Company >>> Components/Integrations >>> Google Tag Manager.
Paste your ID for Google Tag Manager.
This ID only loads your container inside the widget. It does not install GTM on your website. For that, follow step 3.
Step 3: Install the GTM tag on your website
To learn how to install the GTM container on your website, follow this tutorial. Although you can insert the code snippets manually, many tools can help depending on your CMS.
Make sure you do not duplicate the code if your CMS already inserts it by another method. If you use a custom thank-you page, GTM must also be installed on that page, where the purchase is placed.
Step 4: Import the TuriTop container or create your own configuration
Your marketing team can configure GTM tags and triggers if preferred, but we provide two predefined containers you can easily import, one for each thank-you page type.
If you want to use our container or use it as a template, see the next section.
If you prefer to configure it from scratch:
-
Default page: create your tags using the custom event trigger
purchaseand the event fields (you can mapbooking_id>transaction_id,total>value, etc.). Developers who prefer their own code rather than GTM can also listen directly for thepurchaseevent usingwindow.addEventListener("message", …), always filtering bye.data.origin === "turitop". -
Custom page: create your tags by reading the URL parameters on your thank-you page (see Custom page: URL parameters). Do not count the purchase if the URL contains
payment_link=1, and avoid sending it again when the buyer reloads the page.
Step 5: Test in Google Tag Manager
Google recommends verifying that your configured tags work before publishing changes. To test, click "Preview".
You will need to enter your website URL where the widget is installed and click "Connect". Then, preferably, make a test booking for an amount greater than 0 and complete payment.
Make sure you have already installed the Google Tag Manager tag on your website.
Import the TuriTop container
We provide preconfigured containers for recording the purchase event.
-
turitop-container-default-page.json: For the default TuriTop thank-you page. -
turitop-container-custom-page.json: For the custom thank-you page.
Using both pages? Import both files into the same GTM container. Their names do not conflict: elements in one start with "TuriTop Default -" and elements in the other start with "TuriTop Custom -".
Step 1: Import the container
Open your Google Tag Manager dashboard and click "Admin".
From the container options menu, select "Import Container".
In the window that opens:
- Select the file matching your thank-you page (
turitop-container-default-page.jsonoturitop-container-custom-page.json). - Choose which workspace to install it in (usually Default Workspace).
- Choose whether to overwrite the existing configuration. We recommend "Merge" followed by "Overwrite conflicting tags, triggers and variables".
To complete the import, click "Add to Workspace".
Step 2: Edit the IDs
After importing the container, you will see the following triggers and tags in your dashboard:
You only need to edit three constant variables with your own IDs:
-
Const - GA4 Measurement ID: replace
G-XXXXXXXXXXwith your GA4 Measurement ID. -
Google Ads Conversion ID: replace
AW-XXXXXXXXXXwith the numeric ID of your conversion action. - Google Ads Conversion Label: replace the placeholder with your conversion label.
Go to "Variables", select "Const - GA4 Measurement ID", click the pencil icon to edit it, enter your Google Analytics 4 ID, and click "Save" to save your changes. Repeat for "Const - Google Ads Conversion ID" and "Const - Google Ads Conversion Label". Do not change anything else.
How do I find my GA4 ID? If you are not sure where to find it, follow this tutorial.
Step 3: Publish the changes
When you have made all the necessary changes to the container, click "Submit", name the version and click "Publish" to make the changes live.
Custom page: thank-you page script (optional)
In Company >>> Components/Integrations >>> Thank-you page code generator, you can generate a script to display the buyer’s booking details on your page (reference, download button, and payment information).
This script was originally used to send data, but we have kept it so you can display booking details to customers on your custom page.
- You must select "Display only" before copying the code. This ensures the script sends nothing to Google Ads, GA4, GTM, or Facebook, and the purchase is not counted twice.
- Do not enter your GTM ID in the script.
What does the script look like on the website?
The following elements (showing the specific booking information) will be inserted into your website thank-you page. You can easily change the wording or appearance.
Cookie consent
- The GA4 tag requires
analytics_storage. - The Google Ads tag requires
ad_storage.
If your website uses a cookie banner with Google Consent Mode and the buyer does not consent, the purchase is not sent. On a custom page, if the buyer grants consent after the thank-you page loads without reloading it, the purchase is not sent either.
The buyer’s IP address is never sent.

Comments
0 comments
Please sign in to leave a comment.