Google Tag Manager & Analytics

Track booking conversions in GA4, Google Ads and Meta

Every step of the booking form sends an event to Google Tag Manager (GTM), so you can build GA4 funnels, report Google Ads conversions with the real booking value, and feed Meta or any other platform from one container. Where the events go depends on where the customer books. On your website, the embedded form delivers them to your page and your own GTM handles them; the form loads no tags of its own. On your hosted booking page, the page loads the container you enter in PestBooker. Each booking reports through exactly one of these paths, so the same container can cover both without double-counting.

Requirements

  • A Google Tag Manager web container (GTM-XXXXXXX) that you can publish. GA4, Google Ads and Meta are set up as tags inside it.
  • That container installed on the page where the booking form is embedded
  • A GA4 property and/or a Google Ads account with a conversion action
  • Admin access in PestBooker to enter the container ID (only needed for the hosted booking page)

Embedded on your website

Customer books

in the embedded form

Event delivered

to your page's dataLayer

Your GTM fires tags

GA4, Google Ads, Meta…

Conversion recorded

with value + order ID

On your hosted booking page

Customer books

from a link, email or Google

Booking page loads

the GTM ID from Settings

Same events, same GTM

same triggers fire

Conversion recorded

with value + order ID

Which setup covers which bookings
Where they bookWhat records itWhat you need
Embedded formThe GTM container on your page. The form adds no tags of its own.GTM installed on the page that holds the form
Hosted booking pageThe GTM container entered in PestBookerContainer ID in Integrations → Google Analytics & Tag Manager
1

Install GTM on the Page With the Booking Form

  • Events are delivered to the exact page that holds the form. If the form lives on /schedule, GTM must be installed on /schedule, not just on your homepage.
  • If your site already runs GTM site-wide, there is nothing to install. Booking events will start appearing in your container automatically.
  • The booking form never loads tags inside itself when embedded, so it cannot double-count with your site. Your consent banner settings also apply to booking events, because they run through your container.
  • Running GA4 through the gtag.js snippet without GTM? Booking events are Tag Manager events, and gtag.js alone ignores them. Install GTM (recommended) or add the forwarding snippet below to the same page.
Only for sites using gtag.js without GTM
<script>
  // Forwards PestBooker booking events to GA4 as gtag events.
  // Paste after your gtag.js snippet, on the page with the booking form.
  window.addEventListener('message', function (e) {
    if (e.origin !== 'https://getpestcontrol.services') return;
    // Only accept messages from a booking form embedded on this page.
    var frames = document.querySelectorAll('iframe[src^="https://getpestcontrol.services/"]');
    var fromForm = Array.prototype.some.call(frames, function (f) {
      return f.contentWindow === e.source;
    });
    if (!fromForm) return;
    var msg = e.data;
    if (!msg || msg.type !== 'getpestcontrol_analytics') return;
    var p = msg.payload;
    if (!p || typeof p !== 'object' || typeof p.event !== 'string') return;
    var params = {};
    // Contact details are deliberately left out (no personal data in GA4).
    ['step_name', 'step_number', 'planType', 'frequency',
     'value', 'currency', 'transaction_id'].forEach(function (k) {
      if (p[k] !== undefined) params[k] = p[k];
    });
    gtag('event', p.event, params);
  });
</script>
GA4 receives the funnel events but nothing for Google Ads or Meta. For those, use GTM.
2

Add the Same Container ID to PestBooker

  • Go to Dashboard → Integrations → Google Analytics & Tag Manager
  • Paste your container ID (GTM-XXXXXXX) and click Save Changes
  • Use the same container that runs on your website. One set of triggers and tags then covers every booking, wherever it happens.
  • Why this matters even if you only embed: customers who come back through a "finish your booking" email or text, a Google listing, or a referral link book on the hosted page, not your website. Without this ID those bookings never reach your analytics.
  • Embedded visits ignore this setting, so adding it never double-counts your website's bookings.
  • Use a Tag Manager ID (GTM-…) if you can. A GA4 measurement ID (G-…) also works here, but it reports to GA4 only: no Google Ads or Meta conversions and no enhanced conversions.
