Wechat payment jsapi

Time:2021-8-18

20200701 wechat payment

Jsapi (open in mobile wechat for payment)

   1.Introducing API packages

Download PHP version API
        https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
Note:
Under the 1.tp5.1 framework, put the subfolders of API files into extend / wxpay
2. If the framework is used, please use public as the current path for file path processing
3. When receiving the callback, write the file first. When reading the file, direct reading may be empty

  2.Prepare parameters

//Wechat merchant information const appid = ''// Merchant unique identification
        const MCHID = ''; // Merchant Collection account number
         const KEY = ''; // The transaction process generates a signed key
         const APPSECRET = ''; // Appsecret is the interface password corresponding to appid, which is used to obtain the interface call credential access_ Used when token
3. Get openid
//Determine whether there is openid
        public function initialize(){
 

            if(session('?openid')){
 

                $openid = session('openid');
 

            }else{
            
                $weixin=new \app\admin\controller\Weixin();
                //Get openid
                $weixin->getUserOpenId();
                
            }
        
        }
 

        /**
        *Get user 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{
                //Get access for page authorization_ token
                $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code";
            
                //3. Pull the openid of the user
                $res = $this->http_curl($url,'get');
                
                $access_token = $res["access_token"];
 

                $openid = $res['openid'];
                
                if($openid){
                    //Pull successful
                    session('openid',$openid,'think');
                    session('access_token',$access_token,'think');
                    $this->redirect('/pay_test/public/wxpay');
                }else{
                    //Pull failed
                    $this - > error ("openid pull failed!");
                }
            }
 

        }
 

        /**
        *$URL interface URL
        *$type request type
        *$res return data type
        *$arr post request parameters
        */
        public function http_curl($url, $type='get', $res='json', $arr=' '){
 

            //1. Initialize curl
            $ch = curl_init();
 

            //2. Set the curl parameter, which defaults to the value requested by the get method
            curl_setopt($ch, CURLOPT_URL, $url);
            //Set URL
 

            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_ setopt($ch, CURLOPT_ RETURNTRANSFER, 1); //  return
            //Post method request
            if($type == 'post') {
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
            }
 

            //3. Acquisition (grabbing)
            $output = curl_exec($ch);
            if($res == 'json') {
                if(curl_errno($ch)) {
                    //The request failed with an error message
                    return curl_error($ch);
                }else {
                    return json_decode($output, true);
                }
            }
 

            //4. Close curl
            curl_close($ch);
        }

4. Unified order

//Unified order
        public function pay(){
 
            $request = Request::instance();
            //Payment amount (min)
            $price = 1;
            
            $openid = session('openid');
 
            if(!empty($openid)){

                //Wechat payment generation
                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);
                
                //Callback address after payment
                $notifyurl="http://xxx/pay_test/public/wxpay/redata";
 
                //Unified order
                $input = new \WxPayUnifiedOrder();
                //Product description
                $input - > setbody ("test order");
                //Merchant order number
                $input->SetOut_trade_no($out_trade_no);
                //Additional data
                $input - > setattach ("test additional data");
                //Bid price amount
                $input->SetTotal_fee($price);  
                //Transaction start time
                $input->SetTime_start(date("YmdHis"));
                //Transaction end time
                $input->SetTime_expire(date("YmdHis", time() + 600));
                //Order discount mark
                $input->SetGoods_ Tag ("test offer mark");
                //Notification address
                $input->SetNotify_url($notifyurl);
                //Transaction type
                $input->SetTrade_type("JSAPI");
                //User ID
                $input->SetOpenid($openid);
                $config = new \WxPayConfig();
 
                //Obtain unified order data
                $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 cannot be empty"];
                
            }

        }
5. Jsapi payment
//Wechat payment jsapi
        public function index(){

            //Unified order
            $data = $this->pay();
            //Return data
            $redata= $data['data'];
            //String to array
            $redata = json_decode($redata);
            
            foreach($redata as $k=>$val){
 
                //Get package
                if( $k == "package"){
                    $targer = $val;
                }

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

                //Get paysign
                if($k == 'paySign'){
                    $sign = $val;
                }
 
                //Get 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. Call out wechat payment plug-in
var nonceStr = "{$noncestr}";
            var time = "{$time}";
            var paySign = "{$sign}";
            var package = "{$package}";
            var out_trade_no = "{$out_trade_no}";
            var price = "{$price}";
        
        
        function onBridgeReady(){
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    The name "appId": "XXX" // official account is introduced by merchants.     
                    "Timestamp": time, // timestamp, the number of seconds since 1970     
                    "Noncestr": noncestr, // random string     
                    "package":package,     
                    "Signtype": "MD5", // wechat signature method:     
                    "Paysign": paysign // wechat signature 
                },
                
                function(res){
                if(res.err_msg == "get_brand_wcpay_request:ok" ){
                //Using the above methods to judge the front-end return, the wechat team solemnly prompts: res.err_ MSG will return OK after the user pays successfully, but it is not guaranteed to be absolutely reliable
                
                    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();
        }
7. The payment is successful and the callback is received
public function redata(){
            $get_data = request()->get();
            
            //Receive wechat return information
            $redata = file_get_contents("php://input");
            //Server root
            define('BASE_PATH',$_SERVER['DOCUMENT_ROOT']);
            //File directory
            $dir = BASE_PATH.'/pay_test/public/uploads/admin/wxpay/'.date("Ymd")."/";
            //File name
            $filepath = date('Y-m-d h:i:s', time())."txt";
            //Determine whether the directory exists
            if(!file_exists($dir)){
                //Create directory
                mkdir($dir,0777,true);
            }
            //Write received information
            file_put_contents($dir.$filepath,$redata,FILE_APPEND);
            //Get the information in the file and convert it into a string
            $data = file_get_contents($dir.$filepath);
            //Convert to array
            $redata_array = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        
            var_dump($redata_array);
            
            return ''; 
            
        }