Skip to content

Commit

Permalink
新增微信支付V3
Browse files Browse the repository at this point in the history
  • Loading branch information
25362583 committed Dec 29, 2022
1 parent fe753d4 commit 65f95be
Show file tree
Hide file tree
Showing 3 changed files with 556 additions and 1 deletion.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
],
"require": {
"php": "^7.0",
"littlemo/utils": "~1.2.0"
"littlemo/utils": "~1.2.0",
"wechatpay/wechatpay": "*"
},
"require-dev": {},
"autoload": {
Expand Down
294 changes: 294 additions & 0 deletions src/pay/v3/Base.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
<?php

// +----------------------------------------------------------------------
// | Little Mo - Tool [ WE CAN DO IT JUST TIDY UP IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2021 http://ggui.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: littlemo <25362583@qq.com>
// +----------------------------------------------------------------------

namespace littlemo\wechat\pay\v3;

use littlemo\wechat\core\LWechatException;

use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;

/**
* 微信支付公共方法
*
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-09-15
* @version 2021-09-15
*/
class Base
{

/**
* 由微信生成的应用ID,全局唯一
*
* @var string
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-11-11
* @version 2021-11-11
*/
protected $appid = null;

/**
* 由微信生成的应用ID,全局唯一
*
* @var string
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-11-11
* @version 2021-11-11
*/
protected $subAppid = null;


/**
* 商户号,由微信支付生成并下发
*
* @var string
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-11-11
* @version 2021-11-11
*/
protected $mchid = null;

/**
* 子商户号,由微信支付生成并下发
*
* @var string
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-11-11
* @version 2021-11-11
*/
protected $subMchid = null;

/**
* 微信支付商户APIV3支付密钥
*
* @var string
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-11-11
* @version 2021-11-11
*/
protected $apiv3Key = null;

/**
* 微信支付证书cert路径
*/
protected $sslCertPath = '';

/**
* 微信支付证书key路径
*/
protected $sslKeyPath = '';

/**
* 微信支付平台证书路径
*/
protected $platformCertPath = '';

/**
* APIv3 客户端实例
* @var object
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2022-12-26
* @version 2022-12-26
*/
protected $instance = null;


/**
* 狗仔函数
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2022-12-27
* @version 2022-12-27
* @param array $certPath 证书路径 public:公钥,private:私钥,platform:平台证书
* @param array $mchid 商户号 sp:商户号,sub:下级商户号
* @param array $apiv3Key V3支付密钥
* @param array $appid 应用ID sp:应用appid,sub:下级应用appid
*/
public function __construct(array $certPath, array $mchid, string $apiv3Key = null, array $appid = [])
{
// 证书
if (isset($certPath['public'])) {
$this->sslCertPath = 'file:///' . $certPath['public'];
}
if (isset($certPath['private'])) {
$this->sslKeyPath = 'file:///' . $certPath['private'];
}

if (isset($certPath['platform'])) {
$this->platformCertPath = 'file:///' . $certPath['platform'];
}

// 商户号
$this->mchid = $mchid['sp'];

if (isset($mchid['sub'])) {
$this->subMchid = $mchid['sub'];
}


// API KEY
$this->apiv3Key = $apiv3Key;


// APPID
if (isset($appid['sp'])) {
$this->appid = $appid['sp'];
}
if (isset($appid['sub'])) {
$this->subAppid = $appid['sub'];
}

$this->init();
}

public function init()
{
// 设置参数

// 商户号
$merchantId = $this->mchid; //'1633500065';

// 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
// $merchantPrivateKeyFilePath = $this->sslKeyPath; //'file:///' . dirname(__DIR__, 3) . '/demo/pay/cert/apiclient_key.pem';
// $merchantPublicKeyFilePath = $this->sslCertPath; //'file:///' . dirname(__DIR__, 3) . '/demo/pay/cert/apiclient_key.pem';
$merchantPrivateKeyInstance = Rsa::from($this->sslKeyPath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = PemUtil::parseCertificateSerialNo($this->sslCertPath);
// $merchantCertificateSerial = '74D657DDCBB881F684BA1D94A0CCE6453B4E86F7';
// 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
// $platformCertificateFilePath = $this->platformCertPath; //'file:///' . dirname(__DIR__, 3) . '/demo/pay/cert/wechatpay_39C8FA681DDDB06C88C8D851294CDA5E86376089.pem';
$platformPublicKeyInstance = Rsa::from($this->platformCertPath, Rsa::KEY_TYPE_PUBLIC);

// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($this->platformCertPath);

// 构造一个 APIv3 客户端实例
$this->instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $platformPublicKeyInstance,
],
]);

// // 发送请求
// $resp = $instance->chain('v3/certificates')->get(
// ['debug' => true] // 调试模式,https://docs.guzzlephp.org/en/stable/request-options.html#debug
// );
// echo $resp->getBody(), PHP_EOL;
}

