GzcApiRequest.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. declare (strict_types=1);
  3. namespace app\traits;
  4. use think\facade\Log;
  5. /**
  6. * 请求公证处统一请求API
  7. * Trait GzcApiRequest
  8. * @package app\traits
  9. */
  10. trait GzcApiRequest
  11. {
  12. /**
  13. * 发送请求
  14. * @return mixed|string
  15. * @author php迷途小书童
  16. * @created 2021/1/14 14:34
  17. */
  18. public static function request(string $method, string $url, array $params = [], array $options = [])
  19. {
  20. $base_uri = env('GZC.HOSTNAME');
  21. $request_uri = $base_uri.$url;
  22. try {
  23. $data = json_encode($params);
  24. $headerArray =array(
  25. "Content-type:application/json;charset='utf-8'",
  26. "Accept:application/json"
  27. );
  28. if ($url != '/v1/api/third/auth/token') {
  29. $Token = self::getTokenFromServer();
  30. $accessToken = $Token['extendData']['accessToken'];
  31. array_push($headerArray, "token:".$accessToken);
  32. }
  33. Log::info($data);
  34. $curl = curl_init();
  35. curl_setopt($curl, CURLOPT_URL, $request_uri);
  36. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  37. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
  38. curl_setopt($curl, CURLOPT_POST, 1);
  39. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  40. curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
  41. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  42. $output = curl_exec($curl);
  43. curl_close($curl);
  44. return json_decode($output, true);
  45. } catch (\Throwable $e) {
  46. return $e->getMessage();
  47. }
  48. }
  49. /**
  50. * 查询账户余额
  51. * @author php迷途小书童
  52. * @created 2021/1/14 16:34
  53. */
  54. public static function checkAmount($user)
  55. {
  56. $data = [
  57. 'platformNo' => env('GZC.PLATFORM_NO'),
  58. 'appNo' => env('GZC.APP_NO'),
  59. 'conName' => $user['user_name'],
  60. 'conCertType' => 1,
  61. 'conCertNo' => $user['user_card'],
  62. ];
  63. foreach (['conName', 'conCertNo'] as $key) {
  64. if (empty($data[$key])) {
  65. Log::error('[checkAmount] 参数缺失', [
  66. 'missing_field' => $key,
  67. 'user' => $user,
  68. 'data' => $data
  69. ]);
  70. }
  71. }
  72. $tokenData = self::getTokenFromServer();
  73. $token = $tokenData['extendData']['accessToken'] ?? null;
  74. if (empty($token)) {
  75. Log::error('[checkAmount] Token 获取失败', [
  76. 'tokenData' => $tokenData,
  77. 'user' => $user
  78. ]);
  79. } else {
  80. Log::info('[checkAmount] 成功获取 Token', ['token' => $token]);
  81. }
  82. Log::info('[checkAmount] 请求开始', [
  83. 'url' => '/v1/api/third/in/in30',
  84. 'data' => $data,
  85. 'user' => $user
  86. ]);
  87. $response = self::request('POST', '/v1/api/third/in/in30', $data);
  88. Log::info('[checkAmount] 接口返回', [
  89. 'response' => $response
  90. ]);
  91. $code = $response['code'] ?? null;
  92. $msg = $response['msg'] ?? '';
  93. $amount = $response['data']['amount'] ?? null;
  94. if ($code !== 200) {
  95. Log::error('[checkAmount] 接口返回异常状态码', [
  96. 'code' => $code,
  97. 'msg' => $msg,
  98. 'user' => $user,
  99. 'response' => $response
  100. ]);
  101. }
  102. if (!isset($response['data']['amount'])) {
  103. Log::error('[checkAmount] 响应结构异常,缺少金额字段', [
  104. 'user' => $user,
  105. 'response' => $response
  106. ]);
  107. }
  108. // 情况三:金额为 0,分析可能原因
  109. if ($amount === 0) {
  110. $possibleReasons = [];
  111. if (empty($token)) {
  112. $possibleReasons[] = 'Token 获取失败或未附带';
  113. }
  114. if (empty($data['conCertNo']) || empty($data['conName'])) {
  115. $possibleReasons[] = '用户姓名或身份证号为空';
  116. }
  117. if (stripos($msg, '未开户') !== false || stripos($msg, '未实名') !== false) {
  118. $possibleReasons[] = '用户未开户或未实名';
  119. }
  120. if (stripos($msg, '无账户') !== false) {
  121. $possibleReasons[] = '第三方系统中不存在此账户';
  122. }
  123. if (stripos($msg, 'success') !== false && $amount === 0) {
  124. $possibleReasons[] = '接口返回成功但余额确实为0(正常情况)';
  125. }
  126. Log::warning('[checkAmount] 返回金额为0,可能原因如下', [
  127. 'user' => $user,
  128. 'params' => $data,
  129. 'response' => $response,
  130. 'token' => $token,
  131. 'possible_reasons' => $possibleReasons
  132. ]);
  133. }
  134. return $response;
  135. // return self::request('POST', '/v1/api/third/in/in30', $data);
  136. }
  137. /**
  138. * 获取TOKEN
  139. * @return mixed|string
  140. * @author php迷途小书童
  141. * @created 2021/1/14 14:38
  142. */
  143. public static function getTokenFromServer()
  144. {
  145. $timestamp = (int)(microtime(true) * 1000);
  146. $appid = env('GZC.APP_ID');
  147. $data = [
  148. 'appid' => $appid,
  149. 'sign' => self::getSignContent($timestamp, $appid),
  150. 'timestamp' => $timestamp
  151. ];
  152. return self::request('POST', '/v1/api/third/auth/token', $data);
  153. }
  154. /**
  155. * 获取签名
  156. * @return string
  157. * @author php迷途小书童
  158. * @created 2020/10/29 9:35
  159. */
  160. public static function getSignContent(int $timestamp, string $appid) {
  161. $appsecret = md5(env('GZC.APP_SECRET'));
  162. $stringToBeSigned = "appid={$appid}&secret={$appsecret}&timestamp={$timestamp}";
  163. return md5($stringToBeSigned);
  164. }
  165. }