Test.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. namespace app\api\controller;
  3. use app\api\service\TencentCloudService;
  4. use app\common\controller\Api;
  5. class Test extends Api
  6. {
  7. protected $noNeedLogin = ["*"];
  8. function phpinfo()
  9. {
  10. dump(ini_get("oci8.default_prefetch"));
  11. echo phpinfo();
  12. }
  13. function payment()
  14. {
  15. $params = json_decode(file_get_contents("php://input"), true);
  16. dump($params['A']);
  17. // $service = (new WxService);
  18. // $SR = $service->appletPay("oQ_977SN3KhBetHY9OPckGP9DNNc", self::getRandomStr(20), "sbsbsb", 0.01);
  19. // $SR->code() ? $this->success($SR->data()) : $this->error($SR->msg());
  20. }
  21. function sms()
  22. {
  23. $valid = TencentCloudService::tencent_cloud_sms_send("2280835", "15574920253", [random_int(1000, 9999)]);
  24. $valid->code() ? $this->success($valid->data()) : $this->error($valid->msg());
  25. }
  26. function test1()
  27. {
  28. $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', "wxpay.wx_applet_secret")));
  29. var_dump($result);
  30. }
  31. /**
  32. * 获取证书
  33. * @return mixed
  34. */
  35. public static function certificates()
  36. {
  37. //请求参数(报文主体)
  38. $headers = self::sign('GET', 'https://api.mch.weixin.qq.com/v3/certificates', '');
  39. $result = self::curl_get('https://api.mch.weixin.qq.com/v3/certificates', $headers);
  40. $result = json_decode($result, true);
  41. dump($result);//解密后的内容,就是证书内容
  42. $aa = self::decryptToString($result['data'][0]['encrypt_certificate']['associated_data'], $result['data'][0]['encrypt_certificate']['nonce'], $result['data'][0]['encrypt_certificate']['ciphertext']);
  43. var_dump($aa);//解密后的内容,就是证书内容
  44. }
  45. /**
  46. * 签名
  47. * @param string $http_method 请求方式GET|POST
  48. * @param string $url url
  49. * @param string $body 报文主体
  50. * @return array
  51. */
  52. public static function sign($http_method = 'POST', $url = '', $body = '')
  53. {
  54. $mch_private_key = self::getMchKey();//私钥
  55. $timestamp = time();//时间戳
  56. $nonce = self::getRandomStr(32);//随机串
  57. $url_parts = parse_url($url);
  58. $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
  59. //构造签名串
  60. $message = $http_method . "\n" .
  61. $canonical_url . "\n" .
  62. $timestamp . "\n" .
  63. $nonce . "\n" .
  64. $body . "\n";//报文主体
  65. //计算签名值
  66. openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
  67. $sign = base64_encode($raw_sign);
  68. //设置HTTP头
  69. $config = self::config();
  70. $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
  71. $config['mchid'], $nonce, $timestamp, $config['serial_no'], $sign);
  72. return [
  73. 'Accept: application/json',
  74. 'User-Agent: */*',
  75. 'Content-Type: application/json; charset=utf-8',
  76. 'Authorization: ' . $token,
  77. ];
  78. }
  79. //私钥
  80. public static function getMchKey()
  81. {
  82. //path->私钥文件存放路径
  83. return openssl_get_privatekey(file_get_contents("file://D:/project_c/billiards-server/certificate/wx/apiclient_key.pem"));
  84. }
  85. /**
  86. * 获得随机字符串
  87. * @param $len integer 需要的长度
  88. * @param $special bool 是否需要特殊符号
  89. * @return string 返回随机字符串
  90. */
  91. public static function getRandomStr($len, $special = false)
  92. {
  93. $chars = array(
  94. "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
  95. "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
  96. "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
  97. "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  98. "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
  99. "3", "4", "5", "6", "7", "8", "9"
  100. );
  101. if ($special) {
  102. $chars = array_merge($chars, array(
  103. "!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
  104. "%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
  105. "}", "<", ">", "~", "+", "=", ",", "."
  106. ));
  107. }
  108. $charsLen = count($chars) - 1;
  109. shuffle($chars); //打乱数组顺序
  110. $str = '';
  111. for ($i = 0; $i < $len; $i++) {
  112. $str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
  113. }
  114. return $str;
  115. }
  116. /**
  117. * 配置
  118. */
  119. public static function config()
  120. {
  121. return [
  122. 'appid' => '',
  123. 'mchid' => '1638097896',//商户号
  124. 'serial_no' => '13A336433257E2C58CB5A6BC469B7040EF7E7456',//证书序列号
  125. 'description' => '',//应用名称(随意)
  126. 'notify' => '',//支付回调
  127. ];
  128. }
  129. //get请求
  130. public static function curl_get($url, $headers = array())
  131. {
  132. $info = curl_init();
  133. curl_setopt($info, CURLOPT_RETURNTRANSFER, true);
  134. curl_setopt($info, CURLOPT_HEADER, 0);
  135. curl_setopt($info, CURLOPT_NOBODY, 0);
  136. curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false);
  137. curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false);
  138. curl_setopt($info, CURLOPT_SSL_VERIFYHOST, false);
  139. //设置header头
  140. curl_setopt($info, CURLOPT_HTTPHEADER, $headers);
  141. curl_setopt($info, CURLOPT_URL, $url);
  142. $output = curl_exec($info);
  143. curl_close($info);
  144. return $output;
  145. }
  146. const KEY_LENGTH_BYTE = 32;
  147. const AUTH_TAG_LENGTH_BYTE = 16;
  148. /**
  149. * Decrypt AEAD_AES_256_GCM ciphertext
  150. *
  151. * @param string $associatedData AES GCM additional authentication data
  152. * @param string $nonceStr AES GCM nonce
  153. * @param string $ciphertext AES GCM cipher text
  154. *
  155. * @return string|bool Decrypted string on success or FALSE on failure
  156. */
  157. public static function decryptToString($associatedData, $nonceStr, $ciphertext)
  158. {
  159. $aesKey = '5a523a148c428bf8c4af91000fc307a6';
  160. $ciphertext = \base64_decode($ciphertext);
  161. if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
  162. return false;
  163. }
  164. // ext-sodium (default installed on >= PHP 7.2)
  165. if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
  166. return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
  167. }
  168. // ext-libsodium (need install libsodium-php 1.x via pecl)
  169. if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) {
  170. return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
  171. }
  172. // openssl (PHP >= 7.1 support AEAD)
  173. if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
  174. $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
  175. $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);
  176. return \openssl_decrypt($ctext, 'aes-256-gcm', $aesKey, \OPENSSL_RAW_DATA, $nonceStr,
  177. $authTag, $associatedData);
  178. }
  179. throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
  180. }
  181. }
  182. /**
  183. * 各省定价不相同 获取服务时候 根据位置获取服务
  184. * 抽成比例更换
  185. */