回传、像素与图片标签:只有一种能拿来结算佣金
三种上报转化的机制,讲到非工程师也能拿得住,外加对接真正会坏掉的六种方式。写给那些在晚上十一点调过这些东西的运营商和技术型联盟经理。

一次转化可以用三种方式上报:图片标签、JavaScript 像素,或者服务器到服务器回传。只有回传稳到可以拿来结算佣金,因为它不需要玩家的浏览器配合。大多数「追踪不到」的对接根本不是回传坏了,而是玩家记录上缺了 click id。
电话总是在不合适的钟点打来。某个联盟经理手上有个合作方威胁要撤流量,运营商发誓对接已经上线,后台显示是零。有人发来一张截图,是入金成功页页脚里的一个标签,问为什么它不工作。
它不工作,是因为它是一个页面的页脚里的一个标签。
上报一次转化是个小问题,却有很多种做错的方式,而且这些方式十年来没怎么变。变的是三种机制里有两种悄悄不再可靠了,而所有人还在照发不误。这篇是您应该在对接之前、而不是之后交给工程师的那一篇。
说明玩家已入金的三种方式
图片标签。最老的一种。您的页面里放一个一像素图片,它的地址属于追踪平台。浏览器试图加载这张图,那个请求打到平台,请求本身就是消息。并不真的需要一张图,重点是这次抓取。它除了 HTML 什么都不需要,这也是为什么它在那些没人想碰 JavaScript 的模板系统里活了这么久。
JavaScript 像素。同样的想法,把图片换成脚本。页面里跑一段代码,收集一点上下文,然后发出调用。它更灵活:可以读页面写进变量的值,可以等一个确认渲染出来,可以传一个运行时才知道的入金金额。它也更脆弱,因为它依赖脚本加载成功、变量存在,以及它上面的页面没有抛错。
服务器到服务器回传。完全没有浏览器。当您的后端记录下那个重要事件时,它向一个地址发出一个 HTTP 请求,带上玩家最初到达时交给它的标识。您的支付服务确认了一笔入金,您的系统写下这笔交易,而在同一条路径上某处发出一个请求,说:这个玩家、这个事件、这个金额、这个币种。
就这么回事。它听起来没有另外两种聪明,而这恰恰是它扛得住的原因。
为什么三种里有两种不再可靠
没有单一原因,而是一摞原因,其中任何一条单独出现都还能撑。
Safari 和 Firefox 默认屏蔽第三方 Cookie,Firefox 还会屏蔽发往其追踪器名单上域名的请求。Chrome 仍然允许第三方 Cookie,所以在 Chrome 上屏蔽来自广告拦截器而不是浏览器。Safari 额外限制脚本写入的存储能活多久,某些情况下短到几天,这意味着任何依赖「点击时写入、入金时读取」的做法,有效期只有正常决策周期的一小段。广告拦截器叠在这一切之上,而且恰恰在那些注册前会读对比内容的人群里最普遍。这些都不会自己出声。您的运营商看到页面渲染正常,就断定对接是好的。
然后是浏览器设置修不了的那一部分。玩家在公司的台式机上点击,想了想,当晚用手机入金。或者在网页上注册,在原生 App 里入金,那里没有浏览器、没有页面,也没有标签可以触发。尤其在体育博彩里,入金跟着赛程表走而不是跟着点击走,而且它跟进了 App。如果您想看这两种旅程差别有多大,赌场与体育博彩流量恰好在这一点上分岔。
一个像素没法从浏览器从未去过的地方触发。这一点不是靠更好的埋点位置能修好的。
| 您关心的点 | 图片标签 | JavaScript 像素 | 服务器到服务器回传 |
|---|---|---|---|
| 从哪里触发 | 玩家的浏览器 | 玩家的浏览器 | 您自己的后端 |
| 扛得住广告拦截器吗 | 很少 | 很少 | 能,根本不参与 |
| 扛得住跨设备吗 | 不能 | 不能 | 能 |
| 扛得住 App 内入金吗 | 不能 | 不能 | 能 |
| 能读运行时页面状态吗 | 不能 | 能 | 不适用 |
| 上报的是已结算金额吗 | 只有页面知道的 | 只有页面知道的 | 能,来自记录系统 |
| 什么时候用 | 改不动的历史系统 | 同会话信号,作为次要来源 | 任何决定钱的事 |

