{"id":101463,"date":"2025-02-21T12:34:08","date_gmt":"2025-02-21T12:34:08","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/prevent-duplicate-transactions-in-google-analytics-with-customtask\/"},"modified":"2025-02-21T12:34:08","modified_gmt":"2025-02-21T12:34:08","slug":"prevent-duplicate-transactions-in-google-analytics-with-customtask","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=101463","title":{"rendered":"Prevent Duplicate Transactions In Google Analytics With customTask"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>One of the big problems in <a href=\"https:\/\/analytics.google.com\/\">Google Analytics\u2019<\/a> data model is the immutability of historical data. Once a row of data is written into the data table, it is there practically for good. This is especially annoying in two cases: <a href=\"https:\/\/help.analyticsedge.com\/article\/definitive-guide-to-removing-google-analytics-spam\/\">spam<\/a> and bogus ecommerce hits. The first is a recognized issue with an <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/protocol\/v1\/\">open and public data collection protocol<\/a>, the latter is an annoyance that can explode into full-blown sabotage (you can use the Measurement Protocol to send hundreds of huge transactions to your competitor\u2019s GA property, for example).<\/p>\n<p>In this article, I\u2019ll tackle a different symptom. I\u2019ve covered this <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/prevent-repeat-transactions\/\">before<\/a>, and David Vallejo\u2019s written an <a href=\"https:\/\/www.thyngster.com\/preventing-duplicate-transactions-in-universal-analytics-with-google-tag-manager\/\">excellent article<\/a> about this topic as well.<\/p>\n<p>The problem is <strong>duplicate transactions<\/strong>. It\u2019s very common if your site has a receipt page that can be revisited via the browser cache or history. By revisiting the receipt page, it\u2019s often the case that the transaction details are written into <code>dataLayer<\/code> (or sent with the <code>ga()<\/code> method) again, resulting in the inflation of your ecommerce data.<\/p>\n<p>A simpler way to confirm if this is an issue is to create <strong>custom report<\/strong> where you inspect Transaction IDs against the Transactions metric. Optimally, you\u2019d have one transaction per ID, unless you\u2019ve decided to enable transaction updates\/upgrades in your data collection.<\/p>\n<div style=\"aspect-ratio: 1686 \/ 704;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/duplicate-transactions.jpg\" title=\"Duplicate transactions\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"704\" width=\"1686\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/duplicate-transactions.jpg#ZgotmplZ\" alt=\"Duplicate transactions\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>I\u2019ve decided to upgrade my solution to utilize <a href=\"https:\/\/www.simoahava.com\/analytics\/customtask-the-guide\/\">customTask<\/a>, since it lets you do without extra triggers or variable logic. We\u2019ll set things up with <a href=\"https:\/\/tagmanager.google.com\/\">Google Tag Manager<\/a>, but there\u2019s nothing stopping you from doing this with on-page analytics.js, too.<\/p>\n<p>                <span class=\"simmer\"><br \/>\n  <span class=\"close\">X<\/span><\/p>\n<p>\n    <span class=\"fa fa-md fa-bell\"\/><br \/>\n    <strong>The Simmer Newsletter<\/strong>\n  <\/p>\n<p>\n    Subscribe to the <a href=\"https:\/\/www.simoahava.com\/newsletter\/\">Simmer newsletter<\/a> to get the latest news and content from Simo Ahava into your email inbox!\n  <\/p>\n<p>  <\/span><\/p>\n<h2 id=\"how-it-works\">How it works<\/h2>\n<p>When you add the <code>customTask<\/code> variable to your tags, it activates any time the tag tries to send a hit to Google Analytics.<\/p>\n<p>During this activation, the method looks for the key <code>&amp;ti<\/code> in the hit model. This key corresponds to the <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/protocol\/v1\/parameters#ti\"><strong>Transaction ID<\/strong><\/a> value.<\/p>\n<p>Next, it looks into your browser storage for any transaction IDs already sent from the current browser.<\/p>\n<p>If the transaction ID in the hit is found in browser storage, this <code>customTask<\/code> blocks the hit from ever being fired, this preventing the duplicated information from reaching Google Analytics.<\/p>\n<p>If the transaction ID in the hit is <strong>not<\/strong> found in browser storage, the <code>customTask<\/code> sends the hit to GA normally, but it also stores the transaction ID in the list of transactions that has already been recorded. Thus, it blocks any <strong>future<\/strong> hits with this ID from being sent.<\/p>\n<div style=\"aspect-ratio: 3128 \/ 2162;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/duplicate-transaction-process.jpg\" title=\"deduplication process\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"2162\" width=\"3128\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/duplicate-transaction-process.jpg#ZgotmplZ\" alt=\"deduplication process\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p><strong>NOTE!<\/strong> This auto-blocking feature only works with <a href=\"https:\/\/www.simoahava.com\/analytics\/enhanced-ecommerce-guide-for-google-tag-manager\/\">Enhanced Ecommerce<\/a>. With Standard Ecommerce, the <code>customTask<\/code> will only update browser storage but it won\u2019t block anything. You\u2019ll need to use triggers instead (read on for instructions how to do this).<\/p>\n<h2 id=\"the-customtask-variable\">The customTask variable<\/h2>\n<p>You can use the <a href=\"https:\/\/www.simoahava.com\/tools\/customtask-builder\/\">customTask Builder tool<\/a> to generate the necessary variable, or you can simply copy-paste the code below into a <strong>Custom JavaScript variable<\/strong>, if you wish. The benefit of using the builder tool is that you can combine this <code>customTask<\/code> with all the other setups I\u2019ve added to the tool.<\/p>\n<p>Anyway, this is what the Custom JavaScript variable should end up looking like:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#aaa;font-style:italic\">\/\/ customTask Builder by Simo Ahava\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#aaa;font-style:italic\">\/\/\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#aaa;font-style:italic\">\/\/ More information about customTask: https:\/\/www.simoahava.com\/analytics\/customtask-the-guide\/\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#aaa;font-style:italic\">\/\/\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#aaa;font-style:italic\">\/\/ Change the default values for the settings below.\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>\n  <span style=\"color:#aaa;font-style:italic\">\/\/ transactionDeduper: Configuration object for preventing duplicate transactions from being recorded.\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#aaa;font-style:italic\">\/\/ https:\/\/bit.ly\/2AvSZ2Y\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> transactionDeduper = {\n    keyName: <span style=\"color:#a50\">'_transaction_ids'<\/span>,\n    cookieExpiresDays: <span style=\"color:#099\">365<\/span>\n  };\n\n  <span style=\"color:#aaa;font-style:italic\">\/\/ DO NOT EDIT ANYTHING BELOW THIS LINE\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> readFromStorage = <span style=\"color:#00a\">function<\/span>(key) {\n    <span style=\"color:#00a\">if<\/span> (!<span style=\"color:#0aa\">window<\/span>.Storage) {\n      <span style=\"color:#aaa;font-style:italic\">\/\/ From: https:\/\/stackoverflow.com\/a\/15724300\/2367037\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> value = <span style=\"color:#a50\">'; '<\/span> + <span style=\"color:#0aa\">document<\/span>.cookie;\n      <span style=\"color:#00a\">var<\/span> parts = value.split(<span style=\"color:#a50\">'; '<\/span> + key + <span style=\"color:#a50\">'='<\/span>);\n      <span style=\"color:#00a\">if<\/span> (parts.length === <span style=\"color:#099\">2<\/span>) <span style=\"color:#00a\">return<\/span> parts.pop().split(<span style=\"color:#a50\">';'<\/span>).shift();\n    } <span style=\"color:#00a\">else<\/span> {\n      <span style=\"color:#00a\">return<\/span> <span style=\"color:#0aa\">window<\/span>.localStorage.getItem(key);\n    }\n  };\n\n  <span style=\"color:#00a\">var<\/span> writeToStorage = <span style=\"color:#00a\">function<\/span>(key, value, expireDays) {\n    <span style=\"color:#00a\">if<\/span> (!<span style=\"color:#0aa\">window<\/span>.Storage) {\n      <span style=\"color:#00a\">var<\/span> expiresDate = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Date<\/span>();\n      expiresDate.setDate(expiresDate.getDate() + expireDays);\n      <span style=\"color:#0aa\">document<\/span>.cookie = key + <span style=\"color:#a50\">'='<\/span> + value + <span style=\"color:#a50\">';expires='<\/span> + expiresDate.toUTCString();\n    } <span style=\"color:#00a\">else<\/span> {\n      <span style=\"color:#0aa\">window<\/span>.localStorage.setItem(key, value);\n    }\n  };\n\n  <span style=\"color:#00a\">var<\/span> globalSendHitTaskName   = <span style=\"color:#a50\">'_ga_originalSendHitTask'<\/span>;\n\n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#00a\">function<\/span>(customTaskModel) {\n\n    <span style=\"color:#0aa\">window<\/span>[globalSendHitTaskName] = <span style=\"color:#0aa\">window<\/span>[globalSendHitTaskName] || customTaskModel.get(<span style=\"color:#a50\">'sendHitTask'<\/span>);\n    <span style=\"color:#00a\">var<\/span> tempFieldObject, dimensionIndex, count, ga, tracker, decorateTimer, decorateIframe, iframe;\n\n    customTaskModel.set(<span style=\"color:#a50\">'sendHitTask'<\/span>, <span style=\"color:#00a\">function<\/span>(sendHitTaskModel) {\n\n      <span style=\"color:#00a\">var<\/span> originalSendHitTaskModel = sendHitTaskModel,\n          originalSendHitTask      = <span style=\"color:#0aa\">window<\/span>[globalSendHitTaskName],\n          canSendHit               = <span style=\"color:#00a\">true<\/span>;\n\n      <span style=\"color:#00a\">var<\/span> hitPayload, hitPayloadParts, param, val, regexI, trackingId, snowplowVendor, snowplowVersion, snowplowPath, request, originalTrackingId, hitType, nonInteraction, d, transactionId, storedIds;\n\n      <span style=\"color:#00a\">try<\/span> {\n\n        <span style=\"color:#aaa;font-style:italic\">\/\/ transactionDeduper\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>        <span style=\"color:#00a\">if<\/span> (<span style=\"color:#00a\">typeof<\/span> transactionDeduper === <span style=\"color:#a50\">'object'<\/span> &amp;&amp; transactionDeduper.hasOwnProperty(<span style=\"color:#a50\">'keyName'<\/span>) &amp;&amp; transactionDeduper.hasOwnProperty(<span style=\"color:#a50\">'cookieExpiresDays'<\/span>) &amp;&amp; <span style=\"color:#00a\">typeof<\/span> sendHitTaskModel.get(<span style=\"color:#a50\">'&amp;ti'<\/span>) !== <span style=\"color:#a50\">'undefined'<\/span>) {\n          transactionId = sendHitTaskModel.get(<span style=\"color:#a50\">'&amp;ti'<\/span>);\n          storedIds = JSON.parse(readFromStorage(transactionDeduper.keyName) || <span style=\"color:#a50\">'[]'<\/span>);\n          <span style=\"color:#00a\">if<\/span> (storedIds.indexOf(transactionId) &gt; -<span style=\"color:#099\">1<\/span> &amp;&amp; [<span style=\"color:#a50\">'transaction'<\/span>, <span style=\"color:#a50\">'item'<\/span>].indexOf(sendHitTaskModel.get(<span style=\"color:#a50\">'hitType'<\/span>)) === -<span style=\"color:#099\">1<\/span>) {\n            canSendHit = <span style=\"color:#00a\">false<\/span>;\n          } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (storedIds.indexOf(transactionId) === -<span style=\"color:#099\">1<\/span>) {\n            storedIds.push(transactionId);\n            writeToStorage(transactionDeduper.keyName, JSON.stringify(storedIds), transactionDeduper.cookieExpiresDays);\n          }\n        }\n        <span style=\"color:#aaa;font-style:italic\">\/\/ \/transactionDeduper\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>\n        <span style=\"color:#00a\">if<\/span> (canSendHit) {\n          originalSendHitTask(sendHitTaskModel);\n        }\n\n      } <span style=\"color:#00a\">catch<\/span>(e) {\n        originalSendHitTask(originalSendHitTaskModel);\n      }\n\n    });\n\n  };\n}\n<\/code><\/pre>\n<\/div>\n<p>There\u2019s a configuration object in the variable <code>transactionDeduper<\/code> that you can modify, if you wish. The configuration object must have both <code>keyName<\/code> and <code>cookieExpiresDays<\/code>.<\/p>\n<p>Set <code>keyName<\/code> to what you want the name of the cookie or the <code>localStorage<\/code> key to be. The default value is <code>_transaction_ids<\/code>.<\/p>\n<p>Set <code>cookieExpiresDays<\/code> to the number of days the cookie should exist. A cookie is only used if the user\u2019s browser doesn\u2019t support <code>localStorage<\/code>. If <code>localStorage<\/code> is used, no expiration is set.<\/p>\n<p>The main logic happens near the end of the code block, where I\u2019ve boxed the solution with <code>\/\/ transactionDeduper<\/code> and <code>\/\/ \/transactionDeduper <\/code>.<\/p>\n<p>It really is very simple, and it follows the process I outlined in the previous chapter.<\/p>\n<p>If you\u2019re using <strong>Enhanced Ecommerce<\/strong>, then this <code>customTask<\/code> will take care of everything for you. In case the transaction ID is found in the list of stored IDs, it will simply block the hit from departing to Google Analytics.<\/p>\n<p>If you\u2019re using <strong>Standard Ecommerce<\/strong>, the <code>customTask<\/code> will only write the ID into storage, and you\u2019ll need to handle the blocking logic yourself.<\/p>\n<p>In any case, you need to add this <code>customTask<\/code> variable to all the Enhanced Ecommerce and\/or Transaction tags that have the power to send purchase information to Google Analytics. For instructions how to add the <code>customTask<\/code> to your tags, see <a href=\"https:\/\/www.simoahava.com\/analytics\/customtask-the-guide\/#how-to-add-customtask-to-your-hits\">this guide<\/a> or follow the instructions in the <a href=\"https:\/\/www.simoahava.com\/tools\/customtask-builder\/#general-deployment-instructions\">customTask Builder tool<\/a>.<\/p>\n<h2 id=\"triggers-and-variables-for-standard-ecommerce\">Triggers and variables for Standard Ecommerce<\/h2>\n<p>Due to how Standard Ecommerce is split into <code>transaction<\/code> and <code>item<\/code> hits, the blocking logic would be extremely difficult to automate in <code>customTask<\/code>. This is why you\u2019ll need to create an <strong>exception<\/strong> trigger for your Transaction tag, which blocks the tag from firing if the transaction ID is found in the list of stored IDs.<\/p>\n<h3 id=\"data-layer-variable-for-the-transaction-id\">Data Layer variable for the Transaction ID<\/h3>\n<p>Create a <strong>Data Layer variable<\/strong> for <code>transactionId<\/code>, like this:<\/p>\n<div style=\"aspect-ratio: 1256 \/ 874;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/dlv-transactionid.jpg\" title=\"DLV - transcationId\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"874\" width=\"1256\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/dlv-transactionid.jpg#ZgotmplZ\" alt=\"DLV - transcationId\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"1st-party-cookie-variable-for-the-transaction-id-list\">1st Party Cookie variable for the transaction ID list<\/h3>\n<p>Create a 1st Party Cookie variable for the transaction ID list, using the <code>keyName<\/code> you configured in the <code>customTask<\/code>. This is what a default setup would look like:<\/p>\n<div style=\"aspect-ratio: 1048 \/ 658;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/cookie-transaction-ids.jpg\" title=\"Cookie - transcation IDs\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"658\" width=\"1048\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/cookie-transaction-ids.jpg#ZgotmplZ\" alt=\"Cookie - transcation IDs\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"custom-javascript-variable-to-check-if-the-id-is-within-the-list\">Custom JavaScript variable to check if the ID is within the list<\/h3>\n<p>Finally, create a Custom JavaScript variable which returns <code>true<\/code> if the transaction ID is found in the list.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#aaa;font-style:italic\">\/\/ Change this to match the keyName you added to customTask:\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> keyName = <span style=\"color:#a50\">'_transaction_ids'<\/span>;\n  \n  <span style=\"color:#00a\">var<\/span> ids = JSON.parse((!!<span style=\"color:#0aa\">window<\/span>.Storage ? <span style=\"color:#0aa\">window<\/span>.localStorage.getItem(keyName) : {{Cookie - _transaction_ids}}) || <span style=\"color:#a50\">'[]'<\/span>);\n  <span style=\"color:#00a\">return<\/span> ids.indexOf({{DLV - transactionId}}) &gt; -<span style=\"color:#099\">1<\/span>;\n}\n<\/code><\/pre>\n<\/div>\n<p>Name the variable something like <strong>{{JS &#8211; transactionId sent}}<\/strong>.<\/p>\n<h3 id=\"the-exception-trigger\">The exception trigger<\/h3>\n<p>The last step is to create a trigger which blocks your transaction tag from firing. It must use the same <strong>event<\/strong> as the transaction tag. So, if the transaction tag fires on a Page View trigger, the exception trigger must also be a Page View trigger (read more about exceptions <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/block-your-tags-with-trigger-exceptions\/\">here<\/a>).<\/p>\n<p>In the trigger conditions, check if {{JS &#8211; transactionId sent}} equals <code>true<\/code>. Thus, the exception will block the tag it is attached to if the transaction ID is found in the list of IDs already recorded.<\/p>\n<p>Here\u2019s an example of what the exception looks like with a Custom Event trigger, and how the exception is added to the tag.<\/p>\n<div style=\"aspect-ratio: 2310 \/ 1060;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/exception-trigger.jpg\" title=\"Exception trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1060\" width=\"2310\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/exception-trigger.jpg#ZgotmplZ\" alt=\"Exception trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<div style=\"aspect-ratio: 1944 \/ 926;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/tag-exception.jpg\" title=\"Tag with exception\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"926\" width=\"1944\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/tag-exception.jpg#ZgotmplZ\" alt=\"Tag with exception\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h2 id=\"final-thoughts\">Final thoughts<\/h2>\n<p>My quest for improving Google Analytics\u2019 data quality using <code>customTask<\/code> continues.<\/p>\n<p>Preventing hits from being sent if certain conditions arise is nice and elegant to run through <code>customTask<\/code>, since you don\u2019t have to mess with complicated triggers cluttering your GTM interface.<\/p>\n<p>However, every <code>customTask<\/code> used does increase the opaqueness of your setup, so the trade-off is that you won\u2019t know what individual tags do at a glance without drilling into their set fields (and understanding what <code>customTask<\/code> does in the first place).<\/p>\n<p>As always, let me know what you think about this solution in the comments, and let me know also if you have suggestions for improving it! Thank you.<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>One of the big problems in Google Analytics\u2019 data model is the immutability of historical data. Once a row of data is written into the data table, it is there practically for good. This is especially annoying in two cases: spam and bogus ecommerce hits. The first is a recognized issue with an open and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":101464,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[12765,47087,14494,1531,16371,11028],"dealstore":[],"offerexpiration":[],"class_list":["post-101463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-analytics","tag-customtask","tag-duplicate","tag-google","tag-prevent","tag-transactions"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Prevent Duplicate Transactions In Google Analytics With customTask - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=101463\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Prevent Duplicate Transactions In Google Analytics With customTask - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"One of the big problems in Google Analytics\u2019 data model is the immutability of historical data. Once a row of data is written into the data table, it is there practically for good. This is especially annoying in two cases: spam and bogus ecommerce hits. The first is a recognized issue with an open and [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=101463\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-21T12:34:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1686\" \/>\n\t<meta property=\"og:image:height\" content=\"704\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=101463#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=101463\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Prevent Duplicate Transactions In Google Analytics With customTask\",\"datePublished\":\"2025-02-21T12:34:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=101463\"},\"wordCount\":1133,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=101463#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg\",\"keywords\":[\"Analytics\",\"customTask\",\"Duplicate\",\"Google\",\"Prevent\",\"Transactions\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=101463#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=101463\",\"url\":\"https:\/\/fivemor.com\/?p=101463\",\"name\":\"Prevent Duplicate Transactions In Google Analytics With customTask - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=101463#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=101463#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg\",\"datePublished\":\"2025-02-21T12:34:08+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=101463#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=101463\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=101463#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg\",\"width\":1686,\"height\":704},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=101463#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Prevent Duplicate Transactions In Google Analytics With customTask\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Prevent Duplicate Transactions In Google Analytics With customTask - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=101463","og_locale":"en_US","og_type":"article","og_title":"Prevent Duplicate Transactions In Google Analytics With customTask - Som2ny Network","og_description":"One of the big problems in Google Analytics\u2019 data model is the immutability of historical data. Once a row of data is written into the data table, it is there practically for good. This is especially annoying in two cases: spam and bogus ecommerce hits. The first is a recognized issue with an open and [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=101463","og_site_name":"Som2ny Network","article_published_time":"2025-02-21T12:34:08+00:00","og_image":[{"width":1686,"height":704,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=101463#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=101463"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Prevent Duplicate Transactions In Google Analytics With customTask","datePublished":"2025-02-21T12:34:08+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=101463"},"wordCount":1133,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=101463#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg","keywords":["Analytics","customTask","Duplicate","Google","Prevent","Transactions"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=101463#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=101463","url":"https:\/\/fivemor.com\/?p=101463","name":"Prevent Duplicate Transactions In Google Analytics With customTask - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=101463#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=101463#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg","datePublished":"2025-02-21T12:34:08+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=101463#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=101463"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=101463#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/duplicate-transactions.jpg","width":1686,"height":704},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=101463#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Prevent Duplicate Transactions In Google Analytics With customTask"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/101463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=101463"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/101463\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/101464"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=101463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=101463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=101463"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=101463"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=101463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}