分佣机制

zxbandzby
0
2026-02-09

关于芋道源码分佣系统的详细说明

一、分佣机制概览

1.1 双模式设计

项目分佣机制支持两种模式:

① 基于用户绑定关系的多级分佣

  • 原理:通过用户上下级推荐关系进行分佣
  • 层级:支持二级分销(一级推广人、二级推广人)
  • 资金归属:直接入账至推广用户的个人分佣账户
  • 提现能力:支持用户自主提现

② 平台级统一分佣

  • 原理:按商品维度配置固定比例或金额
  • 计算方式:每笔订单向平台结算分佣
  • 资金归属:计入平台专属账户
  • 提现能力:不支持提现,仅用于内部财务结算与对账

二、分佣逻辑详解

2.1 分佣触发时机

订单支付成功(TradeBrokerageOrderHandler.afterPayOrder)
    ↓
查找一级推广人(通过 bindUserId)
    ↓
计算一级分佣(比例或固定金额)
    ↓
查找二级推广人(一级推广人的 bindUserId)
    ↓
计算二级分佣(比例或固定金额)
    ↓
写入佣金记录(trade_brokerage_record)
    ↓
更新用户佣金账户(trade_brokerage_user)

2.2 分佣计算基准

关键代码位置TradeOrderConvert.java 第 267 行

BrokerageAddReqBO bo = new BrokerageAddReqBO()
    .setBasePrice(item.getPayPrice())  // ⭐ 基于实付金额计算

重点

  • ✅ 分佣是基于 payPrice(用户实际支付金额)计算的
  • ❌ 不是基于商品原价 totalPrice

2.3 分佣计算方式

系统支持两种分佣计算方式(优先级从高到低):

方式一:固定佣金(优先)

  • 在商品 SKU 中设置 firstBrokeragePricesecondBrokeragePrice
  • 需要商品 SPU 的 subCommissionType = true
  • 直接使用固定金额,不按比例计算

方式二:比例佣金

  • 使用全局配置的 brokerageFirstPercent(一级分佣比例)
  • 使用全局配置的 brokerageSecondPercent(二级分佣比例)
  • 佣金金额 = 实付金额 × 分佣比例

计算逻辑BrokerageRecordServiceImpl.calculatePrice 方法):

int calculatePrice(Integer basePrice, Integer percent, Integer fixedPrice) {
    // 1. 优先使用固定佣金
    if (fixedPrice != null && fixedPrice > 0) {
        return fixedPrice;
    }
    // 2. 根据比例计算佣金
    if (basePrice != null && basePrice > 0 && percent != null && percent > 0) {
        return MoneyUtils.calculateRatePriceFloor(basePrice, Double.valueOf(percent));
    }
    return 0;
}

三、分佣配置详解

3.1 基础配置项(TradeConfigBaseVO)

配置项字段名说明示例值
是否启用分佣brokerageEnabled分佣功能总开关true
分佣模式brokerageEnabledCondition1=人人分销,2=指定分销1
绑定关系模式brokerageBindMode1=首次绑定,2=注册绑定,3=覆盖绑定1
一级返佣比例brokerageFirstPercent0-100%5
二级返佣比例brokerageSecondPercent0-100%3
佣金冻结天数brokerageFrozenDays防止恶意退款7
最低提现金额brokerageWithdrawMinPrice单位:分1000
提现手续费比例brokerageWithdrawFeePercent百分比1
分销海报图brokeragePosterUrls推广素材["https://..."]
提现方式brokerageWithdrawTypes支持多选[1,2,5]

3.2 提现方式枚举(BrokerageWithdrawTypeEnum)

编号名称说明
1钱包转入平台钱包(自动)
2银行卡手动打款
3微信收款码手动打款
4支付宝收款码手动打款
5微信零钱自动打款(微信转账API)
6支付宝余额自动打款(支付宝转账API)

四、资金流转详解

4.1 分佣资金来源

核心结论:分佣资金来源于商品实际成交价,从用户支付的金额中按比例扣除,不属于额外增收。

案例 1:100元商品,无优惠

商品原价:100 元
优惠金额:0 元
实付金额:100 元

一级分佣(5%):100 × 5% = 5 元
二级分佣(3%):100 × 3% = 3 元
商家实际收入:100 - 5 - 3 = 92 元

案例 2:100元商品,用券后80元

商品原价:100 元
优惠券减免:20 元
实付金额:80 元

