mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-04-06 03:58:04 +08:00
ComposerUpdate
This commit is contained in:
parent
fa08383513
commit
a28f8fb8fd
1
vendor/composer/autoload_classmap.php
vendored
1
vendor/composer/autoload_classmap.php
vendored
@ -296,6 +296,7 @@ return array(
|
||||
'think\\admin\\command\\Database' => $vendorDir . '/zoujingli/think-library/src/command/Database.php',
|
||||
'think\\admin\\command\\Install' => $vendorDir . '/zoujingli/think-library/src/command/Install.php',
|
||||
'think\\admin\\command\\Queue' => $vendorDir . '/zoujingli/think-library/src/command/Queue.php',
|
||||
'think\\admin\\command\\Replace' => $vendorDir . '/zoujingli/think-library/src/command/Replace.php',
|
||||
'think\\admin\\command\\Version' => $vendorDir . '/zoujingli/think-library/src/command/Version.php',
|
||||
'think\\admin\\extend\\CodeExtend' => $vendorDir . '/zoujingli/think-library/src/extend/CodeExtend.php',
|
||||
'think\\admin\\extend\\DataExtend' => $vendorDir . '/zoujingli/think-library/src/extend/DataExtend.php',
|
||||
|
1
vendor/composer/autoload_static.php
vendored
1
vendor/composer/autoload_static.php
vendored
@ -424,6 +424,7 @@ class ComposerStaticInit4f89fd0e0503ccf740f2fa5757825d7b
|
||||
'think\\admin\\command\\Database' => __DIR__ . '/..' . '/zoujingli/think-library/src/command/Database.php',
|
||||
'think\\admin\\command\\Install' => __DIR__ . '/..' . '/zoujingli/think-library/src/command/Install.php',
|
||||
'think\\admin\\command\\Queue' => __DIR__ . '/..' . '/zoujingli/think-library/src/command/Queue.php',
|
||||
'think\\admin\\command\\Replace' => __DIR__ . '/..' . '/zoujingli/think-library/src/command/Replace.php',
|
||||
'think\\admin\\command\\Version' => __DIR__ . '/..' . '/zoujingli/think-library/src/command/Version.php',
|
||||
'think\\admin\\extend\\CodeExtend' => __DIR__ . '/..' . '/zoujingli/think-library/src/extend/CodeExtend.php',
|
||||
'think\\admin\\extend\\DataExtend' => __DIR__ . '/..' . '/zoujingli/think-library/src/extend/DataExtend.php',
|
||||
|
26
vendor/composer/installed.json
vendored
26
vendor/composer/installed.json
vendored
@ -937,12 +937,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zoujingli/ThinkLibrary.git",
|
||||
"reference": "f8a4e65cf6b57531c8536462b30892eae49c7809"
|
||||
"reference": "e1cc4dcb049fc1cedbb99807d235e5bda3dcdf71"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/f8a4e65cf6b57531c8536462b30892eae49c7809",
|
||||
"reference": "f8a4e65cf6b57531c8536462b30892eae49c7809",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/e1cc4dcb049fc1cedbb99807d235e5bda3dcdf71",
|
||||
"reference": "e1cc4dcb049fc1cedbb99807d235e5bda3dcdf71",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -959,7 +959,7 @@
|
||||
"ext-mbstring": "*",
|
||||
"topthink/framework": "^6.0"
|
||||
},
|
||||
"time": "2020-12-18T05:04:10+00:00",
|
||||
"time": "2020-12-26T08:29:41+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
@ -992,17 +992,17 @@
|
||||
},
|
||||
{
|
||||
"name": "zoujingli/wechat-developer",
|
||||
"version": "v1.2.26",
|
||||
"version_normalized": "1.2.26.0",
|
||||
"version": "v1.2.27",
|
||||
"version_normalized": "1.2.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zoujingli/WeChatDeveloper.git",
|
||||
"reference": "5ecafcd810627cd9217c3d7f18c7026612418278"
|
||||
"reference": "94de6626f1c9e3d12f16640c30fb9319b37ff34c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/5ecafcd810627cd9217c3d7f18c7026612418278",
|
||||
"reference": "5ecafcd810627cd9217c3d7f18c7026612418278",
|
||||
"url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/94de6626f1c9e3d12f16640c30fb9319b37ff34c",
|
||||
"reference": "94de6626f1c9e3d12f16640c30fb9319b37ff34c",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -1022,7 +1022,7 @@
|
||||
"ext-xml": "*",
|
||||
"php": ">=5.4"
|
||||
},
|
||||
"time": "2020-09-13T06:01:11+00:00",
|
||||
"time": "2020-12-24T09:44:04+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -1056,10 +1056,6 @@
|
||||
"wechat",
|
||||
"wechatpay",
|
||||
"wepay"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/zoujingli/WeChatDeveloper/issues",
|
||||
"source": "https://github.com/zoujingli/WeChatDeveloper/tree/v1.2.26"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2020-12-23 16:37:11
|
||||
// This file is automatically generated at:2020-12-26 16:45:15
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'think\\admin\\Library',
|
||||
|
@ -18,11 +18,12 @@ namespace think\admin;
|
||||
use think\admin\command\Database;
|
||||
use think\admin\command\Install;
|
||||
use think\admin\command\Queue;
|
||||
use think\admin\command\Replace;
|
||||
use think\admin\command\Version;
|
||||
use think\admin\multiple\BuildUrl;
|
||||
use think\admin\multiple\command\Build;
|
||||
use think\admin\multiple\command\Clear;
|
||||
use think\admin\multiple\Multiple;
|
||||
use think\admin\multiple\BuildUrl;
|
||||
use think\admin\service\AdminService;
|
||||
use think\admin\service\SystemService;
|
||||
use think\middleware\LoadLangPack;
|
||||
@ -41,7 +42,7 @@ class Library extends Service
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
const VERSION = '6.0.22';
|
||||
const VERSION = '6.0.23';
|
||||
|
||||
/**
|
||||
* 启动服务
|
||||
@ -62,7 +63,7 @@ class Library extends Service
|
||||
// 替换 ThinkPHP 指令
|
||||
$this->commands(['build' => Build::class, 'clear' => Clear::class]);
|
||||
// 注册 ThinkAdmin 指令
|
||||
$this->commands([Queue::class, Install::class, Version::class, Database::class]);
|
||||
$this->commands([Queue::class, Install::class, Version::class, Database::class, Replace::class]);
|
||||
// 动态应用运行参数
|
||||
SystemService::instance()->bindRuntime();
|
||||
}
|
||||
|
89
vendor/zoujingli/think-library/src/command/Replace.php
vendored
Normal file
89
vendor/zoujingli/think-library/src/command/Replace.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | Library for ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://gitee.com/zoujingli/ThinkLibrary
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// +----------------------------------------------------------------------
|
||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace think\admin\command;
|
||||
|
||||
use think\admin\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\Output;
|
||||
use think\helper\Str;
|
||||
|
||||
/**
|
||||
* 数据库字符替换
|
||||
* Class Replace
|
||||
* @package app\wechat\command
|
||||
*/
|
||||
class Replace extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('xadmin:replace');
|
||||
$this->addArgument('search', Argument::OPTIONAL, '查找替换的字符内容', '');
|
||||
$this->addArgument('replace', Argument::OPTIONAL, '目标替换的字符内容', '');
|
||||
$this->setDescription('Database Character Field Replace for ThinkAdmin');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行指令
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @throws \think\admin\Exception
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$search = $input->getArgument('search');
|
||||
$repalce = $input->getArgument('replace');
|
||||
if ($search === '') $this->queue->error('查找替换字符内容不能为空!');
|
||||
if ($repalce === '') $this->queue->error('目标替换字符内容不能为空!');
|
||||
|
||||
[$count, $used] = [count($tables = $this->getTables()), 0];
|
||||
foreach ($tables as $table) {
|
||||
$data = [];
|
||||
$this->queue->message($count, ++$used, sprintf("准备替换数据表 %s", Str::studly($table)));
|
||||
foreach ($this->app->db->table($table)->getFields() as $field => $attrs) {
|
||||
if (preg_match('/char|text/', $attrs['type'])) {
|
||||
$data[$field] = $this->app->db->raw(sprintf('REPLACE(`%s`,"%s","%s")', $field, $search, $repalce));
|
||||
}
|
||||
}
|
||||
if (count($data) > 0) {
|
||||
if ($this->app->db->table($table)->where('1=1')->update($data) !== false) {
|
||||
$this->queue->message($count, $used, sprintf("成功替换数据表 %s", Str::studly($table)), 1);
|
||||
} else {
|
||||
$this->queue->message($count, $used, sprintf("失败替换数据表 %s", Str::studly($table)), 1);
|
||||
}
|
||||
} else {
|
||||
$this->queue->message($count, $used, sprintf("无需替换数据表 %s", Str::studly($table)), 1);
|
||||
}
|
||||
}
|
||||
$this->queue->success('批量替换成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库的数据表
|
||||
* @return array
|
||||
*/
|
||||
protected function getTables(): array
|
||||
{
|
||||
$tables = [];
|
||||
foreach ($this->app->db->query("show tables") as $item) {
|
||||
$tables = array_merge($tables, array_values($item));
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
}
|
3
vendor/zoujingli/wechat-developer/We.php
vendored
3
vendor/zoujingli/wechat-developer/We.php
vendored
@ -28,6 +28,7 @@ use WeChat\Exceptions\InvalidInstanceException;
|
||||
* @method \AliPay\Bill AliPayBill($options) static 支付宝电子面单下载
|
||||
* @method \AliPay\Pos AliPayPos($options) static 支付宝刷卡支付
|
||||
* @method \AliPay\Scan AliPayScan($options) static 支付宝扫码支付
|
||||
* @method \AliPay\Trade AliPayTrade($options) static 支付宝标准接口
|
||||
* @method \AliPay\Transfer AliPayTransfer($options) static 支付宝转账到账户
|
||||
* @method \AliPay\Wap AliPayWap($options) static 支付宝手机网站支付
|
||||
* @method \AliPay\Web AliPayWeb($options) static 支付宝网站支付
|
||||
@ -86,7 +87,7 @@ class We
|
||||
* 定义当前版本
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.2.26';
|
||||
const VERSION = '1.2.27';
|
||||
|
||||
/**
|
||||
* 静态配置
|
||||
|
@ -128,21 +128,21 @@ class BasicWeChat
|
||||
|
||||
/**
|
||||
* 设置外部接口 AccessToken
|
||||
* @param string $access_token
|
||||
* @param string $accessToken
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @author 高一平 <iam@gaoyiping.com>
|
||||
*
|
||||
* 当用户使用自己的缓存驱动时,直接实例化对象后可直接设置 AccessToekn
|
||||
* 当用户使用自己的缓存驱动时,直接实例化对象后可直接设置 AccessToken
|
||||
* - 多用于分布式项目时保持 AccessToken 统一
|
||||
* - 使用此方法后就由用户来保证传入的 AccessToekn 为有效 AccessToekn
|
||||
* - 使用此方法后就由用户来保证传入的 AccessToken 为有效 AccessToken
|
||||
*/
|
||||
public function setAccessToken($access_token)
|
||||
public function setAccessToken($accessToken)
|
||||
{
|
||||
if (!is_string($access_token)) {
|
||||
if (!is_string($accessToken)) {
|
||||
throw new InvalidArgumentException("Invalid AccessToken type, need string.");
|
||||
}
|
||||
$cache = $this->config->get('appid') . '_access_token';
|
||||
Tools::setCache($cache, $this->access_token = $access_token);
|
||||
Tools::setCache($cache, $this->access_token = $accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,8 +169,7 @@ class BasicWeChat
|
||||
} catch (InvalidResponseException $exception) {
|
||||
if (isset($this->currentMethod['method']) && empty($this->isTry)) {
|
||||
if (in_array($exception->getCode(), ['40014', '40001', '41001', '42001'])) {
|
||||
$this->delAccessToken();
|
||||
$this->isTry = true;
|
||||
[$this->delAccessToken(), $this->isTry = true];
|
||||
return call_user_func_array([$this, $this->currentMethod['method']], $this->currentMethod['arguments']);
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ class Tools
|
||||
return call_user_func_array(self::$cache_callable['get'], func_get_args());
|
||||
}
|
||||
$file = self::_getCacheName($name);
|
||||
if (file_exists($file) && ($content = file_get_contents($file))) {
|
||||
if (file_exists($file) && is_file($file) && ($content = file_get_contents($file))) {
|
||||
$data = unserialize($content);
|
||||
if (isset($data['expired']) && (intval($data['expired']) === 0 || intval($data['expired']) >= time())) {
|
||||
return $data['value'];
|
||||
|
@ -16,6 +16,7 @@ namespace WePay;
|
||||
|
||||
use WeChat\Contracts\BasicWePay;
|
||||
use WeChat\Contracts\Tools;
|
||||
use WeChat\Exceptions\InvalidDecryptException;
|
||||
use WeChat\Exceptions\InvalidResponseException;
|
||||
|
||||
/**
|
||||
@ -55,6 +56,7 @@ class Refund extends BasicWePay
|
||||
/**
|
||||
* 获取退款通知
|
||||
* @return array
|
||||
* @throws InvalidDecryptException
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function getNotify()
|
||||
@ -63,16 +65,14 @@ class Refund extends BasicWePay
|
||||
if (!isset($data['return_code']) || $data['return_code'] !== 'SUCCESS') {
|
||||
throw new InvalidResponseException('获取退款通知XML失败!');
|
||||
}
|
||||
if (!class_exists('Prpcrypt', false)) {
|
||||
include dirname(__DIR__) . '/WeChat/Contracts/Prpcrypt.php';
|
||||
try {
|
||||
$key = md5($this->config->get('mch_key'));
|
||||
$decrypt = base64_decode($data['req_info']);
|
||||
$response = openssl_decrypt($decrypt, 'aes-256-ecb', $key, OPENSSL_RAW_DATA);
|
||||
$data['result'] = Tools::xml2arr($response);
|
||||
return $data;
|
||||
} catch (\Exception $exception) {
|
||||
throw new InvalidDecryptException($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
$pc = new \Prpcrypt(md5($this->config->get('mch_key')));
|
||||
$array = $pc->decrypt(base64_decode($data['req_info']));
|
||||
if (intval($array[0]) > 0) {
|
||||
throw new InvalidResponseException($array[1], $array[0]);
|
||||
}
|
||||
$data['decode'] = $array[1];
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
49
vendor/zoujingli/wechat-developer/WePayV3/Cert.php
vendored
Normal file
49
vendor/zoujingli/wechat-developer/WePayV3/Cert.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://think.ctolog.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// +----------------------------------------------------------------------
|
||||
// | github开源项目:https://github.com/zoujingli/WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace WePayV3;
|
||||
|
||||
use WeChat\Exceptions\InvalidResponseException;
|
||||
use WePayV3\Contracts\BasicWePay;
|
||||
use WePayV3\Contracts\DecryptAes;
|
||||
|
||||
/**
|
||||
* 平台证书管理
|
||||
* Class Cert
|
||||
* @package WePayV3
|
||||
*/
|
||||
class Cert extends BasicWePay
|
||||
{
|
||||
|
||||
/**
|
||||
* 商户平台下载证书
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function download()
|
||||
{
|
||||
try {
|
||||
$aes = new DecryptAes($this->config['mch_v3_key']);
|
||||
$result = $this->doRequest('GET', '/v3/certificates');
|
||||
foreach ($result['data'] as $vo) {
|
||||
$this->tmpFile($vo['serial_no'], $aes->decryptToString(
|
||||
$vo['encrypt_certificate']['associated_data'],
|
||||
$vo['encrypt_certificate']['nonce'],
|
||||
$vo['encrypt_certificate']['ciphertext']
|
||||
));
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new InvalidResponseException($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
}
|
||||
}
|
219
vendor/zoujingli/wechat-developer/WePayV3/Contracts/BasicWePay.php
vendored
Normal file
219
vendor/zoujingli/wechat-developer/WePayV3/Contracts/BasicWePay.php
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://think.ctolog.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// +----------------------------------------------------------------------
|
||||
// | github开源项目:https://github.com/zoujingli/WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace WePayV3\Contracts;
|
||||
|
||||
use WeChat\Contracts\Tools;
|
||||
use WeChat\Exceptions\InvalidArgumentException;
|
||||
use WeChat\Exceptions\InvalidResponseException;
|
||||
use WeChat\Exceptions\LocalCacheException;
|
||||
use WePayV3\Cert;
|
||||
|
||||
/**
|
||||
* 微信支付基础类
|
||||
* Class BasicWePay
|
||||
* @package WePayV3
|
||||
*/
|
||||
abstract class BasicWePay
|
||||
{
|
||||
/**
|
||||
* 接口基础地址
|
||||
* @var string
|
||||
*/
|
||||
protected $base = 'https://api.mch.weixin.qq.com';
|
||||
|
||||
/**
|
||||
* 实例对象静态缓存
|
||||
* @var array
|
||||
*/
|
||||
static $cache = [];
|
||||
|
||||
/**
|
||||
* 配置参数
|
||||
* @var array
|
||||
*/
|
||||
protected $config = [
|
||||
'appid' => '', // 微信绑定APPID,需配置
|
||||
'mch_id' => '', // 微信商户编号,需要配置
|
||||
'mch_v3_key' => '', // 微信商户密钥,需要配置
|
||||
'cert_serial' => '', // 商户证书序号,无需配置
|
||||
'cert_public' => '', // 商户公钥内容,需要配置
|
||||
'cert_private' => '', // 商户密钥内容,需要配置
|
||||
];
|
||||
|
||||
/**
|
||||
* BasicWePayV3 constructor.
|
||||
* @param array $options [mch_id, mch_v3_key, cert_public, cert_private]
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
if (empty($options['mch_id'])) {
|
||||
throw new InvalidArgumentException("Missing Config -- [mch_id]");
|
||||
}
|
||||
if (empty($options['mch_v3_key'])) {
|
||||
throw new InvalidArgumentException("Missing Config -- [mch_v3_key]");
|
||||
}
|
||||
if (empty($options['cert_private'])) {
|
||||
throw new InvalidArgumentException("Missing Config -- [cert_private]");
|
||||
}
|
||||
if (empty($options['cert_public'])) {
|
||||
throw new InvalidArgumentException("Missing Config -- [cert_public]");
|
||||
}
|
||||
|
||||
$this->config['appid'] = isset($options['appid']) ? $options['appid'] : '';
|
||||
$this->config['mch_id'] = $options['mch_id'];
|
||||
$this->config['mch_v3_key'] = $options['mch_v3_key'];
|
||||
$this->config['cert_public'] = $options['cert_public'];
|
||||
$this->config['cert_private'] = $options['cert_private'];
|
||||
$this->config['cert_serial'] = openssl_x509_parse($this->config['cert_public'])['serialNumberHex'];
|
||||
|
||||
if (empty($this->config['cert_serial'])) {
|
||||
throw new InvalidArgumentException("Failed to parse certificate public key");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态创建对象
|
||||
* @param array $config
|
||||
* @return static
|
||||
*/
|
||||
public static function instance(array $config)
|
||||
{
|
||||
$key = md5(get_called_class() . serialize($config));
|
||||
if (isset(self::$cache[$key])) return self::$cache[$key];
|
||||
return self::$cache[$key] = new static($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟发起请求
|
||||
* @param string $method 请求访问
|
||||
* @param string $pathinfo 请求路由
|
||||
* @param string $jsondata 请求数据
|
||||
* @param bool $verify 是否验证
|
||||
* @return array
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function doRequest($method, $pathinfo, $jsondata = '', $verify = false)
|
||||
{
|
||||
list($time, $nonce) = [time(), uniqid() . rand(1000, 9999)];
|
||||
$signstr = join("\n", [$method, $pathinfo, $time, $nonce, $jsondata, '']);
|
||||
// 生成数据签名TOKEN
|
||||
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
|
||||
$this->config['mch_id'], $nonce, $time, $this->config['cert_serial'], $this->signBuild($signstr)
|
||||
);
|
||||
list($header, $content) = $this->_doRequestCurl($method, $this->base . $pathinfo, [
|
||||
'data' => $jsondata, 'header' => [
|
||||
"Accept: application/json", "Content-Type: application/json",
|
||||
'User-Agent: https://thinkadmin.top', "Authorization: WECHATPAY2-SHA256-RSA2048 {$token}",
|
||||
],
|
||||
]);
|
||||
if ($verify) {
|
||||
$headers = [];
|
||||
foreach (explode("\n", $header) as $line) {
|
||||
if (stripos($line, 'Wechatpay') !== false) {
|
||||
list($name, $value) = explode(':', $line);
|
||||
list(, $keys) = explode('wechatpay-', strtolower($name));
|
||||
$headers[$keys] = trim($value);
|
||||
}
|
||||
}
|
||||
try {
|
||||
$string = join("\n", [$headers['timestamp'], $headers['nonce'], $content, '']);
|
||||
if (!$this->signVerify($string, $headers['signature'], $headers['serial'])) {
|
||||
throw new InvalidResponseException("验证响应签名失败");
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new InvalidResponseException($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
}
|
||||
return json_decode($content, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过CURL模拟网络请求
|
||||
* @param string $method 请求方法
|
||||
* @param string $location 请求方法
|
||||
* @param array $options 请求参数 [data, header]
|
||||
* @return array [header,content]
|
||||
*/
|
||||
private function _doRequestCurl($method, $location, $options = [])
|
||||
{
|
||||
$curl = curl_init();
|
||||
// POST数据设置
|
||||
if (strtolower($method) === 'post') {
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $options['data']);
|
||||
}
|
||||
// CURL头信息设置
|
||||
if (!empty($options['header'])) {
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $options['header']);
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_URL, $location);
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$content = curl_exec($curl);
|
||||
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
|
||||
curl_close($curl);
|
||||
return [substr($content, 0, $headerSize), substr($content, $headerSize)];
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成数据签名
|
||||
* @param string $data 签名内容
|
||||
* @return string
|
||||
*/
|
||||
protected function signBuild($data)
|
||||
{
|
||||
$pkeyid = openssl_pkey_get_private($this->config['cert_private']);
|
||||
openssl_sign($data, $signature, $pkeyid, 'sha256WithRSAEncryption');
|
||||
return base64_encode($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证内容签名
|
||||
* @param string $data 签名内容
|
||||
* @param string $sign 原签名值
|
||||
* @param string $serial 证书序号
|
||||
* @return int
|
||||
* @throws InvalidResponseException
|
||||
* @throws LocalCacheException
|
||||
*/
|
||||
protected function signVerify($data, $sign, $serial = '')
|
||||
{
|
||||
$cert = $this->tmpFile($serial);
|
||||
if (empty($cert)) {
|
||||
Cert::instance($this->config)->download();
|
||||
$cert = $this->tmpFile($serial);
|
||||
}
|
||||
return @openssl_verify($data, base64_decode($sign), openssl_x509_read($cert), 'sha256WithRSAEncryption');
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入或读取临时文件
|
||||
* @param string $name
|
||||
* @param null|string $content
|
||||
* @return string
|
||||
* @throws LocalCacheException
|
||||
*/
|
||||
protected function tmpFile($name, $content = null)
|
||||
{
|
||||
if (is_null($content)) {
|
||||
return base64_decode(Tools::getCache($name) ?: '');
|
||||
} else {
|
||||
return Tools::setCache($name, base64_encode($content), 7200);
|
||||
}
|
||||
}
|
||||
}
|
81
vendor/zoujingli/wechat-developer/WePayV3/Contracts/DecryptAes.php
vendored
Normal file
81
vendor/zoujingli/wechat-developer/WePayV3/Contracts/DecryptAes.php
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://think.ctolog.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// +----------------------------------------------------------------------
|
||||
// | github开源项目:https://github.com/zoujingli/WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace WePayV3\Contracts;
|
||||
|
||||
use WeChat\Exceptions\InvalidArgumentException;
|
||||
use WeChat\Exceptions\InvalidDecryptException;
|
||||
|
||||
/**
|
||||
* Aes 解密工具类
|
||||
* Class DecryptAes
|
||||
* @package WePayV3\Contracts
|
||||
*/
|
||||
class DecryptAes
|
||||
{
|
||||
|
||||
private $aesKey;
|
||||
|
||||
const KEY_LENGTH_BYTE = 32;
|
||||
const AUTH_TAG_LENGTH_BYTE = 16;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $aesKey
|
||||
*/
|
||||
public function __construct($aesKey)
|
||||
{
|
||||
if (strlen($aesKey) != self::KEY_LENGTH_BYTE) {
|
||||
throw new InvalidArgumentException('无效的ApiV3Key,长度应为32个字节');
|
||||
}
|
||||
$this->aesKey = $aesKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt AEAD_AES_256_GCM ciphertext
|
||||
* @param string $associatedData AES GCM additional authentication data
|
||||
* @param string $nonceStr AES GCM nonce
|
||||
* @param string $ciphertext AES GCM cipher text
|
||||
* @return string|bool Decrypted string on success or FALSE on failure
|
||||
* @throws InvalidDecryptException
|
||||
*/
|
||||
public function decryptToString($associatedData, $nonceStr, $ciphertext)
|
||||
{
|
||||
$ciphertext = \base64_decode($ciphertext);
|
||||
if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// ext-sodium (default installed on >= PHP 7.2)
|
||||
if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
|
||||
return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey);
|
||||
}
|
||||
// ext-libsodium (need install libsodium-php 1.x via pecl)
|
||||
if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) {
|
||||
return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey);
|
||||
}
|
||||
// openssl (PHP >= 7.1 support AEAD)
|
||||
if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
|
||||
$ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
|
||||
$authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);
|
||||
return \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new InvalidDecryptException($exception->getMessage(), $exception->getCode());
|
||||
} catch (\SodiumException $exception) {
|
||||
throw new InvalidDecryptException($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
throw new InvalidDecryptException('AEAD_AES_256_GCM 需要 PHP 7.1 以上或者安装 libsodium-php');
|
||||
}
|
||||
}
|
106
vendor/zoujingli/wechat-developer/WePayV3/Order.php
vendored
Normal file
106
vendor/zoujingli/wechat-developer/WePayV3/Order.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://think.ctolog.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// +----------------------------------------------------------------------
|
||||
// | github开源项目:https://github.com/zoujingli/WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace WePayV3;
|
||||
|
||||
use WeChat\Contracts\Tools;
|
||||
use WeChat\Exceptions\InvalidArgumentException;
|
||||
use WeChat\Exceptions\InvalidDecryptException;
|
||||
use WeChat\Exceptions\InvalidResponseException;
|
||||
use WePayV3\Contracts\BasicWePay;
|
||||
use WePayV3\Contracts\DecryptAes;
|
||||
|
||||
/**
|
||||
* 订单支付接口
|
||||
* Class Order
|
||||
* @package WePayV3
|
||||
*/
|
||||
class Order extends BasicWePay
|
||||
{
|
||||
const WXPAY_H5 = 'h5';
|
||||
const WXPAY_APP = 'app';
|
||||
const WXPAY_JSAPI = 'jsapi';
|
||||
const WXPAY_NATIVE = 'native';
|
||||
|
||||
/**
|
||||
* 创建支付订单
|
||||
* @param string $type 支付类型
|
||||
* @param array $data 支付参数
|
||||
* @return array
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function create($type, $data)
|
||||
{
|
||||
$types = [
|
||||
'h5' => '/v3/pay/transactions/h5',
|
||||
'app' => '/v3/pay/transactions/app',
|
||||
'jsapi' => '/v3/pay/transactions/jsapi',
|
||||
'native' => '/v3/pay/transactions/native',
|
||||
];
|
||||
if (empty($types[$type])) {
|
||||
throw new InvalidArgumentException("Payment {$type} not defined.");
|
||||
} else {
|
||||
// 创建预支付码
|
||||
$result = $this->doRequest('POST', $types[$type], json_encode($data, JSON_UNESCAPED_UNICODE), true);
|
||||
if (empty($result['prepay_id'])) return $result;
|
||||
// 支付参数签名
|
||||
$time = (string)time();
|
||||
$appid = $this->config['appid'];
|
||||
$prepayId = $result['prepay_id'];
|
||||
$nonceStr = Tools::createNoncestr();
|
||||
if ($type === 'app') {
|
||||
$sign = $this->signBuild(join("\n", [$appid, $time, $nonceStr, $prepayId]));
|
||||
return ['partnerId' => $this->config['mch_id'], 'prepayId' => $prepayId, 'package' => 'Sign=WXPay', 'nonceStr' => $nonceStr, 'timeStamp' => $time, 'sign' => $sign];
|
||||
} elseif ($type === 'jsapi') {
|
||||
$sign = $this->signBuild(join("\n", [$appid, $time, $nonceStr, "prepay_id={$prepayId}"]));
|
||||
return ['appId' => $appid, 'timeStamp' => $time, 'nonceStr' => $nonceStr, 'package' => "prepay_id={$prepayId}", 'signType' => 'RSA', 'paySign' => $sign];
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单查询
|
||||
* @param string $orderNo 订单单号
|
||||
* @return array
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function query($orderNo)
|
||||
{
|
||||
$pathinfo = "/v3/pay/transactions/out-trade-no/{$orderNo}";
|
||||
return $this->doRequest('GET', "{$pathinfo}?mchid={$this->config['mch_id']}", '', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付通知
|
||||
* @return array
|
||||
* @throws InvalidDecryptException
|
||||
*/
|
||||
public function notify()
|
||||
{
|
||||
$body = file_get_contents('php://input');
|
||||
$data = json_decode($body, true);
|
||||
if (isset($data['resource'])) {
|
||||
$aes = new DecryptAes($this->config['mch_v3_key']);
|
||||
$data['result'] = $aes->decryptToString(
|
||||
$data['resource']['associated_data'],
|
||||
$data['resource']['nonce'],
|
||||
$data['resource']['ciphertext']
|
||||
);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
75
vendor/zoujingli/wechat-developer/WePayV3/Refund.php
vendored
Normal file
75
vendor/zoujingli/wechat-developer/WePayV3/Refund.php
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://think.ctolog.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( https://mit-license.org )
|
||||
// +----------------------------------------------------------------------
|
||||
// | github开源项目:https://github.com/zoujingli/WeChatDeveloper
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace WePayV3;
|
||||
|
||||
use WeChat\Contracts\Tools;
|
||||
use WeChat\Exceptions\InvalidDecryptException;
|
||||
use WeChat\Exceptions\InvalidResponseException;
|
||||
use WePayV3\Contracts\BasicWePay;
|
||||
|
||||
/**
|
||||
* 订单退款接口
|
||||
* Class Refund
|
||||
* @package WePayV3
|
||||
*/
|
||||
class Refund extends BasicWePay
|
||||
{
|
||||
/**
|
||||
* 创建退款订单
|
||||
* @param array $data 退款参数
|
||||
* @return array
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function create($data)
|
||||
{
|
||||
return $this->doRequest('POST', '/v3/ecommerce/refunds/apply', json_encode($data, JSON_UNESCAPED_UNICODE), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款订单查询
|
||||
* @param string $refundNo 退款单号
|
||||
* @return array
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function query($refundNo)
|
||||
{
|
||||
$pathinfo = "/v3/ecommerce/refunds/out-refund-no/{$refundNo}";
|
||||
return $this->doRequest('GET', "{$pathinfo}?sub_mchid={$this->config['mch_id']}", '', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取退款通知
|
||||
* @return array
|
||||
* @throws InvalidDecryptException
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function notify()
|
||||
{
|
||||
$data = Tools::xml2arr(file_get_contents("php://input"));
|
||||
if (!isset($data['return_code']) || $data['return_code'] !== 'SUCCESS') {
|
||||
throw new InvalidResponseException('获取退款通知XML失败!');
|
||||
}
|
||||
try {
|
||||
$key = md5($this->config['mch_v3_key']);
|
||||
$decrypt = base64_decode($data['req_info']);
|
||||
$response = openssl_decrypt($decrypt, 'aes-256-ecb', $key, OPENSSL_RAW_DATA);
|
||||
$data['result'] = Tools::xml2arr($response);
|
||||
return $data;
|
||||
} catch (\Exception $exception) {
|
||||
throw new InvalidDecryptException($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
16
vendor/zoujingli/wechat-developer/_test/pay-v3-config-cert.php
vendored
Normal file
16
vendor/zoujingli/wechat-developer/_test/pay-v3-config-cert.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
try {
|
||||
// 1. 手动加载入口文件
|
||||
include "../include.php";
|
||||
|
||||
// 2. 准备公众号配置参数
|
||||
$config = include "./pay-v3-config.php";
|
||||
|
||||
$payment = \WePayV3\Cert::instance($config);
|
||||
|
||||
$payment->download();
|
||||
|
||||
} catch (\Exception $exception) {
|
||||
// 出错啦,处理下吧
|
||||
echo $exception->getMessage() . PHP_EOL;
|
||||
}
|
17
vendor/zoujingli/wechat-developer/_test/pay-v3-config.php
vendored
Normal file
17
vendor/zoujingli/wechat-developer/_test/pay-v3-config.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'appid' => '绑定的APPID',
|
||||
'mch_id' => '您的商户编号',
|
||||
'mch_v3_key' => '您的V3接口密码',
|
||||
'cert_public' => <<<EOF
|
||||
-----BEGIN CERTIFICATE-----
|
||||
您的证书内容
|
||||
-----END CERTIFICATE-----
|
||||
EOF,
|
||||
'cert_private' => <<<EOF
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
您的证书内容
|
||||
-----END PRIVATE KEY-----
|
||||
EOF,
|
||||
];
|
30
vendor/zoujingli/wechat-developer/_test/pay-v3-order-create.php
vendored
Normal file
30
vendor/zoujingli/wechat-developer/_test/pay-v3-order-create.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
try {
|
||||
// 1. 手动加载入口文件
|
||||
include "../include.php";
|
||||
|
||||
// 2. 准备公众号配置参数
|
||||
$config = include "./pay-v3-config.php";
|
||||
|
||||
// 3. 创建接口实例
|
||||
$payment = \WePayV3\Order::instance($config);
|
||||
|
||||
// 4. 组装支付参数
|
||||
$result = $payment->create('jsapi', [
|
||||
'appid' => 'wx60a43dd8161666d4',
|
||||
'mchid' => $config['mch_id'],
|
||||
'description' => '商品描述',
|
||||
'out_trade_no' => date("YmdHis"),
|
||||
'notify_url' => 'https://thinkadmin.top',
|
||||
'payer' => ['openid' => 'o38gps3vNdCqaggFfrBRCRikwlWY'],
|
||||
'amount' => ['total' => 1, 'currency' => 'CNY'],
|
||||
]);
|
||||
|
||||
echo '<pre>';
|
||||
echo "\n--- 创建支付参数 ---\n";
|
||||
var_export($result);
|
||||
|
||||
} catch (\Exception $exception) {
|
||||
// 出错啦,处理下吧
|
||||
echo $exception->getMessage() . PHP_EOL;
|
||||
}
|
8
vendor/zoujingli/wechat-developer/readme.md
vendored
8
vendor/zoujingli/wechat-developer/readme.md
vendored
@ -11,6 +11,7 @@ WeChatDeveloper for PHP
|
||||
* 微信的部分接口需要缓存数据在本地,因此对目录需要有写权限;
|
||||
* 我们鼓励大家使用 composer 来管理您的第三方库,方便后期更新操作;
|
||||
* WeChatDeveloper 已历经数个线上项目考验,欢迎 fork 或 star 此项目。
|
||||
* 微信商户支持已经支持 v2 接口,组件开发版支持 v3 接口。
|
||||
|
||||
功能描述
|
||||
----
|
||||
@ -260,8 +261,5 @@ try {
|
||||
* WeChatDeveloper 基于`MIT`协议发布,任何人可以用在任何地方,不受约束
|
||||
* WeChatDeveloper 部分代码来自互联网,若有异议,可以联系作者进行删除
|
||||
|
||||
赞助支持
|
||||
----
|
||||

|
||||
|
||||
|
||||
## 赞助打赏
|
||||

|
||||
|
Loading…
x
Reference in New Issue
Block a user