获取微信用户openid
/**
* 实例化redis对象
* @return Redis redis对象
*/
function newRedis()
{
$redis=new \Redis();
$redis->connect("127.0.0.1",6379);
$redis->auth("redis密码");
return $redis;
}
/**
* 请求微信api
*/
private $_openUrlAuthorize = "https://open.weixin.qq.com/connect/oauth2/authorize";
public function requestUrl()
{
require_once './Wpay/lib/WxPay.Api.php';
//该参数可用于防止csrf攻击(跨站请求伪造攻击)
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol)-1;
for($i=0;$i<10;$i++){
$str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
}
$uid=get_cookie("uid");
$stats = $uid . $str;
$redis = newRedis();
$redis->set('wx_state'.$uid,$stats);//把随机字符串写入redis,验证时对比
$url=$this->_openUrlAuthorize."?appid=".\WxPayConfig::APPID."&redirect_uri=".urlencode("回调地址")."&response_type=code&scope=snsapi_userinfo&state=".$stats."#wechat_redirect";
/**
* 生成二维码
*/
require './Wpay/example/phpqrcode/phpqrcode.php';
// 纠错级别:L、M、Q、H
$level = 'L';
// 点的大小:1到10,用于手机端4就可以了
$size = 4;
// 下面注释了把二维码图片保存到本地的代码,如果要保存图片,用$fileName替换第二个参数false
//$path = "images/";
// 生成的文件名
//$fileName = $path.$size.'.png';
\QRcode::png($url, false, $level, $size);
}
/**
* 获取提现人的openid
*/
private $_openUrlToken = "https://api.weixin.qq.com/sns/oauth2/access_token";
public function getOpenid()
{
$code = I('code');//只能使用1次即销毁
$state =I('state');
//获取uid
$patterns = "/\d+/";
preg_match_all($patterns,$state,$arr);
$uid=$arr[0][0];
//获取redis里面的state
$redis = newRedis();
$wx_state = $redis->get("wx_state".$uid);
if($state != $wx_state){
$this->error("请重新扫描二维码",'控制器/requestUrl');
exit();
}
$redis->del("wx_state".$uid);//清除这个redis
require './Wpay/lib/WxPay.Api.php';
//获取access_token和openid信息,还有用户唯一标识unionid
$url = $this->_openUrlToken.'?appid='.\WxPayConfig::APPID.'&secret='.\WxPayConfig::APPSECRET.'&code='.$code.'&grant_type=authorization_code';
$ken = $this->httpGet($url);//获取token数据
if($ken['errcode'] == 40029){
$this->error("code参数已经过期",U("Index/index"));
}
//获取微信用户信息
$wxinfo=$this->wxUserInfo($ken["access_token"],$ken['openid']);
if($wxinfo['errcode']){
$this->error("拉取微信信息失败,请稍后再试",U("Index/index"));
}
$re=M("Memberdetail")->where(array("member_id"=>$uid))->save(array("weixin_openid"=>$ken['openid'],"weixin_nickname"=>$wxinfo["nickname"]));
if($re === false){
$this->error("绑定微信号出错,请稍后再试",U("Index/index"));
}
$this->success("绑定微信号成功,请在电脑上继续操作",U("Index/index"));
}
//CURL获取url返回值
function httpGet($url){
$oCurl = curl_init();//实例化
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );//是否返回值,1时给字符串,0输出到屏幕
$sContent = curl_exec($oCurl);//获得页面数据
$aStatus = curl_getinfo($oCurl);//获取CURL连接数据的信息
curl_close($oCurl);//关闭资源
//获取成功
$output_array = json_decode($sContent,true);//转换json格式
if(intval($aStatus["http_code"])==200){
return $output_array;
}else{
return false;
}
}
进行微信企业打款
require './Wpay/lib/WxPay.Api.php';
require './Wpay/example/log.php';
//初始化日志
$logHandler= new \CLogFileHandler("./Wpay/logs/".date('Y-m-d').'.log');
$log = \Log::Init($logHandler, 15);
/**
* 微信提现
*/
$branch=number_format($record["money"],"2",".","");
$postData=array(
"mch_appid"=>\WxPayConfig::APPID, //绑定支付的APPID
"mchid"=>\WxPayConfig::MCHID, //商户号
"nonce_str"=>"rand".rand(100000, 999999), //随机数
"partner_trade_no"=>$record["businessman_sn"], //商户订单号
"openid"=>$record["weixin_openid"], //用户唯一标识
"check_name"=>"NO_CHECK", //校验用户姓名选项,NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
"re_user_name"=>$record["txnickname"], //用户姓名
"amount"=>$branch*100, //金额(以分为单位,必须大于100)
"desc"=>"您在艺XXX申请提现".$branch."元受理成功,请在微信零钱进行查看", //描述
"spbill_create_ip"=>$_SERVER["REMOTE_ADDR"], //请求ip
);
/**
* 生成签名
*/
ksort($postData);
$buff = "";
foreach ($postData as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$string = trim($buff, "&");
$string = $string . "&key=".\WxPayConfig::KEY;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$sign = strtoupper($string);
$postData["sign"]=$sign;
/**
* 组装xml数据
*/
$xml = "<xml>";
foreach ($postData as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
/**
* 发送post请求
*/
$url="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
//如果有配置代理这里就设置代理
if(\WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
&& \WxPayConfig::CURL_PROXY_PORT != 0){
curl_setopt($ch,CURLOPT_PROXY, \WxPayConfig::CURL_PROXY_HOST);
curl_setopt($ch,CURLOPT_PROXYPORT, \WxPayConfig::CURL_PROXY_PORT);
}
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, \WxPayConfig::SSLCERT_PATH);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, \WxPayConfig::SSLKEY_PATH);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$dataRe = curl_exec($ch);
//返回结果
if($dataRe){
curl_close($ch);
/**
* xml转数组
*/
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$dataArr = json_decode(json_encode(simplexml_load_string($dataRe, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
if($dataArr["return_code"] == "SUCCESS" && $dataArr["result_code"] == "SUCCESS"){
$typeStr = "微信";
$saveData = array(
'id' => $data['id'],
'status' => $data['status'],
'memo' => $data['memo'],
'check_time' => date('Y-m-d H:i:s')
);
if (false === D('Record')->save($saveData)) {
throw new \Exception('提现失败');
}
}elseif($dataArr["err_code"] == "SYSTEMERROR"){
\Log::DEBUG("error:" . $dataRe);
throw new \Exception('微信系统繁忙,请稍后再试。');
}else{
\Log::DEBUG("error:" . $dataRe);
throw new \Exception('微信提现失败:'.$dataArr["err_code_des"]);
}
} else {
$error = curl_errno($ch);
curl_close($ch);
\Log::DEBUG("error:" . $error);
throw new \Exception("curl出错,错误码:$error");
}