关于退款有几点说明
1,退款需要证书 apiclient_cert.pem和apiclient_key.pem证书
2,数据库需要保存相关微信返回的参数 trade_no 例如是:4200000122201806222222222222
3,另外就是appid和mch_id一整套。
下面是相关退款的方法和执行流程
直接调用 wxRefund() 方法即可,根据返回的退款信息进行下一步操作。
public function wxRefund() { $userpayinfo = Db::table('支付工具记录表')->find(); //查询订单表trad_num,主要是用这个字段到支付记录表换取$tradLog记录 $trad_num = Db::table('订单表')->value('trad_num'); $tradLog = Db::table('交易记录表')->where(['itemid'=>$itemid,'trad_num'=>$trad_num])->field('transaction_id,total_fee')->find(); $trade_no = $tradLog['transaction_id']; $total_fee = $tradLog['total_fee']; //支付信息 $appid = $userpayinfo['appid']; $mch_id = $userpayinfo['mchid']; $nonce_str = $this->getNonceStr(); $op_user_id = $userpayinfo['mchid']; //随机生成的退款单号 $out_refund_no = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT),$transaction_id = $trade_no; $refund_fee = $refund_money*100; $total_fee = $total_fee*100; $key = $userpayinfo['partnerkey']; $apiclient_cert = $userpayinfo['certpath']; $apiclient_key = $userpayinfo['publicpath']; $ref= strtoupper(md5("appid=".$appid."&mch_id=".$mch_id."&nonce_str=".$nonce_str."&op_user_id=".$op_user_id."&out_refund_no=".$out_refund_no."&refund_fee=".$refund_fee."&total_fee=".$total_fee."&transaction_id=".$transaction_id."&key=".$key));//sign加密MD5 $refund=array( 'appid'=>$appid,//应用ID,固定 'mch_id'=>$mch_id,//商户号,固定 'nonce_str'=>$nonce_str,//随机字符串 'op_user_id'=>$op_user_id,//操作员 'out_refund_no'=>$out_refund_no,//商户内部唯一退款单号 'transaction_id'=>$transaction_id,//微信订单号 微信生成的订单号,在支付通知中有返回 'refund_fee'=>$refund_fee,//退款金额 'total_fee'=>$total_fee,//总金额 'sign'=>$ref//签名 ); //微信退款地址,post请求 $url="https://api.mch.weixin.qq.com/secapi/pay/refund";//微信退款地址,post请求 $xml=$this->arrayToXml($refund); $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); // curl_setopt($ch,CURLOPT_HEADER,1); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);//证书检查 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'pem'); curl_setopt($ch,CURLOPT_SSLCERT,getcwd().$apiclient_cert); // curl_setopt($ch,CURLOPT_SSLCERT,'/data/wwwroot/项目名/public/upload/certificate/1498007396990/apiclient_cert.pem'); curl_setopt($ch,CURLOPT_SSLCERTTYPE,'pem'); curl_setopt($ch,CURLOPT_SSLKEY,getcwd().$apiclient_key); // curl_setopt($ch,CURLOPT_SSLKEY,'/data/wwwroot/项目名/public/upload/certificate/1498007396990/apiclient_key.pem'); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data=curl_exec($ch); curl_close($ch); $return = $this->xmlToArray($data); return $return; }
退款方法中需要调用的其他函数
//生成随机字符串 public function getNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } //数组转为xml格式 public function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key=>$val){ if(is_array($val)){ $xml.="<".$key.">".arrayToXml($val)."</".$key.">"; }else{ $xml.="<".$key.">".$val."</".$key.">"; } } $xml.="</xml>"; return $xml ; } //xml格式转化为数组 public function xmlToArray($xml) { libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring),true); return $val; }
希望大家能用的上,谢谢大家的观看!