微信退款全解析

作者: Tsy远 | 来源:发表于2016-07-11 11:46 被阅读8791次

    简单介绍了微信退款的请求处理和一些注意事项

    0 系列文章

    系列一 微信App支付全解析
    系列二 支付宝App支付全解析
    系列三 微信公众号支付全解析
    系列四 微信扫码支付全解析
    系列五 支付宝即时到账支付全解析
    系列六 微信退款全解析
    系列七 支付宝退款全解析
    系列八 支付宝开放平台支付更新升级全解析

    1 申请退款

    官方接口文档

    当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。

    注意:

    1. 交易时间超过一年的订单无法提交退款
    2. 微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。

    需要证书验证。证书下载:
    用于退款等一些需要证书验证的接口使用。在微信商户平台点击「账户中心 - API 安全」,点击「下载证书」

    Paste_Image.png

    证书下载后,打开压缩包会看到「apiclient_cert.pem」和「apiclient_key.pem」和rootca.pem证书。

    $appid = "";  //你的appid
    $mch_id = "";  //商户id
    $wx_api_key = "";    //商户api秘钥
    $out_trade_no = "";  //待退款交易的业务交易号
    $out_refund_no = "";  //业务生成的唯一退款单号
    $total_fee = "1";    //待退款交易的总金额
    $refund_fee = "1";  //退款金额 单位分
    
    $REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";  //退款
    
    $data = array();
    $data['appid'] = $appid; 
    $data['mch_id'] =$mch_id;
    $data['nonce_str'] = randomStr(20);  //随机20位字符串
    $data['out_trade_no'] = $out_trade_no;    
    $data['out_refund_no'] = $out_refund_no;   
    $data['total_fee'] = $total_fee;
    $data['refund_fee'] = $refund_fee;
    $data['op_user_id'] = mch_id;
    $data['sign'] =sign($data, $wx_api_key);    //签名
    
    //转为xml格式
    $xml_str = arrayToXmlStr($data); 
    
    //证书设置
    $opt_arr = array(    
      CURLOPT_SSLCERT => "../" . $config['wx_pemcert'],      
      CURLOPT_SSLKEY => "../" . $config['wx_pemkey'],    
      CURLOPT_CAINFO => "../key/wx_rootca.pem");
    
    //发送请求 使用封装好的curl_post
    $result = Curl::curl_post($REFUND_URL, $xml_str, $opt_arr);
    
    //解析得到的值
    $get_data = simplexml_load_string($raw_data, 'SimpleXMLElement', LIBXML_NOCDATA);
    $get_para = array();
    $get_sign = "";
    foreach ($get_data->children() as $child) 
    {    
      if($child->getName() == 'sign') {        
        $get_sign = strval($child);    
      } else {        
        $get_para[strval($child->getName())] = strval($child);    
       }
    }
    
    if($get_para['return_code'] !== "SUCCESS") {
        //return code fail
    }
    
    //验证签名
    if(!verifySign($get_sign, $get_para, $wx_api_key)) {
        //验证签名非法
    }
    //验证result code
    if($get_para['result_code'] !== 'SUCCESS') {
      //申请失败
    }
    
    //退款申请成功
    //todo
    

    2 退款查询

    由于微信退款会根据支付渠道而到账时间不同,所有微信本身不提供到账回调。
    退款申请成功并不能代表到账成功,所有业务方需要定时调用查询退款状态。
    一般零钱和银行卡支付的20分钟内到账,信用卡会2-3天到账。

    所以我设置的定时任务是分别在退款申请成功后的15s 2min 20min 1day 1day 2day 2day频率进行退款查询。

    官方接口文档

    $appid = "";  //你的appid
    $mch_id = "";  //商户id
    $wx_api_key = "";    //商户api秘钥
    $out_refund_no = "";  //待查询的退款单号
    
    $REFUND_QUERY_URL = "https://api.mch.weixin.qq.com/pay/refundquery";  //退款查询
    
    $data = array();
    $data['appid'] = $appid; 
    $data['mch_id'] =$mch_id;
    $data['nonce_str'] = randomStr(20);  //随机20位字符串
    $data['out_refund_no'] = $out_refund_no;   
    $data['sign'] =sign($data, $wx_api_key);    //签名
    
    //转为xml格式
    $xml_str = arrayToXmlStr($data); 
    //发送请求 使用封装好的curl_post
    $result = Curl::curl_post($REFUND_QUERY_URL, $xml_str);
    
    //解析得到的值
    $get_data = simplexml_load_string($raw_data, 'SimpleXMLElement', LIBXML_NOCDATA);
    $get_para = array();
    $get_sign = "";
    foreach ($get_data->children() as $child) 
    {    
      if($child->getName() == 'sign') {        
        $get_sign = strval($child);    
      } else {        
        $get_para[strval($child->getName())] = strval($child);    
       }
    }
    
    if($get_para['return_code'] !== "SUCCESS") {
        //return code fail
    }
    
    //验证签名
    if(!verifySign($get_sign, $get_para, $wx_api_key)) {
        //验证签名非法
    }
    //验证result code
    if($get_para['result_code'] !== 'SUCCESS') {
      //退款失败记录log
      //todo
    }
    //退款成功 修改退款状态
    //todo
    

    结尾

    更多文章关注我的公众号


    我的公众号

    相关文章

      网友评论

      • 3fdb581ec682:问下大神,那个查询退款的话,后台设置查询退款的频率时间,按照你弄的出现过退款异常吗
        Tsy远:我这边暂时没有遇到过
      • 21ea7cf2d4a9:非全额退款怎么处理呀!!!
        21ea7cf2d4a9:@对于你而言 http://bbs.csdn.net/topics/392088329
        21ea7cf2d4a9:@Tsy远 我的地区小于全额金额,可还是失败呀
        Tsy远:微信本身支持非全额退款,只要你退款金额小于支付金额就行
      • 8af345d3ee91:看了微信公众号的规则,公众号的收入会(满500元)自动转出到银行卡。如果我给公众号充值2000元,这部分钱会(满500元)自动转出吗?
        8af345d3ee91:@Tsy远 感谢回复,后经测试确实如此。
        Tsy远:在公众号里充值是不会的

      本文标题:微信退款全解析

      本文链接:https://www.haomeiwen.com/subject/amfjjttx.html