435 lines
19 KiB
PHP
435 lines
19 KiB
PHP
<?php
|
||
//过时
|
||
namespace ciy;
|
||
|
||
class wxfunc {
|
||
public $appid;
|
||
public $mchid;
|
||
public $appsecret;
|
||
public $pem_path;
|
||
public $pem_no;
|
||
public $accesstoken;
|
||
|
||
function __construct($cfg = null) {
|
||
if(!is_array($cfg))
|
||
return;
|
||
$this->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;
|
||
}
|
||
}
|