appid = $cfg['appid']; $this->appsecret = $cfg['appsecret']; $this->mchid = $cfg['mchid']; $this->pem_no = $cfg['pem_no']; $this->pem_path = $cfg['pem_path']; if(isset($cfg['accesstoken'])) $this->accesstoken = $cfg['accesstoken']; } function getaccess() { $cfg['ssl'] = true; $result = $this->curlOpen( 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $this->appid . '&secret=' . $this->appsecret, $cfg ); $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器无法连接getaccess', $result); if (toint(@$json['errcode']) != 0) return $this->err(@$json['errmsg'], $result); $accesstoken = @$json['access_token']; if (empty($accesstoken)) return $this->err('微信授权失败', $result); $exptimes = time() + toint($json['expires_in']); return array('accesstoken' => $accesstoken, 'exptimes' => $exptimes); } function code2Session($code) { $cfg['ssl'] = true; $result = $this->curlOpen('https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code&appid=' . $this->appid . '&secret=' . $this->appsecret . '&js_code=' . $code, $cfg); $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器无法连接code2session', $result); if (toint(@$json['errcode']) != 0) return $this->err(@$json['errmsg'], $result); return $json; } public function decryptData($encryptedData, $iv, $loginiv) { if (strlen($loginiv) != 24) return 'AES解密失败session len'; $aesKey = base64_decode($loginiv); if (strlen($iv) != 24) return 'AES解密失败iv len'; $aesIV = base64_decode($iv); $aesCipher = base64_decode($encryptedData); $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); if ($result === false) return '请再点击一次'; $json = json_decode($result, true); if ($json === null) return 'AES解密失败json'; return $json; } public function pay($param) { $param['appid'] = $this->appid; $param['mchid'] = $this->mchid; $result = $this->httppay('https://api.mch.weixin.qq.com','/v3/pay/transactions/jsapi',$param); if(is_string($result)) return $result; $timestamp = time() . ''; $nonce = uniqid() . uniqid(); $pkey = openssl_pkey_get_private(file_get_contents($this->pem_path)); $message = $this->appid . "\n" . $timestamp . "\n" . $nonce . "\nprepay_id=" . $result['prepay_id'] . "\n"; openssl_sign($message, $raw_sign, $pkey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); $ret['appId'] = $this->appid; $ret['timeStamp'] = $timestamp; $ret['nonceStr'] = $nonce; $ret['package'] = 'prepay_id=' . $result['prepay_id']; $ret['signType'] = 'RSA'; $ret['paySign'] = $sign; return $ret; } public function transfer($param) { $param['appid'] = $this->appid; $result = $this->httppay('https://api.mch.weixin.qq.com','/v3/fund-app/mch-transfer/transfer-bills',$param); if(is_string($result)) return $result; return $result; } public function getwxacodeunlimit($param) { $cfg['ssl'] = true; $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); $result = $this->curlOpen( 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $this->accesstoken, $cfg ); return $result; } function httppay($domain, $url, $param) { if(!file_exists($this->pem_path)) return '证书文件不存在'.$this->pem_path; $timestamp = time() . ''; $nonce = uniqid() . uniqid(); $post = json_encode($param, JSON_UNESCAPED_UNICODE); $message = "POST\n".$url."\n" . $timestamp . "\n" . $nonce . "\n" . $post . "\n"; $pkey = openssl_pkey_get_private(file_get_contents($this->pem_path)); openssl_sign($message, $raw_sign, $pkey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); $token = 'mchid="' . $this->mchid . '",nonce_str="' . $nonce . '",timestamp="' . $timestamp . '",serial_no="' . $this->pem_no . '",signature="' . $sign . '"'; $http = new \ciy\http(); $http->set_headeronce('Content-Type','application/json'); $http->set_headeronce('Accept','application/json'); $http->set_headeronce('Authorization','WECHATPAY2-SHA256-RSA2048 ' . $token); $http->request($domain.$url, $post); $statcode = $http->get_statcode(); if($statcode == 200 || $statcode == 204){ $result = $http->get_data(); $json = json_decode($result, true); if ($json === null) return array('code' => 1); if (isset($json['message'])) return $this->err('微信服务器返回错误:' . $json['message']); $json['code'] = 1; return $json; }else{ $res['errmsg'] = 1; $result = $http->get_data(); $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器无法连接pay', $result); if (isset($json['message'])) return $this->err('微信服务器返回错误:' . $json['message']); return $this->err('微信服务器返回json:' . $result); } } public function pay2($param) { $param['appid'] = $this->appid; $param['mchid'] = $this->mchid; $cfg['ssl'] = true; $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); $cfg['header'] = array(); $cfg['header'][] = 'Content-Type: application/json'; $timestamp = time() . ''; $nonce = uniqid() . uniqid(); $message = "POST\n/v3/pay/transactions/jsapi\n" . $timestamp . "\n" . $nonce . "\n" . $cfg['post'] . "\n"; $pkey = openssl_pkey_get_private(file_get_contents($this->pem_path)); openssl_sign($message, $raw_sign, $pkey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); $token = 'mchid="' . $param['mchid'] . '",nonce_str="' . $nonce . '",timestamp="' . $timestamp . '",serial_no="' . $this->pem_no . '",signature="' . $sign . '"'; $cfg['header'][] = 'Authorization: WECHATPAY2-SHA256-RSA2048 ' . $token; $result = $this->curlOpen('https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi', $cfg); $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器无法连接pay', $result); if (isset($json['message'])) return $this->err('微信服务器返回错误:' . $json['message']); $message = $param[''] . "\n" . $timestamp . "\n" . $nonce . "\nprepay_id=" . $json['prepay_id'] . "\n"; openssl_sign($message, $raw_sign, $pkey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); $ret[''] = $param['appid']; $ret['timeStamp'] = $timestamp; $ret['nonceStr'] = $nonce; $ret['package'] = 'prepay_id=' . $json['prepay_id']; $ret['signType'] = 'RSA'; $ret['paySign'] = $sign; return $ret; } public function payrefund($param) { $json = $this->httppay('https://api.mch.weixin.qq.com','/v3/refund/domestic/refunds',$param); return $json; } // static public function xcx_setactive($accesstoken, $param) { // $cfg['ssl'] = true; // $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); // $result = curlOpen('https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send?access_token=' . $accesstoken, $cfg); // $json = json_decode($result, true); // if ($json === null) // return xcxerr('微信服务器无法连接setactive', $result); // if (toint(@$json['errcode']) != 0) // return xcxerr(@$json['errmsg'], $result); // return $json; // } // function xcx_getactive($accesstoken) { // 开房/开团后返回activeID,调用updateShareMenu后分享,每次进人setactive,直至开始/成功。 // $cfg['ssl'] = true; // $result = curlOpen('https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=' . $accesstoken, $cfg); // $json = json_decode($result, true); // if ($json === null) // return xcxerr('微信服务器无法连接getactive', $result); // if (toint(@$json['errcode']) != 0) // return xcxerr(@$json['errmsg'], $result); // return $json; // } // function xcx_sendsubscribe($accesstoken, $param) { // 发送模板消息 // $cfg['ssl'] = true; // $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); // $result = curlOpen('https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $accesstoken, $cfg); // $json = json_decode($result, true); // if ($json === null) // return xcxerr('微信服务器无法连接sendsubscribe', $result); // if (toint(@$json['errcode']) != 0) // return xcxerr(@$json['errmsg'], $result); // return $json; // } // function xcx_sendmb($accesstoken, $param) { // 发送模板消息 // $cfg['ssl'] = true; // $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); // $result = curlOpen('https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=' . $accesstoken, $cfg); // $json = json_decode($result, true); // if ($json === null) // return xcxerr('微信服务器无法连接sendmb', $result); // if (toint(@$json['errcode']) != 0) // return xcxerr(@$json['errmsg'], $result); // return $json; // } // function xcx_senduniform($accesstoken, $param) { // 发送统一服务消息 // $cfg['ssl'] = true; // //https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/uniform-message/uniformMessage.send.html // $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); // $result = curlOpen('https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=' . $accesstoken, $cfg); // $json = json_decode($result, true); // if ($json === null) // return xcxerr('微信服务器无法连接senduniform', $result); // if (toint(@$json['errcode']) != 0) // return xcxerr(@$json['errmsg'], $result); // return $json; // } // function xcx_getqrcode($accesstoken, $tmppath, $fname, $param, $bgparam = null) { // $cfg['ssl'] = true; // $cfg['post'] = json_encode($param, JSON_UNESCAPED_UNICODE); // $result = curlOpen('https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $accesstoken, $cfg); // if (empty($result)) // return xcxerr('微信服务器无法连接getqrcode'); // if ($result[0] == '{') { // $json = json_decode($result, true); // if (toint(@$json['errcode']) != 0) // return xcxerr(@$json['errmsg'], $result); // else // return xcxerr('未知错误', $result); // } // if (empty($fname)) // $fname = date('Y-m-d_H-i-s', time()) . '_' . rand(100000, 999999); // $filename = $tmppath . $fname; // if ($bgparam === null) { // if ($param['is_hyaline']) // $filename .= '.png'; // else // $filename .= '.jpg'; // $fp = fopen(PATH_ROOT . $filename, 'w'); // fwrite($fp, $result); // @fclose($fp); // } else { // // 背景图 // $x = toint($bgparam['x']); // $y = toint($bgparam['y']); // $wh = toint($param['width']); // $imgbg = imagecreatefrompng($bgparam['bgimg']); // if (isset($bgparam['icon'])) { // $icon = $bgparam['icon']; // $ext = substr($icon['img'], -4); // if ($ext == 'png') // $imgicon = imagecreatefrompng($icon['img']); // else // $imgicon = imagecreatefromjpeg($icon['img']); // $iconw = imagesx($imgicon); // $iconh = imagesy($imgicon); // if (function_exists('imagecopyresampled')) // imagecopyresampled($imgbg, $imgicon, $icon['x'], $icon['y'], 0, 0, $icon['w'], $icon['h'], $iconw, $iconh); // else // imagecopyresized($imgbg, $imgicon, $icon['x'], $icon['y'], 0, 0, $icon['w'], $icon['h'], $iconw, $iconh); // } // if (isset($bgparam['text'])) { // $text = $bgparam['text']; // $color = imagecolorallocate($imgbg, toint(@$text['r']), toint(@$text['g']), toint(@$text['b'])); // imagettftext($imgbg, $text['size'], 0, $text['x'], $text['y'], $color, 'pingfangbold.ttf', $text['txt']); // } // $imgqrcode = imagecreatefromstring($result); // imagecopy($imgbg, $imgqrcode, $x, $y, 0, 0, $wh, $wh); // $filename = $filename . '.jpg'; // $ret = imagejpeg($imgbg, PATH_ROOT . $filename, 80); // imagedestroy($imgbg); // imagedestroy($imgqrcode); // if (!$ret) // return xcxerr('保存合并图失败'); // } // return array('url' => $filename); // } // function xcx_decryptData($encryptedData, $iv, $loginiv) { // if (strlen($loginiv) != 24) // return 'AES解密失败session len'; // $aesKey = base64_decode($loginiv); // if (strlen($iv) != 24) // return 'AES解密失败iv len'; // $aesIV = base64_decode($iv); // $aesCipher = base64_decode($encryptedData); // $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); // if ($result === false) // return '请再点击一次'; // $json = json_decode($result, true); // if ($json === null) // return xcxerr('AES解密失败', $result . ''); // return $json; // } // function calsign($param, $key) { // ksort($param); // $buff = ''; // foreach ($param as $k => $v) { // if ($k != 'sign' && $v != '' && !is_array($v)) // $buff .= $k . '=' . $v . '&'; // } // $buff .= 'key=' . $key; // $string = strtoupper(md5($buff)); // return $string; // } function err($ret, $log = '') { if (!empty($log)) savelogfile('WXPAY', $ret . $log); return $ret; } function filter_utf8_char($ostr) { preg_match_all('/[\x{FF00}-\x{FFEF}|\x{0000}-\x{00ff}|\x{4e00}-\x{9fff}]+/u', $ostr, $matches); $str = join('', $matches[0]); if ($str == '') { // 含有特殊字符需要逐個處理 $returnstr = ''; $i = 0; $str_length = strlen($ostr); while ($i <= $str_length) { $temp_str = substr($ostr, $i, 1); $ascnum = Ord($temp_str); if ($ascnum >= 224) { $returnstr = $returnstr . substr($ostr, $i, 3); $i = $i + 3; } elseif ($ascnum >= 192) { $returnstr = $returnstr . substr($ostr, $i, 2); $i = $i + 2; } elseif ($ascnum >= 65 && $ascnum <= 90) { $returnstr = $returnstr . substr($ostr, $i, 1); $i = $i + 1; } elseif ($ascnum >= 128 && $ascnum <= 191) { // 特殊字符 $i = $i + 1; } else { $returnstr = $returnstr . substr($ostr, $i, 1); $i = $i + 1; } } $str = $returnstr; preg_match_all('/[\x{FF00}-\x{FFEF}|\x{0000}-\x{00ff}|\x{4e00}-\x{9fff}]+/u', $str, $matches); $str = join('', $matches[0]); } return $str; } function curlOpen($url, $config = array()) { $arr = array('post' => false, 'referer' => $url, 'cookie' => '', 'useragent' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; customie8)', 'timeout' => 50, 'return' => 1, 'proxy' => '', 'userpwd' => '', 'nobody' => 0, 'gzip' => 0, 'ssl' => 1); $arr['header'] = array(); $arr = array_merge($arr, $config); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //$arr['return'] curl_setopt($ch, CURLOPT_NOBODY, $arr['nobody']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_USERAGENT, $arr['useragent']); curl_setopt($ch, CURLOPT_REFERER, $arr['referer']); //curl_setopt($ch, CURLOPT_TIMEOUT, $arr['timeout']); if ($arr['gzip']) curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); if ($arr['ssl']) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); } if (!empty($arr['cookie'])) { curl_setopt($ch, CURLOPT_COOKIEJAR, $arr['cookie']); curl_setopt($ch, CURLOPT_COOKIEFILE, $arr['cookie']); } if (!empty($arr['proxy'])) { //curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_setopt($ch, CURLOPT_PROXY, $arr['proxy']); if (!empty($arr['userpwd'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $arr['userpwd']); } } //ip比较特殊,用键值表示 if (!empty($arr['header']['ip'])) { array_push($arr['header'], 'X-FORWARDED-FOR:' . $arr['header']['ip'], 'CLIENT-IP:' . $arr['header']['ip']); unset($arr['header']['ip']); } $arr['header'] = array_filter($arr['header']); if (!empty($arr['header'])) { curl_setopt($ch, CURLOPT_HTTPHEADER, $arr['header']); } if ($arr['post'] != false) { curl_setopt($ch, CURLOPT_POST, true); if (is_array($arr['post'])) { $post = http_build_query($arr['post']); } else { $post = $arr['post']; } curl_setopt($ch, CURLOPT_POSTFIELDS, $post); } $result = curl_exec($ch); //var_dump(curl_getinfo($ch)); curl_close($ch); $ind = strpos($result, 'HTTP'); if ($ind < 2) { $ind = strpos($result, "\r\n\r\n"); if ($ind > 0) { $result = substr($result, $ind + 4); } } if (strpos($result, '{') === 0) { $ind = strrpos($result, '}'); if ($ind < strlen($result)) $result = substr($result, 0, $ind + 1); } return $result; } }