pay-split-accountlisted
Install: claude install-skill 1398281322-a11y/java-backend-guardrails
# 支付分账
## When to Invoke
平台收一笔、再分给门店/景区/达人;微信分账、延迟结算、抽佣。文旅多门店、电商多商家常见面试题。
## When NOT
购物车拆子单 → `split-order`(履约拆单)。平台账本上的应付/账期打款 → `finance-settlement`(那不是渠道划款)。退款渠道 API → `pay-refund-channel`。GMV 报表 → `finance-stats`。
## 风险(面试考点)
用户付给 **平台商户号**,门店要钱。实时分账:退款时钱可能已在门店,平台垫退失败。默认 **延迟分账**(确认收货/核销完成后再分,或 T+N)。
微信官方约束(面试常背错):
- 需分账的订单,资金先 **冻结**;可实时或 **支付后 30 天内** 发起分账,逾期自动解冻。
- 一笔订单最多分 **50 次**,每次最多 **50 个** 接收方。
- 服务商模式默认最高分账比例约 **30%**(以商户平台授权为准),不是 100% 随便切。
- 查询 `status=FINISHED` 只表示这次动账跑完;**每个接收方看 `receivers.result`**(SUCCESS/CLOSED)。
- `unfreeze_unsplit=true` 或调 **完结分账** 后剩余解冻,**不能再分**。多次分账只在最后一次完结。
- **分账回退**:已分账后退款,先把钱从接收方拉回再退。仅 **MERCHANT_ID** 且接收方开通「同意回退」;**分给个人零钱不能回退**;时限约 **180 天**;同一分账单回退最多 50 次;`out_return_no` 稳定,处理中禁止换单号。
- 回退与退款 API **不耦合**(微信原文),业务上仍应 **先回退成功再退款**,否则平台户余额不够垫。
分账失败、部分接收方失败、接收方未入驻,都会导致平台账上有钱门店没收到。要有分账单状态和对账。
分账金额之和 + 平台佣金 = 实付。单位分,四舍五入规则写死(最后一方吃差额)。
渠道已分账则平台结算单只做对账,禁止再打一笔(见 `finance-settlement`)。
## 方案选型(轻量优先)
| 模式 | 用在 | 不要用在 |
|------|------|----------|
| 不分账,月结打款 | 门店少、能接受账期 | 渠道强制分账 |
| 延迟分账(核销/收货后) | 默认 | 秒级到账承诺没能力时 |
| 支付成功即时分账 | 明确要求且退款能回分 | 高退款、分给个人还要退 |
```text
t_pay_split split_no, pay_trade_no, receiver_mch, amount_fen, status
uk(pay_trade_no, receiver_mch, split_no)
```
流程:支付 SUCCESS(资金冻结)→ 履约完成事件 → 调渠道分账(幂等 split_no)→ 查单直到各接收方终态 → 最后一笔完结/解冻剩余。退款:未分账直接退(或先完结解冻);已分账先回退再退款。
## 默认方案
核销完成(文旅)或确认收货(电商)发消息 `split-request`。**不要在支付回调里同步分账。**
```java
if (splitMapper.insertIgnore(row) == 0) return; // 已发起
channel.profitShare(spl