Google Analytics 4 Ecommerce Tracking on HubSpot | Blue Frog Docs

Google Analytics 4 Ecommerce Tracking on HubSpot

Set up GA4 ecommerce tracking for HubSpot Commerce, payments, and product interactions.

Google Analytics 4 Ecommerce Tracking on HubSpot

If you're using HubSpot Payments, HubSpot Commerce features, or selling products through HubSpot, this guide will help you implement GA4 ecommerce tracking.

Prerequisites

  1. Install GA4 on HubSpot
  2. Have HubSpot Payments or Commerce Hub enabled
  3. Access to HubSpot Site Header HTML or template code

HubSpot Ecommerce Capabilities

What HubSpot Offers for Ecommerce

HubSpot Payments:

  • Process one-time and recurring payments
  • Payment links and forms
  • Quote-to-payment workflows
  • Integrated with CRM deals

HubSpot Commerce Hub (Enterprise):

  • Product catalog
  • Shopping cart functionality
  • Order management
  • Invoicing and subscriptions

Third-Party Integrations:

GA4 Ecommerce Events for HubSpot

Event When to Fire HubSpot Context
view_item Product page viewed HubSpot product catalog page
add_to_cart Item added to cart HubSpot cart interactions
begin_checkout Checkout initiated Payment form loaded
add_payment_info Payment method added Payment details entered
purchase Transaction completed Payment confirmation page

Tracking Product Views

Track when visitors view products in your HubSpot product catalog.

Product View Tracking

Add to product template or use HubL in product pages:

<script>
  // Track product view
  gtag('event', 'view_item', {
    'currency': '{{ product.currency }}',
    'value': {{ product.price }},
    'items': [{
      'item_id': '{{ product.id }}',
      'item_name': '{{ product.name }}',
      'item_category': '{{ product.category }}',
      'price': {{ product.price }},
      'quantity': 1
    }]
  });
</script>

With HubL Variables

If using HubSpot product properties:

{% if content.product_id %}
<script>
  gtag('event', 'view_item', {
    'currency': 'USD',
    'value': {{ content.product_price|default(0) }},
    'items': [{
      'item_id': '{{ content.product_id }}',
      'item_name': '{{ content.product_name }}',
      'item_category': '{{ content.product_category }}',
      'price': {{ content.product_price|default(0) }},
      'quantity': 1
    }]
  });
</script>
{% endif %}

Tracking Add to Cart

Track when items are added to a shopping cart or payment form.

For HubSpot payment links and buttons:

<script>
  document.addEventListener('click', function(event) {
    var paymentLink = event.target.closest('a[href*="payments.hubspot.com"], .hs-payment-link');

    if (paymentLink) {
      var productName = paymentLink.getAttribute('data-product-name') || paymentLink.textContent.trim();
      var productPrice = paymentLink.getAttribute('data-product-price') || '';

      gtag('event', 'add_to_cart', {
        'currency': 'USD',
        'value': parseFloat(productPrice) || 0,
        'items': [{
          'item_name': productName,
          'price': parseFloat(productPrice) || 0,
          'quantity': 1
        }]
      });
    }
  });
</script>

Custom Add to Cart Buttons

If you've built custom cart functionality:

<button class="add-to-cart-btn"
        data-product-id="PROD-123"
        data-product-name="Premium Package"
        data-product-price="99.00">
  Add to Cart
</button>

<script>
  document.addEventListener('click', function(event) {
    if (event.target.classList.contains('add-to-cart-btn')) {
      var productId = event.target.getAttribute('data-product-id');
      var productName = event.target.getAttribute('data-product-name');
      var productPrice = event.target.getAttribute('data-product-price');

      gtag('event', 'add_to_cart', {
        'currency': 'USD',
        'value': parseFloat(productPrice),
        'items': [{
          'item_id': productId,
          'item_name': productName,
          'price': parseFloat(productPrice),
          'quantity': 1
        }]
      });
    }
  });
</script>

Tracking Checkout Process

Begin Checkout Event

Fire when payment form is loaded:

<script>
  // Check if on payment/checkout page
  if (window.location.href.includes('payment') || window.location.href.includes('checkout')) {
    gtag('event', 'begin_checkout', {
      'currency': 'USD',
      'value': {{ total_amount }},
      'items': [{
        'item_name': '{{ product_name }}',
        'price': {{ product_price }},
        'quantity': 1
      }]
    });
  }
</script>

Add Payment Info Event

Fire when payment method is entered:

