文件
xionggeshop/addons/shopro/tests/huifu_delay_reconcile.sql
可乐加冰 0d1256a679 ```
feat(shopro): 添加汇付延时分账对账功能

- 新增 huifu_delay_reconcile.sql 对账脚本,包含多个维度的分账核对查询
- 在 split_commission_verify.php 中添加 audit-delay 命令,支持实时查询汇付未确认金额
- 实现递归解析汇付查单响应的功能,支持嵌套JSON数据提取
- 提供延时分账订单审计功能,可对比本地状态与汇付侧 unconfirm_amt
- 支持批量诊断延时分账待确认订单,便于排查资金卡顿问题
```
2026-10-23 15:12:47 +08:00

151 行
5.4 KiB
SQL

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

-- 汇付「延时分账待交易确认」与商城分账记录对账
-- 用法:在 MySQL 执行(表前缀 fa_ 请按实际修改)
-- 图1 汇付控台「商品描述=商城订单{order_sn}」可与 order_sn 直接对应
SELECT '=== 1. 当前分账配置(是否支付即分账)===' AS section;
SELECT name, value, description
FROM fa_shopro_split_config
WHERE name IN (
'split_enable', 'split_mode', 'split_provider', 'split_timing',
'split_amount_source', 'delay_acct_enable', 'platform_huifu_id'
);
-- 汇付控台截图中的 8 笔订单号(可按需增删)
SET @huifu_pending_sns = '202605495163454091004900,202609215157744091003800,202604274596990091003800,202606500438103091004500,202608341834105091004400,202607585392320091004300,202602490038750091003800,202602385010837091001400';
SELECT '=== 2. 汇付待确认列表 vs 商城分账/支付扩展(核心对账)===' AS section;
SELECT
o.id AS order_id,
o.order_sn,
o.status AS order_status,
o.pay_fee,
FROM_UNIXTIME(o.paytime) AS pay_time,
FROM_UNIXTIME(
NULLIF(CAST(JSON_UNQUOTE(JSON_EXTRACT(o.ext, '$.confirm_time')) AS UNSIGNED), 0)
) AS buyer_confirm_time,
pe.delay_acct_flag,
pe.confirm_status,
pe.confirm_hf_seq_id,
pe.hf_seq_id,
so.id AS split_order_id,
so.status AS split_status,
CASE so.status
WHEN 0 THEN '待分账'
WHEN 1 THEN '分账中'
WHEN 2 THEN '成功'
WHEN 3 THEN '部分成功'
WHEN 4 THEN '失败'
ELSE IF(so.id IS NULL, '无分账记录', so.status)
END AS split_status_label,
so.split_source,
so.split_amount,
LEFT(so.wx_result, 160) AS split_fail_hint,
CASE
WHEN pe.delay_acct_flag IS NULL OR pe.delay_acct_flag = '' THEN '⚠ 无 pay_ext 或未记录 delay 标记'
WHEN UPPER(pe.delay_acct_flag) <> 'Y' THEN '✗ 非延时分账单,控台待确认需单独核对'
WHEN pe.confirm_status = 'S' OR so.status = 2 THEN '✓ 已交易确认/分账成功'
WHEN so.id IS NULL THEN '✗ 从未生成分账记录(常见:split_timing≠当前订单状态,或支付时未开分账)'
WHEN so.status = 4 THEN '✗ 分账失败,未 confirm 成功(资金仍可能卡在汇付)'
WHEN so.status IN (0, 1) THEN '… 分账处理中'
ELSE '请人工核对'
END AS reconcile_hint
FROM fa_shopro_order o
LEFT JOIN fa_shopro_huifu_pay_ext pe ON pe.order_id = o.id
LEFT JOIN (
SELECT t.*
FROM fa_shopro_split_order t
INNER JOIN (
SELECT order_id, MAX(id) AS max_id
FROM fa_shopro_split_order
WHERE channel = 'huifu'
GROUP BY order_id
) x ON x.max_id = t.id
) so ON so.order_id = o.id
WHERE FIND_IN_SET(o.order_sn, REPLACE(@huifu_pending_sns, ' ', ''))
ORDER BY o.paytime DESC;
SELECT '=== 3. 近90天:延时分账(Y)但未 confirm 成功(与控台待释放资金相关)===' AS section;
SELECT
o.id AS order_id,
o.order_sn,
o.pay_fee,
FROM_UNIXTIME(o.paytime) AS pay_time,
pe.confirm_status,
pe.confirm_hf_seq_id,
IFNULL(so.status, -1) AS split_status,
LEFT(so.wx_result, 120) AS fail_msg
FROM fa_shopro_order o
INNER JOIN fa_shopro_huifu_pay_ext pe ON pe.order_id = o.id
LEFT JOIN (
SELECT order_id, MAX(status) AS status, MAX(wx_result) AS wx_result
FROM fa_shopro_split_order WHERE channel = 'huifu' GROUP BY order_id
) so ON so.order_id = o.id
WHERE o.pay_type = 'huifu_wechat'
AND o.paytime >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY))
AND UPPER(IFNULL(pe.delay_acct_flag, '')) = 'Y'
AND IFNULL(pe.confirm_status, '') <> 'S'
AND IFNULL(so.status, 0) <> 2
ORDER BY o.paytime DESC
LIMIT 100;
SELECT '=== 4. 有延时分账标记但从未出现分账记录(高概率未触发 split)===' AS section;
SELECT
o.id,
o.order_sn,
FROM_UNIXTIME(o.paytime) AS pay_time,
o.status AS order_status,
pe.delay_acct_flag,
(SELECT value FROM fa_shopro_split_config WHERE name = 'split_timing' LIMIT 1) AS split_timing
FROM fa_shopro_order o
INNER JOIN fa_shopro_huifu_pay_ext pe ON pe.order_id = o.id
LEFT JOIN fa_shopro_split_order so ON so.order_id = o.id AND so.channel = 'huifu'
WHERE o.pay_type = 'huifu_wechat'
AND o.paytime >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY))
AND UPPER(pe.delay_acct_flag) = 'Y'
AND so.id IS NULL
ORDER BY o.id DESC
LIMIT 50;
SELECT '=== 5. 分账失败(status=4) 汇付延时分账单 ===' AS section;
SELECT
so.order_id,
so.order_sn,
so.split_amount,
so.retry_count,
FROM_UNIXTIME(so.createtime) AS split_at,
LEFT(so.wx_result, 200) AS fail_reason
FROM fa_shopro_split_order so
INNER JOIN fa_shopro_order o ON o.id = so.order_id
INNER JOIN fa_shopro_huifu_pay_ext pe ON pe.order_id = o.id
WHERE so.channel = 'huifu'
AND so.status = 4
AND UPPER(IFNULL(pe.delay_acct_flag, '')) = 'Y'
ORDER BY so.id DESC
LIMIT 50;
SELECT '=== 6. 本地标记已 confirm 但可能未真正释放(需 CLI audit-delay --live 核实)===' AS section;
SELECT
o.order_sn,
o.pay_fee,
pe.confirm_status,
pe.confirm_hf_seq_id,
so.status AS split_status,
so.confirm_hf_seq_id AS split_confirm_seq,
FROM_UNIXTIME(so.createtime) AS split_at
FROM fa_shopro_order o
INNER JOIN fa_shopro_huifu_pay_ext pe ON pe.order_id = o.id
LEFT JOIN (
SELECT order_id, MAX(id) AS max_id FROM fa_shopro_split_order WHERE channel = 'huifu' GROUP BY order_id
) x ON x.order_id = o.id
LEFT JOIN fa_shopro_split_order so ON so.id = x.max_id
WHERE o.pay_type = 'huifu_wechat'
AND UPPER(pe.delay_acct_flag) = 'Y'
AND (pe.confirm_status = 'S' OR so.status = 2)
ORDER BY o.paytime DESC
LIMIT 50;