微信支付回调通知问题

浏览:2407 发布日期:2019/08/15 分类:求助交流 关键字: 微信支付
我工作中使用微信支付在本地搭建的项目。后台tp5.1,做支付功能,目前遇到的是,生成微信支付二维码之后,可以支付成功,不过我不知道怎么判断支付成功(我解决办法是前端页面写了一个定时查询订单信息的定时器,不过要3秒查询一次,访问的控制器方法时 orderstate ,具体所有的支付代码我放下面,做过的应该能看的懂)。// 前端访问的控制器
public function index(){
        if (!User::isLogin()) {
            return redirect('index\user\login');
        }
        if (request()->isGet()){
            $product_id = (time()+1).createStr(22);
            $cartId = request()->param('sid');
            $cartId = explode(',', $cartId);
            // 这个方法时把传过来的id数组和自己生成的订单号传到模型中进行插入订单数据的操作
            $this->Order->addPay($cartId,$product_id);
            // 为什么不用thinkphp中的链式操作,试过了,有点问题,一直报未定义的数组,不知道什么原因,所以使用了原生的sql查询中的子查询。
            $pay = Db::query("select id,amount from pa_order where order_id = (select order_id from pa_order where id = (select MAX(id) from pa_order))");
            $arrs = '';
            foreach ($pay as $key => $value){
                $arrs += $value['amount'];
            }
            $nidePrice = $arrs*100;

            $notify = new NativePay();
            $input = new WxPayUnifiedOrder();
            $input->setBody("购买所需");
            $input->setAttach("HC");
            //$input->setOutTradeNo(WxPayConfig::MCHID.date("YmdHis"));
            $input->setOutTradeNo($product_id);
            $input->setTotalFee($nidePrice);//以分为单位,一般是要乘100的。
            $input->setTimeStart(date("YmdHis"));
            $input->setTimeExpire(date("YmdHis", time() + 600));
            $input->setGoodsTag("test");
            $input->setNotifyUrl(wxPayConfig::NOTIFY_URL);
            $input->setTradeType("NATIVE");
            //$product_id 为商品自定义id 可用作订单ID
            $input->setProductId($product_id);
            $result = $notify->getPayUrl($input);
            if (empty($result['code_url'])){
                $qrCode_url = '';
            }else{
                $qrCode_url = $this->setQrcode($result['code_url']);
            }
            return $this->fetch('',[
                'qrCode_url' => $qrCode_url,
                'product_id'    =>  $product_id,
            ]);
        }else{
            return json(['code'=>'1004','data'=>'操作非法']);
        }
    }

// 公用二维码生成,我引入了qrcode第三方插件
    static function setQrcode($url){
        //二维码图片保存路径
        $pathname = date("Ymd",time());
        $pathname = "./public/wxpay/qrcode/" . $pathname;
        if(!is_dir($pathname)) { //若目录不存在则创建之
            mkdir($pathname);
        }
        $qrcode = new QRcode();
        //二维码图片保存路径(若不生成文件则设置为false)
        $filename = $pathname . "/qrcode_" . randOrder() . ".png";
        //二维码容错率,默认L
        $level = "L";
        //二维码图片每个黑点的像素,默认4
        $size = '10';
        //二维码边框的间距,默认2
        $padding = 2;
        //保存二维码图片并显示出来,$filename必须传递文件路径
        $saveandprint = true;
        //生成二维码图片
        $qrcode->png($url,$filename,$level,$size,$padding,$saveandprint);
        //二维码logo
        $logo = "./public/wxpay/images/logo.png";
        $QR = imagecreatefromstring(file_get_contents($filename));
        $logo = imagecreatefromstring(file_get_contents($logo));
        $QR_width = imagesx($QR);
        $QR_height = imagesy($QR);
        $logo_width = imagesx($logo);
        $logo_height = imagesy($logo);
        $logo_qr_width = $QR_width / 5;
        $scale = $logo_width / $logo_qr_width;
        $logo_qr_height = $logo_height / $scale;
        $from_width = ($QR_width - $logo_qr_width) / 2;
        imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
        imagepng($QR,$filename);
        return $filename;
    }
上面这些就是生成订单和二维码的接口,没什么问题,不用看,最主要的来了,下面的这些请给位大神帮忙看看我该怎么改。
前端二维码显示页面代码,这里面我是3秒就去控制器访问一下orderstate方法看看订单状态(我觉得肯定不行,不过我也不知道怎么改。这个借口方法下面紧接着敷上去。)<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Javascript 二维码生成库:QRCode</title>
    <script type="text/javascript" src="__STATIC__/js/jquery-3.3.1.min.js"></script>
    <!-- <script type="text/javascript" src="__STATIC__/js/qrcode.min.js"></script> -->
    <style type="text/css">
        .center{text-align: center;}
    </style>
</head>
<body>
<h2 class="center">微信支付</h2>
<div class="center">
    <img id="img" src="/{$qrCode_url}" alt="" width="50%" />
    <br />
    <div class="onqr">
        <input type="hidden" id="out_trade_no" value="{$product_id}" >
    </div>