<script>
  // Listen for payment form interactions
  var paymentForm = document.querySelector('form[action*="payment"], .hs-payment-form');

  if (paymentForm) {
    var paymentFields = paymentForm.querySelectorAll('input[name*="card"], input[name*="payment"]');

    paymentFields.forEach(function(field) {
      field.addEventListener('blur', function() {
        if (field.value.length > 0 && !window.paymentInfoTracked) {
          window.paymentInfoTracked = true;

          gtag('event', 'add_payment_info', {
            'currency': 'USD',
            'value': {{ payment_amount }},
            'payment_type': 'credit_card'
          });
        }
      });
    });
  }
</script>

Tracking Purchases (Conversions)

Track completed purchases on the payment confirmation page.

HubSpot Payment Confirmation Page

Add to your payment confirmation template:

<script>
  // Track purchase on confirmation page
  gtag('event', 'purchase', {
    'transaction_id': '{{ payment.transaction_id }}',
    'value': {{ payment.amount }},
    'currency': '{{ payment.currency }}',
    'tax': {{ payment.tax|default(0) }},
    'items': [{
      'item_id': '{{ payment.product_id }}',
      'item_name': '{{ payment.product_name }}',
      'price': {{ payment.product_price }},
      'quantity': {{ payment.quantity|default(1) }}
    }]
  });
</script>

Using HubSpot Workflows API Data

If payment data is available via HubSpot's API:

{% if content.payment_confirmed %}
<script>
  gtag('event', 'purchase', {
    'transaction_id': '{{ contact.recent_deal_id }}',
    'value': {{ contact.recent_deal_amount }},
    'currency': 'USD',
    'items': [{
      'item_id': '{{ content.product_id }}',
      'item_name': '{{ content.product_name }}',
      'price': {{ content.product_price }},
      'quantity': 1
    }]
  });
</script>
{% endif %}

Prevent Duplicate Purchase Events

Ensure purchase event only fires once:

<script>
  // Check if purchase already tracked (use session storage)
  var transactionId = '{{ payment.transaction_id }}';

  if (transactionId && !sessionStorage.getItem('tracked_' + transactionId)) {
    gtag('event', 'purchase', {
      'transaction_id': transactionId,
      'value': {{ payment.amount }},
      'currency': 'USD',
      'items': [{
        'item_name': '{{ payment.product_name }}',
        'price': {{ payment.product_price }},
        'quantity': 1
      }]
    });

    // Mark as tracked
    sessionStorage.setItem('tracked_' + transactionId, 'true');
  }
</script>

Tracking HubSpot-Shopify Integration

If you've integrated Shopify with HubSpot, track both platforms separately.

Strategy for HubSpot-Shopify

Track in Shopify:

  • Full ecommerce funnel (view_item, add_to_cart, purchase)
  • Use Shopify's native GA4 integration
  • See Shopify GA4 Setup

Track in HubSpot:

  • Post-purchase engagement (emails, content downloads)
  • CRM interactions (meetings, form submissions)
  • Customer lifecycle progression

Link the Data: Use the same GA4 property for both:

  • Implement User ID tracking with HubSpot contact ID
  • Use cross-domain tracking if needed
  • Match customer emails between systems

Tracking Subscription/Recurring Payments

For HubSpot recurring payment tracking:

Initial Subscription Purchase

<script>
  gtag('event', 'purchase', {
    'transaction_id': '{{ subscription.initial_transaction_id }}',
    'value': {{ subscription.amount }},
    'currency': 'USD',
    'items': [{
      'item_id': '{{ subscription.plan_id }}',
      'item_name': '{{ subscription.plan_name }}',
      'item_category': 'subscription',
      'price': {{ subscription.amount }},
      'quantity': 1
    }]
  });
</script>

Subscription Renewals

Track recurring charges (requires workflow or API integration):

<script>
  // Track renewal (trigger via webhook or workflow)
  gtag('event', 'purchase', {
    'transaction_id': '{{ renewal.transaction_id }}',
    'value': {{ renewal.amount }},
    'currency': 'USD',
    'items': [{
      'item_id': '{{ renewal.plan_id }}',
      'item_name': '{{ renewal.plan_name }}',
      'item_category': 'subscription_renewal',
      'price': {{ renewal.amount }},
      'quantity': 1
    }]
  });
</script>

Enhanced Ecommerce with CRM Data

Leverage HubSpot CRM data for richer ecommerce insights.

Track Customer Lifetime Value

<script>
  {% if contact %}
  gtag('set', 'user_properties', {
    'customer_ltv': '{{ contact.total_revenue }}',
    'lifecycle_stage': '{{ contact.lifecycle_stage }}',
    'customer_since': '{{ contact.createdate }}',
    'total_purchases': {{ contact.num_associated_deals|default(0) }}
  });
  {% endif %}
