setName('shopro_huifu:query-split-config') ->addOption('huifu-id', null, Option::VALUE_OPTIONAL, '主商户汇付号,默认:商城 platform_huifu_id 或插件 huifu_id') ->addOption('json', null, Option::VALUE_NONE, '输出完整 API data JSON') ->setDescription('Query Huifu merchant split config (rule_origin, div_flag, receivers)'); } protected function execute(Input $input, Output $output) { $output->writeln('=== 汇付商户分账配置查询 (v2/merchant/split/query) ==='); if (!Bridge::isEnabled()) { $output->writeln('[FAIL] 汇付插件未启用'); return 1; } $config = HuifuConfig::getInstance(); $huifuId = trim((string) $input->getOption('huifu-id')); if ($huifuId === '') { $huifuId = $this->resolveDefaultHuifuId(); } $output->writeln('env: ' . $config->get('env', 'prod')); $output->writeln('sys_id: ' . $config->get('sys_id')); $output->writeln('product_id: ' . $config->get('product_id')); $output->writeln('查询 huifu_id: ' . $huifuId); $output->writeln('插件 huifu_id: ' . $config->get('huifu_id')); $output->writeln(''); try { $config->validateKeys(); } catch (\Exception $e) { $output->writeln('[FAIL] ' . $e->getMessage()); return 1; } $client = new HuifuClient(); $result = $client->queryMerchantSplitConfig($huifuId); if (!$result['ok']) { $output->writeln('[FAIL] ' . $result['message']); $output->writeln('提示: 需渠道 sys_id 对该 huifu_id 有数据权限;22000002 排查请确认查的是收款主商户号'); return 1; } $data = $result['data'] ?? []; $respCode = (string) ($data['resp_code'] ?? ''); $respDesc = (string) ($data['resp_desc'] ?? ''); $output->writeln('resp_code=' . $respCode . ' ' . $respDesc); if ($respCode !== '' && $respCode !== '00000000') { $output->writeln('[FAIL] 业务未成功,无法读取 rule_origin'); if ($input->getOption('json')) { $output->writeln(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); } return 1; } if ($input->getOption('json')) { $output->writeln(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); return 0; } $items = HuifuClient::parseSplitBillResult($data['split_bill_result'] ?? null); if ($items === []) { $output->writeln(''); $output->writeln('[结论] split_bill_result 为空 = 汇付侧「分账配置申请」尚未生效(或未提交)'); $output->writeln(' 这与支付查单 delay_acct_flag=Y(延时分账/延迟入账)不是同一开关。'); $output->writeln(' 商城 confirm 带 acct_split_bunch 时,无生效分账配置 + 未绑定接收方 → 典型 22000002。'); $output->writeln(''); $output->writeln('应答顶层字段: ' . implode(', ', array_keys($data))); $nested = HuifuClient::collectNestedKeys($data, ['rule_origin', 'div_flag', 'apply_ratio', 'delay_flag']); if ($nested !== []) { $output->writeln('嵌套扫描: ' . json_encode($nested, JSON_UNESCAPED_UNICODE)); } $output->writeln(''); $output->writeln('--- 商户详情补充 (v2/merchant/basicdata/query + product_id) ---'); $basic = $client->queryMerchantBasicdata($huifuId, true); if ($basic['ok']) { $bd = $basic['data'] ?? []; $bCode = (string) ($bd['resp_code'] ?? ''); $delay = (string) ($bd['delay_flag'] ?? ''); $forced = (string) ($bd['forced_delay_flag'] ?? ''); if ($delay !== '' || $forced !== '') { $output->writeln('delay_flag(延迟入账): ' . ($delay !== '' ? $delay : '(未返回)')); $output->writeln('forced_delay_flag: ' . ($forced !== '' ? $forced : '(未返回)')); } else { $scan = HuifuClient::collectNestedKeys($bd, ['delay_flag', 'forced_delay_flag', 'rule_origin', 'div_flag']); if ($scan !== []) { $output->writeln('详情嵌套: ' . json_encode($scan, JSON_UNESCAPED_UNICODE)); } else { $output->writeln('未读到 delay_flag(可 --json 看 basicdata 全文)'); } } if ($bCode !== '' && $bCode !== '00000000') { $output->writeln('basicdata resp_code=' . $bCode . ' ' . ($bd['resp_desc'] ?? '')); } } else { $output->writeln('[SKIP] ' . $basic['message']); } $output->writeln(''); $output->writeln('下一步(汇付实施/工单):'); $output->writeln(' 1) v2/merchant/split/config 提交:rule_origin=01, div_flag=Y, apply_ratio≥业务比例(如30)'); $output->writeln(' 2) 控台/接口绑定分账接收方 6666000245630872(进件通过 ≠ 分账关系已配)'); $output->writeln(' 3) 生效后再跑本命令,应出现 rule_origin;新订单测分账,勿重试 unconfirm_amt=0 的旧单'); $output->writeln('完整 JSON: php think shopro_huifu:query-split-config --json'); return 2; } $idx = 0; foreach ($items as $row) { $idx++; if (count($items) > 1) { $output->writeln(''); $output->writeln('--- 分账配置 #' . $idx . ' ---'); } $ruleOrigin = (string) ($row['rule_origin'] ?? ''); $divFlag = (string) ($row['div_flag'] ?? ''); $applyRatio = (string) ($row['apply_ratio'] ?? ''); $output->writeln('rule_origin: ' . HuifuClient::describeRuleOrigin($ruleOrigin)); $output->writeln('div_flag: ' . ($divFlag !== '' ? $divFlag : '(未返回)')); $output->writeln('apply_ratio(最大分账比例%): ' . ($applyRatio !== '' ? $applyRatio : '(未返回)')); if (!empty($row['repeal_flag'])) { $output->writeln('repeal_flag: ' . $row['repeal_flag']); } if (!empty($row['refund_flag'])) { $output->writeln('refund_flag: ' . $row['refund_flag']); } $receivers = $this->parseReceiverList($row['acct_split_bunch_list'] ?? null); if ($receivers !== []) { $output->writeln('控台分账接收方 (acct_split_bunch_list):'); foreach ($receivers as $r) { $rid = (string) ($r['huifu_id'] ?? ''); $rate = (string) ($r['fee_rate'] ?? ''); $output->writeln(' - huifu_id=' . $rid . ($rate !== '' ? ' fee_rate=' . $rate . '%' : '')); } } elseif ($ruleOrigin === '02') { $output->writeln('[提示] rule_origin=02 时控台应配置 acct_split_bunch_list'); } if ($ruleOrigin === '01') { $output->writeln('[OK] 与商城延时分账 confirm 传 acct_split_bunch 一致'); } elseif ($ruleOrigin === '02') { $output->writeln('[WARN] 当前为控台规则;商城仍传 acct_split_bunch 可能报 22000002,请改 01 或联系汇付实施'); } } return 0; } protected function resolveDefaultHuifuId() { try { $platform = trim((string) Db::name('shopro_split_config')->where('name', 'platform_huifu_id')->value('value')); if ($platform !== '') { return $platform; } } catch (\Exception $e) { // ignore } return trim((string) HuifuConfig::getInstance()->get('huifu_id')); } /** * @return array> */ protected function parseReceiverList($raw) { if ($raw === null || $raw === '') { return []; } if (is_string($raw)) { $decoded = json_decode($raw, true); if (!is_array($decoded)) { return []; } $raw = $decoded; } if (!is_array($raw)) { return []; } if (isset($raw['huifu_id'])) { return [$raw]; } $list = []; foreach ($raw as $item) { if (is_array($item)) { $list[] = $item; } } return $list; } }