From 161d6f7e900559f06fab4d7fb818a1229522caa6 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: Tue, 13 Oct 2026 10:19:54 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(split):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=88=86=E8=B4=A6=E6=A8=A1=E5=BC=8Fscene=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8F=8A=E6=89=A9=E5=B1=95=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在SyncSplitReceivers命令中新增--scene选项,用于指定分账模式 - 支持通过插件配置split_config_scene设置默认分账场景 - 实现buildSplitExtInfoJson方法,根据分账比例和场景自动生成扩展信息 - 当分账比例超过30%或场景为'00'时自动添加业务说明信息 - 在数据库升级脚本中新增分账场景相关配置项 - 完善分账配置的参数验证和错误处理机制 ``` --- .../command/SyncSplitReceivers.php | 5 ++ .../split/HuifuMerchantSplitService.php | 74 +++++++++++++++++++ .../shopro_huifu/upgrade_huifu_split_bind.sql | 7 +- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/addons/shopro_huifu/command/SyncSplitReceivers.php b/addons/shopro_huifu/command/SyncSplitReceivers.php index 23fbac9..e952a2a 100644 --- a/addons/shopro_huifu/command/SyncSplitReceivers.php +++ b/addons/shopro_huifu/command/SyncSplitReceivers.php @@ -18,6 +18,7 @@ class SyncSplitReceivers extends Command ->addOption('dry-run', null, Option::VALUE_NONE, '仅预览将提交的接收方与参数,不调汇付') ->addOption('init-only', null, Option::VALUE_NONE, '仅提交主商户分账开关(rule_origin=01),不带接收方列表') ->addOption('huifu-id', null, Option::VALUE_OPTIONAL, '主商户汇付号,默认 platform_huifu_id 或插件 huifu_id') + ->addOption('scene', null, Option::VALUE_OPTIONAL, '分账模式 scene,默认插件 split_config_scene(A5)') ->setDescription('Submit v2/merchant/split/config and bind approved onboard huifu_ids as split receivers'); } @@ -35,12 +36,16 @@ class SyncSplitReceivers extends Command } $output->writeln('主商户 huifu_id: ' . $main); $output->writeln('apply_ratio(最大分账比例%): ' . $service->resolveApplyRatio()); + $sceneOpt = trim((string) $input->getOption('scene')); + $scene = $sceneOpt !== '' ? $sceneOpt : $service->resolveSplitConfigScene(); + $output->writeln('scene(分账模式): ' . $scene); $dryRun = (bool) $input->getOption('dry-run'); $initOnly = (bool) $input->getOption('init-only'); $options = [ 'dry_run' => $dryRun, 'main_huifu_id' => $main, + 'scene' => $scene, ]; if ($initOnly) { diff --git a/addons/shopro_huifu/library/split/HuifuMerchantSplitService.php b/addons/shopro_huifu/library/split/HuifuMerchantSplitService.php index c222e91..443d50b 100644 --- a/addons/shopro_huifu/library/split/HuifuMerchantSplitService.php +++ b/addons/shopro_huifu/library/split/HuifuMerchantSplitService.php @@ -124,6 +124,11 @@ class HuifuMerchantSplitService $receiverHuifuIds = $this->normalizeReceiverIds($receiverHuifuIds, $mainHuifuId); + $scene = trim((string) ($options['scene'] ?? $this->resolveSplitConfigScene())); + if ($scene === '') { + throw new \InvalidArgumentException('分账模式 scene 不能为空,请在插件配置 split_config_scene 或传 --scene'); + } + $extend = [ 'product_id' => trim((string) $this->config->get('product_id')), 'rule_origin' => $ruleOrigin, @@ -132,8 +137,14 @@ class HuifuMerchantSplitService 'div_flag' => (string) ($options['div_flag'] ?? 'Y'), 'apply_ratio' => $applyRatio, 'start_type' => (string) ($options['start_type'] ?? '0'), + 'scene' => $scene, ]; + $splitExtInfo = $this->buildSplitExtInfoJson($options, floatval($applyRatio), $scene); + if ($splitExtInfo !== null && $splitExtInfo !== '') { + $extend['split_ext_info'] = $splitExtInfo; + } + $asyncUrl = trim((string) ($options['async_return_url'] ?? $this->config->get('split_config_async_url', ''))); if ($asyncUrl !== '') { $extend['async_return_url'] = $asyncUrl; @@ -264,6 +275,69 @@ class HuifuMerchantSplitService return (string) $v !== '0'; } + /** + * 汇付 split/config 必填「分账模式」:A5=线上推广方佣金/抽成,02=线上其他,00=其他(>30% 常需 split_ext_info) + */ + public function resolveSplitConfigScene() + { + $scene = trim((string) $this->config->get('split_config_scene', 'A5')); + return $scene !== '' ? $scene : 'A5'; + } + + /** + * @return string|null JSON 字符串,供 extend.split_ext_info + */ + protected function buildSplitExtInfoJson(array $options, $applyRatio, $scene) + { + if (isset($options['split_ext_info'])) { + $raw = $options['split_ext_info']; + if (is_array($raw)) { + return json_encode($raw, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + $raw = trim((string) $raw); + if ($raw !== '') { + return $raw; + } + } + + $cfgJson = trim((string) $this->config->get('split_config_ext_info', '')); + if ($cfgJson !== '') { + return $cfgJson; + } + + $busi = trim((string) $this->config->get('split_config_busi_instruction', '')); + $capital = trim((string) $this->config->get('split_config_capital_instruction', '')); + $function = trim((string) $this->config->get('split_config_function_instruction', '')); + if ($busi !== '' || $capital !== '' || $function !== '') { + return json_encode([ + 'busi_instruction' => $busi, + 'capital_instruction' => $capital, + 'function_instruction' => $function, + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + + $needExt = $applyRatio > 30.0 || $scene === '00'; + if (!$needExt) { + return null; + } + + return json_encode($this->defaultSplitExtInfoPayload(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + + /** + * 最大分账比例>30% 时的兜底说明(与 docs/汇付分账40%申请说明 一致,可在后台配置覆盖) + * + * @return array + */ + protected function defaultSplitExtInfoPayload() + { + return [ + 'busi_instruction' => '平台运营微信小程序酒类零售,采用自营零售与推广分销、区域代理模式;收款商户负责货源、发货与售后,推广员与区域代理按平台制度获得服务费,单笔订单分账总额不超过实付金额40%,确认收货后延时分账。', + 'capital_instruction' => '消费者微信支付进入平台汇付主商户,开启延时分账暂存;确认收货后由系统接口向各分账接收方子商户划转推广/区域服务费,余额留主商户;退款按汇付与微信规则原路退回,资金均在汇付体系内可追溯。', + 'function_instruction' => '开通延时分账并将最大比例设为40%,用于向已进件推广员、区域代理自动结算服务费,避免人工转账;实际单笔平均分账约15%-25%,基于真实交易及合作协议,不用于违规资金归集。', + ]; + } + /** * @param string[] $huifuIds */ diff --git a/addons/shopro_huifu/upgrade_huifu_split_bind.sql b/addons/shopro_huifu/upgrade_huifu_split_bind.sql index dc13f69..3661e52 100644 --- a/addons/shopro_huifu/upgrade_huifu_split_bind.sql +++ b/addons/shopro_huifu/upgrade_huifu_split_bind.sql @@ -6,4 +6,9 @@ ALTER TABLE `__PREFIX__shopro_huifu_onboard` INSERT IGNORE INTO `__PREFIX__shopro_huifu_config` (`name`, `value`, `group`, `description`) VALUES ('split_auto_bind_receiver', '1', 'split', '进件通过后自动调 v2/merchant/split/config 绑定分账接收方(0关1开)'), -('split_config_async_url', '', 'split', '分账配置异步通知 virgo:// 地址,可选'); +('split_config_async_url', '', 'split', '分账配置异步通知 virgo:// 地址,可选'), +('split_config_scene', 'A5', 'split', '分账模式 scene:A5推广方佣金/02线上其他/00其他,须与汇付控台申请一致'), +('split_config_ext_info', '', 'split', 'split_ext_info 整段 JSON,留空则>30%时用内置说明或下方三字段'), +('split_config_busi_instruction', '', 'split', '业务模式说明 busi_instruction'), +('split_config_capital_instruction', '', 'split', '资金流向说明 capital_instruction'), +('split_config_function_instruction', '', 'split', '功能开通用途 function_instruction');