XEX 上的一个月:从改一个费率,到一笔结清的提取。
六个站点。其中两个不会为一个人打开。下面是每一个站点,以及它写下了什么。
您的薪酬计划是配置,不是代码。
费率、职级、阶梯、门槛、奖池和每个套餐的条款,都在结构化表单里编辑并保存为一个新版本。没有人写 JSON,也没有人为了改一个百分比而发布一次上线。
保存并不会让费率生效。版本会被标记上将要执行它的引擎版本,并保持草稿状态,直到第二位操作员批准它。自我审批会被拒绝两次——一次在 Go 里,一次在数据库里——所以既不能通过直接调用 API 绕过,也不能由一个身兼所有角色的操作员绕过。
因为引擎版本记录在计划版本上,平台计算方式的改变就是一个新的引擎版本,而不是对您的计划上个月付了多少的一次无声更改。一个租户可以固定在某个引擎上,也可以被有意迁移。
internal/program · migrations · POST /v1/admin/programs/{version}/approve
会员付到您的账户,不是我们的。
套餐由您定价、由您销售。钱进的是您自己的账户,平台只是被告知钱到了。
交回自有收银台
rails.host_handoff
链上转账
rails.onchain_transfer
银行转账
rails.bank_transfer
支付宝
rails.alipay
微信支付
rails.wechat_pay
M-PESA
rails.mpesa
以上每一条都用您自己的凭据、配置在您自己的账户上。通道配置会拒绝保存与平台自有凭据相同的凭据——这道检查之所以存在,正是因为“先用我们的顶一下”就是一家软件供应商不小心变成支付机构的方式。
internal/rails
六个引擎,一本总账。
每个引擎写自己的分录,每一行都带着产生它的规则标识,并且全部记入同一本仅可追加的总账。
直推奖
internal/direct
团队差额
internal/team
同级超越奖
internal/samerank
职级
internal/rank
全球奖池
internal/pool
俱乐部与特别安排
internal/club · internal/accommodations
引擎代码里没有硬编码的费率——配置是引擎唯一读取的来源。每个引擎都由黄金用例驱动,Go 测试套件在每次改动时都对它们跑一遍;一旦背后是真钱,这是薪酬引擎保持诚实的唯一办法。
结算周期先是一次空跑。
一个周期先算成谁也不付款的草稿分录。您读它会做什么,然后由另一个人批准它。
控制台会把草稿的薪酬总额与该周期扣除退款后的现金净销售额并列显示。如果这个比率超过您配置的上限,这个周期根本无法被批准——这道检查是失败即拒的,而且就在审批路径里,不是在一份事后有人翻的报表里。
批准必须来自创建该周期之外的另一位操作员。入账是可续跑的:中途中断的周期靠再跑一次来完成,而不是靠某个人手工去对两个各入了一半的周期。您不想要的草稿可以丢弃,丢弃同样是幂等的。
internal/runs · /admin/runs
会员发起提取。您来结算。
一次提取会锁定确切的总账分录并发出一条指令。平台从不持有它正指示您转出的那笔钱。
锁定确切的分录
internal/claims
取消输给结算
internal/claims
没有结算系统?那就用控制台。
internal/httpapi/payouts.go
会员看到的是什么。
您的会员读门户的次数远多于您读控制台,而门户说的话,就是您的项目听起来的样子。
十种语言、十三个门户页面,包含从右到左的排版。余额、团队、按类型划分的收益、套餐、提取、争议以及计划本身,全部由引擎执行的同一份配置渲染——所以会员加入前和加入后读到的是同一套说法。
每一个非正常状态都带着原因和下一步。只写“地区受限”是死路;这里的提示会说明为什么以及该怎么办。对某个数字有异议的会员可以发起争议,它会从待处理走到调查中,再到已解决或已驳回,并附上审计轨迹——对您来说,这个结果远好过同一位会员在群里和他的推荐人吵架。
app/[locale]/portal · internal/disputes · i18n