You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
5.4 KiB
205 lines
5.4 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\MedicalAuth;
|
|
|
|
use App\Utils\Traits\HttpRequest;
|
|
use Exception;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
use JsonException;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
// use JetBrains\PhpStorm\ArrayShape;
|
|
|
|
/**
|
|
* 医保移动支付免密授权 - 微信端
|
|
*
|
|
* @link https://yb.qq.com/yibao-payment/doc?nodeId=83679977515675648
|
|
*/
|
|
class Authorization
|
|
{
|
|
|
|
use HttpRequest;
|
|
|
|
/**
|
|
* 配置数组
|
|
* @var string[]
|
|
*/
|
|
/*#[ArrayShape([
|
|
'app_id' => "string",
|
|
'partner_id' => "string",
|
|
'partner_secret' => "string",
|
|
'channel' => "string",
|
|
'org_chnl_crtf_codg' => "string",
|
|
'org_codg' => "string",
|
|
'org_app_id' => "string",
|
|
'auth_return_url' => "string",
|
|
])]*/
|
|
private array $config;
|
|
|
|
/**
|
|
* 城市编码 441721 香洲区
|
|
* @var string
|
|
*/
|
|
private string $city_code = '441721';
|
|
|
|
/**
|
|
* 授权查询host地址
|
|
* @var string
|
|
*/
|
|
private string $host = 'https://test-receiver.wecity.qq.com';
|
|
// private string $host = 'https://mip-receiver.tengmed.com';
|
|
|
|
/**
|
|
* 免密授权host地址
|
|
* @var string
|
|
*/
|
|
private string $auth_host = 'https://mitest.wecity.qq.com';
|
|
// private string $auth_host = 'https://card.wecity.qq.com';
|
|
|
|
/**
|
|
* Authorization Class Construct.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->config = config('wechat.medical.auth');
|
|
}
|
|
|
|
/**
|
|
* 获取签名
|
|
* @param string $timestamp
|
|
* @return string
|
|
*/
|
|
private function getSign(string $timestamp): string
|
|
{
|
|
return hash_hmac("sha256", $this->config['partner_id'] . $timestamp, $this->config['partner_secret']);
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取RequestId
|
|
* @return string
|
|
*/
|
|
private function getRequestId(): string
|
|
{
|
|
$char_id = strtoupper(md5(uniqid((string)mt_rand(), true)));
|
|
return substr($char_id, 0, 8)
|
|
. substr($char_id, 8, 4)
|
|
. substr($char_id, 12, 4)
|
|
. substr($char_id, 16, 4)
|
|
. substr($char_id, 20, 12);
|
|
}
|
|
|
|
/**
|
|
* 获取毫秒
|
|
* @return int
|
|
*/
|
|
private function getMillisecond(): int
|
|
{
|
|
[$t1, $t2] = explode(' ', microtime());
|
|
return (int)sprintf('%.0f', ((float)$t1 + (float)$t2) * 1000);
|
|
}
|
|
|
|
/**
|
|
* @param string $endpoint
|
|
* @param array $params
|
|
* @param string $method
|
|
* @param array $options
|
|
* @return ResponseInterface|string[]
|
|
*/
|
|
protected function requestHanle(string $endpoint, array $params = [], string $method = 'post', array $options = [])
|
|
{
|
|
$timestamp = $this->getMillisecond();
|
|
$params = array_merge([
|
|
'base_uri' => $this->host,
|
|
'headers' => [
|
|
'god-portal-timestamp' => $timestamp,
|
|
'god-portal-request-id' => $this->getRequestId(),
|
|
'god-portal-signature' => $this->getSign((string)$timestamp),
|
|
],
|
|
'json' => $params
|
|
], $options);
|
|
|
|
try {
|
|
$response = $this->request($endpoint, $method, $params);
|
|
|
|
$this->writerLog($endpoint, $params, $response);
|
|
|
|
return $response;
|
|
|
|
} catch (Exception $e) {
|
|
return [
|
|
'code' => -1,
|
|
//'message' => "{$e->getMessage()} ON {$e->getFile()}:{$e->getLine()}"
|
|
'message' => $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 记录日志
|
|
* @param string $request_url
|
|
* @param mixed $request_data
|
|
* @param mixed $response
|
|
* @return void
|
|
*/
|
|
private function writerLog(string $request_url, mixed $request_data, mixed $response): void
|
|
{
|
|
//写入日志
|
|
$log_content = [
|
|
'[REQUEST TIME] ' . date('Y-m-d H:i:s'),
|
|
'[REQUEST URL] ' . $request_url,
|
|
'[REQUEST PARAM] ' . json_encode($request_data, JSON_UNESCAPED_UNICODE),
|
|
'[RESPONSE PARAM] ' . json_encode($response, JSON_UNESCAPED_UNICODE),
|
|
"\r\n",
|
|
];
|
|
|
|
recordLog('authorization', implode("\r\n", $log_content));
|
|
}
|
|
|
|
/**
|
|
* 获取授权跳转地址
|
|
* @param string $return_url 回调地址
|
|
* @return string
|
|
*/
|
|
public function getAuthRedirectUrl(string $return_url): string
|
|
{
|
|
$url = '/oauth/code';
|
|
$data = [
|
|
'authType' => 2,
|
|
'isDepart' => 2,
|
|
'bizType' => '04107',
|
|
'appid' => $this->config['app_id'],
|
|
'cityCode' => $this->config['city_code'],
|
|
'channel' => $this->config['channel'],
|
|
'orgChnlCrtfCodg' => $this->config['org_chnl_crtf_codg'],
|
|
'orgCodg' => $this->config['org_codg'],
|
|
'orgAppId' => $this->config['org_app_id'],
|
|
'redirectUrl' => $return_url
|
|
];
|
|
|
|
$redirect_url = $this->auth_host . $url . '?' . http_build_query($data);
|
|
|
|
$this->writerLog($url, $data, '');
|
|
|
|
return $redirect_url;
|
|
}
|
|
|
|
/**
|
|
* 查询用户授权
|
|
* @param string $auth_code
|
|
* @param string $open_id
|
|
* @return ResponseInterface|string[]
|
|
* @throws GuzzleException
|
|
*/
|
|
public function userQuery(string $auth_code, string $open_id): array|ResponseInterface
|
|
{
|
|
$uri = '/api/mipuserquery/userQuery/' . $this->config['partner_id'];
|
|
$param = [
|
|
'qrcode' => $auth_code,
|
|
'openid' => $open_id,
|
|
];
|
|
|
|
return $this->requestHanle($uri, $param);
|
|
}
|
|
}
|
|
|