• 微信APP支付,服务器端生成prepay_id,及后续处理


      1 <?php
      2     /*
      3         微信支付类
      4     */
      5     class Wx {
      6         const     APPID             = 'xxxx'; //公众账号ID
      7         const     MCHID             = 'xxxx'; //商户号
      8         const     APPPWD             = 'xxxx'; //APP秘钥
      9         const     URL             = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
     10         private $_config         = array();
     11 
     12         public function __construct($info) {
     13             //生成配置参数
     14             $this->_makeConfig($info);
     15         }
     16 
     17         /*
     18             运行方法
     19         */
     20         public function run() {
     21 
     22             //将config 转换为xml格式数据
     23             $xml_str             = '';
     24             $xml_str             = '<xml>';
     25             foreach ($this->_config as $k => $v) {
     26                 $xml_str         .= '<'.$k.'>' . $v . '</'.$k.'>';
     27             }
     28             $xml_str             .= '</xml>';
     29 
     30             return    $this->_postXmlCurl($xml_str,self::URL);
     31         }
     32 
     33         /*
     34             生成配置文件
     35         */
     36         private function _makeConfig($info) {
     37             if(!is_array($info))
     38                 exit('非法传参');
     39 
     40             //固定参数
     41             $fix_config         = array(
     42                 'appid'                 => strtolower(self::APPID),
     43                 'mch_id'                 => strtolower(self::MCHID),
     44                 'nonce_str'             => strtolower($this->_makeRandom()),
     45                 'spbill_create_ip'         => strtolower(get_client_ip()),
     46                 'trade_type'             => 'APP',
     47             );
     48 
     49             $tmp_config         = array_merge($fix_config,$info);
     50 
     51             $this->_config         =  $this->_sortConfig($tmp_config);
     52 
     53             $this->_makeSign();
     54         }
     55 
     56         /*
     57             生成随机字符串
     58         */
     59         private function _makeRandom() {
     60             return md5(uniqid());
     61         }
     62 
     63         /*
     64             对配置文件进行排序
     65         */
     66         private function _sortConfig($arr) {
     67             $new_arr             = array();
     68             foreach ($arr as $key => $value) {
     69                 if(empty($value))
     70                     continue;
     71 
     72                 $new_arr[$key]     = $value;
     73             }
     74             ksort($new_arr);
     75             return $new_arr;
     76         }
     77 
     78         /*
     79             生成签名
     80         */
     81         private function _makeSign() {
     82             //第一步,将config参数生成 & 分割的字符串
     83             $str_config             = '';
     84             foreach ($this->_config as $key => $value) {
     85                 if(empty($value))
     86                     continue;
     87 
     88                 $str_config         .= $key . '=' . $value . '&';
     89             }
     90 
     91             //拼接API密钥
     92             $str_config             .= 'key=' . self::APPPWD;
     93 
     94             //md5 加密,并转为大写
     95             $sign_info                  = strtoupper(md5($str_config));
     96 
     97             $this->_config['sign']     = $sign_info;
     98         }
     99 
    100 
    101         /**
    102          * 以post方式提交xml到对应的接口url
    103          * 
    104          * @param string $xml  需要post的xml数据
    105          * @param string $url  url
    106          * @param bool $useCert 是否需要证书,默认不需要
    107          * @param int $second   url执行超时时间,默认30s
    108          * @throws WxPayException
    109         */
    110         private function _postXmlCurl($xml, $url, $useCert = false, $second = 30){        
    111             $ch = curl_init();
    112             //设置超时
    113             curl_setopt($ch, CURLOPT_TIMEOUT, $second);
    114             curl_setopt($ch,CURLOPT_URL, $url);
    115             curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
    116             curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
    117             //设置header
    118             curl_setopt($ch, CURLOPT_HEADER, FALSE);
    119             //要求结果为字符串且输出到屏幕上
    120             curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    121         
    122             if($useCert == true){
    123                 //设置证书
    124                 //使用证书:cert 与 key 分别属于两个.pem文件
    125                 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    126                 curl_setopt($ch,CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);
    127                 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    128                 curl_setopt($ch,CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);
    129             }
    130             //post提交方式
    131             curl_setopt($ch, CURLOPT_POST, TRUE);
    132             curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    133             //运行curl
    134             $data = curl_exec($ch);
    135 
    136             //返回结果
    137             if($data){
    138                 curl_close($ch);
    139                 return $data;
    140 
    141             } else { 
    142                 $error = curl_errno($ch);
    143                 curl_close($ch);
    144                 
    145                 return false;
    146             }
    147         }
    148 
    149     }

    调用:

      

     1 /*
     2             微信支付总方法
     3         */    
     4         private function _wxPayAction($need_info) {
     5             if(empty($need_info))
     6                 $this->myreturn(array(),'109802','程序内部初始化失败',-1);
     7 
     8 
     9             //引入微信支付
    10             Vendor('Wx.Wx');
    11             $wx_obj             = new Wx(array(
    12                 'body'             => $need_info['goods_name'],//商品名
    13                 'out_trade_no'     => $need_info['order_index'],//订单号
    14                 // 'total_fee'     => $need_info['price_total'] * 100,//价格,分
    15                 'total_fee'     => 1,
    16                 'attach'         => $need_info['goods_name'],
    17                 'notify_url'     => 'http://' . $_SERVER['HTTP_HOST'] . U('Leasegoods/wx_notify_url_new'),//异步通知页面url
    18             ));
    19 
    20             $wx_return_data     = $wx_obj->run();
    21 
    22             //日志记录
    23             $wx_log_path         = RUNTIME_PATH . '/Wx_log/';
    24 
    25             if(!is_dir($wx_log_path))
    26                 mkdir($wx_log_path,0777,true);
    27 
    28             $wx_log_dir          = $wx_log_path .date('Y-m-d'). '.log';
    29             Log::write('订单编号为 ' . $need_info['order_index'] . '的订单,请求微信prepay_id支付,返回xml为:' . $wx_return_data,Log::DEBUG,Log::FILE,$wx_log_dir);
    30 
    31 
    32 
    33             //获取需要的值
    34             if($wx_return_data === false)
    35                 $this->myreturn(array(),'109803','请求微信支付接口失败',-1);
    36 
    37             //匹配出return_code
    38             $pattern             = '/<return_code><![CDATA[([A-Z]{7})]]></return_code>/iU';
    39             $info                 = preg_match_all($pattern,$wx_return_data, $matches_code);
    40 
    41             if($info) {
    42                 if($matches_code[1][0] == 'SUCCESS') {
    43                     $pattern     = '/<prepay_id><![CDATA[([w]+)]]></prepay_id>/iU';
    44                     $info_id     = preg_match_all($pattern, $wx_return_data, $matches_id);
    45                     if($info_id) {
    46                         $this->myreturn(array('result' => array('prepay_id' => $matches_id[1][0])),'','获取成功',0);
    47                     }else
    48                         $this->myreturn(array(),'109804','匹配prepay_id失败',-1);
    49 
    50                 }else 
    51                     $this->myreturn(array(),'109805','微信同一订单请求失败',-1);
    52                 
    53             }else 
    54                 $this->myreturn(array(),'109806','匹配状态码失败',-1);
    55             
    56         }

    通知处理

      

            /*
                微信支付后回调页面
            */
            public function wx_notify_url_new() {
                $return_info             = file_get_contents('php://input','r');
                if(!$return_info)
                    echo $this->_wxReturnDataFormat(array('code' => 'FILE','mes' => '无返回值'));
    
                //log目录
                $wx_log_path             = RUNTIME_PATH . '/Wx_log/';
                if(!is_dir($wx_log_path))
                    mkdir($wx_log_path,0777,true);
    
                $wx_log_dir              = $wx_log_path .date('Y-m-d'). '.log';
                
                Log::write('服务器获取到的总参数:' . $return_info, Log::DEBUG, Log::FILE, $wx_log_dir);
    
                //匹配return_code
                $return_code             = $this->_wxGetOneInfo('return_code',$return_info);
                if($return_code == 'SUCCESS'){
    
                    //获取订单号
                    $order_index         = $this->_wxGetOneInfo('out_trade_no',$return_info);
    
                    //业务处理。。。。
    
                    echo $this->_wxReturnDataFormat(array('code' => 'SUCCESS','mes' => 'OK'));
    
                }else {
    
                    //暂放
    
                    echo $this->_wxReturnDataFormat(array('code' => 'FILE','mes' => 'code错误'));
                }
    
    
                
            }
    
    
            /*
                匹配某一项内容
                @param         pat     要匹配的内容正则表达式
                            info     内容
            */
            private function _wxGetOneInfo($pat,$info) {
                if($pat == 'total_fee')
                    $pattern                 = '/<total_fee>([d]+)</total_fee>/iU';
                else
                    $pattern                 = '/<'.$pat.'><![CDATA[([sS]+)]]></'.$pat.'>/uiU';
                $mat_int                     = preg_match_all($pattern, $info, $matches);
                if(!$mat_int)
                    return '匹配异常';
    
                return $matches[1][0];
            }
    
    
            /*
                拼接微信返回值信息
            */
            private function _wxReturnDataFormat($arr) {
                $str             = '<xml>';
                $str             .= '<return_code><![CDATA['.$arr['code'].']]></return_code>';
                $str             .= '<return_msg><![CDATA['.$arr['mes'].']]></return_msg>';
                $str             .= '</xml>';
                return $str;
            }
  • 相关阅读:
    文件夹选项查看显示所有文件和文件夹..确定后隐藏文件依然不能显示,.
    加速电脑启动,给电脑瘦身
    进行性肌营养不良症的治疗
    可变量程的直流电压表
    数字图象处理课件 下载
    两顾高楼
    技巧心得:给拥有Google AdSense 帐户 朋友的一点忠告
    进行性肌营养不良研究又有新的发现
    电子通讯系统 >> BAS系统在地铁环境控制中的应用及实现
    J2ME游戏开发中时钟的简单实现
  • 原文地址:https://www.cnblogs.com/lxdd/p/4708140.html
Copyright © 2020-2023  润新知