Blocking Google Analytics Duplicate Transactions Using Google Tag Manager

This post is a follow up to the Finding and Troubleshooting Duplicate Transactions in Google Analytics guide that we recently published. If you have not already, I highly recommend reviewing that post first.

In Google Tag Manager we typically send ecommerce purchase data to Google Analytics either implicitly when the order confirmation page loads or explicitly through a purchase event pushed to the dataLayer. 

Either way, unless the developers take steps to avoid it, the purchase event will be resent each time the page is refreshed.

This can happen if a user has saved a link to the page or if they leave the page open in their browser so that it is re-loaded when they next open their browser. The net result is over reported sales figures in your Analytics.

Here I’m going to show you how to fix the problem using Google Tag Manager. I’m following Google’s recommended practice where an ecommerce purchase event is pushed to the dataLayer along with the purchase data.

The plan is to save each of the user’s transaction ids in a cookie. We will then check the cookie contents before sending each purchase to see the transaction id has already been used. If it has, we don’t send anything to GA.

The cookie will have an expiry date so it won’t hang around forever.

Here are the steps we’re going to follow (Don’t worry it’s not a bad as it looks!):

  1. Create a user defined variable to extract the transaction id from the dataLayer
  2. Create a user defined variable to save the transaction id in a 1st party cookie
  3. Create a user defined variable to retrieve the contents of the 1st party cookie
  4. Create a user defined variable to check if the current transaction is already stored
  5. Update the event trigger for the GA Enhanced Ecommerce Purchase tag to stop it triggering if the current transaction id is in the cookie
  6. Update the GA Enhanced Ecommerce Purchase tag to ensure the transaction id is saved to the cookie.

 

1 – Create a custom dataLayer variable to extract the transaction id from the dataLayer

The dataLayer on the purchase confirmation page should look something like the screenshot below where I’ve highlighted the transaction id.

To make the transaction id available in Google Tag Manager we need to create a new User-Defined dataLayer Variable. I named mine dlv – ecommerce.purchase.actionField.id for clarity. You may already have a variable in GTM for this which you can use.  

For the dataLayer Variable we reference the data we need using a dotted hierarchical notation starting at ecommerce down through the nested purchase and actionField elements. For the id field it looks like this: ecommerce.purchase.actionField.id. (case counts)

 

 

2 – Create a user defined variable to save the transaction id in a 1st party cookie

To save the transaction in a 1st Party cookie we are going to create a user defined Custom JavaScript variable which we will use later when we come to update the Purchase Tag. 

Again, for clarity, I named my variable js – hitcallback – save transaction id to cookie

Paste the code below into the Custom JavaScript window. 

A detailed explanation of the code is beyond the scope of this article but hopefully the comments are self explanatory. 

The {{dlv – ecommerce.purchase.actionField.id}} bit references the variable we created in the previous step 1 to fetch the transaction id and {{Cookie – user_transaction_ids}} references a variable we are going to create in the next step to get the transaction id’s already in the Cookie.

If your variables are named differently you will need to update the code to match. 

 function() {
  return function() {
    var data, dt, expires;
    var transaction_id = {{dlv - ecommerce.purchase.actionField.id}};
    // abort if no transaction id
    if (!transaction_id) {return;}
    // set to expire after 6 months
    dt = new Date();
    dt.setTime(dt.getTime() + 180*24*60*60*1000);
    var expires = 'expires=' + expires.toUTCString();
    // If the cookie exists, append the id
    if ({{Cookie - user_transaction_ids}}) {
      data = {{Cookie - user_transaction_ids}} + ',';
    }
    // otherwise set it    
    document.cookie = 'user_transaction_ids=' + 
          data + transaction_id + '; ' + 
          expires + '; path=/';
  };
}

When you’re done it should look like this:

 

3 – Create a user defined variable to retrieve the contents of the 1st party cookie 

To retrieve the transaction id’s from the cookie we need to create another user-Defined variable, this time the type is 1st Party Cookie. I named mine Cookie – user_transaction_ids.

In the Cookie Name field enter the name of our (yet to be created) cookie which you can see near the bottom of the JavaScript code we called user_transaction_ids

 

4 – Create a user defined variable to check if the current transaction is already stored

When we come to update our event trigger in the next step we will need a way to check if the current transaction id is already in our cookie. For this we need (you guessed it) another Custom JavaScript User-Defined variable.

Mine is imaginatively named js – is transaction id in cookie. 

The code for this one is much simpler. It will return true if the transaction id is in the cookie and false if not. 

Paste the code below into the Custom JavaScript window.

function() {
  return /(,|^){{dlv - transaction id}}/.test({{Cookie - user_transaction_ids}});
}

5 – Update the event trigger for the GA Enhanced Ecommerce Purchase tag to stop it triggering if the current transaction id is in the cookie

Edit the trigger you use to fire the Google Analytics tag with your purchase data. It should be a Custom Event trigger using the purchase event. Mine is called custom event – ecommerce purchase and looks like this.

Change the option for This trigger fires on, from All Custom Events to Some Custom EventsIn the left hand drop-down box select the variable we created in step 4

Mine was js – is transaction id in cookie. Then select equals as the condition and false as the value so it looks like the screenshot below. 

 

Rename the trigger to reflect it’s new behaviour.

 

6 – Update the GA Enhanced Ecommerce Purchase tag to ensure the transaction id is save to the cookie.

We’re nearly there! 

Edit the Google Analytics tag with your purchase data. (The one fired by the trigger we edited in step 5)

Tick the option to Enable overriding settings in this tag and expand the More Settings section. Within that, expand Fields to Set and enter hitCallback in the Field Name field

Click on the lego brick icon to the right of the Value field and select the user defined variable we created in step 2. Mine was called js – hitcallback set transaction id to cookie. 

 
Phew! That’s it

A fair bit of work there, but it should be well worth it. With these changes in place you should not see any more duplicate transactions in GA.

Hope you find that useful. Keep an eye out for more tips on our Polka Dot Data blog.

Polka Dot Data offer a range of Google Analytics services suitable for websites of any size. Speak to our team today to discuss your training  and audit needs.