appPay("oQ_977SN3KhBetHY9OPckGP9DNNc", "G" . time(), "商品购买", 0.01); $SR->code() ? $this->success($SR->data()) : $this->error($SR->msg()); } function sms() { $valid = TencentCloudService::tencent_cloud_sms_send("2280835", "15574920253", [random_int(1000, 9999)]); $valid->code() ? $this->success($valid->data()) : $this->error($valid->msg()); } function test1() { dump(decbin(5)); // dump(5^5); } /** * 获取证书 * @return mixed */ public static function certificates() { //请求参数(报文主体) $headers = self::sign('GET', 'https://api.mch.weixin.qq.com/v3/certificates', ''); $result = self::curl_get('https://api.mch.weixin.qq.com/v3/certificates', $headers); $result = json_decode($result, true); dump($result);// 解密后的内容,就是证书内容 $aa = self::decryptToString($result['data'][0]['encrypt_certificate']['associated_data'], $result['data'][0]['encrypt_certificate']['nonce'], $result['data'][0]['encrypt_certificate']['ciphertext']); var_dump($aa);// 解密后的内容,就是证书内容 } /** * 签名 * @param string $http_method 请求方式GET|POST * @param string $url url * @param string $body 报文主体 * @return array */ public static function sign($http_method = 'POST', $url = '', $body = '') { $mch_private_key = self::getMchKey();//私钥 $timestamp = time();//时间戳 $nonce = self::getRandomStr(32);//随机串 $url_parts = parse_url($url); $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : "")); //构造签名串 $message = $http_method . "\n" . $canonical_url . "\n" . $timestamp . "\n" . $nonce . "\n" . $body . "\n";//报文主体 //计算签名值 openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); //设置HTTP头 $config = self::config(); $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $config['mchid'], $nonce, $timestamp, $config['serial_no'], $sign); return [ 'Accept: application/json', 'User-Agent: */*', 'Content-Type: application/json; charset=utf-8', 'Authorization: ' . $token, ]; } //私钥 public static function getMchKey() { //path->私钥文件存放路径 return openssl_get_privatekey(file_get_contents("file://D:/project_c/billiards-server/certificate/wx/apiclient_key.pem")); } /** * 获得随机字符串 * @param $len integer 需要的长度 * @param $special bool 是否需要特殊符号 * @return string 返回随机字符串 */ public static function getRandomStr($len, bool $special = false) { $chars = array( "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ); if ($special) { $chars = array_merge($chars, array( "!", "@", "#", "$", "?", "|", "{", "/", ":", ";", "%", "^", "&", "*", "(", ")", "-", "_", "[", "]", "}", "<", ">", "~", "+", "=", ",", "." )); } $charsLen = count($chars) - 1; shuffle($chars); //打乱数组顺序 $str = ''; for ($i = 0; $i < $len; $i++) { $str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位 } return $str; } /** * 配置 */ public static function config() { return [ 'appid' => '', 'mchid' => '1638097896',//商户号 'serial_no' => '13A336433257E2C58CB5A6BC469B7040EF7E7456',//证书序列号 'description' => '',//应用名称(随意) 'notify' => '',//支付回调 ]; } //get请求 public static function curl_get($url, $headers = array()) { $info = curl_init(); curl_setopt($info, CURLOPT_RETURNTRANSFER, true); curl_setopt($info, CURLOPT_HEADER, 0); curl_setopt($info, CURLOPT_NOBODY, 0); curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($info, CURLOPT_SSL_VERIFYHOST, false); //设置header头 curl_setopt($info, CURLOPT_HTTPHEADER, $headers); curl_setopt($info, CURLOPT_URL, $url); $output = curl_exec($info); curl_close($info); return $output; } const KEY_LENGTH_BYTE = 32; const AUTH_TAG_LENGTH_BYTE = 16; /** * Decrypt AEAD_AES_256_GCM ciphertext * * @param string $associatedData AES GCM additional authentication data * @param string $nonceStr AES GCM nonce * @param string $ciphertext AES GCM cipher text * * @return string|bool Decrypted string on success or FALSE on failure */ public static function decryptToString($associatedData, $nonceStr, $ciphertext) { $aesKey = '5a523a148c428bf8c4af91000fc307a6'; $ciphertext = \base64_decode($ciphertext); if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) { return false; } // ext-sodium (default installed on >= PHP 7.2) if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) { return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey); } // ext-libsodium (need install libsodium-php 1.x via pecl) if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) { return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey); } // openssl (PHP >= 7.1 support AEAD) if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE); $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE); return \openssl_decrypt($ctext, 'aes-256-gcm', $aesKey, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); } throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'); } } /** * 各省定价不相同 获取服务时候 根据位置获取服务 * 抽成比例更换 */