支付凭证优化
This commit is contained in:
@@ -31,6 +31,8 @@ class EasyWeChatService
|
||||
$this->app = new MiniAppApplication([
|
||||
'app_id' => $this->config['app_id'],
|
||||
'secret' => $this->config['secret'],
|
||||
// 稳定版凭证重复获取不会把上一张作废。旧接口并发刷新会返回 40001
|
||||
'use_stable_access_token' => true,
|
||||
'http' => ['throw' => false, 'timeout' => 10.0],
|
||||
]);
|
||||
|
||||
@@ -46,6 +48,24 @@ class EasyWeChatService
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新小程序 access_token。普通刷新不会使有效凭证失效;force 只在微信返回凭证无效时使用
|
||||
* @param bool $force
|
||||
* @return string
|
||||
*/
|
||||
public function refreshMiniAccessToken($force = false)
|
||||
{
|
||||
$accessToken = $this->app->getAccessToken();
|
||||
if ($force && method_exists($accessToken, 'getStableAccessToken')) {
|
||||
return $accessToken->getStableAccessToken(true);
|
||||
}
|
||||
if ($accessToken instanceof \EasyWeChat\Kernel\Contracts\RefreshableAccessToken) {
|
||||
return $accessToken->refresh();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序登录(code2session)
|
||||
* @param string $code wx.login 获取的 code
|
||||
|
||||
@@ -384,6 +384,33 @@ class VirtualPayService
|
||||
if ($body === false) {
|
||||
throw new \Exception('虚拟支付参数编码失败');
|
||||
}
|
||||
$service = new EasyWeChatService();
|
||||
$result = self::requestXpay($service, $uri, $body, $sessionKey);
|
||||
$errcode = (int)($result['errcode'] ?? 0);
|
||||
// 40001 凭证不是最新,42001 凭证过期。刷新后只重试一次
|
||||
if ($errcode === 40001 || $errcode === 42001) {
|
||||
Log::info('虚拟支付 access_token 失效,刷新后重试 ' . $uri);
|
||||
$service->refreshMiniAccessToken(true);
|
||||
$result = self::requestXpay($service, $uri, $body, $sessionKey);
|
||||
}
|
||||
Log::info('虚拟支付请求 ' . $uri . ' ' . json_encode([
|
||||
'payload' => $payload,
|
||||
'res' => $result,
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return is_array($result) ? $result : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EasyWeChatService $service
|
||||
* @param string $uri
|
||||
* @param string $body
|
||||
* @param string $sessionKey
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function requestXpay(EasyWeChatService $service, $uri, $body, $sessionKey)
|
||||
{
|
||||
// access_token 由小程序 HTTP 客户端自动附在 query 上,不参与 pay_sig
|
||||
$query = [
|
||||
'pay_sig' => hash_hmac('sha256', $uri . '&' . $body, self::appKey()),
|
||||
@@ -392,7 +419,6 @@ class VirtualPayService
|
||||
$query['signature'] = hash_hmac('sha256', $body, $sessionKey);
|
||||
}
|
||||
try {
|
||||
$service = new EasyWeChatService();
|
||||
$response = $service->app->getClient()->post($uri, [
|
||||
'query' => $query,
|
||||
'headers' => ['Content-Type' => 'application/json'],
|
||||
@@ -403,10 +429,6 @@ class VirtualPayService
|
||||
Log::error('虚拟支付请求异常 ' . $uri . ' ' . $e->getMessage());
|
||||
throw new \Exception('虚拟支付请求失败');
|
||||
}
|
||||
Log::info('虚拟支付请求 ' . $uri . ' ' . json_encode([
|
||||
'payload' => $payload,
|
||||
'res' => $result,
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return is_array($result) ? $result : [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user