一级分佣(5%):80 × 5% = 4 元
二级分佣(3%):80 × 3% = 2.4 元
商家实际收入:80 - 4 - 2.4 = 73.6 元

4.2 订单价格组成

价格计算公式TradePriceCalculateRespBO.Price):

最终支付金额 (payPrice) = 
    商品原价总额 (totalPrice)
    - 活动优惠金额 (discountPrice)
    - 优惠券减免金额 (couponPrice)
    - 积分抵扣金额 (pointPrice)
    - VIP会员减免金额 (vipPrice)
    + 运费金额 (deliveryPrice)

4.3 佣金到账流程

订单支付成功 
  ↓
计算分佣金额
  ↓
写入 trade_brokerage_record(佣金记录表)
  ↓
更新 trade_brokerage_user 表的字段:
  - brokeragePrice(可用佣金):立即可提现
  - frozenPrice(冻结佣金):需等待 N 天解冻

重要说明

  • ❌ 佣金不是直接充值到用户钱包
  • ✅ 佣金存储在 trade_brokerage_user 表的专属字段
  • ✅ 提现时才会打款到实际账户(钱包/银行卡/支付宝等)

4.4 用户提现流程

用户发起提现申请
  ↓
扣减 brokeragePrice(可用佣金)
  ↓
创建 trade_brokerage_withdraw(提现申请记录)
  ↓
后台审核通过
  ↓
根据提现方式打款:
  - 钱包:转入支付钱包(自动)
  - 银行卡/微信/支付宝:通过 PayTransferApi 打款(自动/手动)

五、支付手续费与分佣的关系

5.1 手续费计算基数

关键代码位置PayOrderServiceImpl.java 第 361-362 行

.channelFeeRate(channel.getFeeRate())  // 手续费率(如 0.6%)
.channelFeePrice(MoneyUtils.calculateRatePrice(order.getPrice(), channel.getFeeRate()))
// 手续费金额 = 订单支付金额 × 手续费率

重点结论

  • ✅ 手续费是基于用户实际支付金额(100元)计算
  • ❌ 不是基于商家收入(87元)计算

5.2 完整资金流转案例

场景:商品售价 100 元

第一步:平台收到支付款

微信/支付宝收款:100 元
渠道手续费(0.6%):100 × 0.6% = 0.6 元
平台实际到账:99.4 元

第二步:平台系统内部分账

总金额:100 元(逻辑金额)

分佣扣除:
├─ 一级推广人分佣(5%):100 × 5% = 5 元
├─ 二级推广人分佣(3%):100 × 3% = 3 元
└─ 平台分佣(5%):100 × 5% = 5 元

分佣小计:13 元

第三步:商家实际到账

商家收入 = 用户支付 - 渠道手续费 - 分佣总额
        = 100 - 0.6 - 13
        = 86.4 元

5.3 资金分配明细表

金额项计算基数比例/费率金额收款方
用户支付--100.00 元平台代收
渠道手续费100 元0.6%0.60 元微信/支付宝
一级分佣100 元5%5.00 元推广用户A
二级分佣100 元3%3.00 元推广用户B
平台分佣100 元5%5.00 元平台账户
商家到账--86.40 元商家

核算:0.6 + 5 + 3 + 5 + 86.4 = 100 ✅

5.4 渠道手续费 vs 平台分佣

项目说明收款方计算基数扣款时机
渠道手续费微信/支付宝等支付通道收取支付渠道商用户支付金额(100元)支付时立即扣除
平台分佣平台系统内部分配推广用户/平台用户支付金额(100元)订单支付成功后记账

六、商家结算逻辑

6.1 商家实际到账计算公式

商家实际到账 = 用户支付金额 × (1 - 渠道手续费率 - 分佣总比例)

示例:
= 100 × (1 - 0.6% - 13%)
= 100 × 86.4%
= 86.4 元

6.2 商家收款模式

模式一:平台代收代付(推荐)

用户支付 → 平台收款账户 → 定期结算给商家

特点

  • 平台统一收款
  • 扣除分佣和手续费后
  • 按周期(T+7、T+15)结算给商家
  • 通过银行转账或平台钱包

模式二:直连商户(不常见)

用户支付 → 商家微信商户号 → 商家直接收款

特点

  • 商家自己收款
  • 平台通过账单向商家收取分佣
  • 需要商家开通微信/支付宝商户号

6.3 商家定价建议

目标:成本 50 元,期望利润 50 元

