Skip to content

11 · 返佣推广系统

0. 文档说明

内容
版本V1.0

「赚钱」板块的引擎。绑定发生在 05 注册(?ref= 静默携带,无邀请码输入);佣金入账走 02;反套利归 14。

一租户 = 一「本位币站」,站内单币种(→ 00 架构总纲)。下级贡献、佣金计提、佣金池、提取到账口径恒为本位币 wallet.baseCurrency;佣金池是单站单池·本位币口径


一、定位与职责

  • 定义推广关系(推广短链、绑定规则、层级/代理树);
  • 定义佣金计算(基数/档位/分层率)、日结入佣金池(单站单池·本位币)与提取;
  • 定义赚钱面板的展示契约(邀请物料、下级数据、佣金记录)。

层级模型(V1 与 V1.1):租户配 affiliate.maxDepth(1|2|3,默认 1)。maxDepth=1V1 单层返佣(本篇 §二~§八 主线,一切规则的默认形态);maxDepth≥2 启用 V1.1 多级代理(§十一,ADDITIVE:V1 单层为不变默认,不改变任何 V1 语义)。

边界:注册绑定动作在 05;下级流水事实来自 12/03;佣金成本报表归 17。


二、核心概念与数据模型

2.1 推广关系 AffiliateRelation

字段说明
userId / inviterId(= 直属上级 uplineId)/ tenantId下级、直属上级(一次绑定终身不可改);inviterId 即该用户的直属上级 uplineId,V1/V1.1 同字段
refSlug每用户一个推广短链归因码(生成即有,构成短链 域名/i/{slug};slug 即归因,不设邀请码概念)
depth相对层深(多级模式用):某上级对某下级的层深 = 二者在代理树上的距离(直属下级 depth=1,下级的下级 depth=2…);V1(maxDepth=1)恒为 1

代理树(V1/V1.1 共用结构):每个被邀请用户记直属上级 uplineId(= 绑定时的 inviterId),形成闭环有向树——根为无上级的自然获客用户,边由 uplineId 指向上。约束:禁自邀(uplineId≠userId)、禁回环(下级不得成为其任一上级的上级,即建边时校验目标不在自身的祖先/后代闭包中);一次绑定终身不可改(树结构不可事后改接)。V1 只沿直属一层计佣,树深度对计佣无意义(depth 恒 1);V1.1 沿树上溯至多 maxDepth 层计佣(→ §十一)。

绑定规则:注册完成时从落地参数(?ref=<slug>)绑定;自邀、环路、同设备批量注册由 14 拦截;归因全程由落地链接 slug 静默携带,无手动输入邀请码入口

2.2 佣金账 CommissionAccount(用户,单币种)

accrued(可提佣金,本位币)+ 提取记录。佣金池独立于钱包余额,单站单池(本位币),提取动作才入钱包(REWARD_CREDIT(source=AFFILIATE),入本位币钱包)。

2.3 计算模型

下级当期贡献 ──基数 basis──►  贡献额(本位币)
   basis 可配:turnover(有效投注)| ngr(净输赢)| rakebackShare(下级返水分成)
贡献额 × rate(V1:档位 tier;V1.1:按层深 depth 取 `levelRates`,depth=1 取 tiers、depth≥2 取 `ratePct`) ──日结 T+1──► 上级佣金池 accrued +=(本位币)

下级流水/贡献均为本位币值(场馆 CNY 映射链路的注单由通道适配层 1:1 重标本位币,→ 02),计佣零特判。

档位 tier:由有效会员数阶梯决定,Global 实例三档 = 0–9 人 10% / 10–29 人 18% / 30+ 人 25%(即 §四配置 activeInvitees 门槛 0 / 10 / 30,费率 0.10 / 0.18 / 0.25;封顶率 25% 即宣传位「最高 25%」的来源)。V1(maxDepth=1)单层即取当前档位率;多级模式(V1.1)各层费率由 levelRates 定义(level 1 沿用本档位表,level≥2 用固定 override,→ §四/§十一)。

