From b7b3610b54f19e00f648eaed19aaab24aae62d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=AF=E7=AB=8B?= Date: Mon, 21 Nov 2022 16:15:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/payment/WechatPaymentService.php | 120 +++++++++++++----- app/data/view/base/payment/form_wechat.html | 49 ++++++- 2 files changed, 135 insertions(+), 34 deletions(-) diff --git a/app/data/service/payment/WechatPaymentService.php b/app/data/service/payment/WechatPaymentService.php index 8de67101f..183b09849 100644 --- a/app/data/service/payment/WechatPaymentService.php +++ b/app/data/service/payment/WechatPaymentService.php @@ -4,7 +4,8 @@ namespace app\data\service\payment; use app\data\service\PaymentService; use think\admin\Exception; -use WePay\Order; +use WePay\Order as OrderV2; +use WePayV3\Order as OrderV3; /** * 微信官方公众号支持 @@ -15,10 +16,44 @@ class WechatPaymentService extends PaymentService { /** * 微信对象对象 - * @var Order + * @var OrderV2|OrderV3 */ protected $payment; + /** + * 支付接口版本 + * @var string + */ + protected $version; + + + /** + * 微信支付服务初始化 + * @return WechatPaymentService + */ + protected function initialize(): WechatPaymentService + { + $this->version = $this->params['wechat_type'] ?? 'v2'; + if ($this->version === 'v2') { + $this->payment = OrderV2::instance([ + 'appid' => $this->params['wechat_appid'], + 'mch_id' => $this->params['wechat_mch_id'], + 'mch_key' => $this->params['wechat_mch_key'], + 'cache_path' => with_path('runtime/wechat'), + ]); + } else { + $this->payment = OrderV3::instance([ + 'appid' => $this->params['wechat_appid'], + 'mch_id' => $this->params['wechat_mch_id'], + 'mch_v3_key' => $this->params['wechat_mch_v3_key'], + 'cert_public' => $this->params['wechat_mch_v3_public'], + 'cert_private' => $this->params['wechat_mch_v3_private'], + 'cache_path' => with_path('runtime/wechat'), + ]); + } + return $this; + } + /** * 创建订单支付参数 * @param string $openid 用户OPENID @@ -38,18 +73,33 @@ class WechatPaymentService extends PaymentService throw new Exception(sprintf('支付类型[%s]未配置定义!', $this->type)); } $body = empty($payRemark) ? $payTitle : ($payTitle . '-' . $payRemark); - $data = [ - 'body' => $body, - 'openid' => $openid, - 'attach' => $this->code, - 'out_trade_no' => $orderNo, - 'total_fee' => $payAmount * 100, - 'trade_type' => static::TYPES[$this->type]['type'] ?? '', - 'notify_url' => sysuri("@data/api.notify/wxpay/scene/order/param/{$this->code}", [], false, true), - 'spbill_create_ip' => $this->app->request->ip(), - ]; - if (empty($data['openid'])) unset($data['openid']); - $info = $this->payment->create($data); + $notify = sysuri("@data/api.notify/wxpay/scene/order/param/{$this->code}", [], false, true); + if ($this->version === 'v2') { + $dataV2 = [ + 'body' => $body, + 'openid' => $openid, + 'attach' => $this->code, + 'out_trade_no' => $orderNo, + 'total_fee' => $payAmount * 100, + 'trade_type' => static::TYPES[$this->type]['type'] ?? '', + 'notify_url' => $notify, + 'spbill_create_ip' => $this->app->request->ip(), + ]; + if (empty($openid)) unset($dataV2['openid']); + $info = $this->payment->create($dataV2); + } else { + $dataV3 = [ + 'appid' => $this->params['wechat_appid'], + 'mchid' => $this->params['wechat_mch_id'], + 'payer' => ['openid' => $openid], + 'amount' => ['total' => $payAmount * 100, 'currency' => 'CNY'], + 'out_trade_no' => $orderNo, + 'notify_url' => $notify, + 'description' => $body, + ]; + if (empty($openid)) unset($dataV3['payer']); + $info = $this->payment->create(strtolower(static::TYPES[$this->type]['type']), $dataV3); + } if ($info['return_code'] === 'SUCCESS' && $info['result_code'] === 'SUCCESS') { // 创建支付记录 $this->createPaymentAction($orderNo, $payTitle, $payAmount); @@ -89,13 +139,34 @@ class WechatPaymentService extends PaymentService /** * 支付结果处理 * @return string + * @throws \WeChat\Exceptions\InvalidDecryptException * @throws \WeChat\Exceptions\InvalidResponseException */ public function notify(): string { - $notify = $this->payment->getNotify(); - if ($notify['result_code'] == 'SUCCESS' && $notify['return_code'] == 'SUCCESS') { - if ($this->updatePaymentAction($notify['out_trade_no'], $notify['transaction_id'], $notify['cash_fee'] / 100)) { + $data = []; + if ($this->version === 'v3') { + $notify = $this->payment->notify(); + if ($notify['event_type'] === 'TRANSACTION.SUCCESS') { + $data['cash_fee'] = $notify['result']['amount']['total'] ?? 0; + $data['result_code'] = 'SUCCESS'; + $data['return_code'] = 'SUCCESS'; + $data['out_trade_no'] = $notify['result']['out_trade_no']; + $data['transaction_id'] = $notify['result']['transaction_id']; + } else { + $data['result_code'] = $notify['event_type'] ?? 'ERROR'; + } + } else { + $notify = $this->payment->getNotify(); + $data['cash_fee'] = $notify['cash_fee']; + $data['result_code'] = $notify['result_code']; + $data['return_code'] = $notify['return_code']; + $data['out_trade_no'] = $notify['out_trade_no']; + $data['transaction_id'] = $notify['transaction_id']; + } + // 更新订单支付信息 + if ($data['result_code'] == 'SUCCESS' && $data['return_code'] == 'SUCCESS') { + if ($this->updatePaymentAction($data['out_trade_no'], $data['transaction_id'], $data['cash_fee'] / 100)) { return $this->payment->getNotifySuccessReply(); } else { return 'error'; @@ -104,19 +175,4 @@ class WechatPaymentService extends PaymentService return $this->payment->getNotifySuccessReply(); } } - - /** - * 微信支付服务初始化 - * @return WechatPaymentService - */ - protected function initialize(): WechatPaymentService - { - $this->payment = Order::instance([ - 'appid' => $this->params['wechat_appid'], - 'mch_id' => $this->params['wechat_mch_id'], - 'mch_key' => $this->params['wechat_mch_key'], - 'cache_path' => with_path('runtime/wechat'), - ]); - return $this; - } } \ No newline at end of file diff --git a/app/data/view/base/payment/form_wechat.html b/app/data/view/base/payment/form_wechat.html index bf26f4d0c..c5944d14f 100644 --- a/app/data/view/base/payment/form_wechat.html +++ b/app/data/view/base/payment/form_wechat.html @@ -10,7 +10,24 @@ 微信商户编号,需要在微信商户平台获取,微信商户号 与 公众号APPID 匹配 - + + + + + + + + \ No newline at end of file