成本:50 元
期望利润:50 元
渠道手续费:0.6%
分佣比例:13%(5% + 3% + 5%)

定价计算:
售价 = (成本 + 利润) / (1 - 手续费率 - 分佣率)
     = (50 + 50) / (1 - 0.006 - 0.13)
     = 100 / 0.864
     ≈ 115.74 元

验证:
用户支付:115.74 元
渠道手续费:115.74 × 0.6% = 0.69 元
分佣:115.74 × 13% = 15.05 元
商家实收:115.74 - 0.69 - 15.05 = 100 元
扣除成本:100 - 50 = 50 元利润 ✅

七、平台分佣扩展方案

7.1 方案一:独立统计(推荐)

核心思路

  • 平台分佣不走提现流程
  • 直接计入财务账户用于统计

实现要点

1. 新增平台佣金统计表

CREATE TABLE `trade_platform_brokerage_record` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  `biz_id` varchar(64) NOT NULL COMMENT '业务编号(订单项ID)',
  `biz_type` tinyint NOT NULL COMMENT '业务类型(1=订单)',
  `price` int NOT NULL COMMENT '佣金金额(分)',
  `title` varchar(255) NOT NULL COMMENT '标题',
  `description` varchar(500) COMMENT '说明',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) COMMENT='平台佣金记录表';

2. 配置项扩展

// TradeConfigBaseVO.java 中增加
@Schema(description = "平台分佣比例", example = "5")
@Range(min = 0, max = 100, message = "平台分佣比例必须在 0 - 100 之间")
private Integer platformBrokeragePercent;

@Schema(description = "是否启用平台分佣", example = "true")
private Boolean platformBrokerageEnabled;

3. 分佣计算逻辑

// 1. 平台分佣(不涉及提现)
if (BooleanUtil.isTrue(config.getPlatformBrokerageEnabled())) {
    addPlatformBrokerage(list, config.getPlatformBrokeragePercent(), bizType);
}

// 2. 用户分佣(现有逻辑)
if (BooleanUtil.isTrue(config.getBrokerageEnabled())) {
    // 一级、二级分佣...
}

应用场景

  • 财务统计报表
  • 商品利润分析
  • 平台收入趋势分析
  • 不需要提现,直接计入平台收入

7.2 方案二:虚拟用户模式

核心思路

  • 创建虚拟平台用户
  • 复用现有分佣和提现逻辑

实现要点

1. 创建虚拟平台用户

-- 在 member_user 表插入虚拟平台用户
INSERT INTO member_user (id, mobile, password, nickname, status) 
VALUES (1, '00000000000', 'xxx', '平台账户', 0);

-- 在 trade_brokerage_user 表绑定
INSERT INTO trade_brokerage_user (id, brokerage_enabled, brokerage_price, frozen_price)
VALUES (1, 1, 0, 0);

2. 平台分佣计入虚拟用户

private void addPlatformBrokerage(List<BrokerageAddReqBO> list, Integer percent, 
                                  BrokerageRecordBizTypeEnum bizType) {
    Long platformUserId = 1L; // 平台虚拟用户ID
    BrokerageUserDO platformUser = brokerageUserService.getBrokerageUser(platformUserId);
    
    // 复用现有的分佣逻辑
    addBrokerage(platformUser, list, 0, percent, bizType, 0);
}

优缺点

  • ✅ 完全复用现有代码
  • ✅ 提现流程统一管理
  • ⚠️ 虚拟用户可能引起数据混淆
  • ⚠️ 需要前端支持平台账户登录

7.3 方案对比

维度方案一:独立统计方案二:虚拟用户
开发复杂度中等(新建表和逻辑)低(复用现有逻辑)
数据清晰度⭐⭐⭐⭐⭐ 用户/平台分离⭐⭐⭐ 需区分虚拟用户
提现需求❌ 不支持(仅统计)✅ 支持
财务报表⭐⭐⭐⭐⭐ 独立报表⭐⭐⭐ 需筛选虚拟用户
扩展性⭐⭐⭐⭐ 可灵活扩展⭐⭐⭐ 受限于用户模型

八、数据库表结构

8.1 分佣用户表(trade_brokerage_user)

