时间: 2020-09-3|tag: 23次围观|0 条评论

PS:微信支付基础条件

1.一个认证的服务号

2.在服务号后台申请微信支付,成功后获得一个商户号

3.在商户号里面选择native支付,这个就是扫码支付,按照提示开通这项。

PHP微信扫码支付DEMO,thinkphp5+微信支付插图

 

4.按照微信支付文档的说法,扫码支付分两种模式

模式一:生成的二维码没有失效性,但是操作比较复杂,中间步骤比较多,容易出现很多问题。

模式二:生成的二维码有两小时时间限制,但是我感觉也十分够用了,这个步骤比较简单,很容易实现。

按照时序图,大概也就分两步

PHP微信扫码支付DEMO,thinkphp5+微信支付插图1

 

代码结构:

PHP微信扫码支付DEMO,thinkphp5+微信支付插图2

 

 

 

配置文件:

PHP微信扫码支付DEMO,thinkphp5+微信支付插图3

 

 微信支付类:

<?php/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */namespace tools;use think\Config;/** * Description of WxPay * * @author admin */class WxPay {        /**     * 获取签名     * @param type $arr     * @return type     */    public function getSign($arr)    {         //去除数组的空值        array_filter($arr);        if(isset($arr['sign'])){            unset($arr['sign']);        }        //排序        ksort($arr);        //组装字符        $str = $this->arrToUrl($arr) . '&key=' . Config::get('wx_pay')['key'];        //使用md5 加密 转换成大写        return strtoupper(md5($str));    }        /**     * 校验签名     * @param type $arr     * @return boolean     */    public function checkSign($arr){                //生成新签名        $sign = $this->getSign($arr);        //和数组中原始签名比较        if($sign == $arr['sign']){            return true;        }else{            return false;        }    }        /**     * 获取带签名的数组     * @param array $arr     * @return type     */    public function setSign($arr)    {        $arr['sign'] = $this->getSign($arr);        return $arr;    }        /**     * 数组转URL字符串 不带key     * @param type $arr     * @return type     */    public function arrToUrl($arr)    {        return urldecode(http_build_query($arr));    }        /**     * 记录到文件     * @param type $file     * @param type $data     */    public function logs($file,$data)    {        $data = is_array($data) ? print_r($data,true) : $data;        file_put_contents('./public/paylogs/' .$file, $data);    }    /**     * 接收POST推送     * @return type     */    public function getPost()    {        return file_get_contents('php://input');    }        /**     * Xml 文件转数组     * @param type $xml     * @return string     */    public function XmlToArr($xml)    {            if($xml == '') return '';        libxml_disable_entity_loader(true);        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);                return $arr;    }        /**     * 数组转XML     * @param type $arr     * @return string     */    public function ArrToXml($arr)    {        if(!is_array($arr) || count($arr) == 0) return '';        $xml = "<xml>";        foreach ($arr as $key=>$val)        {                if (is_numeric($val)){                        $xml.="<".$key.">".$val."</".$key.">";                }else{                        $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";                }        }        $xml.="</xml>";        return $xml;     }        /**     * 发送POST请求     * @param type $url     * @param type $postfields     * @return type     */    public function postStr($url,$postfields)    {        $ch = curl_init();        $params[CURLOPT_URL] = $url;    //请求url地址        $params[CURLOPT_HEADER] = false; //是否返回响应头信息        $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回        $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向        $params[CURLOPT_POST] = true;        $params[CURLOPT_SSL_VERIFYPEER] = false;//禁用证书校验        $params[CURLOPT_SSL_VERIFYHOST] = false;        $params[CURLOPT_POSTFIELDS] = $postfields;        curl_setopt_array($ch, $params); //传入curl参数        $content = curl_exec($ch); //执行        curl_close($ch); //关闭连接        return $content;    }        /**     * 统一下单     * @param type $params     * @return boolean     */    public function unifiedorder($params)    {        //获取到带签名的数组        $params = $this->setSign($params);        //数组转xml        $xml = $this->ArrToXml($params);        //发送数据到统一下单API地址        $data = $this->postStr(Config::get('wx_pay')['uourl'], $xml);        $arr = $this->XmlToArr($data);        if($arr['result_code'] == 'SUCCESS' && $arr['return_code'] == 'SUCCESS'){            return $arr;        }else{            $this->logs('error.txt', $data);            return false;        }    }}

 

index控制器演示代码

 

<?phpnamespace app\index\controller;use app\common\controller\HomeBase;use tools\WxPay;use think\Config;use phpqrcode\ApiQrcode;use think\Request;use think\Cache;use tools\RetJosn;class Index extends HomeBase {    /**     * 首页     * @param WxPay $wxpay     * @return mixed     */    public function index(WxPay $wxpay) {        //$wxpay->logs('log.txt',['213123','123123123']);        echo 'index';    }    /**     * 扫码支付-模式二     * @param WxPay $wxpay     */    public function index2(Request $request, WxPay $wxpay) {        if ($request->isGet()) {            return $this->fetch();        }    }    /**     * 统一下单,生成二维码     */    public function getQrUrl(Request $request) {        $pid = $request->get('id');        //调用统一下单API        $params = [            'appid' => Config::get('wx_pay')['appid'],            'mch_id' => Config::get('wx_pay')['mchid'],            'nonce_str' => md5(time()),            'body' => '订单号:'.$pid,            'out_trade_no' => $pid,            'total_fee' => 2,            'spbill_create_ip' => $_SERVER['SERVER_ADDR'],            'notify_url' => Config::get('wx_pay')['notify'],            'trade_type' => 'NATIVE',            'product_id' => $pid        ];        $wxpay = new WxPay();        $arr = $wxpay->unifiedorder($params);        if (!empty($arr['code_url'])) {            Cache::set('send' . $params['out_trade_no'], $params['total_fee'], 3600);            ApiQrcode::png($arr['code_url']);        } else {            return '下单失败!';        }    }    /**     * 接收腾讯推送支付通知     * @param WxPay $wxpay     */    public function backOrder(WxPay $wxpay) {        try {            // 获取腾讯传回来的通知数据            $xml = $wxpay->getPost();            // 将XML格式的数据转换为数组            $arr = $wxpay->XmlToArr($xml);            $wxpay->logs('logs.txt', '1');            // 验证签名            if ($wxpay->checkSign($arr)) {                Cache::set('back'.$arr['out_trade_no'],$arr['total_fee'],3600);            }            $wxpay->logs('logs.txt', '2');            $params = [                'return_code' => 'SUCCESS',                'return_msg' => 'OK'            ];            echo $wxpay->ArrToXml($params);        } catch (\Exception $e) {            $wxpay->logs('logs.txt', $e->getMessage());            exit();        }    }    /**     * 查询支付状态     * @param Request $request     * @return type     */    public function checkSuccess(Request $request){        $pid = $request->get('id');        if (Cache::get('send'.$pid) == Cache::get('back'.$pid)) {            return RetJosn::successJson('支付成功');        } else {            return RetJosn::errorJson(Cache::get('send'.$pid).'|'.Cache::get('back'.$pid));        }    }}

 二维码页面代码:

<!DOCTYPE html><!--To change this license header, choose License Headers in Project Properties.To change this template file, choose Tools | Templatesand open the template in the editor.--><html>    <head>        <title>TODO supply a title</title>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0">    </head>    <body>        <div class="btn-box">            <button onclick="getQrcode()">刷新二维码</button>        </div>        <div class="qrcode-box">            <img id="qrimg" src="">        </div>        <div class="status-box">            <h2 id="status"></h2>        </div>    </body>    <script src="__STATIC__/default/js/jquery-1.9.1.min.js"></script>    <script>        (function () {            getQrcode();//二维码生成        })();        /*验证码生成*/        function getQrcode() {            var id = getId(10);            var url = "{:url('Index/getQrUrl')}" + "?id=" + id;            $("#qrimg").attr("src", url);            sessionStorage.setItem('id',id);            checkSuccess();//轮询支付状态        }                /*生成唯一Id*/        function getId(length){            var tmp = Date.parse( new Date() ).toString();            tmp = tmp.substr(0,length);            return tmp;        }                /*轮询支付状态*/        function checkSuccess(){            var interval = window.setInterval(function(){                var id = sessionStorage.getItem('id');                $.ajax({                   url:"{:url('Index/checkSuccess')}?id=" + id,                   dataType:'json',                   success:function(res) {                       if (res.code == 200) {                           $('#status').html('订单号:'+id+','+res.msg);
                clearInterval(interval); } } }) },
2000) } </script></html>

 效果演示:

生成二维码,并开始启动轮询

PHP微信扫码支付DEMO,thinkphp5+微信支付插图4

手机上支付订单:

PHP微信扫码支付DEMO,thinkphp5+微信支付插图5

 

轮询到成功支付的状态:

 

 

PHP微信扫码支付DEMO,thinkphp5+微信支付插图6

 

文章转载于:https://www.cnblogs.com/wordblog/p/12540590.html

原著是一个有趣的人,若有侵权,请通知删除

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《PHP微信扫码支付DEMO,thinkphp5+微信支付
   

还没有人抢沙发呢~