basis=rakebackShare 口径:分成基数 = 下级实际领取的返水净额(下级 RewardClaimed(source=RAKEBACK) 的领取额,已含取消冲正抵扣后的真实到手值),数据源 = 08 rakeback_claimsinviter 聚合当期值;取「已领取」而非「已入池 accrued」或冲正前流水,确保与 08 返水成本口径一致、不双计(→ 08 §九17 §2.3 NGR)。三种 basis 口径均明确:turnover=下级有效投注、ngr=下级净输赢、rakebackShare=下级已领返水净额。


三、业务规则

  1. 日结 T+1:按租户时区日切,聚合下级前一日贡献计佣;结算幂等键 V1 = (inviterId, downlineId, statDate)(V1 每下级到直属上级恒 depth=1);V1.1 加 depth 分量 = (inviterId, downlineId, depth, statDate)(→ §十一)。本位币单口径不变。
  2. 单币种单池:下级流水计入上级唯一佣金池(本位币),站内单口径直入、无换算(→ 02)。
  3. 提取:claim(claimId) → 风控前置(14)→ REWARD_CREDITavailable(本位币钱包)→ 池清零(提取范围);门槛 minClaim(本位币)。
  4. 负贡献:basis=ngr 时下级赢钱产生负贡献 —— 当期佣金下限为 0(不倒扣池),负额结转次期抵扣(可配)。
  5. 数据可见性:上级只能看到下级的聚合脱敏数据(人数/流水/贡献),不可见明细身份信息。
  6. 变更生效:档位/率表改配置,自下一结算日生效,不追溯。

四、★ 租户可配置项(affiliate 命名空间)

jsonc
"affiliate": {
  "enabled": true,
  "basis": "ngr",                       // turnover(下级有效投注)| ngr(下级净输赢)| rakebackShare(下级已领返水净额,→ §2.3)
  "maxDepth": 1,                        // 代理层深上限 1|2|3,默认 1(=V1 单层,不变);≥2 启用 V1.1 多级(→ §十一)
  "levels": [ { "depth": 1, "rateScale": 1.0 } ],   // V1 一级形态;多级另由 levelRates 定义(→ §十一)
  "levelRates": [                       // 分层费率(V1.1;maxDepth=1 时仅 level 1 生效,即等价 V1)
    { "level": 1, "tiers": "→ 下方 tiers" },              // level 1 沿用现有档位 tiers(按有效会员数档)
    { "level": 2, "ratePct": 0.05 },                     // level≥2 用固定 override 费率(小数),超 maxDepth 的层不配/不计
    { "level": 3, "ratePct": 0.02 }
  ],
  "tiers": [                            // 档位(封顶率即宣传「最高 25%」;仅作用于 level 1)
    { "when": { "activeInvitees": 0 },  "rate": 0.10 },   // 青铜 0–9 人
    { "when": { "activeInvitees": 10 }, "rate": 0.18 },   // 白银 10–29 人
    { "when": { "activeInvitees": 30 }, "rate": 0.25 }    // 黄金 30+ 人(封顶)
  ],
  "settle": "daily",                    // 日结 T+1
  "negativeCarryover": true,            // ngr 负贡献结转
  "minClaim": "100",                    // 提取门槛(本位币单值;站内单币种,单一口径)
  "inviteMilestones": [                 // 邀请里程碑(有效好友数 → 一次性奖励,本位币,终身一次)
    { "n": 5, "amount": "58" }, { "n": 20, "amount": "288" },
    { "n": 50, "amount": "888" }, { "n": 100, "amount": "2888" }
  ],
  "assets": { "poster": true, "landing": "?ref=" }
}

