在之前做支付的时候我就想着可能会有这么一天,该来的终究是要来的,这两天开始研究一下微信和支付宝的退款
关于微信支付的方法可以看一下在我之前写的一篇博客‘微信H5支付&公众号支付大型攻略’,几个月过去了,现在想想还是觉得很难受,完全不想再回忆这个流程
支付宝
先来看一下支付宝的文档‘统一收单交易退款接口’,可以说是非常贴心了,下面直接贴了各种语言的demo,基本上复制粘贴过来参数改了就能用了,需要依赖官网SDK‘SDK下载’,下面上代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27$aop = new AopClient ();
// 设置请求参数
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
$aop->appId = 'appid';
$aop->rsaPrivateKey = '商户私钥';
$aop->alipayrsaPublicKey = '支付公钥';
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset = 'GBK'; // 这里要注意编码一致,虽然文档写的是GBK,但是大部分情况下都是UTF-8
$aop->format = 'json';
$request = new AlipayTradeRefundRequest ();
$request->setBizContent(json_encode([
'out_trade_no' => $this->order['order_sn'], // 外部订单号,与流水号二选一
'trade_no' => $this->order['trade_no'], // 支付时支付宝返回的流水号,与外部订单号二选一
'refund_amount' => $this->order['order_amount'] // 退款金额,单位是元,支持两位,需要和微信区别开
]));
// 处理参数,发起请求
$result = $aop->execute($request);
// 拿到请求响应数据 $result->$responseNode
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if(!empty($resultCode) && $resultCode == 10000){
// 成功
} else {
// 失败
}
以上就是需要配置的一些参数了,还有一些请求参数都是在sdk方法中完成的,接下来看一下微信的,基本上也是依赖官方sdk的
微信
依旧先找到文档‘微信支付开发文档’,下载sdk‘SDK下载’,不过微信的sdk,在使用的时候基本上都需要根据自己项目二次封装,这里就不多说了,主要需要用到的是WxPay.Api.php
和WxPay.Data.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 封装后的WxPay.Data.php
$input = new WxPayRefund();
$input->SetAppid('appid');
$input->SetMch_id('mch_id');
$input->SetOut_trade_no($this->order['order_sn']); // 外部订单号和交易单号至少要有一个
$input->SetOut_refund_no($this->order['order_sn'] . time()); // 需要保证每次退款的退款号不同
$input->SetTotal_fee($this->order['order_amount'] * 100); // 订单总额,主意单位为分
$input->SetRefund_fee($this->order['order_amount'] * 100); // 退款金额
// 调用WxPay.Api.php中的refund方法,返回的数据格式是数组
$result = WxPayApi::refund($input);
if ($result['return_code'] != 'SUCCESS') {
// 成功
} else {
// 失败
}
代码部分看上去很简单,不过需要注意的细节还是挺多的,不过做过微信支付的话再做退款可以说是轻车熟路了,大部分东西都已经配好了,不过需要注意的一点就是退款相比支付需要安装一个微信支付安全证书,首先这个证书是需要在微信商户后台进行申请的,关于流程微信文档写的还是比较详细的,照着一步一步来就好了‘如何获取API证书’
然后照着文档把证书申请下载下来之后,接下来的问题就是怎么使用证书了,文档上是这么写的1
请将生成的证书文件转交给技术人员,由技术人员将证书部署到服务器上
你tm在逗我?无奈之下只好自己研究了一下,发现sdk中调用退款请求时,比支付多了一个参数,顺着找到了postXmlCurl
方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20private static function postXmlCurl($xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
……
if($useCert == true){
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
//证书文件请放入服务器的非web目录下
$sslCertPath = "";
$sslKeyPath = "";
$config->GetSSLCertPath($sslCertPath, $sslKeyPath);
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $sslKeyPath);
}
……
}
也就是说把证书丢在服务器上面之后将这里的路径指向两个文件就好了,需要注意的是一定要放在有权限的文件夹下,防止被其他人下载到,还有就是这里的路径需要时绝对路径,否则会返回错误58
over!