1:在微信环境下,我们需要获取到code,拿code去获取openid,在获取openid的时候有2种参数分别是:snsapi_base和snsapi_userinfo,snsapi_base只为获取openid,snsapi_userinfo后者为获取客户授权例如:微信号:头像等等参数!
注:在末尾微信链接可以带参数传值state=值!
code五分钟过期,使用过一次过期!
我们先来上代码:
$appid = 公众号appid;
$redirect_uri = 微信回调链接;
$snsapi =snsapi_base//snsapi_userinfo;
$url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$appid."&redirect_uri=".$redirect_uri."&response_type=code&scope=".$snsapi;
Header("Location:$url");
2:拿到get回来的code值:配合上appid - secret(在公众号设置里获取)+获取来得code,用post拿openid,付上代码:
$code =input('get.code');
$appid =appid值;
$secret =secret值;
$url ="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
$back =$this->geturl($url);//去post拿值
3:到目前位置$back就有openid值了,如果还需要snsapi_userinfo下面的继续参数!通过access_token(获取来得值) + openid 可以获取客户头像
注意:这里会调用到微信插件拉起授权登录!
但是,我在这次开发的时候,微信视乎修改了强制拉起授权界面,已经改为底部提示授权,这个是不太友好的(对于开发者),我目前没有找到强制授权界面的方法。如果找到了,我会更新这里!
$url ='https://api.weixin.qq.com/sns/userinfo?access_token='.$back['access_token'].'&openid='.$back['openid'].'&lang=zh_CN';
$backWeixin = $this ->geturl($url); //这里用curl get
4:拿到openid值,我们可以开始支付准备了!
$openid ='上面获取的openid';
$appid ='公众号appid';
$key ='支付商户号里api安全里设置';//我目前用的是V2
$mch_id ='微信商户号';//注意不要选服务商号
$total_fee = 1; //微信已分计算
$body = '商品名称'; //商品描述
$out_trade_no = '订单号'; //订单号
$nonce_str = MD5($out_trade_no);//随机字符串
$spbill_create_ip = '获取ip';
$trade_type = 'JSAPI';//交易类型
$notify_url = '回调域名';
$scene_info ='{"h5_info":{"type":"Wap","wap_url":"域名","wap_name":"名称"}}'; //场景信息
$signA = "appid=$appid&body=$body&mch_id=$mch_id&nonce_str=$nonce_str¬ify_url=$notify_url&openid=$openid&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
$strSignTmp = $signA."&key=$key"; //拼接字符串
$sign = strtoupper(md5($strSignTmp)); // MD5 后转换成大写
$date = "<xml>
<appid>$appid</appid>
<body>$body</body>
<mch_id>$mch_id</mch_id>
<nonce_str>$nonce_str</nonce_str>
<notify_url>$notify_url</notify_url>
<openid>$openid</openid>
<out_trade_no>$out_trade_no</out_trade_no>
<scene_info>$scene_info</scene_info>
<spbill_create_ip>$spbill_create_ip</spbill_create_ip>
<total_fee>$total_fee</total_fee>
<trade_type>$trade_type</trade_type>
<sign>$sign</sign>
</xml>";
$dataxml = $this->http_post("https://api.mch.weixin.qq.com/pay/unifiedorder",$date);
$objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA);
5:到上一步我们主要拿的值是prepay_id;如果你用过post拿到了正常的值,那么我们就剩下最后2步了
$prepayId ='上面获取到的值';
$pay = array(
'appId' => $appid,
'timeStamp' => '' . time() . '', //时间戳
'nonceStr' => $this->createNoncestr(), //随机串
'package' => 'prepay_id='.$prepayId, //数据包
'signType' => 'MD5'//签名方式
);
$pay['paySign'] = $this->getSign($pay);
这里是2个方法
private function createNoncestr($length = 32) {
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } //作用:生成签名
private function getSign($Obj) { foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
$String = $String . "&key=1DKJ48bncxh3jd83ndcdAA23fvcf4g5w";
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
///作用:格式化参数,签名过程需要使用
private function formatBizQueryParaMap($paraMap, $urlencode) {
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
6:到这一步我们就可以$pay里拿到所有值了!如果你没有报错的话,报错请一步步检查!
下面我们就把$pay的值返回给前端页面;
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId" :'{$vo.appId}', //公众号ID
"timeStamp" :'{$vo.timeStamp}', //时间戳,当前系统的时间,具体格式,请看API
"nonceStr" : '{$vo.nonceStr}', //随机串,具体格式请看API
"package" : '{$vo.package}',//扩展包
"signType" : "MD5", //微信签名方式:sha1
"paySign" : '{$vo.paySign}', //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
成功跳转
}else{
失败跳转
}
});
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
注:微信环境内部H5页面,微信提供了2种支付方法:我这个是一种,直接付款的!
另外一种支付方法适合多种方法里使用:例如微信内部支付,微信内部转发,微信内部那个啥!