| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <?php
- namespace App\Common\Services;
- use App\Common\Library\AES;
- use App\Exceptions\ApiException;
- use App\Services\CommonBaseService;
- use GuzzleHttp\Client;
- use GuzzleHttp\Exception\RequestException;
- use Illuminate\Support\Facades\Cache;
- use Illuminate\Support\Facades\Log;
- class WechatService extends CommonBaseService
- {
- protected $cache = true;
- protected $cacheBucket = 'wechat:';
- protected $client = null;
- protected $appId = null;
- protected $appSecret = null;
- public function __construct()
- {
- $client = new Client();
- $this->client = $client;
- $this->appId = config('wechat.app_id');
- $this->appSecret = config('wechat.app_secret');
- }
- public function getAccessToken()
- {
- $accessTokenKey = 'wechat:access:key';
- $cache = Cache::get($accessTokenKey);
- if($cache) {
- return $cache;
- }
- $url = 'https://api.weixin.qq.com/cgi-bin/stable_token';
- $formParams = [
- 'appid' => $this->appId,
- 'secret' => $this->appSecret,
- 'grant_type' => 'client_credential'
- ];
- try {
- $options = [
- 'json' => $formParams,
- 'headers' => [
- 'Content-Type' => 'application/json'
- ]
- ];
- $response = $this->client->request('POST', $url, $options);
- // 获取响应体并解码为数组
- $body = json_decode($response->getBody()->getContents(), true);
- if (!empty($body['errcode'])) {
- $this->throwApiError($options, json_encode($body['errcode']).json_encode($body['errmsg']));
- } else {
- Cache::put($accessTokenKey, $body['access_token'], 240);
- return $body['access_token'];
- }
- } catch (RequestException $e) {
- $this->throwApiError($options, $e->getMessage(), $e->getCode());
- }
- }
- public function getSessionInfo($code)
- {
- $url = 'https://api.weixin.qq.com/sns/jscode2session';
- // 准备请求参数
- $formParams = [
- 'appid' => $this->appId,
- 'secret' => $this->appSecret,
- 'js_code' => $code,
- 'grant_type' => 'authorization_code'
- ];
- try {
- $options = [
- 'query' => $formParams
- ];
- $response = $this->client->request('GET', $url, $options);
- // 获取响应体并解码为数组
- $body = json_decode($response->getBody()->getContents(), true);
- if (!empty($body['errcode'])) {
- $this->throwApiError($options, json_encode($body['errcode']).json_encode($body['errmsg']));
- } else {
- // $openid = $data['openid'];
- // $sessionKey = $data['session_key'];
- return $body;
- }
- } catch (RequestException $e) {
- $this->throwApiError($options, $e->getMessage(), $e->getCode());
- }
- }
- public function getUserPhoneNumber($code)
- {
- $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber';
- // 准备请求参数
- try {
- $options = [
- 'query' => ['access_token' => $this->getAccessToken()],
- 'json' => ['code' => $code],
- 'headers' => [
- 'Content-Type' => 'application/json'
- ]
- ];
- $response = $this->client->request('POST', $url, $options);
- // 获取响应体并解码为数组
- $body = json_decode($response->getBody()->getContents(), true);
- if (!empty($body['errcode'])) {
- $this->throwApiError($options, json_encode($body['errcode']).json_encode($body['errmsg']));
- } else {
- /*
- * {
- "errcode":0,
- "errmsg":"ok",
- "phone_info": {
- "phoneNumber":"xxxxxx",
- "purePhoneNumber": "xxxxxx",
- "countryCode": 86,
- "watermark": {
- "timestamp": 1637744274,
- "appid": "xxxx"
- }
- }
- }
- */
- return $body;
- }
- } catch (RequestException $e) {
- $this->throwApiError($options, $e->getMessage(), $e->getCode());
- }
- }
- public function getWxaQueryScheme($scheme)
- {
- //https://api.weixin.qq.com/wxa/queryscheme?access_token=ACCESS_TOKEN
- //query_type
- $keyScheme = 'key:wechat:key:scheme';
- $cache = Cache::get($keyScheme);
- if($cache) {
- return $cache;
- }
- $url = 'https://api.weixin.qq.com/wxa/generatescheme';
- // 准备请求参数
- try {
- $options = [
- 'query' => ['access_token' => $this->getAccessToken()],
- 'json' => ['expire_time' => strtotime('+28 day', time()), 'expire_type' => 0],
- 'headers' => [
- 'Content-Type' => 'application/json'
- ]
- ];
- $response = $this->client->request('POST', $url, $options);
- // 获取响应体并解码为数组
- $body = json_decode($response->getBody()->getContents(), true);
- if (!empty($body['errcode'])) {
- $this->throwApiError($options, json_encode($body['errcode']).json_encode($body['errmsg']));
- } else {
- Cache::put($keyScheme, $body['openlink'], 20 * 24 * 60 * 60);
- return $body['openlink'] ?? '';
- }
- } catch (RequestException $e) {
- $this->throwApiError($options, $e->getMessage(), $e->getCode());
- }
- }
- public function decryptData(string $sessionKey, string $iv, string $encrypted)
- {
- $decrypted = AES::decrypt(
- base64_decode($encrypted, false), base64_decode($sessionKey, false), base64_decode($iv, false)
- );
- $decrypted = json_decode($this->pkcs7Unpad($decrypted), true);
- if (!$decrypted) {
- $this->throwApiError([$sessionKey, $iv, $encrypted], '解密失败', 500);
- }
- return $decrypted;
- }
- public function pkcs7Unpad(string $text)
- {
- $pad = ord(substr($text, -1));
- if ($pad < 1 || $pad > 32) {
- $pad = 0;
- }
- return substr($text, 0, (strlen($text) - $pad));
- }
- private function throwApiError($options, $error, $code = 200)
- {
- $key = createGuid();
- Log::info('Wechat第三方接口出错key:'.$key);
- Log::info('Wechat第三方接口出错params:'.json_encode($options));
- Log::info('Wechat第三方接口出错:'.$code.','.$error);
- throw new ApiException(500);
- }
- }
|