3

Know the Events

  • registration_started: booking form loaded
  • registration_step_completed: a funnel step finished (step_name + step_number)
  • registration_completed: booking confirmed. This is your conversion.
  • registration_completed fires only once the appointment actually exists. If you require a signed service agreement before booking, it waits until the customer signs.
  • Bookings that start from a Google listing choose their plan first, so their step 3 arrives before steps 1 and 2. Build funnels on step_name rather than assuming the order.
  • registration_completed carries value (the initial service price), currency (USD) and transaction_id (the order ID). On the Checkout design it also carries planType (plan name) and frequency (treatments per year).
  • Use registration_completed as your one and only conversion. Step events are for funnels: billing_setup fires when the customer reaches payment on the Checkout design, before they have paid. checkout_booked fires at the same moment as registration_completed, so counting both doubles every sale.
  • Contact details: once the customer has entered them, events also include email, phone_number (10 digits, US), first_name and last_name. They are there for Google Ads enhanced conversions and Meta advanced matching, and are always filled on registration_completed (step events before the contact step carry them empty). Never add them to GA4 tags, because Google prohibits personal data in GA4.
  • Street address and payment details are never included in any event
Funnel steps (registration_step_completed)
step_namestep_numberWhat happened
address_selection1Customer entered their address
customer_creation2Contact details submitted (a lead now exists)
appointment_scheduling3Plan step done (Checkout design: plan chosen / Classic design: time picked)
billing_setup4Reached payment (Checkout design) / paid (Classic design, same moment as registration_completed)
out_of_service_lead0Address outside your service area; contact saved as a lead
address_incomplete0Address was missing details and could not be priced
lead_created_no_api_keys0Online booking not connected yet; contact saved as a lead
Other events
EventWhat happened
abandoned_cart_resumedCustomer came back to finish a booking from an email or text link
magic_link_accessed / _success / _expired / _error / _already_convertedA "finish your booking" link was opened, and how that went (hosted page)
referral_landing_view / referral_landing_cta_clickCustomer-referral landing page viewed / clicked through (hosted page)
checkout_lead_captured / checkout_bookedCheckout-design twins of customer_creation / registration_completed. Do not count them as well.
checkout_sign_gate_shown / _signed, classic_sign_gate_shown / _signedService agreement shown / signed before the booking is confirmed
checkout_chat_opened / _message / _escalatedBooking assistant chat used
checkout_resumed_from_linkCheckout-design booking reopened from a saved link (alongside the magic_link events)
checkout_existing_customer_linkExisting customer sent to the customer portal instead
checkout_start_overCustomer cleared the form and started again
checkout_sign_prompt_clickedCustomer opened the service agreement from the confirmation
Example: registration_completed in the dataLayer
{
  event: 'registration_completed',
  event_category: 'registration_form',
  value: 149,
  currency: 'USD',
  transaction_id: '284715',
  planType: 'Quarterly',     // Checkout design
  frequency: 4,              // Checkout design
  email: 'jane@example.com', // for ad matching only
  phone_number: '5555550123',
  first_name: 'Jane',
  last_name: 'Doe'
}
4

Create Triggers and Variables in GTM

  • Triggers → New → Custom Event. Create one for registration_completed (your conversion) and one for registration_step_completed (your funnel). Add registration_started if you want funnel entry.
  • Variables → New → Data Layer Variable. Create one each for value, currency, transaction_id, step_name and step_number, named like "DLV - value". Add planType and frequency if you use the Checkout design.
  • For Google Ads enhanced conversions or Meta advanced matching, also create email, phone_number, first_name and last_name
  • phone_number arrives as 10 US digits. Google expects +1 in front, so use the Custom JavaScript variable below for the phone field.
Custom JavaScript variable: phone in E.164 format
function () {
  var p = {{DLV - phone_number}};
  if (!p) return undefined;
  var digits = String(p).replace(/\D/g, '').slice(-10);
  return digits.length === 10 ? '+1' + digits : undefined;
}
Replace {{DLV - phone_number}} with whatever you named the phone_number Data Layer Variable.
5

