WXLittle.class.php 代码如下
/**
* 微信小程序操作表
* wxtoken 表结构
* id
* access_token
* addtime
* wxticket 表结构
* id
* ticket
* addtime
*/
class WXLittle {
private $appid;
private $appserect;
private $mch_id;
private $mchkey; //微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
private $curl;
private $msg;
protected $errs = array(
'-1' => '系统繁忙,此时请开发者稍候再试',
'0' => '请求成功',
'40001' => 'AppSecret错误或者AppSecret不属于这个公众号,请开发者确认AppSecret的正确性',
'40002' => '请确保grant_type字段值为client_credential',
'40164' => '调用接口的IP地址不在白名单中,请在接口IP白名单中进行设置。',
);
function __construct($appid, $appserect) {
$this->appid = $appid;
$this->appserect = $appserect;
$this->curl = new Curl();
}
public function setMchInfo($appid, $key) {
$this->mch_id = $appid;
$this->mchkey = $key;
}
/*
获取小程序token
*/
public function getAccessToken() {
$addtime = TIMESTAMP - 7200;
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->appserect}";
$row = C::t(PT_WXTOKEN)->getNew($addtime, 2);
if ($row) {
/*
access_token string 获取到的凭证
expires_in number 凭证有效时间,单位:秒
errcode number 错误码
errmsg string 错误信息
*/
return $row['access_token'];
} else {
$result = $this->curl->doGet($url);
if (!$result) {
$this->msg = "无法获取令牌内容";
return false;
}
$result = json_decode($result, true);
if (!$result) {
$this->msg = "解析令牌内容失败";
return false;
}
if ($result['access_token']) {
C::t(PT_WXTOKEN)->addToken($result['access_token'], 2);
return $result['access_token'];
} else {
$this->msg = "获取令牌失败" . $result['errmsg'];
return false;
}
}
}
// 创建小程序二维码 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html
public function createWXAQRCode($access_token, $scene, $path, $width, $auto_color = false, $line_color = null, $is_hyaline = false) {
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}";
$data = array(
'scene' => $scene,
'path' => $path,
'width' => $width,
'auto_color' => $auto_color,
'line_color' => $line_color,
'is_hyaline' => $is_hyaline,
);
$data = json_encode($data);
$content = curlPost($url, $data);
if (!$content) {
$this->msg = "无法获取小程序二维码";
return false;
}
$result = json_decode($content, true);
if (!$result) {
//获取图片上传路径
$dir = getUploadDir('table');
//图片二进制数据 直接保存
$name = md5(uniqid()) . '.jpg';
$file = $dir . $name;
$tarDir = dirname($file);
if (!is_dir($tarDir)) {
dmkdir($tarDir);
}
file_put_contents($file, $content);
return $file;
} else {
$this->msg = $result['errmsg'];
return false;
}
}
// 小程序code码换openid等 openid session_key unionid
public function code2session($code) {
$url = "https://api.weixin.qq.com/sns/jscode2session?appid={$this->appid}&secret={$this->appserect}&js_code={$code}&grant_type=authorization_code";
$result = $this->curl->doGet($url);
if (!$result) {
$this->msg = "无法获取会话信息";
return false;
}
$json = json_decode($result, true);
if ($json['errcode']) {
$this->msg = $json['errMsg'];
return false;
}
return $json;
}
//获取预付款订单号
public function getPreorder(&$params) {
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$str = '<xml>
<appid>%s</appid>
<mch_id>%s</mch_id>
<device_info>%s</device_info>
<nonce_str>%s</nonce_str>
<sign>%s</sign>
<sign_type>%s</sign_type>
<body>%s</body>
<detail>%s</detail>
<attach>%s</attach>
<out_trade_no>%s</out_trade_no>
<fee_type>%s</fee_type>
<total_fee>%s</total_fee>
<spbill_create_ip>%s</spbill_create_ip>
<time_start>%s</time_start>
<time_expire>%s</time_expire>
<goods_tag>%s</goods_tag>
<notify_url>%s</notify_url>
<trade_type>%s</trade_type>
<product_id>%s</product_id>
<limit_pay>%s</limit_pay>
<openid>%s</openid>
</xml>';
$params['appid'] = $this->appid;
$params['mch_id'] = $this->mch_id;
ksort($params);
$string = $this->ToUrlParams($params);
$string .= "&key={$this->mchkey}";
if (strtoupper($params['sign_type']) == 'MD5') {
$sign = md5($string);
} else {
$sign = hash_hmac($string);
}
$params['sign'] = $sign;
$data = sprintf(
$str,
$params['appid'],
$params['mch_id'],
$params['device_info'],
$params['nonce_str'],
$params['sign'],
$params['sign_type'],
$params['body'],
$params['detail'],
$params['attach'],
$params['out_trade_no'],
$params['fee_type'],
$params['total_fee'],
$params['spbill_create_ip'],
$params['time_start'],
$params['time_expire'],
$params['goods_tag'],
$params['notify_url'],
$params['trade_type'],
$params['product_id'],
$params['limit_pay'],
$params['openid']
);
$result = curlPost($url, $data);
$return = toXmlTree($result);
if (!$return) {
$this->msg = '无法获取预付订单号';
return false;
}
$vals = $return['vals'];
$index = $return['index'];
$prepay_id = getXmlValue($vals, 'prepay_id');
if (!$prepay_id) {
$this->msg = getXmlValue($vals, 'return_msg');
return false;
}
return $prepay_id;
}
// 二次签名 数据返回给小程序
public function resignAgain($package, $timeStamp, $nonceStr, $signType = 'MD5') {
$params = array('package' => $package, 'timeStamp' => $timeStamp, 'nonceStr' => $nonceStr, 'appId' => $this->appid, 'signType' => $signType);
ksort($params);
$string = $this->ToUrlParams($params);
$string .= "&key={$this->mchkey}";
if (strtoupper($params['signType']) == 'MD5') {
$sign = md5($string);
} else {
$sign = hash_hmac($string);
}
return $sign;
}
// 微信支付退款
public function returnmoney(&$params) {
$url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
$str = '<xml>
<appid>%s</appid>
<mch_id>%s</mch_id>
<nonce_str>%s</nonce_str>
<sign>%s</sign>
<sign_type>%s</sign_type>
<transaction_id>%s</transaction_id>
<out_trade_no>%s</out_trade_no>
<out_refund_no>%s</out_refund_no>
<total_fee>%s</total_fee>
<refund_fee>%s</refund_fee>
<refund_fee_type>%s</refund_fee_type>
<refund_desc>%s</refund_desc>
<refund_account>%s</refund_account>
<notify_url>%s</notify_url>
</xml>';
$params['appid'] = $this->appid;
$params['mch_id'] = $this->mch_id;
ksort($params);
$string = $this->ToUrlParams($params);
$string .= "&key={$this->mchkey}";
if (strtoupper($params['sign_type']) == 'MD5') {
$sign = md5($string);
} else {
$sign = hash_hmac($string);
}
$params['sign'] = $sign;
$data = sprintf(
$str,
$params['appid'],
$params['mch_id'],
$params['nonce_str'],
$params['sign'],
$params['sign_type'],
$params['transaction_id'],
$params['out_trade_no'],
$params['out_refund_no'],
$params['total_fee'],
$params['refund_fee'],
$params['refund_fee_type'],
$params['refund_desc'],
$params['refund_account'],
$params['notify_url']
);
$flag = $this->curl_post_ssl($url, $data, $msg);
if (!$flag) {
$this->msg = $msg;
return false;
}
$return = toXmlTree($msg);
if (!$return) {
$this->msg = '无法获取退款信息';
return false;
}
$vals = $return['vals'];
$index = $return['index'];
$return_code = getXmlValue($vals, 'return_code');
if ($return_code != "SUCCESS") {
$this->msg = getXmlValue($vals, 'return_msg');
return false;
}
$result_code = getXmlValue($vals, 'result_code');
if ($result_code != "SUCCESS") {
$this->msg = getXmlValue($vals, 'err_code_des');
return false;
}
return true;
}
protected function curl_post_ssl($url, $vars,&$msg = '', $second = 30, $fileDir = "C:/cert/", $aHeader = array()) {
$ch = curl_init();
//超时时间
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//以下两种方式需选择一种
//第一种方法,cert 与 key 分别属于两个.pem文件
//默认格式为PEM,可以注释
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, $fileDir . '/1269973401_20181119_cert.pem');
//默认格式为PEM,可以注释
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, $fileDir . '/1269973401_20181119_key.pem');
//第二种方式,两个文件合成一个.pem文件
// curl_setopt($ch, CURLOPT_SSLCERT, getcwd() . '/all.pem');
if (count($aHeader) >= 1) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
$data = curl_exec($ch);
if ($data) {
curl_close($ch);
$msg = $data;
return true;
} else {
$error = curl_errno($ch);
$msg = "call faild, errorCode:$error\n";
curl_close($ch);
return false;
}
}
// 获取消息内容
public function getMsg() {
return $this->msg;
}
/**
* 格式化参数格式化成url参数
*/
public function ToUrlParams($data) {
$buff = "";
foreach ($data as $k => $v) {
if ($k != "sign" && $v != "" && !is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
}
相关函数
// CURL发送
function curlPost($url, $jsonData) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function curlGet($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function getUploadDir($type) {
global $identifier;
if ($type) {
return "./data/attachment/{$identifier}/image/{$type}/";
} else {
return "./data/attachment/{$identifier}/image/upload/";
}
}
// xml格式转换成json格式
function xmlTojson($xmlstr) {
$xml = simplexml_load_string($xmlstr);
$json = json_decode(json_encode($xml), true);
return $json;
}
//解析成xml树
function toXmlTree($xml) {
$p = xml_parser_create();
xml_parse_into_struct($p, $xml, $vals, $index);
xml_parser_free($p);
return array('vals' = > $vals, 'index' = > $index);
}
//与 toXmlTree 配合解析 节点元素
function getXmlValue($vals, $key) {
$value = null;
$key = strtoupper($key);
foreach($vals as $k = > $v) {
if ($v['tag'] == $key) {
$value = $v['value'];
}
}
return $value;
}
function guid() {
if (function_exists('com_create_guid')) {
return com_create_guid();
} else {
mt_srand((double) microtime() * 10000); //optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);
$uuid = chr(123).substr($charid, 0, 8).$hyphen.substr($charid, 8, 4).$hyphen.substr($charid, 12, 4).$hyphen.substr($charid, 16, 4).$hyphen.substr($charid, 20, 12).chr(125);
return $uuid;
}
}