CREATE TABLE `trade_brokerage_user` (
  `id` bigint NOT NULL COMMENT '用户编号(对应 MemberUserDO.id)',
  `bind_user_id` bigint COMMENT '推广员编号',
  `bind_user_time` datetime COMMENT '推广员绑定时间',
  `brokerage_enabled` bit NOT NULL COMMENT '是否有分销资格',
  `brokerage_time` datetime COMMENT '成为分销员时间',
  `brokerage_price` int NOT NULL DEFAULT 0 COMMENT '可用佣金(单位:分)',
  `frozen_price` int NOT NULL DEFAULT 0 COMMENT '冻结佣金(单位:分)',
  PRIMARY KEY (`id`)
) COMMENT='分销用户表';

8.2 佣金记录表(trade_brokerage_record)

CREATE TABLE `trade_brokerage_record` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_id` bigint NOT NULL COMMENT '用户编号',
  `biz_id` varchar(64) NOT NULL COMMENT '业务编号',
  `biz_type` tinyint NOT NULL COMMENT '业务类型',
  `title` varchar(255) NOT NULL COMMENT '标题',
  `price` int NOT NULL COMMENT '金额(单位:分)',
  `total_price` int NOT NULL COMMENT '当前总佣金',
  `description` varchar(500) COMMENT '说明',
  `status` tinyint NOT NULL COMMENT '状态(0=待结算,1=已结算,2=已取消)',
  `frozen_days` int NOT NULL COMMENT '冻结时间(天)',
  `unfreeze_time` datetime COMMENT '解冻时间',
  `source_user_level` int COMMENT '来源用户等级(1=一级,2=二级)',
  `source_user_id` bigint COMMENT '来源用户编号',
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) COMMENT='佣金记录表';

8.3 提现申请表(trade_brokerage_withdraw)

CREATE TABLE `trade_brokerage_withdraw` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_id` bigint NOT NULL COMMENT '用户编号',
  `price` int NOT NULL COMMENT '提现金额(单位:分)',
  `fee_price` int NOT NULL COMMENT '提现手续费(单位:分)',
  `type` tinyint NOT NULL COMMENT '提现方式',
  `status` tinyint NOT NULL COMMENT '状态',
  `user_account` varchar(64) COMMENT '用户账号',
  `user_name` varchar(32) COMMENT '用户姓名',
  `audit_reason` varchar(255) COMMENT '审核原因',
  `audit_time` datetime COMMENT '审核时间',
  `pay_transfer_id` bigint COMMENT '打款订单编号',
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) COMMENT='佣金提现申请表';

九、常见问题解答

Q1: 分佣的钱从哪来?

A: 从用户实际支付的金额中按比例扣除,不是额外增收。例如用户支付 100 元,按 13% 分佣,则 13 元分给推广用户和平台,87 元归商家。

Q2: 使用优惠券后分佣如何计算?

A: 基于用户实际支付金额计算。例如商品 100 元,用券后 80 元,分佣按 80 元计算,不是按 100 元。

Q3: 支付手续费是基于哪个金额计算的?

A: 基于用户实际支付金额(100元),不是基于商家收入(87元)。

Q4: 佣金是直接打入用户钱包吗?

A: 不是。佣金存储在 trade_brokerage_user 表的 brokeragePrice 字段,用户发起提现后才会打款到实际账户。

Q5: 佣金冻结的作用是什么?

A: 防止恶意退款。订单完成后佣金先冻结 N 天(如 7 天),确认无售后问题后才解冻,用户才能提现。

Q6: 平台分佣和用户分佣有什么区别?

A:

  • 用户分佣:推广用户可提现,资金需要实际支付
  • 平台分佣:计入平台收入,用于财务统计,不需要提现

Q7: 商家如何定价才能保证利润?

A: 使用公式:售价 = (成本 + 利润) / (1 - 手续费率 - 分佣率)

Q8: 分佣比例可以按商品设置吗?

A: 可以。商品 SPU 设置 subCommissionType = true 后,每个 SKU 可以设置独立的 firstBrokeragePricesecondBrokeragePrice,优先使用固定佣金而不是比例。


十、关键代码位置索引

功能模块文件路径关键方法/字段
订单分佣处理TradeBrokerageOrderHandler.javaafterPayOrder()
佣金计算逻辑BrokerageRecordServiceImpl.javaaddBrokerage(), calculatePrice()
分佣配置TradeConfigBaseVO.java分佣相关字段
分佣用户实体BrokerageUserDO.javabrokeragePrice, frozenPrice
提现服务BrokerageWithdrawServiceImpl.javacreateBrokerageWithdraw()
支付订单PayOrderServiceImpl.java手续费计算
价格计算TradePriceCalculateRespBO.java订单价格结构

动物装饰