</div>
<script type="text/javascript">
    // 产看订单状态
    var time = setInterval("check()",3000);    //3秒查询一次是否支付成功
    function check() {
        var url = "{:url('/index/Wxpay/orderstate')}";
        var out_trade_no = $("#out_trade_no").val();
        var param = {'out_trade_no':out_trade_no};
        $.post(url,param,function(data){
            var obj = eval(data);
            if (obj.trade_state == 'SUCCESS') {
                time = window.clearInterval(time);
                $(".onqr").hide();
                // 支付成功把二维码替换成支付成功图标
                $("#img").attr('src','/public/wxpay/images/success.png');
            }else{
                // console.log(obj);
                console.log('你还没付款,请支付!');
            }
        });
    }
</script>
</body>
</html>
orderstate判断订单转台接口方法/**
     * 查看订单的状态
     */
    public function orderstate(){
        error_reporting(E_ERROR);
        ini_set('date.timezone','Asia/Shanghai');
        $transaction_id = $_REQUEST['transaction_id'];
        $out_trade_no = $_REQUEST['out_trade_no'];
        if(request()->param('transaction_id') != null && request()->param('transaction_id') != ""){
            $input = new WxPayOrderQuery();
            $input->setTransactionId($transaction_id);
            if (WxPayApi::orderQuery($input)['trade_state']==='SUCCESS'){
                db('order')->where('order_id',$transaction_id)->update(['ispay'=>'1']);
                $res = db('order')->where('order_id',$transaction_id)->field('id,order_id,oid')->select();
                if (!empty($res['oid'])){
                    $oid = explode(',',$res['oid']);
                    foreach ($oid as $key => $value) {
                        db('order')->where('id',$value)->update(['ispay' => '1']);
                    }
                }
            }else{
                // 支付失败
                $res = db('order')->where('order_id',$transaction_id)->field('id,order_id,oid')->select();
                if (!empty($res['oid'])){
                    db('order')->where('order_id',$transaction_id)->update(['ispay' => '0','status'=>'0']);
                }else{
                    db('order')->where('order_id',$transaction_id)->update(['ispay'=>'2']);
                }
            }
            return json(WxPayApi::orderQuery($input));
        }

        if(request()->param('out_trade_no') != null && request()->param('out_trade_no') != ""){
            $input = new WxPayOrderQuery();
            $input->setOutTradeNo($out_trade_no);
            if (WxPayApi::orderQuery($input)['trade_state']==='SUCCESS'){
                db('order')->where('order_id',$out_trade_no)->update(['ispay'=>'1']);
                $res = db('order')->where('order_id',$out_trade_no)->field('id,order_id,oid')->select();
                if (!empty($res['oid'])){
                    $oid = explode(',',$res['oid']);
                    foreach ($oid as $key => $value) {
                        db('order')->where('id',$value)->update(['ispay' => '1']);
                    }
                }
            }else{
                // 支付失败
                $res = db('order')->where('order_id',$out_trade_no)->field('id,order_id,oid')->select();
                if (!empty($res['oid'])){
                    db('order')->where('order_id',$out_trade_no)->update(['ispay' => '0','status'=>'0']);
                }else{
                    db('order')->where('order_id',$out_trade_no)->update(['ispay'=>'2']);
                }
            }
            return json(WxPayApi::orderQuery($input));
        }
    }
以上就是我的代码了,可以实现支付,不过就是需要在弹出的支付二维码页面有个3秒定时器,不停的差订单状态,根据状态判断页面跳转这些,然后我不明白的是微信有个config文件,里面有个const NOTIFY_URL = 'http://www.hcadmin123.com/index/wxpay/notify';里面的这个www.hcadmin123.com是我本地的项目域名,前面提到了,这个项目是我本地的项目,没有上线。
我页面中的notify函数我复制上去,不过这个路径在支付成功之后是不会走的。这点我不理解,是因为这个notify_url这个路径不是线上的路径还是说一定要是线上的路径,同时要添加在微信开发平台上的回调白名单中?求教
notify接口代码复制上去/**
     * 微信支付 回调逻辑处理
     * @return string
     */
    public function notify(){
        $wxData = file_get_contents("php://input");
        //file_put_contents('/tmp/2.txt',$wxData,FILE_APPEND);
        try{
            $resultObj = new WxPayResults();
            $wxData = $resultObj->Init($wxData);
        }catch (\Exception $e){
            $resultObj ->setData('return_code','FAIL');
            $resultObj ->setData('return_msg',$e->getMessage());
            return $resultObj->toXml();
        }

        if ($wxData['return_code']==='FAIL'||
            $wxData['return_code']!== 'SUCCESS'){
            $resultObj ->setData('return_code','FAIL');
            $resultObj ->setData('return_msg','error');
            return $resultObj->toXml();
        }
        // TODO 根据订单号 out_trade_no 来查询订单数据
        $out_trade_no = $wxData['out_trade_no'];
        //此处为举例
        $input = new WxPayUnifiedOrder();
        db('order')->where('order_id',$input->getOutTradeNo())->update(['ispay'=>'1']);
        db('order')->where('order_id',$out_trade_no)->update(['ispay'=>'2']);
        $order = db('order')->where(['order_id' => $out_trade_no])->find();

        if (!$order || $order->status == 1){
            $resultObj ->setData('return_code','SUCCESS');
            $resultObj ->setData('return_msg','OK');
            return $resultObj->toXml();
        }
        //TODO 数据更新 业务逻辑处理 $order
    }
最佳答案
评论( 相关
后面还有条评论,点击查看>>