feat(shopro_huifu): 添加汇付延时分账资金冻结状态检查功能

- 在分账服务中新增 assertDelayFundsReadyForConfirm 方法,
  检查汇付查单中的 fund_freeze_stat 字段
- 当资金处于 FREEZE 状态时抛出运行时异常,并提供详细处理建议
- 更新测试脚本中的查单摘要,添加 fund_freeze_stat、freeze_time、
  unfreeze_time 字段
- 在文档中补充常见汇付错误码说明,包括 23000003 和 23000004
  的处理方案
```
这个提交包含在:
可乐加冰
2026-10-02 14:35:03 +08:00
父节点 41cd174686
当前提交 acf7314916
共有 3 个文件被更改,包括 42 次插入 和 5 次删除

查看文件

@@ -479,11 +479,14 @@ function trySplitOrder($orderSn, $execute)
try {
$query = (new \addons\shopro_huifu\library\HuifuQueryService())->queryByOrderSn($order['order_sn']);
$snippet = [
'trans_amt' => $query['trans_amt'] ?? null,
'unconfirm_amt' => $query['unconfirm_amt'] ?? null,
'settlement_amt' => $query['settlement_amt'] ?? null,
'delay_acct_flag'=> $query['delay_acct_flag'] ?? null,
'trans_stat' => $query['trans_stat'] ?? null,
'trans_amt' => $query['trans_amt'] ?? null,
'unconfirm_amt' => $query['unconfirm_amt'] ?? null,
'settlement_amt' => $query['settlement_amt'] ?? null,
'delay_acct_flag' => $query['delay_acct_flag'] ?? null,
'fund_freeze_stat' => $query['fund_freeze_stat'] ?? null,
'freeze_time' => $query['freeze_time'] ?? null,
'unfreeze_time' => $query['unfreeze_time'] ?? null,
'trans_stat' => $query['trans_stat'] ?? null,
];
echo '查单摘要: ' . json_encode($snippet, JSON_UNESCAPED_UNICODE) . "\n";
} catch (\Throwable $e) {

查看文件

@@ -306,6 +306,15 @@ php think shopro_huifu:split-retry
2. 分账记录若 `status=4`,点 **重试**
3. 若无任何分账记录,检查规则是否算出大于 0 的金额
### 7.3 常见汇付错误码
| 错误码 | 含义 | 处理 |
|--------|------|------|
| **23000003** | 确认金额与可确认余额不一致 | 确认基数应使用查单 `unconfirm_amt`(内扣手续费后常小于商城 `pay_fee`)。部署最新 `HuifuSplitService` 后重试;CLI 可看 `confirm_base`。 |
| **23000004** | 延迟交易资金冻结,不能发起交易确认 | **非金额问题**。小程序 + 延时分账时,微信侧资金常处于在途/冻结,需 **发货并同步微信**(`shopro_wechat_trade` → `upload_shipping_info`),用户 **确认收货**(`notify_confirm_receive`)或等待自动解冻后再分账。查单若 `fund_freeze_stat=FREEZE`,应把 **分账时机** 改为 `confirm` 或 `finish`,勿在 `payed` 立即 confirm。 |
微信交易合规插件:见 `addons/shopro_wechat_trade/README.md`(小程序后台需签署订单中心协议、开通发货信息管理服务)。
---
## 8. 定时任务建议

查看文件

@@ -67,6 +67,7 @@ class HuifuSplitService
$outOrderNo = 'HFPS' . date('YmdHis') . $orderId;
$ext = HuifuPayService::getPayExt($orderId);
$this->assertDelayFundsReadyForConfirm($order['order_sn']);
Db::startTrans();
try {
@@ -194,6 +195,30 @@ class HuifuSplitService
return $this->resolveConfirmPayFee($orderSn, $orderPayFee);
}
/**
* 微信小程序 + 延时分账:通道侧资金可能处于 FREEZE,需发货/确认收货或等待解冻后才能 delaytrans/confirm。
*/
protected function assertDelayFundsReadyForConfirm($orderSn)
{
try {
$query = (new HuifuQueryService())->queryByOrderSn($orderSn);
} catch (\Throwable $e) {
return;
}
$freezeStat = strtoupper(trim((string) ($this->queryFieldRecursive($query, 'fund_freeze_stat') ?? '')));
if ($freezeStat !== 'FREEZE') {
return;
}
$unfreezeTime = trim((string) ($this->queryFieldRecursive($query, 'unfreeze_time') ?? ''));
$hint = '汇付查单 fund_freeze_stat=FREEZE:延迟交易资金仍被通道冻结,暂不能交易确认分账。'
. '小程序场景通常需:后台发货并同步微信 upload_shipping_info,用户在微信确认收货(或等待自动解冻,约 2–3 天)后再分账;'
. '建议分账时机改为「确认收货」而非「支付成功」。';
if ($unfreezeTime !== '') {
$hint .= ' 预计解冻时间(unfreeze_time)=' . $unfreezeTime;
}
throw new \RuntimeException($hint);
}
protected function resolveConfirmPayFee($orderSn, $orderPayFee)
{
$fallback = number_format((float) $orderPayFee, 2, '.', '');