< $length; $i++ ) { $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; }}以上就是微信支付的相关流程 。在理清思路后,流程还是比较清晰和简单的 。重点在于需要注意一些细节问题,例如数据格式,加密方法等 。
下面说一下微信小程序退款的具体实现
二.退款
小程序退款的流程和付款相似,但有一些细节上的不同 。
首先退款的步骤通常如下:
- 用户前端点击退款按钮后,后端接收到用户的退款请求通过商城后台呈现给商户,商户确定允许退款后,后端再发起向微信退款接口的请求来请求退款 。
- 后端向微信退款接口发送请求后,得到响应信息,确定退款是否完成,根据退款是否完成再去进行改变订单状态等业务逻辑 。
值得注意的有以下两点:
1.向微信退款接口请求退款后,根据得到的响应是可以直接确定退款是否完成的 。不再需要设置专门的回调接口等待微信通知 。当然如果需要也是可以在微信商户平台设置回调接口接受从而接受微信回调的,但并不是必须的 。
2.退款请求需要在请求服务器安装微信提供的安全证书,也就是说,发起退款请求相比较支付请求在请求时请求方法不能复用,因为微信退款需要携带证书的请求,此证书可在申请微信商户号成功后从微信商户平台自行下载,linux下的PHP开发环境的证书只需要放在网站根目录的cert文件夹中即可 。其他开发环境可能需要导入操作 。
下面讲解一下退款的具体步骤
一. 用户发起退款请求
用户在前端发起退款请求,后端接收到退款请求,将相应订单标记为申请退款,展示在后台.商户查看后,如果同意退款再进行相应操作.此后才进入真正的退款流程.
二. 商户发起退款请求
商户同意退款后,后端即向微信提供的退款 API 发起请求.
同请求微信支付API一样.退款请求也需要将需要的参数进行签名后以XML发送到微信的退款API [https://api.mch.weixin.qq.com/pay/refund](https://api.mch.weixin.qq.com/pay/refund)
退款请求需要的参数如下(多个参数在支付API请求时也有使用):
- 小程序 appid 。
- 商户号 mch_id。申请开通微信支付商户认证成功后微信发给你的邮件里有
- 商户订单号 out_trade_no。退款订单在支付时生成的订单号
- 退款订单号 out_refund_no。由后端生成的退款单号,需要保证唯一,因为多个同样的退款单号只会退款一次 。
- 总金额 total_fee。订单总金额,单位为分 。
- 退款金额 refund_fee 需要退款的金额,单位同样为分
- 操作员 op_user_id .与商户号相同即可
- 随机字符串 nonce_str。同支付请求
- 签名 sign。使用上面的所有参数进行相应处理加密生成签名 。(具体处理方式与支付相同,可直接复用 。)
在发起退款请求后,就可以直接根据请求的响应XML中的 result_code字段来判断退款是否成功,从而对订单状态进行处理和后续操作 。不需要像支付那样等待另一个接口的通知来确定请求状态 。当然如上文所说,如果需要微信服务器发送通知到后端的话,可以到微信商户平台进行设置 。
退款因为流程与支付大同小异,因此退款的PHP类我选择了直接继承支付类,
代码如下,注意区分退款请求方法postXmlSSLCurl和支付请求方法postXmlCurl的区别,这也就是上文提到的退款需要的双向证书的使用 。
class WinXinRefund extends WeiXinPay{ protected $SSLCERT_PATH = 'cert/apiclient_cert.pem';//证书路径 protected $SSLKEY_PATH = 'cert/apiclient_key.pem';//证书路径 protected $opUserId = '1234567899';//商户号function __construct($openid,$outTradeNo,$totalFee,$outRefundNo,$refundFee){ //初始化退款类需要的变量 $this->openid = $openid; $this->outTradeNo = $outTradeNo; $this->totalFee = $totalFee; $this->outRefundNo = $outRefundNo; $this->refundFee = $refundFee;} public function refund(){ //对外暴露的退款接口 $result = $this->wxrefundapi(); return $result;}private function wxrefundapi(){ //通过微信api进行退款流程 $parma = array( 'appid'=> $this->APPID, 'mch_id'=> $this->MCHID, 'nonce_str'=> $this->createNoncestr(), 'out_refund_no'=> $this->outRefundNo, 'out_trade_no'=> $this->outTradeNo, 'total_fee'=> $this->totalFee, 'refund_fee'=> $this->refundFee, 'op_user_id' => $this->opUserId, ); $parma['sign'] = $this->getSign($parma); $xmldata = https://www.isolves.com/it/cxkf/ydd/xcx/2019-08-12/$this->arrayToXml($parma); $xmlresult = $this->postXmlSSLCurl($xmldata,'https://api.mch.weixin.qq.com/secapi/pay/refund'); $result = $this->xmlToArray($xmlresult); return $result;}//需要使用证书的请求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, $this->SSLCERT_PATH); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_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"."
推荐阅读
- 解秋乏的小窍门 按摩几个穴位就能搞定
- 小心“地雷”啦!秋季护肤注意这些“雷区”
- 知道这些秋季小常识 等于安全度过整个秋季
- 小米家用监控摄像头哪款好 小米无线监控摄像头
- 梦见小女孩拉屎了 梦见小女孩拉稀屎是什么意思
- 梦见龙凤是什么预兆 梦见龙凤胎小孩是什么征兆
- 开通抖音小店的步骤图解 怎么开通抖音小店教程
- 红米k305g和荣耀30青春版哪个好 小米10青春版5g和红米k30哪个好
- 小儿夏季发烧 当心是“小儿夏季热”
- 夏季喝啤酒解暑倍儿爽 但滥喝的危害也不容小觑
