Conversion tracking for Eventbrite embedded checkout in GA4, Meta, Google Ads

The client's problem

We are looking for an expert in Google Tag Manager (GTM), Google Analytics 4 (GA4), Meta Pixel/Conversions API, Google Ads Conversion Tracking, and WordPress to correctly implement end-to-end event tracking for our event website.

Our website is built on WordPress, but all ticket sales occur through Eventbrite embeds (iframe).
Each city/event has its own landing page.
For example: crawlwith.us/minneapolis/halloween
Because Eventbrite is embedded in an iframe, we need someone who understands cross-domain tracking and iframe event tracking.
We are looking for someone who has solved this exact problem before.

Project Goals

Implement complete conversion tracking across:

  • WordPress
  • Eventbrite embedded checkout (iframe)
  • Google Tag Manager
  • Google Analytics 4
  • Google Ads
  • Meta Pixel
  • Meta Conversions API (if recommended)

We need to track visitors throughout the entire purchase funnel, including:

  • Page Views
  • Scroll Depth
  • Time on Page
  • Button Clicks
  • "Buy Tickets" clicks
  • Eventbrite iframe opens
  • Checkout Started
  • Add Payment Info (if available)
  • Purchase Completed
  • Purchase Value
  • Event Name
  • Event ID
  • Ticket Type
  • Abandoned Checkout (if technically possible)
  • Any additional meaningful engagement events

My solution

1

Create variables in GTM for the necessary tracking identifiers: GA4 Client ID (client_id), Meta Browser ID (_fbp), Meta Click ID (_fbc), and Google Ads Click ID (gclid).

2

Create tags and triggers in GTM to track the visitor engagements you listed: «Page Views», «Scroll Depth», «Time on Page», «Buy Tickets» clicks, etc.

3

When the Eventbrite Checkout Widget is rendered, it sends an undocumented message containing Eventbrite's Event ID from its iframe to the parent window:

window.parent.postMessage({
    messageName: 'widgetRenderComplete',
    eventId: '1611364838609'
}, 'https://crawlwith.us/');

3.1

This undocumented message is visible both in the DOM of the widget's iframe and in the widget's source code: eventbrite.com/static/widgets/eb_widgets.js

3.2

Eventbrite's Event ID must be pushed to the Data Layer (to be sent to GTM):

window.addEventListener('message', e => {
    if ('widgetRenderComplete' === e.data?.messageName) {
     	window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            'event': 'eb_checkout_started',
            'eventbrite_event_id': e.data.eventId
        });
    }
});

3.3

In GTM, create a «Custom Event» trigger for the eb_checkout_started event.
The tags fired by this trigger must send the begin_checkout event to GA4 and the InitiateCheckout event to Meta: for both events, it is necessary to pass eventbrite_event_id in the platform-specific parameters (as item_id in the items array for GA4 and in the content_ids array for Meta).

4

Similarly to §3, when the visitor closes the widget, the widget sends an undocumented message to the parent window:

window.parent.postMessage({
    messageName: 'widgetModalClose',
    eventId: '1611364838609'
}, 'https://crawlwith.us/');

Processing this event similarly to §3 makes it possible to track abandoned checkouts, provided that the order has not been completed.

5

When a visitor buys a ticket, the widget calls the onOrderComplete callback: eventbrite.com/platform/docs/embedded-checkout
The documentation at the link above does not document the parameters of this callback, but the source code of eb_widgets.js (§3.1) shows that the callback receives an object containing Eventbrite's Order ID:

e.userConfig.onOrderComplete({orderId:n})

Eventbrite's Order ID must be pushed to the Data Layer (as in §3.2):

window.dataLayer.push({
    'event': 'eb_order_success_browser',
    'eventbrite_order_id': orderData.orderId 
});

6

A tag in GTM fired by the eb_order_success_browser trigger must collect the data from §1 and §5 into a single object and send it to your server.

7

In the Eventbrite Account Settings, it is necessary to configure a webhook for the «Order» → «Placed» action: eventbrite.com/platform/docs/webhooks
This webhook makes a POST request to your server, passing a payload with an API URL containing Eventbrite's Order ID.
Next, after a short delay, using this Order ID and the expand parameter, your server must request full information about the order: eventbrite.com/platform/api#/reference/order/retrieve/retrieve-order-by-id

8

Next, your server must combine the information from §6 and §7.2 using this Order ID.

8.1

Then, this information must be passed to Meta, GA4, and Google Ads using their APIs:

Meta Conversions API:

GA4 Measurement Protocol:

Google Ads API (Offline Conversions and Enhanced Conversions):

developers.google.com/google-ads/api/docs/conversions/upload-offline

8.2

For deduplication, pass Eventbrite's Order ID as event_id for Meta, as transaction_id for GA4, and as order_id for Google Ads.

8.3

For session attribution in GA4, pass the GA4 Client ID (§1) as client_id and the GA4 Session ID as session_id.

8.4

For attribution in Google Ads, use Offline Conversions (passing the Google Ads Click ID from §1) and Enhanced Conversions (passing the hashed buyer data from §7).