thinkPHP 3.2 微信公众号支付 + 扫码支付

发布时间:2017年12月15日 17:18:06编辑:admin阅读(1670)评论(0)

    微信用的人越来越好多,微信支付也顺手。顺便微信就弄来个微信支付,

    mmp,出了好多浏览器,程序员就要考虑浏览器的兼容性

    出了支付,程序员就又要做微信支付,支付宝支付,银联支付

    真特么智 ....智慧树下智慧果,我爱代码,爱程序。


    微信支付,不提供源代码下载, 提供一下源代码,自己整合。

    显示公众号支付的:  jsapi支付  // 注意:此 Demo 使用 2.7 版本支付接口实现,建议使用此接口时参考微信支付相关最新文档。

    看前端先

    index.html  支付页面  需要导入包   



    //第一种微信公众号支付
    
    function fist_pay(){
        var index = layer.load(1, {shade: [0.1,'#fff']});    //导入layer 包  一款漂亮的插件
        var project_id="{:I('get.id')}";         //项目id
        var number_n=$("#num").text();     //数量
        var address=$("#address_id").val();    //  收货地址id
        var total_fee=$(".money").text();     // 支付金额  可后台重新计算
        var remarks=$(".adpro_intro").val();   //购买留言
        var repty_as=$(".check input").val();  //商品类型 
        if(address==""){
            layer.msg("请填写地址");
            layer.close(index);
        return false;
    }
    var data={
        "project_type":1,
        "pay_type":1,
        "project_id":project_id,
        "number_n":number_n,
        "address":address,
        "total_fee":total_fee,
        "remarks":remarks,
        "repty":repty_as,
        "from":{:I('get.from/d',0)},
    };
    $.post("{:U('Pay/getPackage')}",data,function(da){
        if(da.status==1){
            wx.chooseWXPay({
             timestamp: da.timestamp,
             nonceStr: da.nonceStr,
             package: da.package,
             signType: da.signType, // 注意:新版支付接口使用 MD5 加密
             paySign: da.paySign,
             success: function (res) {
             if(res.errMsg == "chooseWXPay:ok"){
                 layer.msg("支付成功");
                 }
                 },
            });
                layer.close(index);
            }else{
            layer.close(index);
                layer.msg(da.msg);
            }
        })
    }


    下面支付接口  PayController.class.php

    public function getPackage(){
        if(IS_POST){
            //  $da  订单一下参数  自行修改,不一一解释了  不明白的可以看上面
            $da=array(
                "project_type"=>$project['pro_type'],
                "project_id"=>I("post.project_id"),
                "number_n"=>I("post.number_n"),
                "pay_type"=>I("post.pay_type"),
                "address_id"=>I("post.address"),
                "total_fee"=>I("post.total_fee",'',float),
                "remarks"=>I("post.remarks"),
                "user_id"=>$_SESSION["user_id"],//查session
                "out_trade_no"=>rand(1,1000)."_".time(),
                "repty"=>I("post.repty"),
                "creat_time"=>time(),
                "froms"=>I("post.from/d")
            );
            //dump($da);die;
            if($da["project_id"]==""){
                return $this->ajaxReturn(array("status"=>0,"msg"=>"非法"));
                die;
            }
            if($da["total_fee"]==""){
                return $this->ajaxReturn(array("status"=>0,"msg"=>"非法"));
                die;
            }
            if($orderid = M("supporter")->add($da)){     //添加订单
                $us_daa=M("wx_users")->where("id=".$_SESSION["user_id"])->find();
                $config = C("WX_PAY_CONFIG");           //config.php  配置,内容我就不贴出来,在下面,找找,
                $rand = md5(date("YmdHis"). mt_rand(0,1000));
                $param["appid"] = $config['appid'];
                $param["openid"] = $us_daa["openid"];
                $param["mch_id"] = $config["mchid"];
                $param["nonce_str"] = $rand;
                $param["body"] = "xxxx支持项目";       
                $param["total_fee"] =$da["total_fee"]*100;
                $param["out_trade_no"] =$da["out_trade_no"];
                $param["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"];
                $param["notify_url"] = "<a href="http://项目名.com/index.php/Home/Wxpay";">http://项目名.com/index.php/Home/Wxpay";     //wxpay这个控制器,没写接口名称 其实是默认 __notify
                $param["trade_type"] = "JSAPI";
                $signStr = 'appid='.$param["appid"]."&body=".$param["body"]."&mch_id=".$param["mch_id"]."&nonce_str=".$param["nonce_str"]."&notify_url=".$param["notify_url"]."&openid=".$param["openid"]."&out_trade_no=".$param["out_trade_no"]."&spbill_create_ip=".$param["spbill_create_ip"]."&total_fee=".$param["total_fee"]."&trade_type=".$param["trade_type"];
                $signStr = $signStr."&key=".$config["key"];
                $param["sign"] = strtoupper(MD5($signStr));
                $data = ' ';
                $postResult = myCurl("https://api.mch.weixin.qq.com/pay/unifiedorder",$data);
                
                $postObj = simplexml_load_string($postResult, 'SimpleXMLElement', LIBXML_NOCDATA); 
                $msg = "".$postObj->return_msg;
                if($msg == "OK"){
                $result["timestamp"] = time();
                $result["nonceStr"] = "".$postObj->nonce_str;  //不加""拿到的是一个json对象
                $result["package"] = "prepay_id=".$postObj->prepay_id;
                $result["signType"] = "MD5";
                $paySignStr = 'appId='.$param["appid"].'&nonceStr='.$result["nonceStr"].'&package='.$result["package"].'&signType='.$result["signType"].'&timeStamp='.$result["timestamp"];
                $paySignStr = $paySignStr."&key=".$config["key"];
                $result["paySign"] = strtoupper(MD5($paySignStr));
                $result["status"]=1;
                $result["order"]=$param["out_trade_no"];
                $result["orderid"]=$orderid;
                $this->ajaxReturn($result);
            }else{
              $this->ajaxReturn("", "".$msg, 0);
            }
            }
            }else{
                return $this->ajaxReturn(array("status"=>0,"msg"=>"非法"));
                return false;
            }
    
        }
    
    
     /*'WX_PAY_CONFIG' => array(
            'appid' => 'wxe6a66980fxxxxxxx', //公众号AppId
            'appsecret' => 'a3749866973b2909023cxxxxxxxxxxxxxx', //公众号AppSecret
            'mchid' => '14854xxxxxx', //商户号
            'key' => 'xxxxxxxxxxxxxx30231198005273716jg', //密钥
            'notify_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/notify.php' //回调地址
        ),*/


    好了,上面的支付这样写就可以了,jsapi支付就是这样,


    然后是回调

    WxpayController.class.php

    public function __notify($data) {
        \Think\Log::record($data);
                if ($data['result_code'] == 'SUCCESS' && $data['return_code'] == 'SUCCESS') {
        //查订单
        $supporter = M("supporter")->where("out_trade_no='".$data["out_trade_no"]."' and pay_status=0")->find();
        if($supporter){
            //改订单状态
            $uppay=array("pay_status"=>1,"update_time"=>time());
            if(M("supporter")->where("out_trade_no='".$data["out_trade_no"]."'")->save($uppay)){
            				        
                                                    //支付成功回调之后修改订单支付状态  然后根据需要给用户发送模板消息,也可以不放......
            //给项目用户发模板消息
            template_type($project['user_id'],'dabing',$supporter['id']);
            //给支持用户发模板消息
            template_type($supporter['user_id'],'juankuan',$supporter['id']);
            }
        }
                return true;
            } else {
                if ($data["return_code"] == "FAIL") {
                    \Think\Log::record("【通信出错】:{$data['return_msg']}");
                } elseif ($data["result_code"] == "FAIL") {
                    //此处应该更新一下订单状态,商户自行增删操作
                    \Think\Log::record("【业务出错】:{$data['err_code']}--{$data['err_code_des']}");
                }
                return false;
            }
            return true;
        }

    微信的jsapi支付就是这样,啃文档是个漫长而痛苦,不断花钱的过程,也许微信故意不惜的那么详细,让你慢慢啃(慢慢支付测试

    哈哈哈哈!!!微信公众号支付说完了,下面说下扫码支付的


    第一步需要支付的地方,还是原来的index.html 还是原来的位置 

    第二种扫码支付


    //第二扫码支付

    function second(){
       var index = layer.load(1, {
         shade: [0.1,'#fff'] //0.1透明度的白色背景
        });
        var project_id="{:I('get.id')}";
        var number_n=$("#num").text();
        var address=$("#address_id").val();
        var total_fee=$(".money").text();
        var remarks=$(".adpro_intro").val();
        var repty_as=$(".check input").val();
        if(address==""){
            layer.msg("请填写地址");
            layer.close(index);
            return false;
        }
        var data={"project_type":1,"pay_type":1,"project_id":project_id,"number_n":number_n,"address":address,"total_fee":total_fee,"remarks":remarks,"repty":repty_as};
        $.post("{:U('saoma/index')}",data,function(da){
          window.location.href="__ROOT__/Home/Saoma/show_qrcode?rcode="+da.url+"&Out_trade_no="+da.Out_trade_no; 
        })
    }

    saoma/index   先获取要生成要支付二维码的参数,然后跳转到二维码页面


    saoma/index 方法如下

    public function index() {
        if(IS_POST){
        import ( "Vendor.pcwxpay.WxPayNativePay" );
        $da=array(
            "project_type"=>I("post.project_type"),
            "project_id"=>I("post.project_id"),
            "number_n"=>I("post.number_n"),
            "pay_type"=>I("post.pay_type"),
            "address_id"=>I("post.address"),
            "total_fee"=>I("post.total_fee",'',float),
            "remarks"=>I("post.remarks"),
            "user_id"=>$_SESSION["user_id"],//查session
            "out_trade_no"=>\WxPayConfig::MCHID . date ( "YmdHis" ),
            "repty"=>I("post.repty"),
            "creat_time"=>time()
        );
        if(M("supporter")->add($da)){
            ini_set ( 'date.timezone', 'Asia/Shanghai' );
            error_reporting ( E_ERROR );
            $notify = new \WxPayNativePay ();
            $url1 = $notify->GetPrePayUrl ( "123456789" );
            // 开始处理
            $input = new \WxPayUnifiedOrder ();
            $input->SetBody ( "应用名");
            $input->SetAttach ( "应用名" );
            $input->SetOut_trade_no ($da["out_trade_no"]);
            $input->SetTotal_fee ($da["total_fee"]*100);
            $input->SetTime_start ( date ( "YmdHis" ) );
            $input->SetTime_expire ( date ( "YmdHis", time () + 600 ) );
            $input->SetGoods_tag ( "应用名-tag" );
            $input->SetNotify_url ( "http://域名.com/index.php/Home/Saoma/notify" );
            $input->SetTrade_type ( "NATIVE" );
            $input->SetProduct_id ( rand ( 4, 8 ) );
            $result = $notify->GetPayUrl ( $input );
            $url2 = $result ["code_url"];
        }
            $this->ajaxReturn(array("url"=>$url2,"Out_trade_no"=>$da["out_trade_no"]));
        }
    
    }

    SaomaController 控制器  show_qrcode接口获取到的参数直接assign就行  我是 assign('url',$_GET)


    然后在支付二维码页面显示支付二维码  

    这样就行了  去执行  show_er 方法 



    Public function show_qrcode(){
        $url=I("get.rcode");
        $this->assign("url",$url);
        $this->display();
     }
     Public function show_er(){
        error_reporting ( E_ERROR );
        import ( "Vendor.pcwxpay.PHPQRCODE" );
        $url = urldecode (I("get.url"));
        \QRcode::png ($url,false,H,6);
    }


    生存二维码要导入微信支付生成二维码包

    PHPQRCODE  下载地址: 百度网盘  密码: r7qs


    页面写个请求,每隔一段时间就去请求 ,检查订单是不是已经支付了,如果支付成功则当前页面跳转到订单页面

    Public function jiance(){
        $arr=M("supporter")->field("pay_status")->where(array("out_trade_no"=>I("post.danhao")))->find();
        if($arr["pay_status"]==1){
            $this->ajaxReturn(array("status"=>1));
        }
    }



    支付成功之后回调不能落下

     notify()

    public function notify() {
        // 获取微信回调的数据
        $notifiedData = $GLOBALS ['HTTP_RAW_POST_DATA'];
        // 加载相关的类
        import ( "Vendor.pcwxpay.WxPayNativePay" );
        import ( "Vendor.pcwxpay.WxPayData" );
        import ( "Vendor.pcwxpay.WxPayNotify" );
        import ( "Vendor.pcwxpay.PayNotifyCallBack" );
        $data=\WxPayDataBase::FromXml_4_babbage ( $notifiedData );
        if($data["result_code"]=="SUCCESS"){
            $uppay=array("pay_status"=>1,"update_time"=>time());
            M("supporter")->where(array("out_trade_no"=>$data["out_trade_no"]))->save($uppay);
        }
        // 给微信返回支付状态值
        $notify = new \PayNotifyCallBack ();
        // 返回状态
        $notify->Handle ( false );
    }


    好了,微信公众号的支付到这里说完了,支付使用的是jsapi支付,部分包没提供下载地址的,自己麻烦一下去下载

    扫码支付跟公众号支付是一个样一个样的,只不过是用了一下微信的支付二维码生成包生成二维码让手机取扫码支付


    最后还想再写写微信自定义分享的。。。。分享就放在模板消息一起发,就那么丢丢,模板消息也就那么丢丢,省的不好看

关键字微信支付