File: /www/wwwroot/my.esfyn.top/vendor/overtrue/wechat/src/MicroMerchant/Kernel/BaseClient.php
<?php
/*
* This file is part of the overtrue/wechat.
*
* (c) overtrue <i@overtrue.me>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace EasyWeChat\MicroMerchant\Kernel;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Support;
use EasyWeChat\MicroMerchant\Application;
use EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException;
use EasyWeChat\Payment\Kernel\BaseClient as PaymentBaseClient;
/**
* Class BaseClient.
*
* @author liuml <liumenglei0211@163.com>
* @DateTime 2019-07-10 12:06
*/
class BaseClient extends PaymentBaseClient
{
/**
* @var string
*/
protected $certificates;
/**
* BaseClient constructor.
*/
public function __construct(Application $app)
{
$this->app = $app;
$this->setHttpClient($this->app['http_client']);
}
/**
* Extra request params.
*
* @return array
*/
protected function prepends()
{
return [];
}
/**
* httpUpload.
*
* @param bool $returnResponse
*
* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
*
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function httpUpload(string $url, array $files = [], array $form = [], array $query = [], $returnResponse = false)
{
$multipart = [];
foreach ($files as $name => $path) {
$multipart[] = [
'name' => $name,
'contents' => fopen($path, 'r'),
];
}
$base = [
'mch_id' => $this->app['config']['mch_id'],
];
$form = array_merge($base, $form);
$form['sign'] = $this->getSign($form);
foreach ($form as $name => $contents) {
$multipart[] = compact('name', 'contents');
}
$options = [
'query' => $query,
'multipart' => $multipart,
'connect_timeout' => 30,
'timeout' => 30,
'read_timeout' => 30,
'cert' => $this->app['config']->get('cert_path'),
'ssl_key' => $this->app['config']->get('key_path'),
];
$this->pushMiddleware($this->logMiddleware(), 'log');
$response = $this->performRequest($url, 'POST', $options);
$result = $returnResponse ? $response : $this->castResponseToType($response, $this->app->config->get('response_type'));
// auto verify signature
if ($returnResponse || 'array' !== ($this->app->config->get('response_type') ?? 'array')) {
$this->app->verifySignature($this->castResponseToType($response, 'array'));
} else {
$this->app->verifySignature($result);
}
return $result;
}
/**
* request.
*
* @param string $method
* @param bool $returnResponse
*
* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
*
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function request(string $endpoint, array $params = [], $method = 'post', array $options = [], $returnResponse = false)
{
$base = [
'mch_id' => $this->app['config']['mch_id'],
];
$params = array_merge($base, $this->prepends(), $params);
$params['sign'] = $this->getSign($params);
$options = array_merge([
'body' => Support\XML::build($params),
], $options);
$this->pushMiddleware($this->logMiddleware(), 'log');
$response = $this->performRequest($endpoint, $method, $options);
$result = $returnResponse ? $response : $this->castResponseToType($response, $this->app->config->get('response_type'));
// auto verify signature
if ($returnResponse || 'array' !== ($this->app->config->get('response_type') ?? 'array')) {
$this->app->verifySignature($this->castResponseToType($response, 'array'));
} else {
$this->app->verifySignature($result);
}
return $result;
}
/**
* processing parameters contain fields that require sensitive information encryption.
*
* @return array
*
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException
*/
protected function processParams(array $params)
{
$serial_no = $this->app['config']->get('serial_no');
if (null === $serial_no) {
throw new InvalidArgumentException('config serial_no connot be empty.');
}
$params['cert_sn'] = $serial_no;
$sensitive_fields = $this->getSensitiveFieldsName();
foreach ($params as $k => $v) {
if (in_array($k, $sensitive_fields, true)) {
$params[$k] = $this->encryptSensitiveInformation($v);
}
}
return $params;
}
/**
* To id card, mobile phone number and other fields sensitive information encryption.
*
* @return string
*
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException
*/
protected function encryptSensitiveInformation(string $string)
{
$certificates = $this->app['config']->get('certificate');
if (null === $certificates) {
throw new InvalidArgumentException('config certificate connot be empty.');
}
$encrypted = '';
$publicKeyResource = openssl_get_publickey($certificates);
$f = openssl_public_encrypt($string, $encrypted, $publicKeyResource);
openssl_free_key($publicKeyResource);
if ($f) {
return base64_encode($encrypted);
}
throw new EncryptException('Encryption of sensitive information failed');
}
/**
* get sensitive fields name.
*
* @return array
*/
protected function getSensitiveFieldsName()
{
return [
'id_card_name',
'id_card_number',
'account_name',
'account_number',
'contact',
'contact_phone',
'contact_email',
'legal_person',
'mobile_phone',
'email',
];
}
/**
* getSign.
*
* @return string
*
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
*/
protected function getSign(array $params)
{
$params = array_filter($params);
$key = $this->app->getKey();
$encryptMethod = Support\get_encrypt_method(Support\Arr::get($params, 'sign_type', 'MD5'), $key);
return Support\generate_sign($params, $key, $encryptMethod);
}
}