</script>

Track Deal Stage Progression

<script>
  // Track when deals move to specific stages
  window.addEventListener('message', function(event) {
    if (event.data.type === 'hubspot_deal_update') {
      var dealStage = event.data.dealStage;

      if (dealStage === 'closedwon') {
        gtag('event', 'purchase', {
          'transaction_id': event.data.dealId,
          'value': event.data.dealAmount,
          'currency': 'USD'
        });
      }
    }
  });
</script>

GTM Implementation for Ecommerce

For complex ecommerce setups, use Google Tag Manager.

Create Data Layer for Products

In product templates:

<script>
  window.dataLayer = window.dataLayer || [];
  dataLayer.push({
    'event': 'view_item',
    'ecommerce': {
      'currency': 'USD',
      'value': {{ product.price }},
      'items': [{
        'item_id': '{{ product.id }}',
        'item_name': '{{ product.name }}',
        'item_category': '{{ product.category }}',
        'price': {{ product.price }},
        'quantity': 1
      }]
    }
  });
</script>

Create GTM Triggers

  1. Product View Trigger:

    • Type: Custom Event
    • Event: view_item
  2. Purchase Trigger:

    • Type: Custom Event
    • Event: purchase

See GTM Data Layer Guide for complete implementation.

Testing Ecommerce Tracking

1. Use GA4 DebugView

  • Enable debug mode in GA4 config
  • Go through purchase funnel
  • Verify events fire in correct order:
    1. view_item
    2. add_to_cart
    3. begin_checkout
    4. add_payment_info
    5. purchase

2. Check Ecommerce Reports

After 24-48 hours:

  • GA4 → Reports → Monetization → Ecommerce purchases
  • Verify transactions appear
  • Check revenue amounts match

3. Test Purchase Event Parameters

Use browser DevTools:

// Check data layer (if using GTM)
console.log(dataLayer);

// Check most recent purchase event
dataLayer.filter(item => item.event === 'purchase');

4. Verify Transaction IDs Are Unique

  • Each purchase should have unique transaction_id
  • Prevents duplicate revenue counting
  • Test by refreshing confirmation page (shouldn't fire again)

Troubleshooting

Duplicate Purchase Events

Problem: Purchase event fires multiple times

Solutions:

  1. Use sessionStorage to track fired events
  2. Ensure code only on confirmation page, not thank you page
  3. Check for multiple GA4 implementations

Fix:

var txnId = '{{ transaction_id }}';
if (!sessionStorage.getItem('purchase_' + txnId)) {
  gtag('event', 'purchase', {...});
  sessionStorage.setItem('purchase_' + txnId, '1');
}

Missing Revenue Data

Problem: Events fire but no revenue in reports

Causes:

  • Missing value parameter
  • value set to 0 or null
  • Wrong currency format
  • Items array malformed

Verify:

// Ensure value is a number, not string
'value': parseFloat('{{ amount }}') || 0

HubL Variables Not Available

Problem: Product data not accessible in templates

Solutions:

  1. Verify you're on a product/payment page
  2. Check HubSpot product catalog is configured
  3. Use HubSpot's product object structure
  4. Test with static data first

Ecommerce Events Not Showing in GA4

Check:

  1. GA4 base configuration is working
  2. Ecommerce measurement is enabled in GA4 (Admin → Data Settings)
  3. Event syntax matches GA4 spec exactly
  4. Items array is properly formatted
  5. No ad blockers during testing

Advanced: Server-Side Ecommerce Tracking

For more accurate tracking, consider server-side implementation.

Using HubSpot Workflows

Create workflow that sends purchase data to GA4 Measurement Protocol:

  1. Trigger: Deal stage changes to "Closed Won"
  2. Action: Webhook to GA4 Measurement Protocol
  3. Endpoint: https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXXXX&api_secret=YOUR_SECRET
  4. Payload:
{
  "client_id": "{{ contact.vid }}",
  "events": [{
    "name": "purchase",
    "params": {
      "transaction_id": "{{ deal.id }}",
      "value": {{ deal.amount }},
      "currency": "USD",
      "items": [{
        "item_name": "{{ deal.dealname }}",
        "price": {{ deal.amount }}
      }]
    }
  }]
}

See GA4 Measurement Protocol documentation for details.

Next Steps

For general GA4 ecommerce concepts, see GA4 Ecommerce Guide.

// SYS.FOOTER