Google Analytics for the Climber App​

Capitan has a built-in Google Analytics 4 (GA4) integration for the Climber App. Once you add your Google Analytics Measurement ID to your organization settings, Capitan automatically does two things on every page of your Climber App:

  1. Tracks page views and traffic, so you can see how many people visit your Climber App, which pages they land on, and where they came from (search, social, email campaigns, and so on).
  2. Tracks ecommerce events, so you can see your customers move through the buying journey: viewing a product, starting checkout, and completing a purchase, along with the revenue from each sale.

No code, tags, or scripts are required. You paste one ID into Capitan, click Save, and both kinds of tracking turn on across the entire Climber App.

Three settings sit alongside the Measurement ID and change what Google receives: customer info, which attaches identifiers to each event; the privacy notices the Climber App shows visitors, which can stop tracking entirely; and a Measurement Protocol API secret, which sends a second copy of each purchase from Capitan's servers for the visits where the Google tag is blocked.

New to Google Analytics? GA4 is Google's free analytics product. It collects data about how people use your Climber App and presents it as reports and dashboards. This article assumes you already have (or can create) a free Google Analytics account.


Before you begin

You'll need a GA4 Measurement ID. It looks like G-XXXXXXXXXX  (the letter "G", a dash, then a string of letters and numbers).

To get one:

  1. In Google Analytics, create a GA4 property for your business (or use an existing one).
  2. Inside that property, create a Web data stream pointed at your Climber App's web address.
  3. Copy the Measurement ID shown for that Web stream.

Google's own walkthrough is here: Find your G- Measurement ID.

It must be the "G-" Measurement ID from a GA4 Web Stream. Not an old Universal Analytics "UA-" ID, not a "G-" tag ID from a different stream type, and not a Measurement Protocol API secret (that has its own field). Capitan validates the format and rejects anything that is not a valid GA4 Measurement ID.


Getting Started: Add your Measurement ID in Capitan

  1. On the Staff Site, go to Organization Settings.
  2. Find the Google Analytics 4 Measurement ID field, under Climber App Settings.
  3. Paste in your G-XXXXXXXXXX  ID.
  4. Click Save.

That's the entire setup. From this point on, every Climber App page automatically loads the official Google tag (gtag.js ) and begins sending data to your GA4 property.

Leave the "Tracking/Analytics Script" field empty for Google Analytics. That field is a separate, advanced tool for other trackers (see Advanced: the "Tracking/Analytics Script" field below). For GA4, the Measurement ID field alone is all you need, because Capitan builds and installs the full tracking script for you. Pasting a Google Analytics snippet into both places would cause double-counting.


Send customer info to Google Analytics

By default GA4 sees anonymous sessions: one browser is one visitor, and the same person on a phone and a laptop counts as two. Send customer info to Google Analytics changes that. It attaches identifiers for the person buying to the page's events, which feeds two Google features at once: enhanced conversions, when the property is linked to Google Ads, and User-ID reporting, which joins a customer's sessions across devices.

Once a Measurement ID is saved, a checkbox appears beneath it in Organization Settings:

  1. Find Send customer info to Google Analytics, directly under the Google Analytics 4 Measurement ID field.
  2. Turn it on.
  3. Click Save.

What Capitan sends, when the setting is on:

  • The customer's email address, first name, last name, and customer ID, with every tracked event.
  • Their phone number, only when they are signed in.

The email, phone number, and name are hashed in the browser before they reach Google, in the one-way form Google's user-provided data collection expects. The customer ID is sent as the GA4 user ID, unhashed, because Google matches it against nothing: it is an opaque number that only means something inside Capitan.

This does nothing until you turn the matching feature on in Google Analytics as well. In GA4, go to Admin, Data streams, your web stream, Google tag, Configure tag settings, and turn on Allow user-provided data capabilities. Until then Google discards what Capitan sends, with no warning in either system. Google's own guide is here: Collect user-provided data.

Sending the customer ID changes your user counts. It switches the property to GA4's User-ID reporting identity, so a person who previously counted as two visitors on two devices becomes one. Expect user and new-user totals to shift after you turn this on, and expect the shift to make historical comparisons uneven across the changeover.

Nobody is identified in these cases, and the events still fire with no customer info attached:

  • The visitor is browsing without signing in and has not entered purchaser details yet.
  • A staff user is using the Climber App on behalf of a customer. That session runs in the staff user's own browser, so matching would tie the staff browser's analytics cookies to the customer's identity.
  • The page is running in kiosk mode.
  • The visitor has not granted consent for tracking. See Privacy notices and what they change.

