为什么转卡码系统需要代理分润体系
在转卡码(卡密转账)业务中,代理分销是最主要的流量获取方式。一个成熟的转卡码系统离不开完善的代理分润机制——它决定了代理商的推广积极性、上下游结算效率和平台运营稳定性。本文将从数据库设计、分润算法、自动结算三个维度,完整讲解如何构建一套生产级别的代理分润体系。
如果你还没有自己的转卡码系统,可以先了解我们的 转卡码系统 V3 版,它内置了完整的代理分润模块,支持一键部署。
一、数据库表结构设计
代理分润体系的核心是四张表:代理表、等级表、分润规则表、分润记录表。下面给出完整的 MySQL 建表语句。
1.1 代理等级表 (agent_levels)
-- 代理等级定义
CREATE TABLE `agent_levels` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL COMMENT '等级名称:铜牌/银牌/金牌/钻石',
`level` tinyint(4) NOT NULL COMMENT '等级数值(1-10,越大越高)',
`min_orders` int(11) NOT NULL DEFAULT 0 COMMENT '达标最低订单数',
`min_amount` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '达标最低流水',
`commission_rate` decimal(5,4) NOT NULL COMMENT '默认分润比例(如 0.0500 = 5%)',
`upgrade_bonus` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '晋级奖励金额',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_level` (`level`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1.2 代理表 (agents)
-- 代理信息,含树形关系
CREATE TABLE `agents` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '关联用户ID',
`parent_id` int(11) DEFAULT NULL COMMENT '上级代理ID(NULL=顶级)',
`level_id` int(11) NOT NULL COMMENT '当前等级ID',
`level_path` varchar(512) DEFAULT '' COMMENT '路径树,如 /1/5/12/',
`total_orders` int(11) NOT NULL DEFAULT 0 COMMENT '累计订单数',
`total_amount` decimal(14,2) NOT NULL DEFAULT 0.00 COMMENT '累计流水',
`total_commission` decimal(14,2) NOT NULL DEFAULT 0.00 COMMENT '累计分润',
`withdrawn` decimal(14,2) NOT NULL DEFAULT 0.00 COMMENT '已提现金额',
`status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '1=正常 0=冻结',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_parent` (`parent_id`),
KEY `idx_level_path` (`level_path`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
level_path 字段使用物化路径模式,存储从根到当前节点的完整路径(如 /1/5/12/),可以非常高效地查询某个代理的整个下级树:
-- 查询代理ID=5 的所有下级(无论多少级)
SELECT * FROM agents
WHERE level_path LIKE CONCAT((SELECT level_path FROM agents WHERE id = 5), '%')
AND id != 5;
1.3 分润规则表 (commission_rules)
CREATE TABLE `commission_rules` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL COMMENT '规则名称',
`product_type` varchar(32) NOT NULL DEFAULT '*' COMMENT '适用产品类型(* 表示全部)',
`level_diff` tinyint(4) NOT NULL COMMENT '等级差(0=同级 1=差一级 ...)',
`rate` decimal(5,4) NOT NULL COMMENT '该等级差对应的分润比例',
`priority` tinyint(4) NOT NULL DEFAULT 0 COMMENT '优先级(数值越小越优先)',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_product` (`product_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1.4 分润记录表 (commission_logs)
CREATE TABLE `commission_logs` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` varchar(64) NOT NULL COMMENT '订单号',
`agent_id` int(11) NOT NULL COMMENT '获得分润的代理ID',
`from_agent_id` int(11) DEFAULT NULL COMMENT '来源代理ID(哪个下级产生的)',
`order_amount` decimal(12,2) NOT NULL COMMENT '订单金额',
`commission_rate` decimal(5,4) NOT NULL COMMENT '实际分润比例',
`commission_amount` decimal(12,2) NOT NULL COMMENT '分润金额',
`level_diff` tinyint(4) NOT NULL COMMENT '等级差',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0=待结算 1=已结算 2=已冻结',
`settle_date` date DEFAULT NULL COMMENT '结算日期',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_agent` (`agent_id`),
KEY `idx_order` (`order_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
二、多级分润算法设计
代理分销通常支持多级分润。以三级为例:A 邀请 B,B 邀请 C,C 邀请 D。当 D 完成一笔订单,A、B、C 各自获得对应级差的分润。核心算法如下:
2.1 等级差计算
每个代理有自己的等级(1-10),分润比例取决于"上级与下级的等级差"。等级差越大,上级获得的提成比例越低。例如:
| 等级差 | 分润比例 | 说明 |
|---|---|---|
| 0(同级) | 1.0% | 平级推荐奖励 |
| 1 | 3.0% | 直接下级 |
| 2 | 1.5% | 间接下级 |
| ≥3 | 0.5% | 跨级收益 |
2.2 Python 分润计算核心实现
# commission_calculator.py
# 转卡码系统代理分润计算核心
from decimal import Decimal, ROUND_HALF_UP
class CommissionCalculator:
"""多级分润计算器"""
def __init__(self, order_amount: Decimal, order_agent_id: int):
self.order_amount = order_amount
self.order_agent_id = order_agent_id
self.commissions = []
def calculate(self, db):
"""
从下单代理向上追溯,为每一级上级计算分润
最多追溯 3 级
"""
current_id = self.order_agent_id
ancestor_level = 0
# 获取下单代理的等级
order_agent = db.fetch_one(
"SELECT a.id, a.parent_id, al.level, al.commission_rate "
"FROM agents a JOIN agent_levels al ON a.level_id = al.id "
"WHERE a.id = %s", (current_id,)
)
if not order_agent:
return []
order_level = order_agent['level']
max_levels = 3
# 向上追溯上级代理
parent_id = order_agent['parent_id']
while parent_id and ancestor_level < max_levels:
parent = db.fetch_one(
"SELECT a.id, a.parent_id, al.level, al.commission_rate "
"FROM agents a JOIN agent_levels al ON a.level_id = al.id "
"WHERE a.id = %s", (parent_id,)
)
if not parent:
break
level_diff = parent['level'] - order_level
if level_diff < 0:
level_diff = 0 # 下级等级更高,按平级算
# 根据等级差获取分润比例
if level_diff == 0:
rate = Decimal('0.010')
elif level_diff == 1:
rate = Decimal('0.030')
elif level_diff == 2:
rate = Decimal('0.015')
else:
rate = Decimal('0.005')
commission = (self.order_amount * rate).quantize(
Decimal('0.01'), rounding=ROUND_HALF_UP
)
# 记录分润
self.commissions.append({
'order_id': None, # 由调用方填充
'agent_id': parent['id'],
'from_agent_id': self.order_agent_id,
'order_amount': self.order_amount,
'commission_rate': rate,
'commission_amount': commission,
'level_diff': level_diff,
})
ancestor_level += 1
parent_id = parent['parent_id']
return self.commissions
三、自动结算流程
分润不能下单后立即到账,需要经过"确认期→结算期→可提现"三个阶段:
- 订单确认期(T+0): 用户下单支付后,分润记录插入 commission_logs,状态为"待结算"
- 结算冷静期(T+1~T+7): 根据平台策略设置 1-7 天的冷静期,期间订单可退款,退款时自动冻结对应分润
- 可提现(T+N): 冷静期过后,分润状态变更为"已结算",代理可以在后台申请提现
# settlement.py — 每日结算定时任务
# 配合 cron 每天凌晨 3:00 执行
from datetime import datetime, timedelta
import pymysql
from decimal import Decimal
def daily_settle(db, cool_days=3):
"""执行每日分润结算,cool_days 为冷静期天数"""
cutoff = datetime.now() - timedelta(days=cool_days)
sql = """
UPDATE commission_logs
SET status = 1,
settle_date = CURDATE()
WHERE status = 0
AND created_at <= %s
"""
affected = db.execute(sql, (cutoff,))
print(f"[结算] 本次结算 {affected} 笔分润记录")
# 更新代理累计分润
sql2 = """
UPDATE agents a
JOIN (
SELECT agent_id, SUM(commission_amount) as total
FROM commission_logs
WHERE status = 1 AND settle_date = CURDATE()
GROUP BY agent_id
) cl ON a.id = cl.agent_id
SET a.total_commission = a.total_commission + cl.total
"""
db.execute(sql2)
print(f"[结算] 代理累计分润已更新")
# crontab: 0 3 * * * python3 /path/to/settlement.py
四、提现审核与风控
代理提现时需要做多重校验,防止恶意套现:
# withdrawal.py — 提现申请与审核
def apply_withdrawal(db, agent_id: int, amount: Decimal):
"""代理提交提现申请"""
agent = db.fetch_one(
"SELECT id, total_commission, withdrawn FROM agents WHERE id = %s",
(agent_id,)
)
available = agent['total_commission'] - agent['withdrawn']
# 校验:可提现金额是否足够
if amount > available:
return {'code': 400, 'msg': f'可提现余额不足,可用 ¥{available}'}
# 校验:单笔最低提现
if amount < Decimal('10.00'):
return {'code': 400, 'msg': '最低提现金额为 ¥10'}
# 校验:单日提现次数限制(最多3次)
today_count = db.fetch_one(
"SELECT COUNT(*) as cnt FROM withdrawal_requests "
"WHERE agent_id = %s AND DATE(created_at) = CURDATE()",
(agent_id,)
)['cnt']
if today_count >= 3:
return {'code': 400, 'msg': '今日提现次数已达上限'}
# 创建提现申请单
db.execute(
"INSERT INTO withdrawal_requests (agent_id, amount, status, created_at) "
"VALUES (%s, %s, 0, NOW())",
(agent_id, amount)
)
return {'code': 200, 'msg': '提现申请已提交,等待审核'}
def audit_withdrawal(db, request_id: int, action: str):
"""管理员审核提现:approve / reject"""
req = db.fetch_one(
"SELECT id, agent_id, amount, status FROM withdrawal_requests WHERE id = %s",
(request_id,)
)
if not req or req['status'] != 0:
return {'code': 400, 'msg': '提现申请不存在或已处理'}
if action == 'approve':
# 更新代理已提现金额
db.execute(
"UPDATE agents SET withdrawn = withdrawn + %s WHERE id = %s",
(req['amount'], req['agent_id'])
)
db.execute(
"UPDATE withdrawal_requests SET status = 1, audit_time = NOW() WHERE id = %s",
(request_id,)
)
return {'code': 200, 'msg': '提现已批准'}
else:
db.execute(
"UPDATE withdrawal_requests SET status = 2, audit_time = NOW() WHERE id = %s",
(request_id,)
)
return {'code': 200, 'msg': '提现已拒绝'}
五、分润看板与数据分析
为代理提供一个清晰的分润看板能极大提升推广意愿。核心数据指标包括:
- 今日收益: 当天已结算的分润总额
- 本月收益: 本月累计分润
- 总收益: 历史累计分润
- 团队规模: 直接下级数量和总下级数量
- 团队业绩: 下级团队产生的总订单金额
-- 代理看板核心查询(MySQL)
SELECT
a.id,
a.total_orders,
a.total_amount,
a.total_commission,
a.total_commission - a.withdrawn AS available_commission,
(SELECT COUNT(*) FROM agents WHERE parent_id = a.id) AS direct_children,
(SELECT COUNT(*) FROM agents
WHERE level_path LIKE CONCAT(a.level_path, '%') AND id != a.id) AS total_team,
al.name AS level_name,
al.commission_rate
FROM agents a
JOIN agent_levels al ON a.level_id = al.id
WHERE a.id = 123;
六、生产部署建议
将代理分润系统部署到生产环境时,有几个关键点需要注意:
- 事务保护: 分润计算必须包裹在数据库事务中,确保订单完成与分润记录写入的原子性
- 幂等处理: 回调通知可能重复到达,使用 order_id + agent_id 联合唯一索引防重复
- 分润上限: 设置单笔订单的分润总额上限(如不超过订单金额的 15%),防止恶意套利
- 日志审计: 所有分润变动记录变更日志,便于对账和纠纷处理
- 定时结算: 使用 crontab 或 Celery Beat 执行每日结算,避免高峰期计算
提示: 如果你想快速拥有一个带完整代理分润功能的转卡码系统,而不需要从头开发,可以直接使用我们的 转卡码系统 V3 版。它内置了多级代理、自动分润结算、提现管理、数据看板等完整功能,支持支付宝/微信双通道,开箱即用。
总结
代理分润体系是转卡码系统的核心竞争力之一。本文从数据库表设计开始,到多级分润算法、自动结算流程、提现审核风控,再到代理看板查询,完整覆盖了一个生产级分润系统的技术实现。核心要点包括:使用物化路径管理代理树形关系、基于等级差的分润比例计算、T+N 冷静期结算机制、以及事务/幂等/上限等生产安全策略。
无论你是自己从零搭建,还是使用现成的系统,理解这些底层原理都能帮你更好地运营和维护你的转卡码业务。