php laravel5.5 iis微信退款接口踩坑避雷经验

微信支付啊,一向以官方文档太烂而著称,怎么说呢,服务器端的demo基本都没有实例,而且重名参数比较多,服务器端开发与app端开发一个参数用错就要找好长时间。支付宝支付开发了很多种类,遇到的问题能很快解决,微信的就呵呵了。
最近看他的退款接口要用证书,而文档中证书怎么使用完全没写。查了很多资料啊
至于如何下载和生成,在商户号里面 api安全 里面设置,也不一一赘述。
生成后的证书解压后如下三个文件,上传服务器自己选定位置,后台退款接口需要用到


image.png

iis安装过程可以参考下面两篇文章
https://blog.csdn.net/yangzhiman/article/details/78997152

https://blog.csdn.net/Sunny_Ran/article/details/77991201
已经很详尽了,我这里就不多写了。
主要介绍代码中使用证书的方法
先定义好几个函数,模型类请用自己的喔,或者直接写原生的查询数据库方法,改动也很简单,以下PayConfig数据库中存储支付配置信息,因为我这边是多应用支付模块
PayOrder为数据库中订单的数据表
这两个都根据自己的实际情况改变

    /**
     * 设置支付参数
     * @param $id
     * @return bool
     */
    public function setConfig($id){
        //查找数据
        $config = PayConfig::where('id',$id)->first();
        if(!$config->id){
            return false;
        }
        /*配置参数*/
        $this->config = [
            'appid' => $config->appid,                  /*微信开放平台上的应用id*/
            'mch_id' => $config->mch_id,                 /*微信申请成功之后邮件中的商户id*/
            'api_key' => $config->publickey,                /*在微信商户平台上自己设定的api密钥 32位*/
            'notify_url' => '回调地址,退款接口不用设置'
        ];
        $this->recher =0;
        return $config;
    }

    //获取指定长度的随机字符串
    public function getRandChar($length){
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol)-1;
        for($i=0;$i<$length;$i++){
            $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }
        return $str;
    }

    //数组转xml
    public function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val))
            {
                $xml.="<".$key.">".$val."</".$key.">";

            }
            else
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }

  /**
     * curl方法
     * @param $xml
     * @param $url
     * @param int $second
     * @param int $cert
     * @return bool|false|string
     */
    public function postXmlCurl($xml,$url,$second=30, $cert=0)
    {
        //初始化curl
        $ch = curl_init();
        //超时时间
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        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);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

        //设置证书
        if($cert){
            //此处证书引用绝对路径
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'pem');
            curl_setopt($ch, CURLOPT_SSLCERT, 'D:\项目名\public\certNotify\apiclient_cert.pem');
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'pem');
            curl_setopt($ch, CURLOPT_SSLKEY, 'D:\项目名\public\certNotify\apiclient_key.pem');
        }
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if($data)
        {
            curl_close($ch);
            return $data;
        }
        else
        {
            $error = curl_errno($ch);
            //echo "curl出错,错误码:$error"."<br>";
            return json_encode(array('code'=>$error,'status'=>0));
            //return false;
        }
    }

    /**
     *xml转成数组
     */
    public function xmlstr_to_array($xmlstr) {

        //将XML转为array
        return json_decode(json_encode(simplexml_load_string($xmlstr, 'SimpleXMLElement',LIBXML_NOCDATA)), true);

    }


 /**
     * 退款方法
     * @param $id 为数据库中订单id,供查询订单使用
     * @return bool
     */
    public function refundOrder($id){
        $order = PayOrder::where('id',$id)->first();
        if(!$order) return false;

        //设置微信配置参数
        $config = $this->setConfig($order->config_id);
        //微信退款接口地址
        $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";

        $this->recher = $onoce_str = $this->getRandChar(32);//随机字符串
        $data["appid"] = $this->config['appid'];//你得APPID
        $data["mch_id"] = $this->config['mch_id'];//商户号
        $data["nonce_str"] = $onoce_str;
        $data["out_refund_no"] = $order->out_trade_no;//你得订单号
        $data["out_trade_no"] = $order->out_trade_no;//你得订单号
        $data["transaction_id"] = $order->trade_no;//订单支付成功后微信返回的微信数据中订单号,传了订单号可不传这个参数
        $total_fee = $order->total_amount;//你得订单号
        $data["refund_fee"] = $total_fee*100;//支付金额
        $data["total_fee"] = $total_fee*100;//支付金额


        $data["sign"] =  $this->getSign($data, false);

        $xml = $this->arrayToXml($data);

        $response = $this->postXmlCurl($xml, $url ,30 ,1 );
       //laravel 的日志打印
        Log::useFiles(storage_path('logs/wxpayapi.log'), 'debug');
        Log::debug($response);
        //将微信返回的结果xml转成数组
        $result = $this->xmlstr_to_array($response);

        //laravel 的日志打印
        Log::debug($result);
        if($result['result_code'] && $result['result_code']=='SUCCESS'){
            //更新数据
            $order->status = 4;
            $order->save();
            $status = true;
        }else{
            //laravel 的日志打印
            Log::useFiles(storage_path('logs/wxpayapi.log'), 'debug');
            Log::debug($result);
            $status = false;
        }
        return $status;
    }

    调用方法
    $this->refundOrder('传入你数据库中的退款订单id');

以上要改动的就是postXmlCurl 中你下载的证书在你服务器的绝对位置。
安装教程也一定要仔细走一遍喔
不然报错400 No required SSL certificate was sent

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 基于PHP的微信支付教程 微信支付作为各大移动支付方式之一,本课程只要向大家介绍并使用微信支付的常用功能,进而集合...
    獨愛凌亂中那抹獨特的華麗阅读 8,545评论 0 7
  • 关于微信支付 1. 生活中的微信支付   目前我们日常生活中接触得比较多的线上电子支付方式主要有两种,一种是支付宝...
    小流歌_阅读 587评论 0 0
  • 数据存储: 在 iOS 开发中数据的存储可以归纳为两类:一类是存储为文件,另一类是存储为数据库. 存储为文件: D...
    青葱烈马阅读 816评论 0 6
  • 摘自--IDO老徐一、输入框1、字符型输入框:(1)字符型输入框:英文全角、英文半角、数字、空或者空格、特殊字符“...
    时间的磨练lolo阅读 1,413评论 0 8
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,476评论 16 22