您现在的位置是:

tp5微信支付native下单回调查询退款

发布时间:2022-03-17作者:小灵龙来源:未知点击:51

1,下载微信支付demo SDK地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
下载完成后复制到/extend/php_sdk_v3
2,修改php_sdk_v3/lib/wxpay.data.php及php_sdk_v3/lib/wxpay.api.php中的引用文件路径,

比如:require_once "D:/web/develop/extend/php_sdk_v3/lib/WxPay.Exception.php";

修改php_sdk_v3/example/wxpay.nativepay.php及php_sdk_v3/example/wxpay.config.php中的引用文件路径
比如:require_once "D:/web/develop/extend/php_sdk_v3/lib/WxPay.Config.Interface.php";
修改php_sdk_v3/example/wxpay.config.php里面的配置,添加上appid、mch_id、回调链接、密钥、证书等值
比如:
public function GetAppId()
    {
        return 'ww86666a62c7';
    }
    public function GetMerchantId()
    {
        return '145408768767678';
    }
3,写一个微信支付类供前端调用
<?php

  namespace app\common\controller;
  use think\Controller;
  use think\Db;
  use think\Request;
  use think\Loader;
  use think\Log;
    /**
    * 微信支付类包含二维码链接、查询、退款
    */

  class Weixinpay extends Controller{   

    //调用微信支付付款二维码链接
    public function showQrcode($request){
        require_once EXTEND_PATH."php_sdk_v3/lib/WxPay.Api.php";
        require_once EXTEND_PATH."php_sdk_v3/example/WxPay.NativePay.php";
        Log::info("调用微信支付付款二维码链接:");
        $input = new \WxPayUnifiedOrder();
        $notify = new \NativePay();
        $total_amount=$request['total_amount']*100;
        $input->SetBody($request['trade_name']);
        $input->SetAttach("test");
        $input->SetOut_trade_no($request['out_trade_no']);//商户订单号
        $input->SetTotal_fee($total_amount);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("test");       
        $input->SetTrade_type("NATIVE");
        $input->SetProduct_id($request['product_id']);

        $result = $notify->GetPayUrl($input);
        Log::info("调用微信支付付款二维码链接返回值:");
        Log::info($result);
        if($result['return_code']=="FAIL"){
            Log::error("调用微信支付付款二维码链接错误返回值:");
            Log::error($result['return_msg']);
            return ['code'=>1001,'msg'=>$result['return_msg'],'data'=>''];
        }
        $data['out_trade_no']=$request['out_trade_no'];       
        $data['money']=$request['total_amount'];                 
        $data['product_id']=$request['product_id'];             
        $data['member_id']=$request['member_id'];
        $data['admin_id']=$request['admin_id'];
        $data['create_time']=time();
        $data['pay_method']=3;
        $data['money_type']=2;
        $data['status']=-1;

        // 客户点击购买进入支付页面后把数据存入数据库
        $db=Db::name('statistics')->insert($data);
        Log::info("客户点击购买进入支付页面后把数据存入数据库返回:".$db);
        return ['code'=>1000,'msg'=>'成功','data'=>$result["code_url"]];
    }
    
    //微信支付成功之后异步回调处理,保存数据到数据库,交易号,交易金额,公共参数:授权appid,签名
    public function notify(Request $request){
        require_once EXTEND_PATH."php_sdk_v3/example/WxPay.Config.php";
        Log::info('微信支付回调');
        //获取微信回调值并转换成数组
        $testxml = file_get_contents('php://input');
        //1将xml转化为json格式
        $jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));
        //2转成数组
        $result = json_decode($jsonxml, true);
        Log::info("微信支付回调返回值:");
        Log::info($result);
        //如果成功返回了 return_code 为SUCCESS的时候有返回
        if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
            //进行改变订单状态等操作。。。。            
            $resxml='';
            $resxml='<xml>
                <return_code><![CDATA[FAIL]]></return_code>
                <return_msg><![CDATA[OK]]></return_msg>
                </xml>';
           
            Db::startTrans();
            try{
                //商户订单号
                $out_trade_no = $result['out_trade_no'];
                //微信支付订单号
                $transaction_id = $result['transaction_id'];
               
                //交易金额
                $total_amount = $result['total_fee']/100;
                $openid = $result['openid'];//微信用户标识
                $time_end = $result['time_end'];//支付完成时间
                // 1,充值消费明细statistics表               
                Log::info('微信支付回调notify_url更新statistics表返回值db_sta:'.$db_sta);
             
                Log::info('微信支付回调已经发送邮件给管理员');               

                //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
                $resxml='<xml>
                <return_code><![CDATA[SUCCESS]]></return_code>
                <return_msg><![CDATA[OK]]></return_msg>
                </xml>';
                Log::info('微信支付回调3');//请不要修改或删除
                Db::commit();
            }catch(\Exception $e){
                Db::rollback();
                Log::error('微信支付回调错误返回值:');
                Log::error($e->getMessage());
            }           
            Log::info('微信支付回调4');
            Log::info($resxml);
            echo  $resxml;
            exit();
        }
    }
    //调用微信支付接口订单查询,返回订单详情数组
    public function orderquery($out_trade_no,$transaction_id){
        require_once EXTEND_PATH."php_sdk_v3/lib/WxPay.Api.php";
      
        require_once EXTEND_PATH."php_sdk_v3/example/WxPay.Config.php";
 
        if((isset($transaction_id) && $transaction_id != ""
        && !preg_match("/^[0-9a-zA-Z]{10,64}$/i", $transaction_id, $matches))
        || (isset($out_trade_no) && $out_trade_no != ""
        && !preg_match("/^[0-9a-zA-Z]{10,64}$/i", $out_trade_no, $matches))){
            header('HTTP/1.1 404 Not Found');
            exit();
        }
       
        if(isset($transaction_id) && $transaction_id != ""){
            try {               
                $input = new \WxPayOrderQuery();
                $input->SetTransaction_id($transaction_id);
                $config = new \WxPayConfig();
                $data= \WxPayApi::orderQuery($config, $input);
                if($data['return_code']=='SUCCESS' && $data['result_code']=='FAIL'){
                    if(isset($out_trade_no) && $out_trade_no != ""){
                        $out_trade_no = $out_trade_no;
                        $input = new \WxPayOrderQuery();
                        $input->SetOut_trade_no($out_trade_no);
                        $config = new \WxPayConfig();
                        $data= \WxPayApi::orderQuery($config, $input);
                    }
                }
            } catch(Exception $e) {
                Log::error("调用微信支付订单查询接口错误返回值:");
                Log::error(json_encode($e));
               
            }      
        }
        Log::info("调用微信支付订单查询接口返回值:");
        Log::info($data);
        return $data;
    }
    
    /*微信退款
    *接收参数:商户订单号、总金额、退款金额、退款原因
    *返回值:
    */
    public function refund($out_trade_no,$total_fee,$refund_fee){       
        require_once EXTEND_PATH."php_sdk_v3/lib/WxPay.Api.php";     
        require_once EXTEND_PATH."php_sdk_v3/example/WxPay.Config.php";
  
      
        $total_fee=$total_fee*100;
        $refund_fee=$refund_fee*100;
        if(    (isset($out_trade_no) && $out_trade_no!=""
            && !preg_match("/^[0-9a-zA-Z]{10,64}$/i", $out_trade_no, $matches))
            || (isset($total_fee) && $total_fee != ""
            && !preg_match("/^[0-9]{0,10}$/i", $total_fee, $matches))
            || (isset($refund_fee) && $refund_fee != ""
            && !preg_match("/^[0-9]{0,10}$/i", $refund_fee, $matches))){
            header('HTTP/1.1 404 Not Found');
            exit();
        }
        $data=array();
       
        if(isset($out_trade_no) && $out_trade_no != ""){
            try{
                $input = new \WxPayRefund();
                $input->SetOut_trade_no($out_trade_no);
                $input->SetTotal_fee($total_fee);
                $input->SetRefund_fee($refund_fee);

                $config = new \WxPayConfig();
                $input->SetOut_refund_no("sdkphp".date("YmdHis"));//商户退款单号
                $input->SetOp_user_id($config->GetMerchantId());
                $data=\WxPayApi::refund($config, $input);
               
            } catch(Exception $e) {
                Log::error("调用微信支付退款接口错误返回值:");
                Log::error(json_encode($e));               
            }
           
        }
        Log::info("调用微信支付退款接口返回值:");
        Log::info($data);
        return $data;
    }
    
  }

