纵有疾风起
人生不言弃

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付

JSAPI支付:是指在微信内置浏览器内调用微信支付模块支付,比如可用于微信公众号内的微信商城之类的。

首先得在微信公众号的公众号设置里,把微信支付的授权目录填上

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图

 

 然后你还得在商户号里,开通微信JSAPI支付的功能

 

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图1

 

然后这里的授权目录也得填上

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图2

 

 

然后按照微信文档的时序图,大概分3步

 

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图3

 

项目结构:

 PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图4

配置文件:

 

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图5

 

 

 Jsapi.php代码:

 

 

<?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;/** * JSAPI支付DEMO * Class Index * @package app\index\controller */class Jsapi extends HomeBase {    /**     * 首页     */    public function index() {        $redirect_uri = urlencode('http://wxpay.ngrok2.xiaomiqiu.cn'.url('Jsapi/index2'));        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.Config::get('wx_pay')['appid'].'&redirect_uri='.$redirect_uri.'&response_type=code&scope=snsapi_base&state=123#wechat_redirect';        $this->redirect($url);    }    /**     * 授权后跳转到此     */    public function index2(Request $request){        $arr = $request->get();        $code = $arr['code'];        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.Config::get('wx_pay')['appid'].'&secret='.Config::get('wx_pay')['secret'].'&code='.$code.'&grant_type=authorization_code';        $ret_json = file_get_contents("$url");        $ret_arr = json_decode($ret_json,true);        $openid = $ret_arr['openid'];        $this->assign('openid',$openid);        return $this->fetch();    }    /**     * 下单获取支付参数     * @param Request $request     * @param WxPay $wxpay     * @return \think\response\Json     */    public function getUrl(Request $request,WxPay $wxpay) {        $pid = $request->get('id');        $openid = $request->get('openid');        //调用统一下单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' => 'JSAPI',            'product_id' => $pid,            'openid' => $openid        ];        $arr = $wxpay->unifiedorder($params);        $wxpay->logs('logs.txt',$arr);        if (isset($arr['prepay_id'])) {            //重新签名            $data = [                'appId' => $arr['appid'],                'timeStamp' => time(),                'nonceStr' => md5(time()),                'package' => 'prepay_id='.$arr['prepay_id'],                'signType' => 'MD5'            ];            $data = $wxpay->setSign($data);            $data['paySign'] = $data['sign'];            unset($data['sign']);            Cache::set('send' . $params['out_trade_no'], $params['total_fee'], 3600);            return RetJosn::successJson('OK',$data);        } else {            return RetJosn::errorJson('err');        }    }    /**     * 接收腾讯推送支付通知     * @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));        }    }}

 

微信支付类:

<?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;        }    }}

 

前端页面:

<!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" />    </head>    <body>        <h1 id="openid"></h1>        <div class="btn-box">            <button onclick="getUrl()">下单</button>        </div>        <div id="info">        </div>    </body>    <script src="__STATIC__/default/js/jquery-1.9.1.min.js"></script>    <script>        var openid = '';        $(function () {            localStorage.getItem('openid');            if (localStorage.getItem('openid')) {                openid = localStorage.getItem('openid');            } else {                openid = '{$openid}';                localStorage.setItem('opendi',openid);            }            $('#openid').html(openid);        });        /*验证码生成*/        function getUrl() {            var id = getId(10);            $.ajax({                url:"{:url('Jsapi/getUrl')}?id=" + id + '&openid=' + openid,                dataType:'json',                success:function(res) {                    if (res.code == 200) {                        alert('1'+JSON.stringify(res));                        var data = res.data;                        wakeup(res.data);                        checkSuccess(id);                    }                }            });        }        function wakeup(data){            WeixinJSBridge.invoke(                'getBrandWCPayRequest', data,                function(res){                    if(res.err_msg == "get_brand_wcpay_request:ok" ){                        // 使用以上方式判断前端返回,微信团队郑重提示:                        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。                        alert('支付成功');                    }                });        }                /*生成唯一Id*/        function getId(length){            var tmp = Date.parse( new Date() ).toString();            tmp = tmp.substr(0,length);            return tmp;        }                /*轮询支付状态*/        function checkSuccess(id){            var interval = window.setInterval(function(){                $.ajax({                   url:"{:url('Jsapi/checkSuccess')}?id=" + id,                   dataType:'json',                   success:function(res) {                       if (res.code == 200) {                           $('#info').html('订单号:'+id+','+res.msg);                           clearInterval(interval);                       }                   }                })            },2000)        }    </script></html>

 

效果演示:

PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图6

 

 PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图7

 

 

 

 PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付插图8

 

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

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

未经允许不得转载:起风网 » PHP微信公众号支付,JSAPI支付方法,ThinkPHP5+微信支付
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录