如何排除掉GA4里的重复购买次数

如果你使用的是WordPress建站系统,且按照我之前写的转化价值追踪教程安装了GTM4WP插件的话,那么,你就可以继续看完这个教程,并按照教程去实践,从而排除GA4里的重复购买次数。

为什么会出现重复的购买次数

在使用Google analystics 去追踪woocommerce的转化次数数,你可能会遇到这种情况。 你创建purchase事件追踪的数量是远远大于真实的转化次数的。而在GA4的报表中,有一个指标叫做“交易量“,你会发现交易量可以反馈真实的订单数量,但是我们自己追踪到的purchase数据却不准确。这是为什么?

这是因为大部分营销人员在进行购买成功的转化追踪时,采用的是页面被浏览的次数来追踪, 他们通常会采用这样的正则表达式,如:

Page location contains /checkout/order-received (woocommerce的付款成功页面URL)

Page path contains thank-you (shopify付款成功的thank you page)

当然我自己也会这样设置,但是这种设置在以下情形下就会多次触发事件,导致重复记录。

  • 通过电子邮件链接或书签返回页面
  • 刷新付款成功页面
  • 导航到不同的页面并通过后退按钮返回
  • 从关闭的浏览器会话或手机上恢复页面

所以想要从根本上解决这个问题,就需要从追踪转化成功的方式来着手。URL的正则表达式已经证明是不靠谱的了,所以只能寻求其他的追踪方式。

直到我找到了这个老外的教程,英文好的同学可以直接看原文,我也按着这个教程走了一遍

https://www.simoahava.com/analytics/prevent-google-analytics-duplicate-transactions-with-customtask/

注意: 前方高能预警,这套解决方案再次涉及到了大量的代码使用,调用逻辑和参数,变量之间的关系。实践起来有些烧脑,如果你有技术的同事,可以让让技术同学一起协助解决。

再次强调,使用这套方案的前提是你已经在网站安装了transactionId的数据层变量,并在GTM创建了相应的变量。如果没有transactionID的变量,那么这套方案,你便无法使用。

排除重复购买的原理

页面会刷新,但是交易ID是唯一的,如果我们以交易ID为维度,去记录购买次数,不就可以拿到100%正确的购买成功次数了吗。

实现的思路是在创建一个叫做customtask的变量,它会在每一次事件被触发的时候开始运行,在任务过程中,该方法会在触发事件的模型中查找键值,如果在浏览器存储中找到触发中的交易 ID,此 customTask 会阻止命中被触发,从而防止重复信息到达 Google Analytics。

直接用老外的图来解释吧

如何排除掉GA4里的重复购买次数

需要注意的时, 要使用这个方案, 你必须要要使用增强型电子商务, 对于 Standard Ecommerce,customTask 只会更新浏览器存储,但不会阻止任何内容。

如何排除重复的购买

我先放一张最终的完成图,按照教程实践后, 你的Google tag manger里会增加3个变量,2个触发器,和对purchase的tag修改。 如下图所示。

如何排除掉GA4里的重复购买次数

我们先看变量部分,虽然是增加了3个变量,但是这3个变量当中, 需要调用到之前已经创建好了的transactionID变量,所以,我圈出了4个变量名称。因为你有可能需要根据你自己的transactionID的名称来修改其中一个变量中的代码。

如何排除掉GA4里的重复购买次数

触发器里有新增了2个。 分别代表着发送transactionID为true 和购买完成

如何排除掉GA4里的重复购买次数

最后就是一个purchase的tag啦,可以看到, 它的触发已经不再依赖于page location的正则表达式了, 而是通过自定义JS来实现。

如何排除掉GA4里的重复购买次数

具体怎么做呢?

首先,创建好3个变量。

第一个变量A: customtask-transaction deduper

如何排除掉GA4里的重复购买次数

以下代码直接复制粘贴进去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
function() {
// customTask Builder by Simo Ahava
var transactionDeduper = {
keyName: '_transaction_ids',
cookieExpiresDays: 365
};

// DO NOT EDIT ANYTHING BELOW THIS LINE
var readFromStorage = function(key) {
if (!window.Storage) {
// From: https://stackoverflow.com/a/15724300/2367037
var value = '; ' + document.cookie;
var parts = value.split('; ' + key + '=');
if (parts.length === 2) return parts.pop().split(';').shift();
} else {
return window.localStorage.getItem(key);
}
};

var writeToStorage = function(key, value, expireDays) {
if (!window.Storage) {
var expiresDate = new Date();
expiresDate.setDate(expiresDate.getDate() + expireDays);
document.cookie = key + '=' + value + ';expires=' + expiresDate.toUTCString();
} else {
window.localStorage.setItem(key, value);
}
};

var globalSendHitTaskName = '_ga_originalSendHitTask';

return function(customTaskModel) {

window[globalSendHitTaskName] = window[globalSendHitTaskName] || customTaskModel.get('sendHitTask');
var tempFieldObject, dimensionIndex, count, ga, tracker, decorateTimer, decorateIframe, iframe;

customTaskModel.set('sendHitTask', function(sendHitTaskModel) {

var originalSendHitTaskModel = sendHitTaskModel,
originalSendHitTask = window[globalSendHitTaskName],
canSendHit = true;

var hitPayload, hitPayloadParts, param, val, regexI, trackingId, snowplowVendor, snowplowVersion, snowplowPath, request, originalTrackingId, hitType, nonInteraction, d, transactionId, storedIds;

try {

// transactionDeduper
if (typeof transactionDeduper === 'object' && transactionDeduper.hasOwnProperty('keyName') && transactionDeduper.hasOwnProperty('cookieExpiresDays') && typeof sendHitTaskModel.get('&ti') !== 'undefined') {
transactionId = sendHitTaskModel.get('&ti');
storedIds = JSON.parse(readFromStorage(transactionDeduper.keyName) || '[]');
if (storedIds.indexOf(transactionId) > -1 && ['transaction', 'item'].indexOf(sendHitTaskModel.get('hitType')) === -1) {
canSendHit = false;
} else if (storedIds.indexOf(transactionId) === -1) {
storedIds.push(transactionId);
writeToStorage(transactionDeduper.keyName, JSON.stringify(storedIds), transactionDeduper.cookieExpiresDays);
}
}
// /transactionDeduper

if (canSendHit) {
originalSendHitTask(sendHitTaskModel);
}

} catch(e) {
originalSendHitTask(originalSendHitTaskModel);
}

});

};
}

第二个变量B: cookie-_transactionId

这里的名字,请和我保持一模一样,不要改动,因为在其他变量里会调用这个名称。

如何排除掉GA4里的重复购买次数

第三个变量C:transactionId_sent

注意大小写, 要一模一样哦

如何排除掉GA4里的重复购买次数

在这段代码里,调用了之前已经创建过的transactionID的变量,所以这个为主,你自己需要检查下。

整段代码如下:

1
2
3
4
5
6
function() {
// Change this to match the keyName you added to customTask:
var keyName = '_transaction_ids';
var ids = JSON.parse((!!window.Storage ? window.localStorage.getItem(keyName) : {{cookie - _transactionId}}) || '[]');
return ids.indexOf({{Ecommerce_Transaction_ID}}) > -1;
}

接下来,是2个触发器

如何排除掉GA4里的重复购买次数

如何排除掉GA4里的重复购买次数

最后, 就是purchase的Tag设置了。

如何排除掉GA4里的重复购买次数

在你照着这套教程去使用的时候,也最好理清一下变量之间的调用关系。

变量B里调用了变量A里的key name:_transaction_ids, 变量,C里调用了变量B的名称和已经创建过了的交易ID变量名称。

完成购物的触发器里的事件名称是woocommerce对于购买的事件名purchase,这个应该是写在GTM4WP这个插件里。

按照这个教程做好配置的后, 接下来要做的事情就是等待和调试了。毕竟购物成功这个东西,我可不想刷信用卡去支付购买再测试。 因为我已经在GTM里做了屏蔽管理员访问的设置。。。

除此之外,我也看到另外一套解决方案,也是要写代码,但是它用到了一个叫做时间戳的变量, timestamp,这个数据层变量需要技术去操作。由于我的插件不支持这个数据层变量的植入,就无法尝试了,感兴趣的同学可以查看下面这个教程。

https://www.bounteous.com/insights/2020/09/02/duplicate-transactions-google-analytics-and-ga4-properties

原创文章,作者:Ada,如若转载,请注明出处:https://yaosocial.com/archives/how-to-exclude-the-dupulicate-conversions-in-ga4/

发表回复

登录后才能评论