protected function post(string $chain, array $body)
{
// var_dump($body);
try {
$resp = $this->instance
->chain($chain)
->post(['json' => $body]);
// var_dump($resp->getStatusCode());
// var_dump($resp->getBody());
return (array)json_decode($resp->getBody(), true);
} catch (\Exception $e) {
// 进行错误处理
$code = $e->getCode();
// var_dump($e->getCode());
$message = $e->getMessage();
$content = compact('code', 'message');
// var_dump($e->getMessage());
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$r = $e->getResponse();
// var_dump($r->getStatusCode());
// var_dump($r->getReasonPhrase());
// var_dump(json_decode($r->getBody(), true));
$content = json_decode($r->getBody(), true);
}
// var_dump($e->getTraceAsString());
throw new LWechatException($content['message'], $content['code'], $content);
}
}

protected function get(string $chain, array $body)
{
// var_dump($body);
try {
$resp = $this->instance
->chain($chain)
->get(['query' => $body]);
// var_dump($resp->getStatusCode());
// var_dump($resp->getBody());
return (array)json_decode($resp->getBody(), true);
} catch (\Exception $e) {
// 进行错误处理
$code = $e->getCode();
// var_dump($e->getCode());
$message = $e->getMessage();
$content = compact('code', 'message');
// var_dump($e->getMessage());
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$r = $e->getResponse();
// var_dump($r->getStatusCode());
// var_dump($r->getReasonPhrase());
// var_dump(json_decode($r->getBody(), true));
$content = json_decode($r->getBody(), true);
}
// var_dump($e->getTraceAsString());
throw new LWechatException($content['message'], $content['code'], $content);
}
}

/**
* 整理接口返回结果
*
* @description
* @example
* @author LittleMo 25362583@qq.com
* @since 2021-11-12
* @version 2021-11-12
* @param sring $result
* @return void
*/
protected function parseResult($result = '', $error_field = 'result_code', $error_code = 'SUCCESS')
{

$code = $result['code'];
$content = $result['content'];

if ($code !== 200 || $content === false) {
throw new LWechatException($result['error_des']);
}
$content = simplexml_load_string($content, "SimpleXMLElement", LIBXML_NOCDATA);

This comment has been minimized.

Copy link
@TheNorthMemory

TheNorthMemory Dec 30, 2022

simplexml_load_string只使用LIBXML_NOCDATA,安全等级可能不够,PHP版本小于8的时候,未包含 LIBXML_NONET 声明,可能存在 xss 远程注入风险。
建议用 \WeChatPay\Transformer::toArray($content); 代替

This comment has been minimized.

Copy link
@littlemolh

littlemolh Dec 30, 2022

Owner

simplexml_load_string只使用LIBXML_NOCDATA,安全等级可能不够,PHP版本小于8的时候,未包含 LIBXML_NONET 声明,可能存在 xss 远程注入风险。 建议用 \WeChatPay\Transformer::toArray($content); 代替

好的

$content = $content !== false ? json_encode($content) : $content;
$content = $content !== false ? json_decode($content) : $content;
if ($content->$error_field != $error_code) {
throw new LWechatException($content->err_code_des, $content->err_code, $content);
}
return $content;
}
}
Loading

0 comments on commit 65f95be

Please sign in to comment.