Schema 校验:率 ≤ 平台风控上限(含 levelRates[].ratePct);basis/tiers/levels 互洽;minClaim/里程碑金额为本位币单值(单位 wallet.baseCurrency,校验其存在)。 maxDepth:枚举 1|2|3,默认 1;compliance 可按 region 收紧上限(超限强制回落,→ §十一)。 levelRates:level 连续覆盖 1..maxDepth;level=1 项以 tiers 为费率源(按有效会员数取档),level≥2 项必含 ratePct(0~平台上限的小数);level>maxDepth 的配置项忽略、对应层不计佣。maxDepth=1levelRates 退化为仅 level 1、与 V1 完全等价(向后兼容:旧配置无 maxDepth/levelRates 视同 maxDepth=1)。


五、与其他系统的关系 / 接口

接口调用方幂等键说明
getReferPanel(userId)展示层邀请短链(域名/i/{slug},slug 即归因,不设邀请码概念)、佣金池(可提/今日新增/累计已提/累计佣金,本位币)、直属/有效人数、档位与升档进度、里程碑状态
listInvitees(userId, filter)展示层下级脱敏列表(ID/注册日/有效态/累计流水/我的佣金,本位币);V1.1 filter 可含 depth(1..maxDepth),按层返回代理树下级(→ §十一)
listCommissions(userId)展示层佣金流水(日结入池/提取,本位币单流)
claim(userId)展示层claimId提取佣金 → 本位币钱包
消费 UserRegistered← 05userId建立绑定(含 refSlug 校验)
消费 BetSettled / DepositSucceeded← 12/03betId/orderId归集当期贡献(日结物化)
RewardClaimed(source=AFFILIATE)→ 02/13/16claimId提取入账(本位币)

六、运营后台能力(→ 15)

能力
平台控制台佣金方案模板、率上限风控线
商户控制台本站方案配置(基数/档位/层级,含 maxDepth/levelRates);推广关系查询(团伙树,配合 14);代理管理:我的代理树(按层)+ 各层佣金分列(脱敏聚合,超 maxDepth 不显示,→ §十一.4);佣金结算单审计;成本报表(→17);异常代理冻结佣金(工单)

七、展示契约(→ 原型映射)

UI 元素数据原型载体系统契约
赚钱面板邀请短链复制、海报赚钱 tab(顶部无余额胶囊 body.no-topbal)getReferPanel;短链=租户主域+/i/{slug}
收益卡可提佣金(本位币)「提取佣金 · ¥214.80」按钮展示可提额(本位币);claim 幂等
宣传位封顶率首页轮播「邀请好友 · 最高赚 25% 佣金」文案取 tiers 封顶率渲染,不写死
下级/佣金记录聚合统计与流水下级列表/佣金记录区listInvitees + 13 领取记录(source=AFFILIATE);金额恒本位币

八、数据库设计(全表含 tenant_id;金额 DECIMAL(32,8))

关键字段约束/索引
affiliate_relationstenant_id, user_id, inviter_id, ref_slug_used, bound_atUK(tenant_id,user_id);IDX(tenant_id,inviter_id)
user_ref_slugstenant_id, user_id, ref_slugUK(tenant_id,ref_slug)
commission_dailyid PK, tenant_id, inviter_id, downline_id, stat_date, basis(turnover/ngr/rakebackShare 快照), basis_amount(本位币;rakebackShare 时=下级当期已领返水净额聚合,→ §2.3), rate, depth(层深 1..maxDepth;V1/maxDepth=1 恒 1), commission, carryoverUK(tenant_id,inviter_id,downline_id,depth,stat_date);IDX(tenant_id,inviter_id,stat_date)
commission_accountstenant_id, user_id, accrued(本位币)UK(tenant_id,user_id)
commission_claimsclaim_id PK, tenant_id, user_id, amount(本位币), created_atUK(tenant_id,claim_id)

(日结/账/提取表金额列恒为本位币口径——站内单币种,单站单池,键内无 currency 分量。)

