From da2ce90ae5cbdf599ef093a3190c6ed22157e2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=AF=E4=B9=90=E5=8A=A0=E5=86=B0?= <11869599+addie66@user.noreply.gitee.com> Date: Mon, 5 Oct 2026 10:29:38 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(shopro):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E5=88=86=E8=B4=A6=E8=AF=8A=E6=96=AD=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在分账诊断中增加 split_max_rate 限制显示,并添加详细的分账明细条目信息 - 添加推广员进件状态检查,验证汇付ID与接收账户一致性 - 新增 printTrySplitChannelHints 函数,提供汇付查单服务和延迟分账标识查询 - 增强错误码 220002 的排查指引,包含详细的问题解决步骤 - 更新执行提示信息,强调确认汇付控台分账关系后再执行 - 添加关于测试单双轨风险的警告提示 ``` --- .../shopro/tests/split_commission_verify.php | 86 ++++++++++++++++++- addons/shopro_huifu/library/HuifuClient.php | 6 ++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/addons/shopro/tests/split_commission_verify.php b/addons/shopro/tests/split_commission_verify.php index 469a8d0..9592452 100644 --- a/addons/shopro/tests/split_commission_verify.php +++ b/addons/shopro/tests/split_commission_verify.php @@ -397,7 +397,45 @@ function diagnoseOrderSplitBlockers($orderId) } } else { $sum = array_sum(array_column($calcItems, 'amount')); - $reasons[] = '当前可算出分账明细 ' . count($calcItems) . ' 条,合计 ' . $sum . ' 元(具备补跑条件,注意 delay_acct_flag)'; + $maxRate = floatval($sc['split_max_rate'] ?? 30); + $reasons[] = '当前可算出分账明细 ' . count($calcItems) . ' 条,合计 ' . $sum . ' 元(受 split_max_rate=' . $maxRate . '% 与 pay_fee 上限约束)'; + foreach ($calcItems as $item) { + $uid = intval($item['role_id'] ?? 0); + $acct = $item['receiver_account'] ?? '-'; + $onboardHint = ''; + if ($uid > 0 && ($item['role_type'] ?? '') === 'promoter') { + $onboard = Db::name('shopro_huifu_onboard') + ->where('user_id', $uid) + ->where('role_type', 'promoter') + ->order('id desc') + ->find(); + if ($onboard) { + $onboardHint = ' 进件=' . ($onboard['onboard_status'] ?? '') . '/' . ($onboard['huifu_id'] ?: '-'); + if (($onboard['huifu_id'] ?? '') !== '' && $onboard['huifu_id'] !== $acct) { + $onboardHint .= ' ⚠与 receiver 不一致'; + } + } else { + $onboardHint = ' 进件=无'; + } + } + $reasons[] = sprintf( + ' → %s user_id=%s huifu_id=%s 金额=%s%s', + $item['role_type'] ?? '-', + $uid ?: '-', + $acct, + number_format((float) ($item['amount'] ?? 0), 2, '.', ''), + $onboardHint + ); + } + $payFee = number_format((float) $order['pay_fee'], 2, '.', ''); + $platformId = trim((string) ($sc['platform_huifu_id'] ?? '')); + $remain = bcsub($payFee, number_format($sum, 2, '.', ''), 2); + if (bccomp($remain, '0.00', 2) > 0) { + $reasons[] = ' → platform 剩余 huifu_id=' . ($platformId !== '' ? $platformId : '(未配 platform_huifu_id,将用插件主商户)') . ' 金额=' . $remain; + } + if ($platformId === '') { + $reasons[] = ' ⚠ platform_huifu_id 为空,请与汇付收款主商户 huifu_id 一致,否则易 22000002'; + } } $walletCnt = 0; @@ -420,6 +458,48 @@ function diagnoseOrderSplitBlockers($orderId) return $reasons; } +function printTrySplitChannelHints(array $order) +{ + if (!class_exists('\\addons\\shopro_huifu\\library\\HuifuQueryService')) { + return; + } + echo "\n【汇付查单】\n"; + try { + $query = (new \addons\shopro_huifu\library\HuifuQueryService())->queryByOrderSn($order['order_sn']); + $keys = ['trans_stat', 'delay_acct_flag', 'unconfirm_amt', 'fund_freeze_stat', 'unfreeze_time']; + foreach ($keys as $key) { + if (isset($query[$key]) && $query[$key] !== '' && $query[$key] !== null) { + echo " · {$key}=" . $query[$key] . "\n"; + } + } + $freeze = strtoupper(trim((string) ($query['fund_freeze_stat'] ?? ''))); + if ($freeze === 'FREEZE') { + echo " → 仍 FREEZE:请先启用 shopro_wechat_trade 并完成发货/微信确认收货,勿 --execute\n"; + } + } catch (\Throwable $e) { + echo ' · 查单失败: ' . $e->getMessage() . "\n"; + } + + $latest = Db::name('shopro_split_order') + ->where('order_id', $order['id']) + ->where('channel', 'huifu') + ->order('id desc') + ->find(); + if ($latest && intval($latest['status']) === 4 && !empty($latest['wx_result'])) { + $raw = is_string($latest['wx_result']) ? $latest['wx_result'] : json_encode($latest['wx_result'], JSON_UNESCAPED_UNICODE); + if (strpos($raw, '22000002') !== false || strpos($raw, '分账配置') !== false) { + echo "\n【最近失败】id={$latest['id']} → 22000002 分账配置有误:控台绑定上述 huifu_id 后再重试\n"; + } elseif (strpos($raw, 'FREEZE') !== false) { + echo "\n【最近失败】id={$latest['id']} → 资金冻结,见上查单\n"; + } + } + + $payHuifuId = Db::name('shopro_huifu_config')->where('name', 'huifu_id')->value('value'); + if ($payHuifuId) { + echo " · 插件支付 huifu_id={$payHuifuId}(应与 platform_huifu_id / 控台主商户一致)\n"; + } +} + function diagnoseMissingSplitOrders($limit) { $since = time() - 90 * 86400; @@ -459,8 +539,10 @@ function trySplitOrder($orderSn, $execute) foreach (diagnoseOrderSplitBlockers($order['id']) as $line) { echo " · {$line}\n"; } + printTrySplitChannelHints($order); if (!$execute) { - echo "\n未执行分账。确认后加 --execute\n"; + echo "\n未执行分账。确认汇付控台分账关系 + 非 FREEZE 后再加 --execute\n"; + echo "(本单若佣金已入钱包,--execute 成功可能造成测试单双轨,正式单请先对齐 split_timing 与分销结算)\n"; return; } if (!class_exists('\\addons\\shopro_huifu\\library\\HuifuSplitService')) { diff --git a/addons/shopro_huifu/library/HuifuClient.php b/addons/shopro_huifu/library/HuifuClient.php index f83b258..c4b3914 100644 --- a/addons/shopro_huifu/library/HuifuClient.php +++ b/addons/shopro_huifu/library/HuifuClient.php @@ -397,6 +397,12 @@ class HuifuClient } + if ($respCode === '22000002') { + + $parts[] = '排查: 1) 汇付控台主商户已开通延时分账/分账业务 2) acct_split_bunch 中每个 huifu_id 已在控台绑定为分账接收方 3) 商城「平台汇付商户号 platform_huifu_id」= 收款主商户 huifu_id 4) 分账接收方账号为进件 huifu_id(非微信 openid)5) 推广员进件成功且与 receiver 一致'; + + } + return implode(',', $parts); }