This is an old revision of the document!


type:
integration
supports-foxycart-version-from:
1.0.0
supports-foxycart-version-to:
1.1.0
system:
Google Analytics (Universal Analytics)
name:
Ecommerce Tracking for Google Analytics (Universal Analytics)
description:
Tutorial to set up ecommerce tracking for Google Analytics analytics.js and FoxyCart
tag:
analytics, tutorial, tracking
date:
2014-02-18
developer:
http://www.foxycart.com/

Google Analytics (Universal Analytics) Ecommerce Tracking

These instructions are new, and while we have done some testing on the set up - the following are new instructions. Where possible we recommend testing this set up on a test profile before setting to your live analytics account, to ensure it works perfectly for your store. Any questions or issues, please get in touch with us.

Read This First:

Assumptions

  1. The instructions and code below is current as of FoxyCart v1.1 and Google Analytics as of 2014-01-14. If you notice things that should be changed please let us know on our forum.
  2. If you've applied any advanced filters to rewrite your request URIs you'll need to take that into account when setting your goal and funnel. If you don't know what that means, you probably don't have to worry about it, but rewriting the request URI can be useful when you're tracking multiple subdomains in one profile.

Requirements

  • Your products should use the SKU parameter in Google Analytics, which is the code parameter in FoxyCart. If your products do not include a code value (as passed to FoxyCart) FoxyCart will attempt to generate one from the name attribute, but FoxyCart will not take into account duplicate product names, which can clobber your data. If you are not using the code parameter for your products, this Google Analytics tracking may not work correctly.
  • All your add-to-cart links and forms must point to https://your_foxycart_domain and not http://your_foxycart_domain.
  • You must be using either foxycart.colorbox.js (the default behavior) or foxycart.js in your website template (do not include this in your cart, checkout, or receipt template). If you don't know what you're using, you're probably using foxycart.colorbox.js and don't have to worry, but you can view your template source to confirm. The code below assumes that fcc has been declared as a new FC.client, so if you're using foxycart.raw.js you'll need to create fcc or modify the FC.ga object accordingly.

Other important Google Analytics stuff

  • We strongly recommend setting up a separate Google Analytics profile to test with. This setup can be tricky, it can't be confirmed immediately because Google Analytics has a delay on reporting, and if you use your primary profile it may dirty up your data (which you cannot undo).
  • Tracking your banner ads and email marketing links. Very cool, and you should definitely do it if you're going to do anything described below.
  • This is all for analytics.js and not urchin.js or ga.js. If you need to use urchin.js or ga.js, see these instructions.

Known Issues and Limitations

  • This code may not work correctly if you're doing direct-to-checkout (cart=checkout) links originating from outside the site being tracked by Google Analytics. For instance, if you have cart=checkout links in an email, the referrer or campaign may not be maintained. If this is an issue for you please let us know.

Setting Up Google Analytics

Getting the Tracking Code

  1. From the “Admin” section of your Google Analytics account, select the “Account” and “Property” you want to add tracking to. (You may want to create a new profile to test with, so as not to dirty up your real account with test data.)
  2. In the “Tracking Info” section under “Property” select “Tracking Code”
  3. Complete the setup as Google Analytics instructs: “Copy and paste it into the code of every page you want to track.” Do not put this code on your FoxyCart cart, checkout, or receipt templates.
  4. We'll refer back to this block of code as the main Google Analytics code block, so make a mental note that this is what we're talking about.
  5. Proceed to the next section.

Configuring Your Profile Settings

  1. Edit your View Settings in your Google Analytics Settings section. (You can get here by clicking the “Admin” link in the top right, then select your “Account” and “Property” dropdowns.) Select “View Settings” under “View”
  2. Add fcsid to the “Exclude URL Query Parameters” in your analytics settings. Details here.
  3. Set your timezone as necessary.
  4. Set your currency as desired and turn on “Ecommerce tracking”.
  5. You may want to set your “Default Page” to index.html or index.php or etc. But make sure you understand what this means, as it affects stuff like yourdomain.com/ as well as yourdomain.com/dir/sub/. More info here and here.
  6. Proceed to the next section.

Excluding Referral Sources

  1. If you are using a custom domain for your website (like store.yourdomain.com), you can skip this section. If you're using a FoxyCart domain (like yourstore.foxycart.com), you will want to complete this section. More details here
  2. Under 'Tracking Info' click 'Referral Exclusion List'. By default, your own website's domain should be present here, but we will need to add your store domain.
  3. Click 'Add Referral Exclusion' and enter your store domain, such as “mystore.foxycart.com”, and click “Create”.
  4. Proceed to the next section