?>

   前端调用
<?php

    namespace app\home\controller;

     use app\common\controller\Weixinpay;
    class tian(){
            
           
       
        //在微信支付类中获取二维码链接后显示二维码
        public function openWeixinPage(){
        
     
            $total_amount=input('total_amount');//付款价格
            $trade_name=input('trade_name');//产品名称
            $tola_product_id=input('tola_product_id');//产品ID
        
           
       
            $params = [
                //商户订单号,商户网站订单系统中唯一订单号,必填
                'out_trade_no'  =>  build_order_no(),
                //订单名称,必填
                'trade_name'       =>  $trade_name,
                //付款金额,必填
                'total_amount'  =>  $total_amount,                
                //产品ID
                'product_id'  =>  $tola_product_id,
                         
                             
            ];
            //客户支付数据保存到数据库
            $res=new Weixinpay();
            $codeurl=$res->showQrcode($params); //返回微信二维码链接,使用phpqrcode类生成二维码图片供用户扫码支付
       
            if($codeurl['code']==1001){
                $this->error($codeurl['msg']);
                exit();
            }
            $this->assign(['codeurl'=>$codeurl['data'],'out_trade_no'=>$params['out_trade_no'],'total_amount'=>$total_amount]);
            return view();
       }
       //前端调用qrcode类生成二维码图片
       public function create_ewm(){
           require_once EXTEND_PATH.'php_sdk_v3/example/phpqrcode/phpqrcode.php';
           $codeurl=input('codeurl');
         
            if(substr($codeurl, 0, 6) == "weixin"){
                header("Content-type:image/png");
                \QRcode::png($codeurl);
                exit();                   
            }else{
                 header('HTTP/1.1 404 Not Found');
            }
        }
        //前端js一秒查询一次用户是否支付
        public function chaxun(){
            $res=new Weixinpay();
            $codeurl=$res->orderquery(input('out_trade_no'),'1234567890');
            Log::info('前端查询chaxun函数返回值:');
            Log::info($codeurl);
            // 以下字段在return_code为SUCCESS的时候有返回
            if($codeurl['return_code']=='SUCCESS'){
                if($codeurl['result_code']=='SUCCESS' && $codeurl['trade_state'] =='SUCCESS'){
                    return json_encode(['code'=>'SUCCESS','msg'=>'订单支付成功']);
                }else{
                    return json_encode(['code'=>'FAIL','msg'=>"支付失败"]);
                }
            }else{
                return json_encode(['code'=>'FAIL','msg'=>$codeurl['return_msg']]);
            }
            return json_encode(['code'=>'FAIL','msg'=>$codeurl['err_code_des']]);
        }
      }



