微信公众号H5页面支付JSAPI

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&notify_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种支付方法:我这个是一种,直接付款的!

另外一种支付方法适合多种方法里使用:例如微信内部支付,微信内部转发,微信内部那个啥!

猜你喜欢

转载自blog.csdn.net/munchmills/article/details/126699432