Why a guest purchase sends no phone number: someone buying without signing in is matched to an existing customer record on name and birthday, so the phone number on that record is not something the visitor typed. A hashed phone number is short enough to recover by brute force, so publishing one into the page would expose a number the visitor never supplied. Everything else sent for a guest is either what they just entered or opaque.

Example use case: a location runs Google Ads for its summer youth program and sees far fewer conversions in Ads than it has bookings in Capitan, because customers click the ad on a phone and complete the purchase on a laptop. Turning this setting on lets Google match the hashed email of the buyer to the account that clicked, so those bookings are credited to the campaign that produced them.

Disclosing this in your privacy policy is your responsibility. Capitan shows visitors a privacy notice and records their choice, but the policy describing what your location shares with Google is yours to write and maintain.


Send purchases from the server with the Measurement Protocol

Ad blockers and browser tracking prevention stop the Google tag on a share of visits, so GA4 never hears about some of the purchases Capitan processes. The Measurement Protocol closes that gap for purchases: with an API secret saved, Capitan sends a second copy of each purchase  event from its own servers, carrying the same transaction ID (the Capitan invoice number) as the browser's copy. Google deduplicates purchase events that share a transaction ID, so the two copies count as one sale, and the sale is still recorded when the browser copy never arrived.

To turn it on:

  1. In Google Analytics, click Admin, then under Data collection and modification click Data streams, select your web stream, and click Measurement Protocol API secrets. Click Create and copy the secret value. Google's own instructions are in the Measurement Protocol documentation.
  2. On the Staff Site, go to Organization Settings and paste the secret into the Measurement Protocol API Secret field, below Send customer info to Google Analytics. The field appears once a Measurement ID is entered.
  3. Click Save.

Clearing the secret turns server-side sending off again. The Google tag keeps working on its own.

Google accepts events sent with a wrong secret without reporting an error, so Capitan cannot warn you about a typo. After saving, make a test purchase in the Climber App and confirm it appears under Reports, Realtime in GA4.

What the server sends: purchase  only, with the same transaction ID, currency, value, and items as the browser event. view_item , begin_checkout , and page views stay browser-only, because Google deduplicates only purchases and a server copy of any other event would be counted twice. Each server purchase carries the visitor's Google Analytics client ID and session ID where the Google tag was able to set its cookies, and, when customer info is on, the same user ID and hashed identifiers the browser sends. With customer info off, no customer identifiers leave the server.

The privacy notice applies to both copies. A visitor who has not granted consent, a staff user acting on a customer's behalf, and a kiosk session produce no server purchase, just as they produce no browser event. Server-side sending never reports anyone the Google tag would not.

purchase  no longer depends on the confirmation page. The server copy is sent when the payment completes, so a customer who pays and closes the tab before the confirmation screen appears is still counted. Purchases that never pass through the Climber App checkout (the Sell Screen, your POS, and automatic membership renewals) are still not sent.

Purchases only the server saw have no traffic source. When the browser never set Google's cookies, GA4 has no session to attach the server copy to, so its revenue counts while its source, device, and location show as "(not set)" in GA4's reports.

Delivery and retries: purchases leave within a minute or two of the payment and are retried for about a day if Google cannot be reached. A purchase older than 48 hours is dropped rather than sent, so a late copy never risks counting a sale twice.

Example use case: a location's GA4 Monetization report shows noticeably less revenue than the Capitan Revenue report for the same week, and most of its members book from phones with tracking prevention on. After an admin adds a Measurement Protocol API secret, the purchases from those phones start reaching GA4, and the two revenue figures move closer together.


Privacy notices and what they change

The Climber App asks visitors about analytics and advertising tracking, and both the Google tag and the Meta Pixel obey the answer. Which notice a visitor sees depends on where they are:

Where the visitor is What they see What happens before they answer
The EU, the wider EEA, and the UK A banner with Reject and Accept Tracking stays off until they choose Accept
The United States A notice with Do Not Sell or Share My Personal Information and OK Tracking runs, and stays on unless they opt out
Everywhere else No notice Tracking runs

Capitan works out where a visitor is from their internet connection, at the country level only. When that cannot be determined, the visitor is treated as being in the EU and gets the banner, because showing a notice to someone who did not need one costs less than the reverse.

