比较提交
2 次代码提交
4094ff5cf7
...
4b537410e0
| 作者 | SHA1 | 提交日期 | |
|---|---|---|---|
|
|
4b537410e0 | ||
|
|
c4df5ae710 |
@@ -9,6 +9,7 @@
|
||||
* php addons/shopro/tests/split_commission_verify.php recent-success [limit=20]
|
||||
* php addons/shopro/tests/split_commission_verify.php diagnose-missing [limit=20]
|
||||
* php addons/shopro/tests/split_commission_verify.php try-split {order_sn} --execute # 补跑汇付分账(慎用)
|
||||
* php addons/shopro/tests/split_commission_verify.php try-split {order_sn} --confirm-only # 仅延时分账确认、不分账(排查22000002)
|
||||
*/
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
@@ -58,11 +59,12 @@ switch ($command) {
|
||||
case 'try-split':
|
||||
$sn = $argv[2] ?? '';
|
||||
$execute = in_array('--execute', $argv, true);
|
||||
trySplitOrder($sn, $execute);
|
||||
$confirmOnly = in_array('--confirm-only', $argv, true);
|
||||
trySplitOrder($sn, $execute, $confirmOnly);
|
||||
break;
|
||||
default:
|
||||
echo "未知命令: {$command}\n";
|
||||
echo "可用: summary | anomalies | order {order_sn} | recent-success [limit] | diagnose-missing [limit] | try-split {order_sn} --execute\n";
|
||||
echo "可用: summary | anomalies | order {order_sn} | recent-success [limit] | diagnose-missing [limit] | try-split {order_sn} [--execute|--confirm-only]\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -567,7 +569,7 @@ function diagnoseMissingSplitOrders($limit)
|
||||
echo " php addons/shopro/tests/split_commission_verify.php try-split {order_sn} --execute\n";
|
||||
}
|
||||
|
||||
function trySplitOrder($orderSn, $execute)
|
||||
function trySplitOrder($orderSn, $execute, $confirmOnly = false)
|
||||
{
|
||||
if ($orderSn === '') {
|
||||
fwrite(STDERR, "请指定订单号\n");
|
||||
@@ -583,16 +585,22 @@ function trySplitOrder($orderSn, $execute)
|
||||
echo " · {$line}\n";
|
||||
}
|
||||
printTrySplitChannelHints($order);
|
||||
if (!$execute) {
|
||||
echo "\n未执行分账。确认汇付控台分账关系 + 非 FREEZE 后再加 --execute\n";
|
||||
echo "(本单若佣金已入钱包,--execute 成功可能造成测试单双轨,正式单请先对齐 split_timing 与分销结算)\n";
|
||||
return;
|
||||
}
|
||||
if (!class_exists('\\addons\\shopro_huifu\\library\\HuifuSplitService')) {
|
||||
fwrite(STDERR, "未安装 shopro_huifu\n");
|
||||
exit(1);
|
||||
}
|
||||
$service = new \addons\shopro_huifu\library\HuifuSplitService();
|
||||
$preview = $service->previewDelaytransConfirmExtend($order['id']);
|
||||
if ($preview) {
|
||||
echo "\n【confirm 请求预览(写入日志 + 下方 JSON)】\n";
|
||||
echo json_encode($preview, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
|
||||
}
|
||||
if (!$execute && !$confirmOnly) {
|
||||
echo "\n未执行分账。确认汇付控台分账关系 + 非 FREEZE 后再加 --execute\n";
|
||||
echo "排查 22000002 可先: try-split {$orderSn} --confirm-only(仅确认、不分账)\n";
|
||||
echo "(本单若佣金已入钱包,--execute 成功可能造成测试单双轨,正式单请先对齐 split_timing 与分销结算)\n";
|
||||
return;
|
||||
}
|
||||
$payFee = number_format((float) $order['pay_fee'], 2, '.', '');
|
||||
$confirmBase = $service->previewConfirmPayFee($order['order_sn'], $payFee);
|
||||
echo "\n汇付确认基数: pay_fee={$payFee} → confirm_base={$confirmBase}";
|
||||
@@ -618,6 +626,18 @@ function trySplitOrder($orderSn, $execute)
|
||||
echo '查单摘要: 失败 ' . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
if ($confirmOnly) {
|
||||
echo "\n>>> 执行 --confirm-only(不传 acct_split_bunch)\n";
|
||||
try {
|
||||
$result = $service->executeConfirmOnlyByOrderId($order['id']);
|
||||
echo "仅确认返回: " . json_encode($result, JSON_UNESCAPED_UNICODE) . "\n";
|
||||
echo "若成功:说明延迟户/解冻正常,22000002 来自分账接收方 6666000245630872 未在控台绑定或 rule_origin≠01\n";
|
||||
} catch (\Throwable $e) {
|
||||
echo "仅确认失败: " . $e->getMessage() . "\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$ok = $service->executeByOrderId($order['id']);
|
||||
if ($ok) {
|
||||
echo "\n分账执行返回: 成功\n";
|
||||
|
||||
@@ -97,7 +97,7 @@ class HuifuSplitService
|
||||
]);
|
||||
}
|
||||
|
||||
$confirmResult = $this->confirm($ext, $acctInfos, $outOrderNo);
|
||||
$confirmResult = $this->confirm($ext, $acctInfos, $outOrderNo, $confirmBase);
|
||||
$splitOrder->status = 2;
|
||||
$splitOrder->confirm_hf_seq_id = $confirmResult['hf_seq_id'] ?? ($confirmResult['confirm_hf_seq_id'] ?? '');
|
||||
$splitOrder->hf_req_seq_id = $outOrderNo;
|
||||
@@ -136,7 +136,77 @@ class HuifuSplitService
|
||||
return $this->executeByOrderId($orderId);
|
||||
}
|
||||
|
||||
protected function confirm($ext, array $acctInfos, $confirmReqSeqId)
|
||||
/**
|
||||
* 预览延时分账 confirm 请求体(调试 22000002)
|
||||
*/
|
||||
public function previewDelaytransConfirmExtend($orderId)
|
||||
{
|
||||
$order = Order::get($orderId);
|
||||
if (!$order || $order['pay_type'] !== 'huifu_wechat') {
|
||||
return null;
|
||||
}
|
||||
$calculator = new SplitCalculator();
|
||||
$items = $calculator->calculate($orderId);
|
||||
if (empty($items)) {
|
||||
return ['error' => '分账明细为空'];
|
||||
}
|
||||
$payFee = number_format((float) $order['pay_fee'], 2, '.', '');
|
||||
$confirmBase = $this->resolveConfirmPayFee($order['order_sn'], $payFee);
|
||||
$allocated = '0.00';
|
||||
foreach ($items as $item) {
|
||||
$allocated = bcadd($allocated, number_format((float) $item['amount'], 2, '.', ''), 2);
|
||||
}
|
||||
if (bccomp($allocated, $confirmBase, 2) > 0) {
|
||||
$items = $this->scaleSplitItemsToCap($items, $allocated, $confirmBase);
|
||||
}
|
||||
$acctInfos = $this->buildAcctInfos($items, $confirmBase);
|
||||
$ext = HuifuPayService::getPayExt($orderId);
|
||||
$bunch = json_encode(['acct_infos' => $acctInfos], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
return [
|
||||
'confirm_base' => $confirmBase,
|
||||
'payment_huifu_id' => $this->config->get('huifu_id'),
|
||||
'org_req_date' => $ext['req_date'] ?? '',
|
||||
'org_req_seq_id' => $ext['req_seq_id'] ?? '',
|
||||
'org_hf_seq_id' => $ext['hf_seq_id'] ?? '',
|
||||
'acct_split_bunch' => $bunch,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅交易确认、不传分账串(用于排查 22000002 是否来自分账接收方配置)
|
||||
*/
|
||||
public function executeConfirmOnlyByOrderId($orderId)
|
||||
{
|
||||
$order = Order::get($orderId);
|
||||
if (!$order || $order['pay_type'] !== 'huifu_wechat') {
|
||||
return false;
|
||||
}
|
||||
$ext = HuifuPayService::getPayExt($orderId);
|
||||
if (!$ext) {
|
||||
throw new \RuntimeException('无 shopro_huifu_pay_ext');
|
||||
}
|
||||
$blockReason = $this->getDelayFundsBlockReason($order['order_sn']);
|
||||
if ($blockReason !== null) {
|
||||
throw new \RuntimeException($blockReason);
|
||||
}
|
||||
$outOrderNo = 'HFPC' . date('YmdHis') . $orderId;
|
||||
SdkLoader::requireRequest('V2TradePaymentDelaytransConfirmRequest.php');
|
||||
$request = new \BsPaySdk\request\V2TradePaymentDelaytransConfirmRequest();
|
||||
$request->setReqDate(date('Ymd'));
|
||||
$request->setReqSeqId($outOrderNo);
|
||||
$request->setHuifuId($this->config->get('huifu_id'));
|
||||
$extend = [
|
||||
'org_req_date' => $ext['req_date'],
|
||||
'org_req_seq_id' => $ext['req_seq_id'],
|
||||
'org_hf_seq_id' => $ext['hf_seq_id'] ?? '',
|
||||
];
|
||||
\think\Log::write('[shopro_huifu] delaytrans confirm-only extend=' . json_encode($extend, JSON_UNESCAPED_UNICODE), 'info');
|
||||
$request->setExtendInfo($extend);
|
||||
$result = $this->client->postRequest($request);
|
||||
return $this->client->parseResponse($result);
|
||||
}
|
||||
|
||||
protected function confirm($ext, array $acctInfos, $confirmReqSeqId, $confirmBase = null)
|
||||
{
|
||||
SdkLoader::requireRequest('V2TradePaymentDelaytransConfirmRequest.php');
|
||||
$request = new \BsPaySdk\request\V2TradePaymentDelaytransConfirmRequest();
|
||||
@@ -144,13 +214,16 @@ class HuifuSplitService
|
||||
$request->setReqSeqId($confirmReqSeqId);
|
||||
$request->setHuifuId($this->config->get('huifu_id'));
|
||||
|
||||
$acctSplitBunch = json_encode(['acct_infos' => $acctInfos], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$request->setExtendInfo([
|
||||
$bunch = ['acct_infos' => $acctInfos];
|
||||
$acctSplitBunch = json_encode($bunch, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$extend = [
|
||||
'org_req_date' => $ext['req_date'],
|
||||
'org_req_seq_id' => $ext['req_seq_id'],
|
||||
'org_hf_seq_id' => $ext['hf_seq_id'] ?? '',
|
||||
'acct_split_bunch' => $acctSplitBunch,
|
||||
]);
|
||||
];
|
||||
\think\Log::write('[shopro_huifu] delaytrans confirm extend=' . json_encode($extend, JSON_UNESCAPED_UNICODE), 'info');
|
||||
$request->setExtendInfo($extend);
|
||||
|
||||
$result = $this->client->postRequest($request);
|
||||
return $this->client->parseResponse($result);
|
||||
|
||||
在新工单中引用
屏蔽一个用户