From 0d1cb506aa781e13b0679d64ef13949e6338eef6 Mon Sep 17 00:00:00 2001 From: xl Date: Mon, 13 Nov 2023 21:20:10 +0800 Subject: [PATCH] eee --- wchat/wx/V3/Notify/GoodsDetail.php | 24 +++++++ wchat/wx/V3/Notify/NotifyModel.php | 93 ++++++++++++++++++++++++++ wchat/wx/V3/Notify/PromotionDetail.php | 23 +++++++ wchat/wx/V3/TransferBatches.php | 11 +-- wchat/wx/V3/WxV3AppPayment.php | 11 +-- wchat/wx/V3/WxV3NativePayment.php | 11 +-- wchat/wx/V3/WxV3Payment.php | 12 +--- wchat/wx/V3/WxV3PaymentNotify.php | 92 +++++++++++++++++++++++++ wchat/wx/V3/WxV3PaymentTait.php | 37 +++++++--- wchat/wx/V3/WxV3Withdrawal.php | 13 +--- 10 files changed, 266 insertions(+), 61 deletions(-) create mode 100644 wchat/wx/V3/Notify/GoodsDetail.php create mode 100644 wchat/wx/V3/Notify/NotifyModel.php create mode 100644 wchat/wx/V3/Notify/PromotionDetail.php create mode 100644 wchat/wx/V3/WxV3PaymentNotify.php diff --git a/wchat/wx/V3/Notify/GoodsDetail.php b/wchat/wx/V3/Notify/GoodsDetail.php new file mode 100644 index 0000000..b1c1af4 --- /dev/null +++ b/wchat/wx/V3/Notify/GoodsDetail.php @@ -0,0 +1,24 @@ +goods_remark = $this->value['goods_remark']; + $this->quantity = $this->value['quantity']; + $this->discount_amount = $this->value['discount_amount']; + $this->goods_id = $this->value['goods_id']; + $this->unit_price = $this->value['unit_price']; + } +} \ No newline at end of file diff --git a/wchat/wx/V3/Notify/NotifyModel.php b/wchat/wx/V3/Notify/NotifyModel.php new file mode 100644 index 0000000..f78f938 --- /dev/null +++ b/wchat/wx/V3/Notify/NotifyModel.php @@ -0,0 +1,93 @@ + 'string'])] + public array $payer = ['openid' => '']; + + + /** + * @var array + */ + #[ArrayShape(['payer_total' => 'int', 'total' => 'int', 'currency' => 'string', 'payer_currency' => 'string'])] + public array $amount = [ + "payer_total" => 100, + "total" => 100, + "currency" => "CNY", + "payer_currency" => "CNY" + ]; + + + /** + * @var array|string[] + */ + #[ArrayShape(['device_id' => 'string'])] + public array $scene_info = [ + 'device_id' => '' + ]; + + /** + * @var array + */ + public array $promotion_detail = []; +} \ No newline at end of file diff --git a/wchat/wx/V3/Notify/PromotionDetail.php b/wchat/wx/V3/Notify/PromotionDetail.php new file mode 100644 index 0000000..1e7c294 --- /dev/null +++ b/wchat/wx/V3/Notify/PromotionDetail.php @@ -0,0 +1,23 @@ + + */ + public array $goods_detail = []; + +} \ No newline at end of file diff --git a/wchat/wx/V3/TransferBatches.php b/wchat/wx/V3/TransferBatches.php index e39e933..20fda63 100644 --- a/wchat/wx/V3/TransferBatches.php +++ b/wchat/wx/V3/TransferBatches.php @@ -33,16 +33,7 @@ class TransferBatches extends SmallProgram $sign = $this->signature('POST', '/v3/transfer/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); - $client = new Client('api.mch.weixin.qq.com', 443, TRUE); - $client->withAddedHeader('Authorization', $sign)->withContentType('application/json') - ->withAgent('application/json')->withBody($json)->withAddedHeader("Accept", "*/*"); - - $proxyHost = $this->getConfig()->getProxyHost(); - $proxyPort = $this->getConfig()->getProxyPort(); - if (!empty($proxyHost) && $proxyPort > 0) { - $client->withProxyHost($proxyHost)->withProxyPort($proxyPort); - } - + $client = $this->createClient($sign, $json); $client->post('/v3/transfer/batches'); $client->close(); diff --git a/wchat/wx/V3/WxV3AppPayment.php b/wchat/wx/V3/WxV3AppPayment.php index 11333ef..6899978 100644 --- a/wchat/wx/V3/WxV3AppPayment.php +++ b/wchat/wx/V3/WxV3AppPayment.php @@ -29,16 +29,7 @@ class WxV3AppPayment extends SmallProgram $sign = $this->signature('POST', '/v3/pay/transactions/components', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); - $client = new Client('api.mch.weixin.qq.com', 443, TRUE); - $client->withAddedHeader('Authorization', $sign)->withContentType('application/json') - ->withAgent('application/json')->withBody($json)->withAddedHeader("Accept", "*/*"); - - $proxyHost = $this->getConfig()->getProxyHost(); - $proxyPort = $this->getConfig()->getProxyPort(); - if (!empty($proxyHost) && $proxyPort > 0) { - $client->withProxyHost($proxyHost)->withProxyPort($proxyPort); - } - + $client = $this->createClient($sign, $json); $client->post('/v3/pay/transactions/components'); $client->close(); diff --git a/wchat/wx/V3/WxV3NativePayment.php b/wchat/wx/V3/WxV3NativePayment.php index 7406759..5ac1884 100644 --- a/wchat/wx/V3/WxV3NativePayment.php +++ b/wchat/wx/V3/WxV3NativePayment.php @@ -29,16 +29,7 @@ class WxV3NativePayment extends SmallProgram $sign = $this->signature('POST', '/v3/pay/transactions/native', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); - $client = new Client('api.mch.weixin.qq.com', 443, TRUE); - $client->withAddedHeader('Authorization', $sign)->withContentType('application/json') - ->withAgent('application/json')->withBody($json)->withAddedHeader("Accept", "*/*"); - - $proxyHost = $this->getConfig()->getProxyHost(); - $proxyPort = $this->getConfig()->getProxyPort(); - if (!empty($proxyHost) && $proxyPort > 0) { - $client->withProxyHost($proxyHost)->withProxyPort($proxyPort); - } - + $client = $this->createClient($sign, $json); $client->post('/v3/pay/transactions/native'); $client->close(); diff --git a/wchat/wx/V3/WxV3Payment.php b/wchat/wx/V3/WxV3Payment.php index 8f05d0e..e4a8733 100644 --- a/wchat/wx/V3/WxV3Payment.php +++ b/wchat/wx/V3/WxV3Payment.php @@ -29,17 +29,7 @@ class WxV3Payment extends SmallProgram $sign = $this->signature('POST', '/v3/pay/transactions/jsapi', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); - $client = new Client('api.mch.weixin.qq.com', 443, TRUE); - $client->withAddedHeader('Authorization', $sign) - ->withContentType('application/json')->withAddedHeader('User-Agent', 'application/json') - ->withBody($json)->withAddedHeader("Accept", "*/*"); - - $proxyHost = $this->getConfig()->getProxyHost(); - $proxyPort = $this->getConfig()->getProxyPort(); - if (!empty($proxyHost) && $proxyPort > 0) { - $client->withProxyHost($proxyHost)->withProxyPort($proxyPort); - } - + $client = $this->createClient($sign, $json); $client->post('/v3/pay/transactions/jsapi'); $client->close(); diff --git a/wchat/wx/V3/WxV3PaymentNotify.php b/wchat/wx/V3/WxV3PaymentNotify.php new file mode 100644 index 0000000..6a4b67c --- /dev/null +++ b/wchat/wx/V3/WxV3PaymentNotify.php @@ -0,0 +1,92 @@ +decode(); + } + + + /** + * @var NotifyModel + */ + public NotifyModel $notifyModel; + + + /** + * @return void + * @throws Exception + */ + public function decode(): void + { + $data = $this->decryptToString($this->resource); + if ($data === false) { + throw new Exception('消息体格式错误, 解码失败.'); + } + $data = json_decode($data, true); + $this->notifyModel = new NotifyModel(); + $this->notifyModel->amount = $data['amount']; + $this->notifyModel->payer = $data['payer']; + $this->notifyModel->scene_info = $data['payer']; + $this->notifyModel->appid = $data['appid']; + $this->notifyModel->mchid = $data['mchid']; + $this->notifyModel->out_trade_no = $data['out_trade_no']; + $this->notifyModel->transaction_id = $data['transaction_id']; + $this->notifyModel->trade_type = $data['trade_type']; + $this->notifyModel->trade_state = $data['trade_state']; + $this->notifyModel->trade_state_desc = $data['trade_state_desc']; + $this->notifyModel->bank_type = $data['bank_type']; + $this->notifyModel->attach = $data['attach']; + $this->notifyModel->success_time = $data['success_time']; + $this->notifyModel->promotion_detail = []; + foreach ($data['promotion_detail'] as $datum) { + $detail = new PromotionDetail(); + $detail->amount = $datum['amount']; + $detail->wechatpay_contribute = $datum['wechatpay_contribute']; + $detail->coupon_id = $datum['coupon_id']; + $detail->scope = $datum['scope']; + $detail->merchant_contribute = $datum['merchant_contribute']; + $detail->name = $datum['name']; + $detail->other_contribute = $datum['other_contribute']; + $detail->currency = $datum['currency']; + $detail->stock_id = $datum['stock_id']; + $detail->goods_detail = []; + foreach ($datum['goods_detail'] as $value) { + $detail->goods_detail[] = new GoodsDetail($value); + } + $this->notifyModel->promotion_detail[] = $detail; + } + } + + +} \ No newline at end of file diff --git a/wchat/wx/V3/WxV3PaymentTait.php b/wchat/wx/V3/WxV3PaymentTait.php index e3d61c5..78bc8cd 100644 --- a/wchat/wx/V3/WxV3PaymentTait.php +++ b/wchat/wx/V3/WxV3PaymentTait.php @@ -3,6 +3,7 @@ namespace wchat\wx\V3; use Exception; +use Kiri\Client; use wchat\common\Help; use function Sodium\crypto_aead_aes256gcm_decrypt; use function Sodium\crypto_aead_aes256gcm_is_available; @@ -30,6 +31,27 @@ trait WxV3PaymentTait } + /** + * @param string $sign + * @param string $json + * @return Client + */ + public function createClient(string $sign, string $json): Client + { + $client = new Client('api.mch.weixin.qq.com', 443, TRUE); + $client->withAddedHeader('Authorization', $sign) + ->withContentType('application/json')->withAddedHeader('User-Agent', 'application/json') + ->withBody($json)->withAddedHeader("Accept", "*/*"); + + $proxyHost = $this->getConfig()->getProxyHost(); + $proxyPort = $this->getConfig()->getProxyPort(); + if (!empty($proxyHost) && $proxyPort > 0) { + $client->withProxyHost($proxyHost)->withProxyPort($proxyPort); + } + return $client; + } + + /** * @param string $http_method * @param string $canonical_url @@ -39,8 +61,8 @@ trait WxV3PaymentTait */ public function signature(string $http_method, string $canonical_url, string $body = ''): string { - $rand = md5(random_bytes(32)); - $time = time(); + $rand = md5(random_bytes(32)); + $time = time(); $message = sprintf("%s\n%s\n%d\n%s\n%s\n", $http_method, $canonical_url, $time, $rand, $body); @@ -90,13 +112,12 @@ trait WxV3PaymentTait /** - * @param $associatedData - * @param $nonceStr - * @param $ciphertext + * @param array $resource * @return bool|string */ - public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string + public function decryptToString(array $resource): bool|string { + [$associatedData, $nonceStr, $cipher_algo, $ciphertext] = [$resource['associated_data'], $resource['nonce'], $resource['nonce'], $resource['ciphertext']]; $ciphertext = \base64_decode($ciphertext); if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) { return FALSE; @@ -107,10 +128,10 @@ trait WxV3PaymentTait if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); } - if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { + if (PHP_VERSION_ID >= 70100 && in_array($cipher_algo, \openssl_get_cipher_methods())) { $ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE); $authTag = substr($ciphertext, -AUTH_TAG_LENGTH_BYTE); - return \openssl_decrypt($ctext, 'aes-256-gcm', 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR', \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); + return \openssl_decrypt($ctext, $cipher_algo, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR', \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); } throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'); } diff --git a/wchat/wx/V3/WxV3Withdrawal.php b/wchat/wx/V3/WxV3Withdrawal.php index 9689387..2438a52 100644 --- a/wchat/wx/V3/WxV3Withdrawal.php +++ b/wchat/wx/V3/WxV3Withdrawal.php @@ -5,7 +5,6 @@ namespace wchat\wx\V3; use Exception; use JetBrains\PhpStorm\ArrayShape; use Kiri\Client; -use Kiri\Message\Stream; use wchat\wx\SmallProgram; class WxV3Withdrawal extends SmallProgram @@ -29,17 +28,7 @@ class WxV3Withdrawal extends SmallProgram $sign = $this->signature('POST', '/v3/pay/transactions/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); - $client = new Client('api.mch.weixin.qq.com', 443, TRUE); - $client->withAddedHeader('Authorization', $sign) - ->withContentType('application/json')->withAddedHeader('User-Agent', 'application/json') - ->withBody($json)->withAddedHeader("Accept", "*/*"); - - $proxyHost = $this->getConfig()->getProxyHost(); - $proxyPort = $this->getConfig()->getProxyPort(); - if (!empty($proxyHost) && $proxyPort > 0) { - $client->withProxyHost($proxyHost)->withProxyPort($proxyPort); - } - + $client = $this->createClient($sign, $json); $client->post('/v3/pay/transactions/batches'); $client->close();