What "not granted" means for Google Analytics. Capitan uses Google Consent Mode v2, so the tag still loads and the page still raises its events, but every storage signal is set to denied: no analytics or advertising cookies are written or read, and no customer info is attached. Events reaching Google in that state carry no identifiers at all, which is what lets Google model the conversions it cannot observe. Meta is treated differently, because its pixel holds events in a queue while consent is revoked rather than sending anonymized ones.

One thing that is withheld completely: anything in the Tracking/Analytics Script field is left out of the page entirely until consent is granted. Capitan has no way to signal consent to an arbitrary pasted script, so the only control available is not to render it.

Staff-on-behalf sessions and kiosks are never asked and never tracked. A staff user helping a customer, or a shared kiosk device, sees no notice, and Capitan records no decision on that device.

A visitor can change their mind at any time from the Climber App settings page, in the Privacy card: the Allow analytics and advertising cookies checkbox, then Save Preferences.

Expect lower reported traffic in the EU and the UK. Sessions from visitors who decline, or who never answer the banner, arrive without cookies, so GA4 cannot stitch them into a returning visitor or attribute them to a campaign. Your Climber App is as busy as it was; the share of it that GA4 can describe is smaller.


What gets tracked automatically

Page views (traffic)

Because you provided a Measurement ID, Capitan injects the Google tag into the <head>  of every Climber App page. The standard GA4 page-view tracking is part of that tag, so a page view is recorded automatically each time a customer loads any page: the login page, the schedule, a membership purchase page, the confirmation screen, and so on.

This is what powers GA4's traffic reporting. With no extra work you'll be able to see:

  • How many people visit your Climber App, and how that changes over time.
  • Which pages are most and least visited.
  • Where visitors come from: direct links, Google search, social media, or marketing campaigns (if you tag your links with UTM parameters).
  • Real-time activity, meaning who is on your Climber App right now.

You do not need to add anything to the "Tracking/Analytics Script" field to get page views. Page-view tracking is included automatically the moment you save a Measurement ID.

Ecommerce events (the purchase funnel)

On top of page views, Capitan sends three standard GA4 ecommerce events as customers move through a purchase in the Climber App. Together they form a funnel:

Funnel stage GA4 event When it fires in the Climber App
👀 Browsing view_item The customer opens a specific product and is choosing who it's for / how many participants.
🛒 Checkout started begin_checkout The customer reaches the payment page for that product.
✅ Purchase complete purchase The customer reaches the confirmation page after paying.

These events fire for every type of product a customer can buy through the Climber App. With a Measurement Protocol API secret saved, purchase  is also sent from Capitan's servers under the same transaction ID, so GA4 counts the two copies once.

What information each event carries

  • view_item : the item's name, a unique item ID, and a quantity of 1. On the pages where the price is already settled it also carries the currency and the value, and the item carries its price. See Where a price is included below.
  • begin_checkout : the item, the currency, and the value (the invoice total at checkout).
  • purchase : everything in begin_checkout , plus a transaction ID (the Capitan invoice number). This is the event that drives your revenue reporting in GA4.

The currency is your organization's configured currency (for example USD or GBP), and the value is the full invoice amount, including any applicable taxes and fees.

Where a price is included

view_item  fires while the customer is still choosing options, so on most product pages the final price is not settled yet. Where the page already knows it, the event carries the currency, the value, and the item's price. That amount is tax-inclusive, so it matches the value the later begin_checkout  and purchase  events read off the invoice.

A price is included on:

  • The gift pages for a membership, an entry pass, and a voucher pack, where the price is the product's own fee plus tax at the purchaser's location.
  • The voucher pack purchase page, where one list price and one tax rate apply to everyone.

No price is included on:

  • The gift card page, where the visitor types the amount.
  • Membership and entry pass pages bought for a specific member, where the price depends on that member's tier or home location.
  • Event and session booking pages, where the price comes from a pricing matrix and the number of participants.

What this changes in your reports: a view_item  with no price still counts as a product view, so the view-to-purchase comparisons in Monetization and funnel explorations are unaffected either way. What you cannot do is read an expected revenue figure off view_item  for the products in the second list.


Understanding the item names

Each tracked product is sent to Google Analytics with a human-readable item name (for example "Adult Annual Membership") and a structured item ID. The item ID uses a consistent prefix so you can tell product types apart and group them in reports:

Item ID format What it represents
membership-{id} A membership
pass-{id} An entry pass
voucher-pack-{id} A voucher pack
event-{id} A session or event booking
membership-gift-{id} A gifted membership
entry-pass-gift-{id} A gifted entry pass
voucher-pack-gift-{id} A gifted voucher pack
gift-card A gift card

A note on gift cards: gift cards have no per-product ID, so every gift card event uses the fixed ID gift-card , on the product page and on the checkout and confirmation pages alike.

In most GA4 reports you'll work with the friendly item name, but the item ID is useful when you want to analyze a specific product or an entire category at once. These are the same product IDs the Meta Pixel integration uses, so if you run both, a product's activity lines up across the two platforms.


How to use this data in Google Analytics

Here's where the integration pays off. A few of the most useful things you can do once data is flowing:

1. Confirm it's working (Realtime). In GA4, open Reports, then Realtime, then open your Climber App in another browser tab and click around. You should see your visit appear within seconds. Start a purchase and you'll see the begin_checkout  and purchase  events show up. For deeper troubleshooting, Google's DebugView shows individual events as they arrive.

2. See revenue and best-sellers (Monetization). Reports, Monetization, Ecommerce purchases breaks down items viewed, checkouts started, items purchased, and total revenue, by item name. This tells you which memberships, passes, and events actually sell through the Climber App, and how much money each brings in.

3. Find where customers drop off (Funnel exploration). In Explore, Funnel exploration, build a funnel of view_item , begin_checkout , purchase . If many customers view a membership but few start checkout, or many start checkout but don't finish, that's a concrete signal about where your online buying experience needs attention.

4. Measure your marketing (key events + campaign tracking). Mark the purchase  event as a key event (GA4's term for a conversion). Then, when you tag the links in your emails, ads, and social posts with UTM parameters, GA4 attributes purchases back to the campaign that drove them, so you can see which marketing actually produces sales. If you link GA4 to Google Ads, you can optimize ad spend against real Climber App revenue.

5. Re-engage shoppers who didn't finish (Audiences). Build an audience of people who triggered begin_checkout  but not purchase , meaning they started buying but didn't complete, and use it for remarketing.

6. Compare interest vs. sales per product. Because both view_item  and purchase  carry the product name, you can compare views to purchases for each product and spot items with lots of interest but weak conversion.


Good to know (limitations & details)

  • It's not retroactive. Google Analytics only collects data from the moment you add your Measurement ID. It can't show you traffic or sales from before setup.
  • Only Climber App purchases are tracked. Sales made by staff using the Staff Site Sell Screen or through your POS, and automatic recurring membership renewals, do not go through the Climber App checkout pages, so they are not sent to Google Analytics. Treat these numbers as customer online activity, not your full revenue. Your Capitan reports remain the source of truth for total revenue.
  • Without a Measurement Protocol API secret, a purchase is counted when the confirmation page loads. If a customer pays but closes the tab before the confirmation screen appears, that purchase does not reach Google Analytics. A Measurement Protocol API secret removes this gap, since the server copy is sent when the payment completes. Small discrepancies between GA4 and your Capitan revenue reports remain normal.
  • Without a Measurement Protocol API secret, all events are sent from the visitor's browser. Visitors whose browsers block trackers (ad blockers, strict privacy settings) are not tracked, which is another reason GA4's revenue runs below your Capitan reports. The Measurement Protocol recovers their purchases, though not their page views or funnel events. Visitors who decline the privacy notice are not tracked either way.
  • Each sale is one line item at the full invoice total. A purchase is reported with a quantity of 1 and a price equal to the whole invoice, even when it covers several people (like a group membership) or multiple participants (like a group booking). Your total revenue in GA4 will be right; the per-item quantity breakdown is not itemized per person.
  • Purchases are de-duplicated. The purchase  event uses the Capitan invoice number as its transaction ID, so a customer refreshing the confirmation page won't double-count the sale.
  • Reporting delay. Realtime and DebugView are nearly instant, but GA4's standard reports can take up to 24 to 48 hours to fully process data.

Advanced: the "Tracking/Analytics Script" field

Below the Measurement ID field in Organization Settings is a larger box labeled Tracking/Analytics Script. Capitan injects whatever you put here into the <head>  of every Climber App page.

Use this field only for analytics or tracking tools where Capitan doesn't have a dedicated integration: a Google Tag Manager container, a heatmap tool, or a third-party analytics provider. Paste in the snippet that tool gives you.

You do not need this field for:

  • Google Analytics 4: use the Measurement ID field instead.
  • Meta Pixel: use the dedicated Meta Pixel ID / Dataset ID field instead (it tracks the same view/checkout/purchase funnel for Meta advertising).

Putting a Google Analytics or Meta snippet here in addition to using the dedicated ID field will cause your data to be counted twice.

Whatever you paste here is subject to the privacy notice too. Unlike the two built-in integrations, a pasted script has no way to be told about consent, so Capitan leaves it out of the page entirely until the visitor grants it. A script here that counts visits will report fewer of them than it did before the notices existed.


Technical reference (optional)

For the technically curious or your web developer. Non-technical users can stop here.

When a Measurement ID is set, Capitan adds the standard Google tag to the <head>  of every Climber App page:

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

The gtag('config', ...)  call is what sends the automatic page_view  event on each page load. The ecommerce events are emitted on the relevant funnel pages. Example payloads:

// On a product page where the price is not settled yet
gtag('event', 'view_item', {
  items: [{ item_id: 'membership-12', item_name: 'Adult Annual Membership', quantity: 1 }]
});

// On a product page where it is (the three gift pages, and the voucher pack page)
gtag('event', 'view_item', {
  currency: 'USD',
  value: 75,
  items: [{ item_id: 'membership-gift-12', item_name: 'Adult Annual Membership', price: 75, quantity: 1 }]
});

// On the payment page
gtag('event', 'begin_checkout', {
  currency: 'USD',
  value: 75,
  items: [{ item_id: 'membership-12', item_name: 'Adult Annual Membership', price: 75, quantity: 1 }]
});

// On the confirmation page
gtag('event', 'purchase', {
  transaction_id: '48213',
  currency: 'USD',
  value: 75,
  items: [{ item_id: 'membership-12', item_name: 'Adult Annual Membership', price: 75, quantity: 1 }]
});

A Consent Mode default command is emitted immediately after the tag loads, before the config  call and before any customer info. Storage signals start denied and are set to granted when the visitor accepts:

gtag('consent', 'default', {
  ad_storage: 'denied',
  ad_user_data: 'denied',
  ad_personalization: 'denied',
  analytics_storage: 'denied',
  security_storage: 'granted',
  functionality_storage: 'granted'
});

With customer info on, consent granted, and somebody to identify, the user-provided data is set before the config  call, and the config  call carries the user ID:

gtag('set', 'user_data', {
  sha256_email_address: '<hash of the normalized email>',
  sha256_phone_number: '<hash of the number in E.164 form>',
  address: {
  sha256_first_name: '<hash of the lowercased first name>',
  sha256_last_name: '<hash of the lowercased last name>'
  }
});

gtag('config', 'G-XXXXXXXXXX', { user_id: '4821' });

Three details worth knowing if you're auditing this:

  • sha256_phone_number  is present only for a signed-in customer, and the address  object carries the name fields only. Capitan holds street addresses for some customers, and a partial address is of no use to Google's matching, so none of it is sent.
  • The email is normalized to Google's rules before hashing, which includes the Gmail dot and plus-address rule. Meta receives a hash of the same address under its own rules, so the two hashes differ by design. The same applies to the phone number: Google wants the leading + , Meta does not.
  • gtag('set', ...)  is page-global, not per-destination. It is the way Google documents supplying user-provided data, and the consequence is that any other Google tag on the page also receives these hashed values, including one pasted into the Tracking/Analytics Script field. The Meta Pixel cannot do this: its identifiers are bound to one pixel ID.

Where consent has not been granted, the user_data  block and the user_id  are both omitted.

With a Measurement Protocol API secret saved, Capitan also POSTs each completed purchase to https://www.google-analytics.com/mp/collect  with your Measurement ID and API secret as query parameters. The body carries:

  • client_id  from the visitor's _ga  cookie. When the browser never set one, Capitan generates a client ID in Google's format, derived from the purchase so a retried send arrives as the same client.
  • timestamp_micros  set to when the payment completed.
  • One purchase  event whose parameters are the browser event's transaction_id , currency , value , and items , plus session_id  from the _ga_<stream>  cookie when present and an engagement_time_msec  of 100 (GA4 shows an event in Realtime only with both).
  • user_id  and user_data , in the same shape as the gtag('set', 'user_data', ...)  call above, only when customer info is on.

No IP address or user agent is sent, which is why server-only purchases show device and location as "(not set)".

Still need help? Contact Us Contact Us