Home  >  Article  >  PHP Framework  >  ThinkPHP6 docking realizes WeChat H5 payment

ThinkPHP6 docking realizes WeChat H5 payment

王雪芹
王雪芹Original
2020-09-09 11:56:583726browse

WeChat H5 payment is an indispensable function for mobile e-commerce web pages. Today we will lead you to implement ThinkPHP6 docking to implement WeChat H5 payment.

1. Preparation

Doing WeChat payment also requires enterprise qualifications and a certified WeChat service account. Of course, this requires paying 300 yuan to WeChat. .

After specifying the qualifications to apply for, we open the WeChat payment platform, click "Product Center" on the navigation - "Click 'H5 Payment', and fill in the And configure the relevant domain name information. After filling it out, you can wait for the official WeChat review and approval. If the application is not approved, WeChat will inform you of the reason until H5 payment is successfully activated.

2. Connect with WeChat H5 payment

We first open the official document of WeChat H5 payment. Unfortunately, WeChat H5 payment does not give us the same payment as Native scan code payment. Prepare official SDK&DEMO. Without official SDK&DEMO, we need to integrate it ourselves.

WeChat H5 payment is not difficult, we fully read the unified ordering chapter.

1. Prepare parameters.

WeChat official has listed the parameters in detail for us. It is not difficult to obtain these parameters. We need to pay attention to two parameters: one is the signature sign, and the other is the terminal IPspbill_create_ip.

Signature official has given detailed instructions. We sort the ASCII codes from small to large in the form of key1=value1&key2=value2. After sorting, StringA is obtained, and then the obtained StringA and key are used to splice them, and finally they are converted to uppercase.

Let’s look at the detailed code:

public function index(){

        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址

        //1.获取调用统一下单接口所需必备参数
        $appid = 'wxff5b6b241a4fb11';//微信公众号appid
        $mch_id = '152223331';//微信支付商户号
        $key = 'b304911d6a9f7728d264dfd695ebae1';//自己设置的微信商家key
        $out_trade_no = time();//平台内部订单号
        $nonce_str=MD5(time());//随机字符串
        $body = '商品购买';//付款内容
        $total_fee = 1;//订单总金额,单位为分
        $spbill_create_ip = $this -> get_client_ip(); //获得用户设备IP
        $attach = 'weixinh5';//附加数据(自定义,在支付通知中原样返回)        
        $notify_url = "http://www.xxx.cn/mobile/WechatPay/notify";//通知地址
        $trade_type = 'MWEB';//交易类型,微信H5支付时固定为MWEB

        //2.将参数按照key=value的格式,并按照参数名ASCII字典序排序生成字符串
        $signA ="appid=$appid&attach=$attach&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&out_trade_no=$out_trade_no&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
        
        //3.拼接字符串
        $strSignTmp = $signA."&key=$key";

        //4.MD5加密后转换成大写
        $sign = strtoupper(MD5($strSignTmp));

        //5.拼接成所需XML格式
        $post_data = "<xml> 
                <appid>$appid</appid> 
                <attach>$attach</attach> 
                <body>$body</body> 
                <mch_id>$mch_id</mch_id> 
                <nonce_str>$nonce_str</nonce_str> 
                <notify_url>$notify_url</notify_url> 
                <out_trade_no>$out_trade_no</out_trade_no> 
                <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>";

    }

A $this is used here -> get_client_ip() To obtain the IP address, let’s look at the code of this method:

public function get_client_ip() {
        if(getenv(&#39;HTTP_CLIENT_IP&#39;) && strcasecmp(getenv(&#39;HTTP_CLIENT_IP&#39;), &#39;unknown&#39;)) {
            $ip = getenv(&#39;HTTP_CLIENT_IP&#39;);
        } elseif(getenv(&#39;HTTP_X_FORWARDED_FOR&#39;) && strcasecmp(getenv(&#39;HTTP_X_FORWARDED_FOR&#39;), &#39;unknown&#39;)) {
            $ip = getenv(&#39;HTTP_X_FORWARDED_FOR&#39;);
        } elseif(getenv(&#39;REMOTE_ADDR&#39;) && strcasecmp(getenv(&#39;REMOTE_ADDR&#39;), &#39;unknown&#39;)) {
            $ip = getenv(&#39;REMOTE_ADDR&#39;);
        } elseif(isset($_SERVER[&#39;REMOTE_ADDR&#39;]) && $_SERVER[&#39;REMOTE_ADDR&#39;] && strcasecmp($_SERVER[&#39;REMOTE_ADDR&#39;], &#39;unknown&#39;)) {
            $ip = $_SERVER[&#39;REMOTE_ADDR&#39;];
        }
        return preg_match ( &#39;/[\d\.]{7,15}/&#39;, $ip, $matches ) ? $matches [0] : &#39;&#39;;
    }

2. Post the parameters to the official address.

The official address is the URL address: https://api.mch.weixin.qq.com/pay/unifiedorder. This address is not allowed to be changed. We post the prepared xml parameters.

$dataxml = $this -> httpRequest($url,'POST',$post_data) ;

The httpRequest method here is used to send post data:

public function httpRequest($url, $method, $postfields = null, $headers = array(), $debug = false) {
        $method = strtoupper($method);
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */
        curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
        switch ($method) {
        case "POST":
            curl_setopt($ci, CURLOPT_POST, true);
            if (!empty($postfields)) {
            $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
            curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
            }
            break;
        default:
            curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
            break;
        }
        $ssl = preg_match(&#39;/^https:\/\//i&#39;,$url) ? TRUE : FALSE;
        curl_setopt($ci, CURLOPT_URL, $url);
        if($ssl){
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
        }
        curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);
        $response = curl_exec($ci);
        $requestinfo = curl_getinfo($ci);
        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);
            echo "=====info===== \r\n";
            print_r($requestinfo);
            echo "=====response=====\r\n";
            print_r($response);
        }
        curl_close($ci);
        return $response;
    }

Let’s take a look at the complete code:

public function index(){

        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址

        //1.获取调用统一下单接口所需必备参数
        $appid = &#39;wxff5b68b241a4fb11&#39;;//微信公众号appid
        $mch_id = &#39;1522223331&#39;;//微信支付商户号
        $key = &#39;b304911d6a19f7728d264dfd695ebae1&#39;;//自己设置的微信商家key
        $out_trade_no = time();//平台内部订单号
        $nonce_str=MD5(time());//随机字符串
        $body = &#39;商品购买&#39;;//付款内容
        $total_fee = 1;//订单总金额,单位为分
        $spbill_create_ip = $this -> get_client_ip(); //获得用户设备IP
        $attach = &#39;weixinh5&#39;;//附加数据(自定义,在支付通知中原样返回)        
        $notify_url = "http://www.dongpaiweb.cn/mobile/WechatPay/notify";//通知地址
        $trade_type = &#39;MWEB&#39;;//交易类型,微信H5支付时固定为MWEB

        //2.将参数按照key=value的格式,并按照参数名ASCII字典序排序生成字符串
        $signA ="appid=$appid&attach=$attach&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&out_trade_no=$out_trade_no&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
        
        //3.拼接字符串
        $strSignTmp = $signA."&key=$key";

        //4.MD5加密后转换成大写
        $sign = strtoupper(MD5($strSignTmp));

        //5.拼接成所需XML格式
        $post_data = "<xml> 
                <appid>$appid</appid> 
                <attach>$attach</attach> 
                <body>$body</body> 
                <mch_id>$mch_id</mch_id> 
                <nonce_str>$nonce_str</nonce_str> 
                <notify_url>$notify_url</notify_url> 
                <out_trade_no>$out_trade_no</out_trade_no> 
                <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>";

        //6.以POST方式向微信传参,并取得微信返回的支付参数
        $dataxml = $this -> httpRequest($url,&#39;POST&#39;,$post_data);
        $objectxml = (array)simplexml_load_string($dataxml, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA); //将微信返回的XML转换成数组
        if($objectxml[&#39;return_code&#39;] == &#39;SUCCESS&#39;){
            if($objectxml[&#39;result_code&#39;] == &#39;SUCCESS&#39;)//如果这两个都为此状态则返回mweb_url,详情看‘统一下单’接口文档
                $return_url = "http://www.dongpaiweb.cn/mobile/WechatPay/return";//支付后跳转地址
                $urls = $objectxml[&#39;mweb_url&#39;] . &#39;&redirect_url=&#39; . urlencode($return_url);
                
                //访问这个url  但是在用下面的方法访问是 报错商家信息有误 所以我把url 放到视图中 跳转
                // header("Location:$urls");
                return view(&#39;mobile_pay&#39;,[
                    &#39;url&#39;=>$urls
                ]);
                //mweb_url是微信返回的支付连接要把这个连接分配到前台
            if($objectxml[&#39;result_code&#39;] == &#39;FAIL&#39;){
                return $err_code_des = $objectxml[&#39;err_code_des&#39;];
            }
                
        }

    }

Need to pay attention , WeChat returns parameters return_code and result_code. Return_code only represents successful communication, not successful transaction. The transaction is successful only when return_code and result_code are both SUCCESS.

Finally, we need to distinguish between the notify address and the return address. The notify address is a payment notification from WeChat to the merchant. It is the same as Native payment and is sent in the form of a data stream. The return address is the jump page after the user pays, and is for the user to see.

The above is the relevant introduction to ThinkPHP6 docking to implement WeChat H5 payment, everyone, come on!

The above is the detailed content of ThinkPHP6 docking realizes WeChat H5 payment. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn