当前结算方案采用"70% 即时结算 + 30% 冻结缓冲池"模式,商家充值后立即可提 70%,剩余 30% 在用户消费时按比例解冻返还,并扣除 10% 平台软件服务费。
该方案存在以下问题:
平台服务费基数 = 总充值 - 总退款 - 跨店支出 + 跨店收入
平台服务费 = 平台服务费基数 × 10%
结算金额 = 总充值
- 总退款
- 跨店支出
+ 跨店收入
- 平台服务费
设计意图:
跨店转账比例:70:30
关键规则:
示例:
5 月份,站点 A 累计用户充值 10,000 元。用户跨店在站点 B 消费了 1,000 元。
| 站点 A | 站点 B | |
|---|---|---|
| 总充值 | 10,000 | 0 |
| 总退款 | 0 | 0 |
| 跨店支出 | 700(1,000 × 70%) | 0 |
| 跨店收入 | 0 | 700(1,000 × 70%) |
| 平台费基数 | 10,000 - 0 - 700 + 0 = 9,300 | 0 - 0 - 0 + 700 = 700 |
| 平台费 | 9,300 × 10% = 930 | 700 × 10% = 70 |
| 结算金额 | 10,000 - 0 - 700 + 0 - 930 = 8,370 | 0 - 0 - 0 + 700 - 70 = 630 |
校验:8,370 + 630 + 1,000(平台费) = 10,000 ✓
A 站留住 300 元拉新奖励,B 站到手 630 元,平台合计收费 1,000 元。
| 项目 | 说明 |
|---|---|
| 结算日 | 每月 15 日 |
| 结算范围 | 上一个自然月(1日 00:00 — 月末 23:59:59) |
| 执行方式 | 定时任务 |
| 失败处理 | 日志记录 + TODO 标记,后续完善重试机制 |
废弃旧模型中的冻结/解冻概念,字段简化如下:
| 字段 | 类型 | 说明 |
|---|---|---|
availableBalance |
int(分) | 已结算金额,可提现 |
frozenWithdrawAmount |
int(分) | 提现申请处理中 |
totalWithdrawnAmount |
int(分) | 累计已提现 |
废弃字段:balance、frozenAmount(旧冻结金额)
不再维护一个独立的"待结算余额"字段,而是通过以下方式动态计算:
待结算资金 = 累计充值 - 累计退款(用户) - 累计消费 + 累计结算
即:充值未消费的部分,自然滚入下一周期,随消费逐步结算。
用户充值 100 元
→ 记入 SplitRecord(type=充值, from=平台, to=站点A)
→ 站点账户不立即增加可提现金额
→ 100 元成为站点的"待结算资金"
用户消费 1,000 元(在站点B,充值站点为A)
→ 本站消费(A = B):
记入 SplitRecord(type=消费, from=站点, to=站点),金额为消费全额
→ 跨店消费(A ≠ B):
以订单实收总额(充值余额 + 赠款余额)的 70% 为跨店转账基数
记入 SplitRecord(type=跨店支出, from=A, to=B, amount=700) ← 实收总额 × 70%
记入 SplitRecord(type=跨店收入, from=A, to=B, amount=700) ← 同上
A 站保留 300 元(30%)作为拉新奖励
赠款为归属站点自行发起的营销成本,参与跨店分账,由归属站承担
充值配置采用「分组 + 配置项」两级模型:
t_recharge_config_group:配置分组,station_id 关联站点(NULL = 平台默认组),每站一个分组t_recharge_config:配置项,group_id 关联分组,单条记录表示一个充值金额档位查询逻辑:先查站点专属分组 → 回退默认分组 → 返回组内配置项列表。充值回调(wxNotify)通过「归属站 + 金额」查找配置项,确保同金额不同组时赠款金额正确。新站点创建时自动创建专属分组并复制默认分组的配置项。
用户退款 15 元
→ 记入 SplitRecord(type=退款, from=站点, to=用户/平台)
→ 在当期结算时扣除
每月 15 日 00:00 定时任务触发
→ 读取上期结算记录的 closing_pending_balance 作为本期期初
→ 汇总各站点上月:充值总额、退款总额、跨店收支
→ 平台服务费基数 = 总充值 - 总退款 - 跨店支出 + 跨店收入
→ 平台服务费 = 基数 × 10%
→ 结算金额 = 总充值 - 总退款 - 跨店支出 + 跨店收入 - 平台服务费
→ 期末待结算余额 = 期初 + 总充值 - 总退款 - 跨店支出 + 跨店收入 - 结算金额
→ 结算金额 > 0:增加站点 availableBalance,状态 = 已结算
→ 结算金额 ≤ 0:结算 0 元,状态 = 异常结算,等待下期资金为正
→ 生成 SettlementRecord(结算单)
与旧方案基本一致,但可用余额来源变为 availableBalance:
商家申请提现
→ 校验:提现金额 ≤ availableBalance
→ 扣减 availableBalance,增加 frozenWithdrawAmount
→ 生成 WithdrawnRecord(待审核)
→ 审核通过 → 扣减 frozenWithdrawAmount,增加 totalWithdrawnAmount
→ 打款确认 → 实际转账(后续对接微信企业付款)
t_settlement_record — 结算单
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| station_id | varchar | 站点 ID |
| settlement_period | varchar | 结算周期(如 2026-05) |
| total_recharge | int | 本期总充值金额(分) |
| total_refund | int | 本期总退款金额(分) |
| total_cross_income | int | 跨店消费收入(分) |
| total_cross_expend | int | 跨店消费支出(分) |
| opening_pending_balance | int | 期初待结算余额(分) |
| closing_pending_balance | int | 期末待结算余额(分) |
| platform_fee_base | int | 平台服务费基数(总充值 - 总退款 - 跨店支出 + 跨店收入) |
| platform_fee | int | 平台服务费(基数 × 10%)(分) |
| settlement_amount | int | 实际结算金额(分) |
| status | tinyint | 0-待结算, 1-已结算, 2-异常结算 |
| remark | varchar | 备注/失败原因 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
t_station_account — 站点账户
| 操作 | 字段 |
|---|---|
| 新增 | available_balance int,已结算可提现金额 |
| 保留 | frozen_withdraw_amount int,提现处理中 |
| 保留 | total_withdrawn_amount int,累计已提现 |
| 废弃 | balance |
| 废弃 | frozen_amount |
t_split_record — 分账记录
| 操作 | 说明 |
|---|---|
| 废弃 | type=3(解冻),不再需要解冻类型 |
t_station_fee_rate / t_platform_fee_rate — 费率表
| 操作 | 字段 |
|---|---|
| 废弃 | frozen_ratio,不再需要冻结比例 |
所有讨论项已确认,无待定事项。
| # | 事项 | 结论 |
|---|---|---|
| 1 | 结算金额为负 | 当期结算 0 元,标记结算记录为"异常结算",等待下期资金为正后正常结算 |
| 2 | 结算单余额追溯 | 记录期初待结算余额、期末待结算余额,便于观察资金趋势 |
| 3 | 定时任务分批 | 无需分批,站点量级不大,单事务直接结算即可 |
当前处于开发环境,存量数据全部清理,不做迁移。
清理范围:
t_station_account 全表t_split_record 全表t_withdrawn_record 全表t_station_fee_rate / t_platform_fee_rate:费率重新配置| 版本 | 日期 | 说明 |
|---|---|---|
| V2.2 | 2026-05-26 | 充值配置分组化(group + item 两级模型) |
| V2.1 | 2026-05-26 | 跨店分账基数调整为充值余额+赠款余额;充值配置站点化(RechargeConfig.stationId)+ 默认配置回退 |
| V2-draft | 2026-05-14 | 初稿,基于业务讨论整理 |