?>

前端view展示

<img src="__URL__/create_ewm?codeurl={$codeurl}" >

<script>

    //设置每隔1000毫秒执行一次load() 方法
    var myIntval=setInterval(function(){loads()},2000);
    var xun_time=1;
 function loads(){
    console.log(xun_time);
    xun_time=xun_time+1;
    <!-- 30个2秒就是一分钟 5分钟后停止查询订单返回上一页-->
    if(xun_time>150){
        clearInterval(myIntval);
        layer.msg('长时间未付款,付款已关闭。若继续付款请重新下单',{icon:2},function(){
            location.href="__URL__/paym";
        })
    }
    var xmlhttp;
  <!-- clearInterval(myIntval); -->
    // 轮询的浏览器设置
    if (window.XMLHttpRequest){
     // code for IE7+, Firefox, Chrome, Opera, Safari
     xmlhttp=new XMLHttpRequest();
    }else{
     // code for IE6, IE5
     xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    xmlhttp.onreadystatechange=function(){
    
        if (xmlhttp.readyState==4 && xmlhttp.status==200){
        trade_state=JSON.parse(xmlhttp.responseText);
        console.log(trade_state);//打印查看轮询的状态,也可以关闭。
      //判断订单支付状态 并用document.getElementById方法赋值到myDiv中;
        if(trade_state.code=='SUCCESS'){
       
            //延迟3000毫秒执行tz() 方法
            clearInterval(myIntval);
            //进行跳转。
            var url = "__URL__/paymentResult";       
            setTimeout("location.href='"+url+"'",1500);
        }else if(trade_state.code=='REFUND'){
       
            clearInterval(myIntval);
        }else if(trade_state.code=='NOTPAY'){
         
        }else if(trade_state.code=='CLOSED'){
       
            clearInterval(myIntval);
        }else if(trade_state.code=='REVOKED'){
       
            clearInterval(myIntval);
        }else if(trade_state.code=='USERPAYING'){
       
        }else if(trade_state.code=='PAYERROR'){
       
            clearInterval(myIntval);
        }
       
        }
    }
  //orderquery.php 文件返回订单状态,通过订单状态确定支付状态
  xmlhttp.open("POST","__URL__/chaxun",false);
  //下面这句话必须有
  //把标签/值对添加到要发送的头文件。
  xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  xmlhttp.send("out_trade_no={$out_trade_no}");
   
 }
  
</script>

如果帮到了您,请打赏一二!

标签: