微信支付jsapi

20200701微信支付 

JsApi(在手机微信中打开进行支付)

   1.引入api包

        下载php版本API
        https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
        注:
    1.tp5.1框架下,将API文件中子文件夹放入extend/wxpay中
        2.若使用框架,请以public为当前路径,进行文件路径处理
        3.接收回调时,先写入文件,在读取文件,直接读取可能为空

  2.准备参数

      //微信商户信息
      const
APPID = ''; //商户唯一标识   const MCHID = ''; //商户收款账号 const KEY = ''; //交易过程生成签名的密钥 const APPSECRET = ''; //AppSecret是APPID对应的接口密码,用于获取接口调用凭证access_token时使用
   3.获取openID
     //判断是否有openId
        public function initialize(){
 

            if(session('?openid')){
 

                $openid = session('openid');
 

            }else{
            
                $weixin=new appadmincontrollerWeixin();
                //获取openId
                $weixin->getUserOpenId();
                
            }
        
        }
 

        /**
        * 获取用户openid
        */
        public function getUserOpenId(){
            
            $request = Request::instance();
            $method = $request->method();
            $code= $request->get('code');
            
            if(empty($code)){
                $redirect_uri = urlencode("http://xxx/pay_test/public/wxpay/openid");
                $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri=".$redirect_uri."&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
                $this->redirect($url);
            }else{
                // 获取页面授权的access_token
                $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code";
            
                // 3、拉取用户的openid
                $res = $this->http_curl($url,'get');
                
                $access_token = $res["access_token"];
 

                $openid = $res['openid'];
                
                if($openid){
                    //拉取成功
                    session('openid',$openid,'think');
                    session('access_token',$access_token,'think');
                    $this->redirect('/pay_test/public/wxpay');
                }else{
                    //拉取失败
                    $this->error("openid拉取失败!");
                }
            }
 

        }
 

        /**
        *   $url 接口url
        *   $type 请求类型
        *   $res 返回数据类型
        *   $arr post请求参数
        */
        public function http_curl($url, $type='get', $res='json', $arr=' '){
 

            // 1、初始化curl
            $ch = curl_init();
 

            // 2、设置curl参数,默认get方法请求的
            curl_setopt($ch, CURLOPT_URL, $url);
            // 设置url
 

            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 返回
            //post方法请求
            if($type == 'post') {
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
            }
 

            // 3、采集(抓取)
            $output = curl_exec($ch);
            if($res == 'json') {
                if(curl_errno($ch)) {
                    // 请求失败,返回错误信息
                    return curl_error($ch);
                }else {
                    return json_decode($output, true);
                }
            }
 

            // 4、关闭curl
            curl_close($ch);
        }

  4.统一下单

     //统一下单
        public function pay(){
 
            $request = Request::instance();
            //付款金额(分)
            $price = 1;
            
            $openid = session('openid');
 
            if(!empty($openid)){

                //微信支付生成
                ini_set('date.timezone','Asia/Shanghai');
                require_once "../extend/wxpay/lib/WxPay.Api.php";
                include_once "../extend/wxpay/example/WxPay.JsApiPay.php";
                require_once '../extend/wxpay/example/log.php';
                require_once '../extend/wxpay/example/WxPay.Config.php';
                $wxpay = new WxPayApi();
                $tools = new JsApiPay();
            
                $out_trade_no = "".date('YmdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
                
                //付款后回调地址
                $notifyurl="http://xxx/pay_test/public/wxpay/redata";
 
                //统一下单
                $input = new WxPayUnifiedOrder();
                //商品描述
                $input->SetBody("测试订单");
                //商户订单号
                $input->SetOut_trade_no($out_trade_no);
                //附加数据
                $input->SetAttach("测试附加数据");
                //标价金额
                $input->SetTotal_fee($price);  
                //交易起始时间
                $input->SetTime_start(date("YmdHis"));
                //交易结束时间
                $input->SetTime_expire(date("YmdHis", time() + 600));
                //订单优惠标记
                $input->SetGoods_tag("测试优惠标记");
                //通知地址
                $input->SetNotify_url($notifyurl);
                //交易类型
                $input->SetTrade_type("JSAPI");
                //用户标识
                $input->SetOpenid($openid);
                $config = new WxPayConfig();
 
                //获取统一下单数据
                $wxdata = $wxpay->unifiedOrder($config,$input);
 
                $jsApiParameters = $tools->GetJsApiParameters($wxdata);
 
                return ["code"=>0,"data"=>$jsApiParameters,"out_trade_no"=>$out_trade_no,"price"=>$price];

            }else{

                return ["code"=>-1,"msg"=>"openid不能为空"];
                
            }

        }
5.jsapi支付
     //微信支付JsApi
        public function index(){

            //统一下单
            $data = $this->pay();
            //返回数据
            $redata= $data['data'];
            //字符串转数组
            $redata = json_decode($redata);
            
            foreach($redata as $k=>$val){
 
                //获取package
                if( $k == "package"){
                    $targer = $val;
                }

                //获取nonceStr
                if($k == 'nonceStr'){
                    $noncestr = $val;
                }

                //获取paySign
                if($k == 'paySign'){
                    $sign = $val;
                }
 
                //获取timeStamp
                if($k == 'timeStamp'){
                    $time = $val;
                }
 
            }
            
            $out_trade_no = $data['out_trade_no'];
            $price = $data['price'];
            $this->assign('out_trade_no',$out_trade_no);
            $this->assign('price',$price);
            $this->assign('package',$targer);
            $this->assign('noncestr',$noncestr);
            $this->assign('sign',$sign);
            $this->assign('time',$time);
            return view('index');
 
        }  

 6.调出微信支付插件
     <script src="/pay_test/public/static/admin/js/jquery-3.1.1.min.js" type="text/javascript"></script>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
        <script>
            var nonceStr = "{$noncestr}";
            var time = "{$time}";
            var paySign = "{$sign}";
            var package = "{$package}";
            var out_trade_no = "{$out_trade_no}";
            var price = "{$price}";
        </script>
        <script>
        function onBridgeReady(){
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId":"xxx",     //公众号名称,由商户传入     
                    "timeStamp":time,         //时间戳,自1970年以来的秒数     
                    "nonceStr":nonceStr, //随机串     
                    "package":package,     
                    "signType":"MD5",         //微信签名方式:     
                    "paySign":paySign //微信签名 
                },
                
                function(res){
                if(res.err_msg == "get_brand_wcpay_request:ok" ){
                // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠
                
                    location.href = "http://xxx/redata?sign="+paySign+"&price="+price;
                    
                } 
            }); 
        }
        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();
        }
        </script>
 7. 支付成功,接收回调
    public function redata(){
$get_data = request()->get(); //接收微信返回信息 $redata = file_get_contents("php://input"); //服务器根目录 define('BASE_PATH',$_SERVER['DOCUMENT_ROOT']); //文件目录 $dir = BASE_PATH.'/pay_test/public/uploads/admin/wxpay/'.date("Ymd")."/"; //文件名 $filepath = date('Y-m-d h:i:s', time())."txt"; //判断是否有该目录 if(!file_exists($dir)){ //创建目录 mkdir($dir,0777,true); } //写入接收到的信息 file_put_contents($dir.$filepath,$redata,FILE_APPEND); //获取文件中信息,转为字符串 $data = file_get_contents($dir.$filepath); //转为数组 $redata_array = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA); var_dump($redata_array); return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; }
原文地址:https://www.cnblogs.com/mrli-php/p/13218376.html