commission_daily 行粒度:每 (inviter_id, downline_id, depth, stat_date) 一行——即「某上级从某个直/间接下级、在该层深、该日」的一条计佣。V1(maxDepth=1):depth 恒 1、每上级每下级每日恰一行,按 inviter_id 聚合即得该上级当日佣金(与 V1.0 语义完全一致,仅显式化 downline_id 维度)。V1.1(maxDepth≥2):同一下级可对其至多 maxDepth 个上级各产生一行(不同 inviter_id/depth),depth 可 >1;结算幂等键 = UK(tenant_id,inviter_id,downline_id,depth,stat_date),重跑不重复(→ §十一)。上级当日总佣金 = 其名下所有行 commission 之和 − 结转。


九、扩展点与代理平面路线图

V1 范围:单层返佣(maxDepth=1,levels=[{depth:1}])、静默 slug 绑定、按有效会员数档位、日结 T+1、单站单池提取。

代理平面路线图:

节点交付物落地要点合规钩子
V1(现·默认)一级返佣maxDepth=1;levels 恒 depth=1;commission_daily depth=1compliance 可强制 maxDepth=1
V1.1(已定义 → §十一)多级代理(depth 1..maxDepth)affiliate.maxDepth(12
V1.1(已定义 → §十一)代理树后台(团队长)受限数据平面商户控制台内「代理管理」角色视图(非独立系统):代理后台可见「我的代理树(按层)」+ 各层佣金分列、直属+下级树脱敏聚合报表(人数/流水/贡献/佣金,身份掩码)、子代理业绩排名;只读、不可见跨代理明细身份(→ §三.5 数据可见性);超出 maxDepth 层不显示跨代理只回聚合、不回传下级身份;导出受 console.dataExport(→ 15)控
V1.1用户端 refer 多层树展示用户端 refer 板「我的代理团队(按层)」:直属/2级/3级 多层下级树 + 各层费率与佣金分列(→ refer.md);maxDepth=1 时降级单层用户端只回本人代理树的脱敏聚合,超 maxDepth 层不展示
V1.2(待运营诉求)代理自设下级分成 / CPA 混合计酬大代理在封顶率内自定义子代理率;CPA=按有效新增人头一次性计酬,与流水分成并存自设率 ≤ 平台风控上限;CPA 反刷号并入 14

其余开放项:

  • 佣金池计息/过期:长期不提取是否过期,默认不过期,待定。
  • 代理层级树重构:绑定关系一次终身不可改;若运营要「代理转移/团队合并」属高危工单,须平台审批 + 审计,V1 不做。

十、验收要点

  • [ ] 带 ?ref=<slug> 注册必绑定且终身不可改;自邀/环路被拒;
  • [ ] 日结幂等:同一 (上级,下级,层深,日期) 重跑不重复计佣;
  • [ ] 佣金单站单池(本位币),下级贡献→计提→提取全链路单口径、无换算;
  • [ ] ngr 负贡献期佣金为 0 且结转正确(V1.1 按 inviter 汇总结转);
  • [ ] 档位门槛/费率正文 = §四 tiers 配置 = refer.md 三处一致(0/10/30 人 → 10%/18%/25%),前端试算取当前档位率、不写死;
  • [ ] basis=rakebackSharebasis_amount = 下级当期已领返水净额(源 08 rakeback_claims),与返水成本不双计;
  • [ ] maxDepth=1(默认)时行为等价 V1:depth 恒 1、单层计佣、幂等/结转/展示与 V1.0 无差异;提取幂等入本位币钱包,佣金池与钱包账变对得上;
  • [ ] V1.1(maxDepth≥2):计佣沿代理树上溯至多 maxDepth 层;超 maxDepth 的层不计佣;level=1tiers 档、level≥2levelRates[].ratePct;每 (inviter,downline,depth,date) 一行且幂等键含 depth;后台代理树按层可见、各层佣金分列,超 maxDepth 不显示;
  • [ ] 宣传位封顶率随 tiers 配置变化,无写死「25%」。

十一、多级代理 V1.1(ADDITIVE;maxDepth=1 为不变默认)

本节为 V1 之上的加法:affiliate.maxDepth=1(默认)时,以下全部退化为 §二~§十 描述的 V1 单层返佣,语义、口径、幂等、结转、展示均不变maxDepth≥2 才启用多级;仍 T+1 日结、本位币单口径、单站单池

11.1 配置

  • affiliate.maxDepth:1|2|3,默认 1。商户可配;compliance 按 region 设上限(超限 maxDepth 截断)。=1 即 V1。
  • affiliate.levelRates:分层费率数组,level 连续覆盖 1..maxDepth——
    • level=1:沿用现有 tiers(按有效会员数档:0/10/30 人 → 10%/18%/25%,封顶 25%),与 V1 完全一致;
    • level≥2:固定 override 费率 ratePct(0~平台上限的小数),不吃 tiers 档;
    • level>maxDepth 的项忽略、对应层不计佣。
  • 分成基数沿用 basis(turnover|ngr|rakebackShare,默认 ngr,口径同 §2.3),各层同基数、仅费率按层取。

11.2 代理树与层深

  • 每个被邀请用户记直属上级 uplineId(= 绑定 inviterId),构成闭环有向树(→ §2.1)。
  • 层深 depth = 上级到下级在树上的距离:直属下级 depth=1,下级的下级 depth=2,……;超过 maxDepth 的层不计佣(截断)。
  • 建树校验:禁自邀(uplineId≠userId)、禁回环(下级不得成为其任一上级的上级——建边时校验目标不在自身祖先/后代闭包内);一次绑定终身不可改。

11.3 计佣

对每个下级当期的 basis_amount(本位币),沿其代理树向上,对每个距离 depth ≤ maxDepth 的上级 inviter:

该 (inviter, downline) 层佣金 = downline.basis_amount(当期,本位币)
                              × rateOf(depth)              // depth=1 取 tiers 当前档;depth≥2 取 levelRates[depth].ratePct
落 commission_daily 一行:(tenant, inviter, downline, depth, stat_date, basis, basis_amount, rate, commission, carryover)
  • 多上级并发:同一下级可同时贡献给其 depth=1..maxDepth 的各上级,各层独立入各自上级池(不是把一份佣金拆分,而是每层按该层费率各自计一份成本)。
  • 负贡献结转:basis=ngr 下级赢钱产生负贡献时,当期该上级佣金下限为 0(不倒扣池);负额按 inviter 汇总结转次期抵扣(沿用 negativeCarryover,口径同 §三.4)。
  • 幂等:结算幂等键 = (tenant, inviter, downline, depth, date);同键重跑不重复计佣(= commission_daily UK)。
  • 结算节奏/口径:仍 T+1 日结、按租户时区日切、本位币单口径、单站单池;提取(§三.3)不变。

11.4 展示 / 后台

  • 代理后台(商户控制台「代理管理」视图,→ §九、15):新增「我的代理树(按层)」+ 各层佣金分列(depth=1/2/3 分列小计);脱敏聚合(人数/流水/贡献/佣金,身份掩码,→ §三.5);超出 maxDepth 的层不显示
  • 用户端 refer 板:「我的代理团队(按层)」呈现多层下级树 + 各层费率与佣金分列(直属/2级/3级,→ refer.md);计佣与数据契约见本篇,UI 细节见 refer.md。maxDepth=1 时用户端与 V1 视图一致。

11.5 防滥用

  • 建树时闭环校验 + 自邀拒绝(→ §2.1、14);
  • maxDepth 截断:超上限的层不建计佣、不入池、不显示;
  • 结算幂等键 (tenant, inviter, downline, depth, date) 保证重跑/补算不双计;
  • 层深上限由 compliance 按 region 强制(「拉人头」判定收紧时可下调 maxDepth,超限层即时回落不计,→ §九合规钩子)。