zoukankan      html  css  js  c++  java
  • 微信支付回调验证签名处理

    微信支付回调验证签名:一定要验证签名,可能不造成伪造数据,或者数据库造到灌水;

    <?php 
    /**
     * 微信支付回调类
     * @name CallbackAction.class.php
     * @author yangzl 
     * @date(20180820)
     */
    
    class CallbackAction extends Action{
        /**
         * @param 获取微信支付回调接口
         * @return [type] [descripti
         * @date(20180820)
         * @author yangzl
         */
        public function getPayMentCallBack(){
            $curl_request = $_SERVER['REQUEST_METHOD']; //获取请求方式
            if($curl_request == 'POST'){ 
                $xmldata=file_get_contents("php://input");
                libxml_disable_entity_loader(true);
                //把微信支付回调结果写入日志
                $this->writeLogs(RUNTIME_PATH.'Logs/','getPayMentCallBack',"
    -------------------".date('Y-m-d H:i:s')."微信支付回调结果---------
    ---响应数据:".json_encode(simplexml_load_string($xmldata, 'SimpleXMLElement', LIBXML_NOCDATA))."
    ------------
    ");
                //处理微信支付返回的xml数据
                $data = json_encode(simplexml_load_string($xmldata, 'SimpleXMLElement', LIBXML_NOCDATA));
                $sign_return = json_decode($data,true)['sign'];
                $sign = $this->appgetSign(json_decode($data,true));
                //给微信返回接收成功通知,生成xml数据
                $this->returnXml();
                if($sign == $sign_return){
                    //把数据提交给订单处理方法
                    $this->proOrders($data);
                }
                
            }
        }
    
    
    
    /*
     * 格式化参数格式化成url参数  生成签名sign
    */
     public  function appgetSign($data){
        require_once WEB_LIB."WxPay.Config.php";
        $config = new WxPayConfig();
        $appwxpay_key = $config->GetKey();
        //签名步骤一:按字典序排序参数
        ksort($data);
        $String = $this->callbackToUrlParams($data);
        //签名步骤二:在string后加入KEY
        if($appwxpay_key){
            $String = $String."&key=".$appwxpay_key;
        }
        //签名步骤三:MD5加密
        $String = md5($String);
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        return $result_;
      }
     
    
    
        /**
         * 格式化参数格式化成url参数
         */
        public function callbackToUrlParams($Parameters){
            $buff = "";
            foreach ($Parameters as $k => $v){
                if($k != "sign" && $v != "" && !is_array($v)){
                    $buff .= $k . "=" . $v . "&";
                }
            }
            $buff = trim($buff, "&");
            return $buff;
        }
    
    
    
        /**
         * @param  拼装xml数据返回 
         * @author  yangzl <[<email address>]>
         */
        public  function returnXml(){
            header("Content-type:text/xml;");
            $xml = "<?xml version='1.0' encoding='UTF-8'?>
    ";
            $xml .= "<xml>
    ";
            $xml .= "<return_code>SUCCESS</return_code>
    ";
            $xml .= "<return_msg>OK</return_msg>
    ";
            $xml .= "</xml>
    ";
            echo  $xml;
        }
    
    
    
    /**
     * @param 支付回调程序处理
     * @author yangzl
     * @date(20180820)
     */
    public function proOrders($data){
        if (!$data) {
            $date = date("Y-m-d H:i:s",time());
            log::write( "proOrders方法错误".$date);
        }
        //处理则返回数据入库 分表
        $orders_info = json_decode($data,true);
        $orders_model = new OrdersModel();
        $branch_id = json_decode($orders_info['attach'],true)['branch_id'];
        //查询排重
        $result_pay_data = $orders_model->get_pay_data($branch_id,$orders_info['transaction_id']);
    
        if(!$result_pay_data){ //不存在
            //存数据
             $table_id = json_decode($orders_info['attach'],true)['table_id']; 
            //根据tableid查询桌台信息
            $tables_model = new TablesModel();
            $table_info = $tables_model->get_table_by_id( $table_id, $branch_id);
            if($table_info['is_delete'] == '0'){
                $title = $table_info['title'];  
            }
            //回调支付信息
            $pay_info = array(
                'branch_id' => $branch_id,
                'transaction_id' => $orders_info['transaction_id'],
                'cash_fee' => sprintf("%.2f",$orders_info['cash_fee']/100),
                'pay_type' => 1,
                'mch_id' =>$orders_info['mch_id'],
                'result_code' => $orders_info['result_code'] == 'SUCCESS' ? 1 : 0,
                'orders_id' =>$orders_info['out_trade_no'],
                'time_end' => $orders_info['time_end'],
                'title' => $title,
                'openid'=> $orders_info['openid'],
                'pay_source' => 1,
                'is_subscribe' => $orders_info['is_subscribe'] == 'Y' ? 1 : 0,  //是否关注公众账号
                'sub_mch_id' => $orders_info['sub_mch_id'],
                'total_fee' =>sprintf("%.2f",$orders_info['total_fee']/100),
                'bank_type' => $orders_info['bank_type'],
            );
            //存数据
            $add_data = $orders_model->add_pay_info($branch_id,$pay_info);  
            if(!$add_data){
                log::write( "支付数据存储失败".$orders_info['transaction_id']);
                return false;
            }
            if($orders_info['result_code'] == 'SUCCESS'){
                    //查询订单信息
                    // $order_data = $orders_model->get_orders_data($table_id, $branch_id);
                
                   $order_data = $orders_model->get_orders_tem($table_id, $branch_id);
    
                    if(!$order_data){
                         log::write( "查询订单信息失败".time());
                        return false;
                    }
                    
                    $this->writeLogs(RUNTIME_PATH.'Logs/','proOrders',"
    -------------------".date('Y-m-d H:i:s')."查询订单信息---------
    ---响应数据:".json_encode($order_data)."
    ------------
    ");
                    //数据处理
                    $data_handle = $orders_model->data_handle($order_data,$table_id,$branch_id,$orders_info['cash_fee']/100,$orders_info['transaction_id']);
    
                    $this->writeLogs(RUNTIME_PATH.'Logs/','proOrders',"
    -------------------".date('Y-m-d H:i:s')."微信支付数据处理结果---------
    ---响应数据:".json_encode($data_handle)."
    ------------
    ");
    
                    //支付方式入库
                    $pay_data = array(
                            'orders_id' => $data_handle['orders_id'],  //订单编号
                            'branch_id' => (int)$branch_id,  // 店铺 ID
                            'pay_sn'    =>  $orders_info['transaction_id'],    // 支付 SN
                            'pay_total' =>  sprintf("%.2f",$orders_info['cash_fee']/100),   // 支付金额
                            'pay_type'  =>  1,  // 支付类型 
                            'table_id'  =>  $table_id,  // 桌台ID
                    );
                //添加副表
                $pay_sn = $orders_model->add_orders_pay_sn($pay_data);
                $pay_state = $data_handle['state'];
                
                if($pay_state == 1){  //完成订单
                    //完成订单后,没有确认的订单也全部清空 add yangzl                
                    $del_redis_orders = $orders_model->del_redis_orders_p($branch_id, $table_id);
                    if (!$del_redis_orders){
                         log::write( "现金订单完成后收尾".$table_id);
                    }
                    //设置状态
                    $table_model = new TablesModel();
                    $state = $table_model->set_table_state($table_id, $branch_id, 4);
                }
                // 服务员下单一对一推送
                $table_base = $table_model->get_table_by_id($table_id,$branch_id);
                $table_title = $table_base['title'];
                Push::app_push_waiter_checkout($table_id, $table_title, '1');
                exit();
    
            }else{ //支付失败
                log::write( "支付订单号数据支付失败::支付订单号".$orders_info['transaction_id']);
                exit();
            }
        }else{
            log::write( "支付订单号数据已处理".$orders_info['transaction_id']);
            $this->returnXml();
            exit();
        }
    }
    
    
    
    
         /**********写入日志方法***********/
        /**
         * 日志记录
         * @param  $path     string   日志文件目录
         * @param  $file     string   日志文件名,不包含后缀
         * @param  $content  string   记录内容
         * @param  @author yangzl     
         * @return void  
         **/
        public function writeLogs($path,$file,$content,$more=true){
            $newpath = '';
            if (!file_exists($path)) {
                mkdir ($path);
                @chmod ($path, 0777 );
            }
            if($more){
                $newpath .= $path.$file.@date('Y-m-d').".log";
            }else{
                $newpath .= $path.$file.".log";
            }       
            $content .="
    "."----------------------------------------------------------------------------------------------------------------"."
    ";
            $this->write_file($newpath,$content,"a+");
        }
    
    
     /**
         * 写内容
         * @param  $filename   string   日志文件名
         * @param  $data       string   记录内容
         * @param  $method     
         * @author yanzl
         **/
        private function write_file($filename,$data,$method="rb+",$iflock=1){
            @touch($filename);
            $handle=@fopen($filename,$method);
            if($iflock){
                @flock($handle,LOCK_EX);
            }
            @fputs($handle,$data);
            if($method=="rb+") @ftruncate($handle,strlen($data));
            @fclose($handle);
            @chmod($filename,0777); 
            if( is_writable($filename) ){
                return 1;
            }else{
                return 0;
            }
        }
    }
    
    
     ?>
  • 相关阅读:
    数据分析之可反复与独立样本的T-Test分析
    朗朗上口的两幅对联
    mysql编码、数据表编码查看和改动总结
    2014-04-19编程之美初赛题目及答案解析
    测试集群模式安装实施Hadoop
    笔记:常用排序算法
    笔记:常用排序算法
    安装Redis并测试
    常见架构风格举例总结
    转载:PostgreSQL SQL的性能提升
  • 原文地址:https://www.cnblogs.com/yangzailu/p/9674356.html
Copyright © 2011-2022 走看看