get(1387); $res = (new ProfitService())->profit($order, db("user")->where("id", $order["user_id"])->find()); if($res->code()) { $this->success($res->msg()); } else { $this->success($res->data()); } } /** * 获取证书 * @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); $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); $headers = [ 'Accept: application/json', 'User-Agent: */*', 'Content-Type: application/json; charset=utf-8', 'Authorization: '.$token, ]; return $headers; } //私钥 public static function getMchKey(){ var_dump(file_get_contents("file:///www/wwwroot/pool_ball_baby_server/certificate/wx/apiclient_key.pem")); //path->私钥文件存放路径 return openssl_get_privatekey(file_get_contents("file:///www/wwwroot/pool_ball_baby_server/certificate/wx/apiclient_key.pem")); } /** * 获得随机字符串 * @param $len integer 需要的长度 * @param $special bool 是否需要特殊符号 * @return string 返回随机字符串 */ public static function getRandomStr($len, $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' => '1651873606',//商户号 'serial_no' => '4C24C6C4B0F88FAB756AA175D720D87A32B6BF23',//证书序列号 '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 = '8b70e85dd34b80b2e519eacd7a1abfd8'; $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'); } }