Skip to main content
Data Runs Deep Menu

Main navigation

  • Home
  • Who We Are
    • Careers
    • What We're Up To
    • What We Believe In
    • Ethical Policy
  • What We Do
  • Google Marketing Platform
    • Analytics 360
    • Tag Manager 360
    • Salesforce and GA360
    • Google Analytics App+Web
    • Data Studio
    • Optimize
  • Google Cloud Platform
    • Google BigQuery
      • Google BigQuery Training
      • Google Analytics Integration
  • Consulting
    • Strategy
    • Implementation
      • Google Analytics Audit
      • Google Tag Manager Audit
      • Enhanced Ecommerce Implementation
      • Google Tag Manager
    • Analysis
      • Google Data Studio
        • Google Data Studio Case Study - Mona
      • UX Analysis
  • Training
    • Five Day Google Analytics Online Workshop
    • Advanced Google Analytics Training
    • Google Tag Manager Training
    • Google Analytics 360 Training
    • Advanced Analytics Bootcamp
  • Partnerships
    • Conductrics
  • Blog
  • The Flying Beagle
  • Merch
  • Contact

Preventing Duplicate Transactions in Google Analytics

By: Max Yodgee
Posted in
  • Google Tag Manager
  • Google Analytics
  • JavaScript
Article Date
October 11, 2018

Transaction tracking is often the key stone data set for reporting purposes, providing attribution to marketing spend, user value and detail breakdowns of how a website/application is performing.

Transactions can also be compared to the core business records, providing the ability to determine how accurate the website/application tracking is. So it really goes without saying that tracking this information accurately is key to gaining trust in the analytics, and providing the business with reliable insights.

One of the common issues that appears in transaction reports is the dreaded duplicate transaction. This issue does not always present itself easily as unless you’re running custom reports, or you’re actively looking for duplicate transactions.

Because they’re hard to find, they may be altering your data in some very negative ways without you actually knowing it. You could find distortion in your transaction totals, your revenue, and your product performance metrics (which, if you’re pure Ecommerce, is basically everything you care about).

The issue is often present when the order/receipt page can be revisited or re-viewed by the user, and this inadvertently triggers the transaction tracking again. That’s the most common cause, though note that some mobile browsers can also store the current website pages in memory when it’s closed/minimized, when loading the browser back up it reloads previous pages and therefore can trigger the order confirmation page again. A scenario that your development time might not be able to assist with.

Spotting the issue

Take a look at your transaction report, then create a custom report (flat table) that looks at Transaction IDs with the metrics of transactions and revenue. The result could be shocking! Take a look at the below example.

Standard Ecommerce Transaction Report

Custom Report “Duplicate Transactions Template link: https://analytics.google.com/analytics/web/template?uid=FK5maX3XRqSoatUVAMDR8A

Using a segment and User Explorer targeted to the “5” Transaction count Id.

Transaction report, specific to the “5” transaction count.

Looking at the above we can see the negative impact, note the user originally purchased 2 of the same item.  As the website allows a user to review their receipt and inadvertently re-sends the transaction with every review we can see Google Analytics records the quantity and revenue x 5 times higher than the business records will.

While the ideal solution is to request your development team to prevent this, note it is possible and should be for most platforms, it’s a potential that this won't be an option for you.

If that's the case then following can help reduce the duplicate transactions but won’t entirely rule them out.

The Concept

  1. After successful  transaction, store the Transaction IDs in the browser's cookie.
  2. Before tracking a transaction check the cookie to see if it has already been tracked.

This solution will use the unique Transaction ID. It will place this in the users browser cookie and before sending a transaction, perform a quick check to see if the id already exists, if it does it won’t resend the transaction. If not it will send and then add the id to the cookie.

As the solution requires cookies it will only work for the same device and browser, therefore if a user purchases on desktop and then reviews the order page on a different device/browser e.g. mobile, this solution won’t work due to how cookies behave. It will however eliminate a significant amount of the duplicates.

The Setup

  • Google Tag Manager implemented on the main website
  • Google Analytics is implemented on the main website
  • Transaction tracking is done via the dataLayer
  • Transaction tracking is using Enhanced Ecommerce

The Solution

Setting up the Variables

In order to store a Transaction ID for use in triggering and duplicate prevention, we need to setup the following variables.

Create the Variables Workspace > Variables >  User-Defined Variables > New

Cookie - gtm-custom-transaction-ids This is used to get the stored transactions ids from the cookie.

Configuration

Value

Choose variable type

1st-Party Cookie

Name/Title

Cookie - gtm-custom-transaction-ids

Cookie Name

gtm-custom-transaction-ids

DLV - EE - Transaction - ID This is used to extract the Transaction ID from the dataLayer.

Configuration

Value

Choose variable type

Data Layer Variable

Name/Title

DLV - EE - Transaction - ID

Data Layer Variable Name

ecommerce.purchase.actionField.id

CJS - Transaction ID is in Cookie This variable will use the current Transaction ID and compare it to values previously stored in the Cookie. If a match is found it will return “yes” otherwise by default it will return “no”.

Configuration

Value

Choose variable type

Custom JavaScript

Name/Title

CJS - Transaction ID is in Cookie

Custom JavaScript

Code Snippet below

Code snippet:

function(){
	try {
		var tid = {{DLV - EE - Transaction - ID}};
		var ctids = {{Cookie - gtm-custom-transaction-ids}};
		if(tid && tid.length > 0 && ctids && ctids.length > 0) {
			var tids = ctids.split(',');
			if(tids.indexOf(tid) >= 0) {
				return 'yes';
			}
		} 
	} catch (err){if({{Debug Mode}}) console.log(err);}
	return 'no';
}

Setting up the Transaction Trigger

The trigger that fires the Transaction Tag needs a rule that checks for duplicate transactions.

Create the Trigger Workspace > Triggers > New

Custom - EE - Transaction Complete - Prevent Duplicate This trigger will fire only when the current Transaction ID is not already present in the stored cookie value.

Configuration

Value

Choose trigger type

Custom Event

Name/Title

Custom - EE - Transaction Complete - Prevent Duplicate

Event name

custom.ecom.purchase

Use regex matching

True

This trigger fires on

Some Custom Events

Trigger Rules

Use Variable

Match Type

Value

CJS - Transaction ID is in Cookie

does not equal

yes

Tag setup

The setup requires two tags. The Google Analytics Transaction Tag (Event or Pageview that includes the enhanced ecommerce purchase data) and a Custom HTML Tag that will store the current Transaction ID in the users cookie.

Create the Tags Workspace > Tags > New

CHTML - Utility - Cookie - Store - Transaction ID This is used to store the  transactions ids in the cookie. Please note this Tag will use sequencing, so no trigger is required.

Configuration

Value

Choose tag type

Custom HTML

Name/Title

CHTML - Utility - Cookie - Store - Transaction ID

HTML

Code Snippet below

Triggering

No Triggers required

Code snippet:


(function(){
	try {
		var tid = {{DLV - EE - Transaction - ID}};
		var ctids = {{Cookie - gtm-custom-transaction-ids}};
		if(tid) {
			var update = false;
			if(ctids && ctids.length > 0) {
				if(ctids.indexOf(tid) == -1 ) {
					ctids += ','+tid;
					update = true;
				}
			} else {
				ctids = tid;
				update = true;
			}
			if(update) {
				var date = new Date();
				date.setTime(date.getTime()+(30*24*60*60*1000)); // create expire time
				var cookieName = 'gtm-custom-tids'; // give cookie a name
				var cookieExpires = date.toGMTString(); // set expire time
				var cookiePath = '/'; // set cookie path
				document.cookie = cookieName + '=' + ctids + '; Expires=' + cookieExpires + '; Path=' + cookiePath; // set cookie
			}
		} 
	} catch (err){if({{Debug Mode}}) console.log(err);}
})();

This snippet will get both the current Transaction ID and any values stored in the users Cookie. If the current value does not exist in the cookie, it will add the value and update/create the cookie. It’s worth noting that the Transaction IDs are stored as a comma separated string, this allows for multiple values to be stored under one cookie key.

Create the Google Analytics Transaction Tag

Please note the Tag required for this next step will be dictated on how you are tracking transactions. This will be different between Standard & Enhanced Ecommerce tracking and could be a Pageview or Event Tag. For the purpose of this setup, the Transaction data is sent via a Google Analytics Event with Enhanced Ecommerce data.

The key configurations of your Tag will be:

  • The Trigger “Custom - EE - Transaction Complete - Prevent Duplicate”
  • Using Tag Sequence to fire the “CHTML - Utility - Cookie - Store - Transaction ID” after the Tag fires.

Workspace > Tags > New UA - Event - EE - Transaction - Complete

Configuration

Value

Choose tag type

Google Analytics - Universal Analytics

Name/Title

UA - Event - EE - Transaction - Complete

Track Type

Event

Category

Ecommerce

Action

Transaction Complete

Label

{{DLV - EE - Transaction - ID}}

Google Analytics settings

Select your Google Analytics settings variable

Enable overriding settings in this tag

True

More Settings > E-commerce > Enable Enhanced Ecommerce Features

True

More Settings > E-commerce > Use Data Layer

Checked

Advanced Settings > Tag Sequencing > Fire a tag after ...

CHTML - Utility - Cookie - Store - Transaction ID

Triggering > Choose a trigger

Custom - EE - Transaction Complete - Prevent Duplicate

Final Thoughts

If your analytics is impacted by duplicate transactions the ideal approach will to be work with your development team to prevent it occuring at the source. The solution presented here is a good short term alternative to help prevent duplicate transactions, however it is limited to the same device & browser.

Whenever you are editing/altering logic around transaction tracking, it should be thoroughly tested. While in principle the functionality is straightforward its purpose is to block transactions from firing, this could lead to legitimate transaction being blocked. So please take care and test, test, test.

I would also highly recommend using the same logic that prevents the transaction to trigger an event that indicates that a transaction was blocked (with no ecommerce data). This way you can see how wide spread the issue is and also help identify any issues with the setup should you be blocking legitimate transactions.

Get in touch

To find out more, email us on hello@datarunsdeep.com.au or complete a quick contact form.

Get in touch

Talk to us: 1300 737 885

08:30 - 16:30, Monday to Friday. We love to chat

Visit us, we’re at:

Level 8, 313 Little Collins Street Melbourne, VIC 3000

Footer

  • Home
    • Who We Are
      • What We Do
      • What We're Up To
      • Careers
      • Contact
  • Training
    • Google Analytics Training Courses
    • Advanced Google Analytics Training
    • Google Tag Manager Training
  • Consulting
    • Analysis
    • Implementation
    • Strategy
    • Google Analytics Audit
    • Google Tag Manager Audit
  • Google Cloud Partner
  • Google Marketing Platform Sales Partner
  • Bitcoin accepted here
  • Registered Looker Consulting Partner Melbourne
  • Twitter
  • LinkedIn
  • Google Plus
  • Blog RSS feed
Copyright © 2009-2021 Data Runs Deep Pty Ltd. All Rights Reserved. Google Analytics is a trademark of Google Inc.
Website by Marin Sekesan