Send Events to GA4

  • Make sure a Google tag with your GA4 measurement ID (G-XXXXXXXXXX) fires on all pages of your site
  • Add a GA4 Event tag for the funnel: event name registration_step_completed, parameters step_name and step_number, triggered by the step trigger
  • Add a GA4 Event tag for the sale, triggered by registration_completed. Name the event purchase so revenue shows in GA4's monetization reports, and add the parameters value, currency and transaction_id. GA4 uses transaction_id to ignore repeat sends of the same order.
  • Do not add email, phone_number, first_name or last_name to any GA4 tag
  • In GA4, go to Admin → Data display → Key events and mark purchase (or your chosen event name) as a key event
  • Use Explore → Funnel exploration with step_number to see exactly where visitors drop off
6

Track Google Ads Conversions

  • In Google Ads: Goals → Conversions → New conversion action → Website, set up manually with Google Tag Manager
  • Category: Purchase. Value: "Use different values for each conversion". Count: Every.
  • In GTM, add a Conversion Linker tag on All Pages if you do not already have one. It keeps the ad click attached to the visitor.
  • Add a Google Ads Conversion Tracking tag with your Conversion ID and Label. Set Conversion Value to {{DLV - value}}, Transaction ID to {{DLV - transaction_id}} and Currency Code to {{DLV - currency}}, and trigger it on registration_completed.
  • Enhanced conversions (recommended): in the same tag, turn on "Include user-provided data from your website", choose Manual configuration, and map email, the E.164 phone variable, first_name and last_name. Then accept the enhanced-conversions terms in Google Ads.
  • Google Ads optimizes on the real booking value, so ROAS bidding works out of the box
7

Add Meta and Other Platforms (Optional)

  • Meta Pixel: fire a Purchase event on registration_completed with value and currency, and use transaction_id as the event ID so Pixel and Conversions API events dedupe
  • Fire a Lead event on registration_step_completed where step_name equals customer_creation to optimize for leads as well as sales
  • With advanced matching on, pass email, phone and name from the variables above
  • Any other platform (Microsoft Ads, LinkedIn, TikTok, a CRM) works the same way: trigger on registration_completed and read value and transaction_id
8

Verify Before You Go Live

  • Open GTM Preview (Tag Assistant) on the page with the embedded form. Booking events appear in the event list on the left as the form is used.
  • registration_started and the first two steps can be checked without booking. Just enter an address and contact details.
  • Seeing registration_completed takes a real booking. Coordinate with the pest control company first so they can cancel it afterwards.
  • Quick check without Preview: run this in the browser console on the host page.
  • dataLayer.filter(e => /^(registration|checkout)_/.test(e.event))
  • Check the hosted page too: in Tag Assistant, connect to your booking page URL (getpestcontrol.services/your-slug)
  • In GA4, watch Admin → DebugView while Preview is connected. In Google Ads, a new conversion action can take a few hours to show a status.

Pro Tips

  • • Make registration_completed your only conversion. Step events, billing_setup and checkout_booked will double-count sales if you count them too.
  • • UTM tags and ad click IDs (gclid, gbraid, wbraid, fbclid, msclkid) on the URL of the page with the booking form are saved with each lead, and remembered for 30 days across pages that have the form, so a visitor who leaves and comes back later still credits the ad. If your ads land on a page without the form, make sure links into the booking page carry the UTM tags; the matching Google Ads or Meta click ID is then recovered automatically.
  • • PestBooker records campaign attribution on its own, independent of your GTM setup. On Pro plans it shows on Dashboard → Analytics, which makes a good cross-check against your ad platforms.
  • • The embedded form doesn't change your page's URL or send page views of its own. Use the step events, not page views, to build your funnel.
  • • Recommended: add getpestcontrol.services to GA4 → Admin → Data streams → Configure tag settings → Configure your domains, so a visitor who clicks from your site to the hosted booking page stays one session

Need help with setup?

Email us and we'll walk you through any integration or setup process.

Contact Sales