折扣卡CPS渠道佣金比例配置功能设计

发布时间:2026/10/20 21:20:43
折扣卡CPS渠道佣金比例配置功能设计
折扣卡CPS渠道佣金比例配置功能设计在折扣卡CPS系统运营过程中不同联盟渠道、不同卡密批次、不同代理商需要差异化的佣金分配方案。如果佣金比例硬编码在代码中每次调整分佣规则都需要改代码、重新发版运营效率低且存在资金风险。本文围绕渠道佣金比例配置功能从业务痛点、数据模型、匹配规则、权限控制、前端交互、引擎匹配逻辑、校验与风控几个方面完成方案设计附带后端核心Java代码。痛点分析第一佣金比例写死在业务代码渠道返点调整、代理商政策变更都要走版本发布周期长。第二缺少多维度优先级规则渠道全局比例、卡批次专属比例、代理商特殊政策混在一起规则冲突无法预判。第三配置缺少强校验容易出现各级佣金总和超过渠道基础返佣造成平台亏损。第四配置修改即时生效没有灰度、变更记录佣金异常后无法追溯是谁、什么时候修改的配置。第五分佣引擎匹配逻辑简单只按渠道匹配无法结合租户、权益卡等级做精细化分佣。第六禁用、过期配置没有隔离已经下线的规则依然被引擎命中产生错误佣金。第七缺少预览功能运营人员配置完成后无法提前测算佣金只能等真实订单下单后验证。整体设计思路设计可可视化维护的分佣模板模板支持多维度条件匹配引擎在CPS订单到达时按优先级顺序匹配唯一模板。支持按渠道、租户、卡密批次三个维度设置匹配条件分配项包含平台抽成、代理商佣金、推广员佣金、用户返利。配置变更采用“保存版本记录”机制每次修改都生成变更日志配置增加生效时间、失效时间、启用状态支持定时切换政策。新增配置预览接口输入渠道基础佣金实时计算各级分佣金额提前校验是否超上限。匹配优先级从高到低卡密批次专属模板 渠道租户模板 渠道全局模板高优先级模板命中后不再向下匹配。模板不支持叠加生效一个订单只能命中一套分佣规则。数据模型设计核心表cps_commission_template分佣模板主表、cps_commission_template_log配置变更日志表。cps_commission_template关键字段id主键IDtenant_id租户ID私有化多商户隔离channel_code渠道编码关联CPS渠道适配器batch_id卡密批次ID为空代表不限制卡批次template_name模板名称运营识别名称agent_rate代理商佣金比例promoter_rate推广员佣金比例user_rebate_rate用户返利比例platform_rate平台抽成比例max_commission该模板单订单佣金上限start_time生效时间end_time失效时间enable是否启用remark备注cps_commission_template_log关键字段id主键template_id模板IDbefore_json修改前完整配置JSONafter_json修改后完整配置JSONoperator_id操作人IDoperator_name操作人名称create_time变更时间配置校验规则模板保存时后端强制校验不通过直接拒绝保存所有比例取值范围0 ~ 1平台、代理商、推广员、用户返利比例之和不能大于1生效时间不能晚于失效时间同一租户、同一渠道、同一批次不能存在时间重叠且同时启用的模板避免规则冲突单订单佣金上限大于等于0。分佣模板匹配逻辑CPS订单进入分佣引擎后携带上下文信息租户ID、渠道编码、卡密batchId。引擎按照优先级依次查询可用模板可用条件enable1、当前时间在start_time和end_time之间。匹配顺序优先查询【租户渠道batchId】的专属模板没有命中则查询【租户渠道】模板仍然没有命中查询【渠道全局】模板batchId为null全部没有命中该订单不生成分佣。核心代码实现模板实体类Data TableName(cps_commission_template) public class CpsCommissionTemplate { private Long id; private String tenantId; private String channelCode; private String batchId; private String templateName; private BigDecimal agentRate; private BigDecimal promoterRate; private BigDecimal userRebateRate; private BigDecimal platformRate; private BigDecimal maxCommission; private LocalDateTime startTime; private LocalDateTime endTime; private Boolean enable; private String remark; }模板匹配服务Service public class CommissionTemplateServiceImpl implements CommissionTemplateService { Autowired private CpsCommissionTemplateMapper templateMapper; Autowired private CpsCommissionTemplateLogMapper logMapper; Override public CpsCommissionTemplate matchTemplate(String tenantId, String channelCode, String batchId) { LocalDateTime now LocalDateTime.now(); // 1.最高优先级批次专属模板 CpsCommissionTemplate batchTemplate templateMapper.selectOne( Wrappers.lambdaQuery(CpsCommissionTemplate.class) .eq(CpsCommissionTemplate::getTenantId, tenantId) .eq(CpsCommissionTemplate::getChannelCode, channelCode) .eq(CpsCommissionTemplate::getBatchId, batchId) .eq(CpsCommissionTemplate::getEnable, true) .le(CpsCommissionTemplate::getStartTime, now) .ge(CpsCommissionTemplate::getEndTime, now) ); if (batchTemplate ! null) { return batchTemplate; } // 2.次优先级租户渠道模板 CpsCommissionTemplate tenantChannelTemplate templateMapper.selectOne( Wrappers.lambdaQuery(CpsCommissionTemplate.class) .eq(CpsCommissionTemplate::getTenantId, tenantId) .eq(CpsCommissionTemplate::getChannelCode, channelCode) .isNull(CpsCommissionTemplate::getBatchId) .eq(CpsCommissionTemplate::getEnable, true) .le(CpsCommissionTemplate::getStartTime, now) .ge(CpsCommissionTemplate::getEndTime, now) ); if (tenantChannelTemplate ! null) { return tenantChannelTemplate; } // 3.最低优先级渠道全局模板 return templateMapper.selectOne( Wrappers.lambdaQuery(CpsCommissionTemplate.class) .eq(CpsCommissionTemplate::getTenantId, tenantId) .eq(CpsCommissionTemplate::getChannelCode, channelCode) .isNull(CpsCommissionTemplate::getBatchId) .eq(CpsCommissionTemplate::getEnable, true) .le(CpsCommissionTemplate::getStartTime, now) .ge(CpsCommissionTemplate::getEndTime, now) ); } /** * 保存模板并记录变更日志 */ Transactional(rollbackFor Exception.class) Override public void saveTemplate(CpsCommissionTemplate template, String operatorId, String operatorName) { // 比例总和校验 BigDecimal total template.getPlatformRate() .add(template.getAgentRate()) .add(template.getPromoterRate()) .add(template.getUserRebateRate()); if (total.compareTo(new BigDecimal(1)) 0) { throw new BusinessException(佣金比例总和不能超过1); } CpsCommissionTemplate old null; if (template.getId() ! null) { old templateMapper.selectById(template.getId()); } templateMapper.insertOrUpdate(template); // 写入变更日志 CpsCommissionTemplateLog log new CpsCommissionTemplateLog(); log.setTemplateId(template.getId()); log.setBeforeJson(old null ? null : JSON.toJSONString(old)); log.setAfterJson(JSON.toJSONString(template)); log.setOperatorId(operatorId); log.setOperatorName(operatorName); logMapper.insert(log); } /** * 佣金预览测算接口 */ Override public MapString,BigDecimal previewCalc(CpsCommissionTemplate template, BigDecimal baseAmount) { MapString,BigDecimal result new HashMap(); BigDecimal agent baseAmount.multiply(template.getAgentRate()); BigDecimal promoter baseAmount.multiply(template.getPromoterRate()); BigDecimal user baseAmount.multiply(template.getUserRebateRate()); BigDecimal platform baseAmount.multiply(template.getPlatformRate()); // 佣金上限控制 BigDecimal totalCommission agent.add(promoter).add(user).add(platform); if (template.getMaxCommission() ! null totalCommission.compareTo(template.getMaxCommission()) 0) { BigDecimal rateScale template.getMaxCommission().divide(totalCommission, 6, BigDecimal.ROUND_HALF_UP); agent agent.multiply(rateScale); promoter promoter.multiply(rateScale); user user.multiply(rateScale); platform platform.multiply(rateScale); } result.put(agentCommission, agent); result.put(promoterCommission, promoter); result.put(userRebate, user); result.put(platformProfit, platform); return result; } }缓存设计模板数据使用Redis缓存keycps:template:match:{tenantId}:{channelCode}:{batchId}。缓存有效期5分钟模板新增、修改、禁用时主动清理对应缓存避免引擎读到脏配置减少频繁查询数据库压力。前端交互与权限控制管理后台页面功能模板列表、新增模板、编辑、启用/禁用、变更日志查看、佣金预览测算。权限控制粒度超级管理员可以维护全部模板租户管理员只能维护自己租户下的模板普通运营角色只允许查看不允许编辑、新增。预览功能运营录入渠道基础返佣金额点击测算页面直接展示平台、代理、推广员、用户各自佣金用于政策评估。风控与兜底规则模板修改不会回溯历史订单只对修改后新进来的CPS订单生效历史分佣保持不变渠道联盟返佣下调后平台需要同步调整模板避免亏损支持设置单订单佣金上限防止大额订单佣金超标模板变更日志永久留存作为资金对账、纠纷核查凭证后台增加配置变更告警高佣金模板修改后推送消息通知负责人复核。总结折扣卡CPS渠道佣金比例配置功能设计核心是多维度条件匹配、优先级控制、保存强校验、变更留痕、预览测算。把佣金规则从代码抽离为可视化可配置模板运营人员可以独立调整渠道、卡批次佣金政策不需要开发发版同时通过比例校验、时间区间、变更日志、缓存机制控制资金风险。该模块和分佣引擎、CPS订单链路追踪、卡密批次模块联动支撑精细化运营适配私有化部署、多租户、多代理商的业务场景。