From 5b2a0174575a33cc2b315c875a8c3063196342e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=93=AD=E6=98=95?= <715557344@qq.com> Date: Wed, 5 Apr 2023 23:12:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=BE=AE=E4=BF=A1v2?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=B8=AD=E7=AD=BE=E7=BA=A6=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=20(#763)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Wechat/Papay/PayContractOrderPlugin.php | 14 +++ .../Pay/Common/InvokePrepayV2Plugin.php | 119 ++++++++++++++++++ src/Plugin/Wechat/Shortcut/PapayShortcut.php | 27 ++++ 3 files changed, 160 insertions(+) create mode 100644 src/Plugin/Wechat/Papay/PayContractOrderPlugin.php create mode 100644 src/Plugin/Wechat/Pay/Common/InvokePrepayV2Plugin.php create mode 100644 src/Plugin/Wechat/Shortcut/PapayShortcut.php diff --git a/src/Plugin/Wechat/Papay/PayContractOrderPlugin.php b/src/Plugin/Wechat/Papay/PayContractOrderPlugin.php new file mode 100644 index 000000000..674d14475 --- /dev/null +++ b/src/Plugin/Wechat/Papay/PayContractOrderPlugin.php @@ -0,0 +1,14 @@ + $rocket]); + + $prepayId = $rocket->getDestination()->get('prepay_id'); + + if (is_null($prepayId)) { + Logger::error('[wechat][InvokePrepayPlugin] 预下单失败:响应缺少 prepay_id 参数,请自行检查参数是否符合微信要求', $rocket->getDestination()->all()); + + throw new InvalidResponseException(Exception::RESPONSE_MISSING_NECESSARY_PARAMS, 'Prepay Response Error: Missing PrepayId', $rocket->getDestination()->all()); + } + + $config = $this->getInvokeConfig($rocket, $prepayId); + + $rocket->setDestination($config); + + Logger::info('[wechat][InvokePrepayPlugin] 插件装载完毕', ['rocket' => $rocket]); + + return $rocket; + } + + /** + * @throws \Yansongda\Pay\Exception\ContainerException + * @throws \Yansongda\Pay\Exception\InvalidConfigException + * @throws \Yansongda\Pay\Exception\ServiceNotFoundException + */ + protected function getSign(Collection $invokeConfig, array $params): string + { + $secret = get_wechat_config($params)['mch_secret_key_v2'] ?? null; + if (empty($secret)) { + throw new InvalidConfigException(Exception::WECHAT_CONFIG_ERROR, 'Missing Wechat Config -- [mch_secret_key_v2]'); + } + + $data = $invokeConfig->toArray(); + ksort($data); + $contents = ''; + foreach ($data as $key => $datum) { + $contents .= $key.'='.$datum.'&'; + } + $contents .= 'key='.$secret; + + return md5($contents); + } + + /** + * @throws \Yansongda\Pay\Exception\ContainerException + * @throws \Yansongda\Pay\Exception\ServiceNotFoundException + * @throws \Exception + */ + protected function getInvokeConfig(Rocket $rocket, string $prepayId): Config + { + $config = new Config([ + 'appId' => $this->getAppId($rocket), + 'timeStamp' => time().'', + 'nonceStr' => Str::random(32), + 'package' => 'prepay_id='.$prepayId, + 'signType' => 'MD5', + ]); + + $config->set('paySign', $this->getSign($config, $rocket->getParams())); + + return $config; + } + + /** + * @throws \Yansongda\Pay\Exception\ContainerException + * @throws \Yansongda\Pay\Exception\ServiceNotFoundException + */ + protected function getAppId(Rocket $rocket): string + { + $config = get_wechat_config($rocket->getParams()); + $payload = $rocket->getPayload(); + + if (Pay::MODE_SERVICE === ($config['mode'] ?? null) && $payload->has('sub_appid')) { + return $payload->get('sub_appid', ''); + } + + return $config[$this->getConfigKey($rocket->getParams())] ?? ''; + } + + protected function getConfigKey(array $params): string + { + $type = $params['_type'] ?? 'mp'; + + return $type.'_app_id'; + } +} diff --git a/src/Plugin/Wechat/Shortcut/PapayShortcut.php b/src/Plugin/Wechat/Shortcut/PapayShortcut.php new file mode 100644 index 000000000..456148b87 --- /dev/null +++ b/src/Plugin/Wechat/Shortcut/PapayShortcut.php @@ -0,0 +1,27 @@ +