微信退款全解析

3,300 阅读2分钟

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

0 系列文章

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

1 申请退款

官方接口文档

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

注意:

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

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

Paste_Image.png
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

结尾

更多文章关注我的公众号

我的公众号
我的公众号