zoukankan      html  css  js  c++  java
  • 封装一个Model或者Vender类

    Model

    <?php
    
    /**
     * User: Eden
     * Date: 2019/3/21
     * 共有内容
     */
    
    class WxPayModel extends Model {
        protected static $SSL_CERT_PATH = './apiclient_cert.pem';//证书路径
        protected static $SSL_KEY_PATH =  './apiclient_key.pem';//证书路径
    
        public static function unifiedOrder($openid,$order_num,$total_fee,$products_name,$notify_url = ''){
            $trade_no = $order_num;
            $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
            $param = [
                'appid'             => C('APPID'),
                'mch_id'            => C('MCHID'),
                'nonce_str'         => self::createNonceStr(),
                'sign_type'         => 'MD5',
                'body'              => $products_name,  //商品名称组合
                'attach'            => C('APP_NAME').'-附加信息',
                'out_trade_no'      => $trade_no,       //订单号
                'fee_type'          => 'CNY',
                'total_fee'         => $total_fee,
                'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],
                'goods_tag'         => C('APP_NAME').'-商品标记',
                'notify_url'        => $notify_url ?:C('NOTIFY_URL'),
                'trade_type'        => 'JSAPI',
                'openid'            => $openid
            ];
    
            $sign = self::MakeSign($param);
            $param['sign'] = $sign;
            $xml = self::ToXml($param);
            $result = self::FromXml(Http::postXmlCurl($url,$xml));
            setlog($param,$result,__METHOD__);
    
            // 加工数据
            $data = [
                'appId' => $result['appid'] ?: C('APPID'),
                'timeStamp' => time(),
                'nonceStr' => self::createNonceStr(),
                'package' => 'prepay_id=' . $result['prepay_id'],
                'signType' => 'MD5'
            ];
            $sign = self::MakeSign($data);
            $data['sign'] = $sign;
            return $data;
        }
    
        /**
         * 处理退款
         * @param $out_trade_no
         * @param $total_fee
         * @param $refund_fee
         * @return array
         * @throws Exception
         */
        public static function refundOrder($out_trade_no,$total_fee,$refund_fee) {
            $refund_no = $out_trade_no.rand('1111,9999');
            $param = array(
                'appid'         => C('APPID'),
                'mch_id'        => C('MCHID'),
                'nonce_str'     => self::createNonceStr(),
                'out_refund_no' => $refund_no, //由后端生成的退款单号,需要保证唯一,因为多个同样的退款单号只会退款一次。
                'out_trade_no'  => $out_trade_no,                   //退款订单在支付时生成的订单号
                'total_fee'     => $total_fee,
                'refund_fee'    => $refund_fee,
                'op_user_id'    => C('MCHID'),          //操作员 op_user_id .与商户号相同即可
            );
    
            $param['sign'] = self::MakeSign($param);
            $xml_data = self::ToXml($param);
            $xml_result = self::postXmlSSLCurl($xml_data,'https://api.mch.weixin.qq.com/secapi/pay/refund');
            $result = self::FromXml($xml_result);
            setlog($param,$result,__METHOD__);
    
            if (!$result){
                $result_arr = [
                    'num'     =>      '0',
                    'desc'   =>      '接口错误',
                ];
                return $result_arr;
            }
    
            if ($result['result_code'] != 'SUCCESS'){
                $result_arr = [
                    'num'     =>      '-1',
                    'desc'    =>      $result['err_code_des']
                ];
            } else {
                $result_arr = [
                    'num'     =>      '1',
                    'desc'    =>      '退款成功',
                    'refund_id'    =>      $result['refund_id'],
                    'refund_no'    =>      $refund_no,
                ];
            }
    
            return $result_arr;
        }
    
        public static function FromXml($xml)
        {
            if(!$xml){
                throw new Exception("xml数据异常!");
            }
            //将XML转为array
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);
            $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            return $values;
        }
    
        public static function ToXml($array){
            if(!is_array($array)|| count($array) <= 0){
                return ;
            }
            $xml = '<xml version="1.0">';
            foreach ($array as $key=>$val){
                if (is_numeric($val)){
                    $xml.="<".$key.">".$val."</".$key.">";
                }else{
                    $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
                }
            }
            $xml.="</xml>";
            return $xml;
        }
    
        public static function createNonceStr($length = 16) {
            $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
            $str = '';
            for ( $i = 0; $i < $length; $i++ )  {
                $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
            }
            return $str;
        }
    
        public static function MakeSign($data)
        {
            //签名步骤一:按字典序排序参数
            ksort($data);
            $string = self::ToUrlParams($data);
            //签名步骤二:在string后加入KEY
            $string = $string . "&key=".C('WEIXIN_PAY_KEY');
            //签名步骤三:MD5加密
            $string = md5($string);
            //签名步骤四:所有字符转为大写
            $result = strtoupper($string);
            return $result;
        }
    
        public static function ToUrlParams($array)
        {
            $buff = "";
            foreach ($array as $k => $v)
            {
                if($k != "sign" && $v != "" && !is_array($v)){
                    $buff .= $k . "=" . $v . "&";
                }
            }
            $buff = trim($buff, "&");
            return $buff;
        }
    
    
        /**
         * 需要使用证书的请求
         */
        public static function postXmlSSLCurl($xml,$url,$second=30)
        {
            $ch = curl_init();
            //超时时间
            curl_setopt($ch, CURLOPT_TIMEOUT, $second);
            //这里设置代理,如果有的话
            //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
            //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            //设置header
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            //要求结果为字符串且输出到屏幕上
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            //设置证书
            //使用证书:cert 与 key 分别属于两个.pem文件
            //默认格式为PEM,可以注释
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLCERT, self::$SSL_CERT_PATH);
            //默认格式为PEM,可以注释
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLKEY, self::$SSL_KEY_PATH);
            //post提交方式
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            $data = curl_exec($ch);
            //返回结果
            if ($data) {
                curl_close($ch);
                return $data;
            } else {
                $error = curl_errno($ch);
                echo "curl出错,错误码:$error" . "<br>";
                curl_close($ch);
                return false;
            }
        }
    }
    
    

    Vendor类

    <?php
    
    /**
     * User: Eden
     * Date: 2019/3/21
     * 共有内容
     */
    
    class WxPay {
        protected static $SSL_CERT_PATH = './apiclient_cert.pem';//证书路径
        protected static $SSL_KEY_PATH =  './apiclient_key.pem';//证书路径
    
        public static function unifiedOrder($openid,$order_num,$total_fee,$products_name,$notify_url = ''){
            $trade_no = $order_num;
            $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
            $param = [
                'appid'             => C('APPID'),
                'mch_id'            => C('MCHID'),
                'nonce_str'         => self::createNonceStr(),
                'sign_type'         => 'MD5',
                'body'              => $products_name,  //商品名称组合
                'attach'            => C('APP_NAME').'-附加信息',
                'out_trade_no'      => $trade_no,       //订单号
                'fee_type'          => 'CNY',
                'total_fee'         => $total_fee,
                'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],
                'goods_tag'         => C('APP_NAME').'-商品标记',
                'notify_url'        => $notify_url ?:C('NOTIFY_URL'),
                'trade_type'        => 'JSAPI',
                'openid'            => $openid
            ];
    
            $sign = self::MakeSign($param);
            $param['sign'] = $sign;
            $xml = self::ToXml($param);
            $result = self::FromXml(Http::postXmlCurl($url,$xml));
            setlog($param,$result,__METHOD__);
    
            // 加工数据
            $data = [
                'appId' => $result['appid'] ?: C('APPID'),
                'timeStamp' => time(),
                'nonceStr' => self::createNonceStr(),
                'package' => 'prepay_id=' . $result['prepay_id'],
                'signType' => 'MD5'
            ];
            $sign = self::MakeSign($data);
            $data['sign'] = $sign;
            return $data;
        }
    
        /**
         * 处理退款
         * @param $out_trade_no
         * @param $total_fee
         * @param $refund_fee
         * @return array
         * @throws Exception
         */
        public static function refundOrder($out_trade_no,$total_fee,$refund_fee) {
            $refund_no = $out_trade_no.rand('1111,9999');
            $param = array(
                'appid'         => C('APPID'),
                'mch_id'        => C('MCHID'),
                'nonce_str'     => self::createNonceStr(),
                'out_refund_no' => $refund_no, //由后端生成的退款单号,需要保证唯一,因为多个同样的退款单号只会退款一次。
                'out_trade_no'  => $out_trade_no,                   //退款订单在支付时生成的订单号
                'total_fee'     => $total_fee,
                'refund_fee'    => $refund_fee,
                'op_user_id'    => C('MCHID'),          //操作员 op_user_id .与商户号相同即可
            );
    
            $param['sign'] = self::MakeSign($param);
            $xml_data = self::ToXml($param);
            $xml_result = self::postXmlSSLCurl($xml_data,'https://api.mch.weixin.qq.com/secapi/pay/refund');
            $result = self::FromXml($xml_result);
            setlog($param,$result,__METHOD__);
    
            if (!$result){
                $result_arr = [
                    'num'     =>      '0',
                    'desc'   =>      '接口错误',
                ];
                return $result_arr;
            }
    
            if ($result['result_code'] != 'SUCCESS'){
                $result_arr = [
                    'num'     =>      '-1',
                    'desc'    =>      $result['err_code_des']
                ];
            } else {
                $result_arr = [
                    'num'     =>      '1',
                    'desc'    =>      '退款成功',
                    'refund_id'    =>      $result['refund_id'],
                    'refund_no'    =>      $refund_no,
                ];
            }
    
            return $result_arr;
        }
    
        public static function FromXml($xml)
        {
            if(!$xml){
                throw new Exception("xml数据异常!");
            }
            //将XML转为array
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);
            $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            return $values;
        }
    
        public static function ToXml($array){
            if(!is_array($array)|| count($array) <= 0){
                return ;
            }
            $xml = '<xml version="1.0">';
            foreach ($array as $key=>$val){
                if (is_numeric($val)){
                    $xml.="<".$key.">".$val."</".$key.">";
                }else{
                    $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
                }
            }
            $xml.="</xml>";
            return $xml;
        }
    
        public static function createNonceStr($length = 16) {
            $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
            $str = '';
            for ( $i = 0; $i < $length; $i++ )  {
                $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
            }
            return $str;
        }
    
        public static function MakeSign($data)
        {
            //签名步骤一:按字典序排序参数
            ksort($data);
            $string = self::ToUrlParams($data);
            //签名步骤二:在string后加入KEY
            $string = $string . "&key=".C('WEIXIN_PAY_KEY');
            //签名步骤三:MD5加密
            $string = md5($string);
            //签名步骤四:所有字符转为大写
            $result = strtoupper($string);
            return $result;
        }
    
        public static function ToUrlParams($array)
        {
            $buff = "";
            foreach ($array as $k => $v)
            {
                if($k != "sign" && $v != "" && !is_array($v)){
                    $buff .= $k . "=" . $v . "&";
                }
            }
            $buff = trim($buff, "&");
            return $buff;
        }
    
    
        /**
         * 需要使用证书的请求
         */
        public static function postXmlSSLCurl($xml,$url,$second=30)
        {
            $ch = curl_init();
            //超时时间
            curl_setopt($ch, CURLOPT_TIMEOUT, $second);
            //这里设置代理,如果有的话
            //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
            //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            //设置header
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            //要求结果为字符串且输出到屏幕上
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            //设置证书
            //使用证书:cert 与 key 分别属于两个.pem文件
            //默认格式为PEM,可以注释
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLCERT, self::$SSL_CERT_PATH);
            //默认格式为PEM,可以注释
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLKEY, self::$SSL_KEY_PATH);
            //post提交方式
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            $data = curl_exec($ch);
            //返回结果
            if ($data) {
                curl_close($ch);
                return $data;
            } else {
                $error = curl_errno($ch);
                echo "curl出错,错误码:$error" . "<br>";
                curl_close($ch);
                return false;
            }
        }
    }
    
    

    使用效果差不多。

  • 相关阅读:
    ORA-28000 帐户已被锁定问题处理
    德邦总管 修改oracle数据库用户密码的方法
    测试面试题目
    python 把一文件包含中文的字符写到另外文件乱码 UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position
    python version 2.7 required,which was not found in the registry
    ImportError: No module named dateutil.parser
    解决python2.x用urllib2证书验证错误, _create_unverified_context
    python多版本兼容性问题:当同时安装Python2和Python3后,如何兼容并切换
    MAC OS git客户端安装及操作
    Pycharm连接gitlab
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/10886489.html
Copyright © 2011-2022 走看看