值得知道的几种失败模式
没人会以有趣的方式弄坏一个对接。几乎所有情况都出自同样的六个错误。
在页面加载时触发,而不是在事件发生时触发。标签放在入金确认页上,于是每次这个页面被打开它都触发一次。玩家刷新、从历史记录回来,或者在一次失败尝试后落到这里,每一次在您的报表里都是一次转化。这会把数字往好看的方向抬,所以它常常能活很久才被人质疑。
它真的是服务器侧的吗?一个后端框架渲染模板,发出来的仍然是一个需要浏览器执行的标签。如果请求源自玩家的设备,那它就是浏览器侧的,不管它写在哪个文件里。测试只要一分钟:在自己的浏览器里屏蔽脚本,看事件还到不到。
然后是玩家记录上缺失的 click id。这是遥遥领先的最常见故障,它下面单独有一节。
入金在结算之前就被上报了。支付被授权,回传发了出去,然后支付失败或被撤销。现在有一笔佣金挂在一笔从未到账的钱上。请在您财务团队认可的那个状态上触发,而不是在您结账页显示的那个状态上。
幂等,或者说没有幂等。网络会超时。一个做得好的发送方会重试,这是对的。如果接收方分不出第二次尝试和第一次是同一个事件,重试就变成了第二次转化。每个事件都需要一个来自您这边的稳定唯一编号,每次重试都用同一个值,这样重复才能被识别并丢弃,而不是被付两次。
事件也会乱序到达。一笔入金比它所属的注册先到,因为两个服务各自触发,其中一个更快。请给互相依赖的事件排序,或者让每个事件都带够能独立成立的上下文。
决定一切的那一件事
上面每一个故障都能在一个下午修好。这一个不能。
当一个玩家通过追踪链接到达时,链接上的那个标识必须在注册时写进玩家记录。不是写进会话,不是写进 Cookie,而是写进您数据库里代表那个账号的那一行,和邮箱并排,在创建它的同一个事务里。
如果这一步没发生,下游的一切都无法归因。玩家三周后入金,您的后端发出一个技术上完美的回传,而它不带任何标识,因为根本没有东西可带。再怎么调回传也修不好。您调的不是一个报表问题,您调的是一个注册问题,而修复在注册流程里。
有两个相关习惯能省掉很多争论。即使值看起来奇怪也把标识留着,因为您在存一个令牌,不是在校验它。以及,把它按账号的生命周期保存,而不是保存三十天,因为一个按合格入金付款的 CPA,需要在入金达标的那一刻链接仍然存在,而那可能是点击之后好几个月。如果合格入金和首次入金这套词汇在您这边还比较模糊,写库表结构之前花十分钟读一下FTD、NGR、CPA、CPL、CPR 术语表是值得的。
在跑流量之前把它测一遍
一次正确的对接测试很无聊,大约花一个小时。
- 点一个真实的追踪链接,像正常玩家那样完成注册。然后在您自己的数据库里看那条玩家记录,确认标识在上面。如果不在,就停下,因为后面的一切都是演戏。
- 用真钱入金。金额小没关系,EUR 20 就够。测试模式的支付经常会跳过触发事件的那段代码路径,这正是对接在预发环境通过、上线第一天挂掉的原因。
- 确认入金事件只到达了一次,金额和币种正确,而且是在支付结算之后而不是提交时到达的。
- 故意再发一次同样的事件。它应该被识别为重复,不被重复计数。
- 在手机上把整个流程再走一遍;如果您有 App,再用 App 内入金走一遍。
一个工程师的一小时加一笔入金,对上和一个已经认定您在克扣他流量的联盟会员对一个月的账。追踪链接 QA 实操讲的是同一个测试的联盟会员那一端,两端一起跑,是您用一个下午而不是一个季度找出错配的办法。
AFFILIFY 对运营商的期待
对接文档在 affilify.partners/docs,包含端点、参数名和接受的事件类型。请从那里读,而不是从一篇博客里读,因为那个页面是我们持续维护的那个。
结构很小。一个事件名、您在点击时收到的标识、一个金额和一个币种,加上您的密钥。注册、首次入金、后续入金和收入事件是各自独立的消息,因为挂在方案上的佣金模型决定了其中哪些重要,而一个联盟计划无法用它从未收到过的数据去付 RevShare。如果您还在模型之间犹豫,CPA、RevShare 与混合列出了每一种对您这边的要求。
有两件事值得说明白。我们这边的归因有多层兜底。那是保险,不是方案。注册时保存的标识是您能控制的部分,请把它发过来。以及,流量质量是持续评估的,这意味着有些转化会在核查期间被暂挂,而不是一到就入账。那不是拒绝,联盟会员看到的是状态,而不是一段无声的空白。
一个会回传标识、把已结算事件只上报一次、并且能用一笔真实入金在一小时内被测通的运营商,永远不会接到那个晚上十一点的电话。这就是这里的全部野心。
常见问题
回传和像素有什么区别?
像素由玩家的浏览器在页面打开时触发。回传由您自己的后端在事件被记录时触发,完全不涉及浏览器。这一个差别决定了其余一切:回传不受广告拦截器或浏览器 Cookie 政策影响,玩家在笔记本上注册、用手机入金时它照样成立,入金发生在从不加载页面的原生 App 里时它也照样成立。它上报的还是您记录系统里的金额,而不是某个页面碰巧知道的金额。
我们能在回传之外保留一个像素做备份吗?
可以,但要清楚它值多少。像素永远只能确认它看得见的事件,那是实际发生事件的一个子集,而这个子集有多大您是看不到的。把它当作开发期间的同会话健全性检查,而不是第二个真实来源,并且永远不要拿它去核对付款。如果两者对同一个事件都触发,您的平台需要一个来自您这边的稳定唯一编号,这样这一对才会被识别为一次转化而不是两次。
我们的回传在发,但什么都没归因上,为什么?
几乎总是因为 click id 在注册时从未被写进玩家记录。回传发得正确、准时、密钥有效,却没带任何可以匹配的东西。先在数据库里查一条真实的玩家记录。如果标识在那里就是缺的,那 bug 在您的注册流程里,不在回传代码里,再多的重试逻辑或端点调优都改变不了结果。
跑流量之前该怎么测回传对接?
点一个真实的追踪链接,作为玩家注册,确认标识落到了账号那一行上。然后用真钱入金,因为测试模式的支付经常会跳过触发事件的那段代码路径。确认入金只到达一次,金额和币种正确,且在支付结算之后到达。故意再发一次同样的事件,确认它被当作重复丢弃。然后在手机上重来一遍,有 App 的话再在 App 里做一遍。一个小时,一笔小额入金。