Creating Your Goals

  1. Under your property's “View”, click “Goals” and then “Create a goal”.
  2. Enter a “Goal Name” that makes sense to you, like “E-commerce Sale” or “Transaction” or etc.
  3. Set the “Goal Type” to “Destination” and click “Next Step”.
  4. Switch the “Destination” dropdown to “Equals To”.
  5. Enter for your Goal URL: /receipt
  6. Turn on the “Funnel” switch and:
    1. Step 1: use “Cart” for the Name and /cart for the Screen/Page. (You won't have this step if you are using “direct to checkout” with the parameter “cart=checkout”). Do not check the “required step” checkbox, as there are situations where the cart can be skipped.
    2. Step 2: “Checkout” for the Screen/Page and /checkout for the URL.
  7. Hit the “Save Changes” button down at the bottom. (The receipt page is the goal, so you don't need to add it in the steps.)

Hosted Payment Method Goals

If you're using a hosted payment method like PayPal Express Checkout or Amazon FPS, you can create additional goals to track specific conversions for those options.

PayPal Express Checkout

Name: “Sale (PayPal as Checkout)“
Destination: /receipt_paypal_from_cart
Funnel:

  1. /cart, Cart
  2. /paypal_checkout, PayPal (Checkout)
  3. /checkout, Checkout (Confirmation)

Name: “Sale (PayPal as Payment Method)”
Destination: /receipt_paypal_from_checkout
Funnel:

  1. /cart, Cart
  2. /checkout, Checkout
  3. /paypal_payment, PayPal (Payment Method)

Amazon FPS

Name: “Sale (Amazon FPS as Checkout)“
Destination: /receipt_amazon_fps_from_cart
Funnel:

  1. /cart, Cart
  2. /amazon_fps_checkout, Amazon FPS (Checkout)
  3. /checkout, Checkout (Confirmation)

Name: “Sale (Amazon FPS as Payment Method)“
Destination: /receipt_amazon_fps_from_checkout
Funnel:

  1. /cart, Cart
  2. /checkout, Checkout
  3. /amazon_fps_payment, Amazon FPS (Payment Method)

Proceed to the next section.

Setting Up Your Site

  1. On your own site, add the following to each page (except your FoxyCart cart, checkout and receipt templates), right before the closing </head> tag - ensuring that it's included after the foxycart.js file you copied from the Sample Code section of your stores FoxyCart administration:
    <script>
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
     
      ga('create', 'UA-XXXX-Y', 'auto');
      ga('send', 'pageview');
     
    </script>
    <script type="text/javascript" charset="utf-8">
      fcc.events.cart.preprocess.add(function(e, arr) {
        if (arr['cart'] == 'checkout' || arr['cart'] == 'updateinfo' || arr['output'] == 'json') {
          return true;
        }
        if (arr['cart'] == 'checkout_paypal_express') {
          ga('send', 'pageview', '/paypal_checkout', {
            'hitCallback': function() {
              jQuery.getJSON('https://' + document.domain + '/cart?' + fcc.session_get() + '&h:_fcpm=paypal|cart&output=json&callback=?', function(cart) {
                fcc.events.cart.preprocess.resume();
              });
            }
          });
          return "pause";
        }
        return true;
      });
      fcc.events.cart.process.add_pre(function(e, arr) {
        ga(function(tracker) {
          jQuery.getJSON('https://' + storedomain + '/cart?' + fcc.session_get() + '&h:ga=' + escape(tracker.get('clientId')) + '&output=json&callback=?', function(data){
            fcc.events.cart.process.resume();
          });
        });
        return "pause";
      });
    </script>
    • In case you're wondering… The key is that we want to keep the FoxyCart session up to date with the GA session data. The code above basically pushes the Google Analytics session id into the FoxyCart session so the GA session can be maintained between your own site's domain and your site's FoxyCart domain.
  2. Do not put this code in your cart, checkout, or receipt templates.
  3. Proceed to the next section.

Setting Up Your FoxyCart Templates, The Full Details

Copy the following and paste it above the closing </head> tag in the respective templates. This can be directly in your FoxyCart admin or (preferably) in a template on your server that you will load into FoxyCart via FoxyCart's template caching functionality

The Cart Template

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
 
  ga('create', 'UA-XXXX-Y', 'auto', {
    'clientId': fc_json.custom_fields['ga'],
    'storage': 'none'
  });
  ga('set', 'page', '/cart');
  ga('send', 'pageview');
 
</script>
<script type="text/javascript" charset="utf-8">
  jQuery(function($){
    if ($('a.fc_cart_checkout_paypal').length > 0) {
      $.getJSON('https://' + document.domain + '/cart?fcsid=' + jQuery("input[name='fcsid']").val() + '&h:_fcpm=&output=json&callback=?', function(cart) { fc_json = cart; });
    }
    $('a.fc_cart_checkout_paypal').click(function(e){
      e.preventDefault();
      var link_url = jQuery(this).attr("href");
      var gateway = (jQuery(this).hasClass("fc_cart_checkout_amazon")) ? "amazon_fps" : "paypal";
      ga('send', 'pageview', '/' + gateway + '_checkout', {
        'hitCallback': function() {
          $form = jQuery('<form method="post" target="_top"></form>').attr("action", link_url).appendTo("body");
          jQuery.getJSON('https://' + document.domain + '/cart?fcsid=' + jQuery("input[name='fcsid']").first().val() + '&h:_fcpm=' + gateway + '|cart&output=json&callback=?', function(cart) {
            $form.submit();
          });
        }
      });
    });
  });
</script>

The Checkout Template

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
 
  ga('create', 'UA-XXXX-Y', 'auto', {
    'clientId': fc_json.custom_fields['ga'],
    'storage': 'none'
  });
  ga('set', 'page', '/checkout');
  ga('send', 'pageview');
 
</script>
<script type="text/javascript" charset="utf-8">
  function ga_tracker() {
    if (typeof(fc_json.custom_fields['ga']) != "undefined") {
      var method, method_co, source = "";
 
      if (typeof(fc_json.custom_fields['_fcpm']) != "undefined" && fc_json.custom_fields['_fcpm'] != "") {
        var fcpm = fc_json.custom_fields['_fcpm'].split("|");
        method = fcpm[0];
        source = fcpm[1];
      }
 
      if (jQuery("input[name='fc_payment_method']:first").attr("type") == "radio") {
        method_co = jQuery("input[name='fc_payment_method']:checked").val();
      } else if (jQuery("input[name='fc_payment_method']:first").attr("type") == "hidden") {
        method_co = jQuery("input[name='fc_payment_method']").val();
      }
 
      if (method != method_co || source == "checkout") {
        method = method_co;
        source = "checkout";
        jQuery.getJSON('https://' + document.domain + '/cart?' + FC.checkout.config.session + '&h:_fcpm=' + method + "|" + source + '&output=json&callback=?', function(cart) { });
        if (method != "plastic" && method != "purchase_order" && source == "checkout") {
          ga('send', 'pageview', '/' + method + '_payment');
        }
      }     
    }
  }
  FC.checkout.overload('validateAndSubmit', 'ga_tracker', null);
</script>

The Receipt Template

There are three lines of Twig code that you need to alter in the receipt template - depending on the specific locale that your store is set to. See below the following code block on how to adjust these.

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
 
  ga('create', 'UA-XXXX-Y', 'auto', {
    'clientId': fc_json.custom_fields['ga'],
    'storage': 'none'
  });
  var pageview = "/receipt";
  if (typeof(fc_json.custom_fields['_fcpm']) != "undefined" && fc_json.custom_fields['_fcpm'] != "") {
    var fcpm = fc_json.custom_fields['_fcpm'].split("|");
    if (fcpm[0] != "plastic" && fcpm[0] != "purchase_order") {
      pageview += "_" + fcpm[0] + "_from_" + fcpm[1];
    }
  }
  ga('set', 'page', pageview);
  {% if first_receipt_display %}
    ga('send', 'pageview');
  {% endif %}
</script>
<script>
  {% if first_receipt_display %}
    {# Update these three variables based on your store configuration #}
    {% set c_symbol = "$" %}
    {% set c_thousands = "," %}
    {% set c_decimal = "." %}
 
    {% set ga_order_total = order_total|replace({ (c_symbol):"", (c_thousands):"" }) %}
    {% set ga_shipping_total = receipt_shipping_cost|replace({ (c_symbol):"", (c_thousands):"" }) %}
    {% set ga_tax_total = receipt_tax|replace({ (c_symbol):"", (c_thousands):"" }) %}
    {% if c_decimal != "." %}
      {% set ga_order_total = ga_order_total|replace({ (c_decimal):"." }) %}
      {% set ga_shipping_total = ga_shipping_total|replace({ (c_decimal):"." }) %}
      {% set ga_tax_total = ga_tax_total|replace({ (c_decimal):"." }) %}
    {% endif %}
    ga('require', 'ecommerce', 'ecommerce.js');
    ga('ecommerce:addTransaction', {
      'id': '{{ order_id }}',
      'affiliation': '{{ store_name|raw }}',
      'revenue': '{{ ga_order_total }}',
      'shipping': '{{ ga_shipping_total }}',
      'tax': '{{ ga_tax_total }}'
    });
    {% for item in items %}
      {% set ga_price_each = item.price_each|replace({ (c_symbol):"", (c_thousands):"" }) %}
      {% if c_decimal != "." %}
        {% set ga_price_each = ga_price_each|replace({ (c_decimal):"." }) %}
      {% endif %}
      ga('ecommerce:addItem', {
        'id': '{{ order_id }}',
        'name': '{{ item.name }}',
        'sku': '{{ item.code }}',
        'category': '{{ item.category_code }}',
        'price': '{{ ga_price_each }}',
        'quantity': '{{ item.quantity }}'
      });
    {% endfor %}
    ga('ecommerce:send');
  {% endif %}
</script>

The three lines you may need to alter for the receipt template are:

{% set c_symbol = "$" %}
{% set c_thousands = "," %}
{% set c_decimal = "." %}

If your store uses Euro's, and uses a decimal point as the thousands operator and a comma as the decimal point, you would update those three lines to look like this:

{% set c_symbol = "€" %}
{% set c_thousands = "." %}
{% set c_decimal = "," %}

Testing

First off, we strongly recommend creating a new profile in Google Analytics to test with. That way you don't have to worry about running 100 transactions and completely destroying the accuracy of the analytics, which is the entire point.

For testing, Google Analytics has a great feature called “Real-Time” which is the first option under “Standard Reports” when looking at an individual analytics profiles reports. Using this section, you can pretty quickly track whether your analytics code is correctly set up. What you'll be doing is switching between Google Analytics Real-Time Overview page and your store as you perform different actions to ensure it's tracking you correctly. If it is, you should see an individual session being tracked as you move throughout the checkout flow - changing pages as you do.

Before starting, try clearing your browser's cookies (at least for the domains in question: your site domain and FoxyCart.com) and preferably using a browser that you don't use to develop in. So if you use Firefox to administer your site through a CMS and to login to the FoxyCart admin, try testing in Chrome or Safari. The goal is to pretend you're a normal customer.

  1. Load up your website in one tab and then load up the Google Analytics Real-Time Overview in a second tab. You should see your analytics session tracking that you're looking at your website.
  2. Add a product to the cart, loading up the cart and then look back and Google Analytics. You should see it change your single user session to be on the cart.
  3. Complete a checkout, confirming after each stage that your Analytics session is tracking you as you go.
  4. After completing a checkout, switch to the 'Conversions' tab in the Real-Time section and ensure that your goal has been correctly tracked.
  5. Clear your cookies, especially any of the Google Analytics cookies, which are named _utm*.
  6. If you're using PayPal Express Checkout or Amazon FPS, try testing that a few times both from the cart and from the checkout. Go all the way through, stop before completing, bail out on the PayPal end of things, etc.
  7. If at any point you see multiple sessions in the 'Overview' page for what you're doing, double check that all of the code is inserted for the page that created a new session as detailed above.
  8. Once you've tested quite a bit go to your Google Analytics → Conversions → Goals → Funnel Visualization. It should hopefully look something like the image to the right. The key is that the numbers in between the steps are not zero. If you have values there it's tracking the user through the steps, indicating that the Google Analytics info is being passed correctly across domains. If you have zeroes in there, go back through the steps to ensure you have all the code inserted as it should be. Post on our forum if you get stuck.
  9. Party down! You're done.

Tracking Your Changes

Working with Analytics can be a big undertaking at times, and as changes to your set up isn't retroactively applied to previous statistics, can lead to some confusion in your data. We recommend setting up an analytics journal to keep track of any and all changes you make to your analytics profile and tracking code. By doing that, you can quickly compare your statistics to when you applied a certain change to make sure it's working, and possibly explain why the data is different to an earlier time period.

Site Tools