1.证书位置
2.退款文件

3.退款代码
<?php/** 咔咔* 2018.6.21 微信退款*/class Refund{const REFUND = 'https://api.mch.weixin.qq.com/secapi/pay/refund';const KEY = 'h5l4P8S3u5n1H5Y4D7E5l9e6J4Y7S8h3';const CODEURL = 'https://open.weixin.qq.com/connect/oauth2/authorize?';const OPENIDURL = 'https://api.weixin.qq.com/sns/oauth2/access_token?';const APPID = 'wxf8a78496174320e9';const SECRET = '6806ae46548d5a27e0939f12139e7a42';const MCHID = '1502276551';const UNURL = 'https://api.mch.weixin.qq.com/pay/unifiedorder';private $params;public function __construct($data) {//组装数据$this->params = ['appid' => self::APPID, //APPID'mch_id' => self::MCHID, //商户号'nonce_str'=> md5(time()), //随机串'sign' => 'md5', //签名方式'transaction_id'=> $data['transaction_id'],//微信支付订单号 与商户订单号二选一//'out_trade_no'=> '', //商户订单号 和微信支付订单号二选一'out_refund_no' => $data['out_refund_no'],//退单号'total_fee' => $data['total_fee'], //订单金额'refund_fee' => $data['refund_fee'] //退款金额];}//发送退款请求public function orderRefund(){//生成签名$signParams = $this->setSign($this->params);//将数据转换为xml$xmlData = $this->ArrToXml($signParams);//发送请求return $this->postStr(self::REFUND, $xmlData);}//post 字符串到接口public function postStr($url,$postfields){$ch = curl_init();$params[CURLOPT_URL] = $url; //请求url地址$params[CURLOPT_HEADER] = false; //是否返回响应头信息$params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回$params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向$params[CURLOPT_POST] = true;$params[CURLOPT_SSL_VERIFYPEER] = false;//禁用证书校验$params[CURLOPT_SSL_VERIFYHOST] = false;//以下是证书相关代码$params[CURLOPT_SSLCERTTYPE] = 'PEM';$params[CURLOPT_SSLCERT] = './cert/apiclient_cert.pem';$params[CURLOPT_SSLKEYTYPE] = 'PEM';$params[CURLOPT_SSLKEY] = './cert/apiclient_key.pem';$params[CURLOPT_POSTFIELDS] = $postfields;curl_setopt_array($ch, $params); //传入curl参数$content = curl_exec($ch); //执行curl_close($ch); //关闭连接return $content;}//生成签名public function getSign($arr){//去除空值$arr = array_filter($arr);if(isset($arr['sign'])){unset($arr['sign']);}//按照键名字典排序ksort($arr);//生成url格式的字符串$str = $this->arrToUrl($arr) . '&key=' . self::KEY;return strtoupper(md5($str));}//获取带签名的数组public function setSign($arr){$arr['sign'] = $this->getSign($arr);;return $arr;}public function arrToUrl($arr){return urldecode(http_build_query($arr));}//验证签名public function chekSign($arr){$sign = $this->getSign($arr);if($sign == $arr['sign']){return true;}else{return false;}}//数组转xmlpublic function ArrToXml($arr){if(!is_array($arr) || count($arr) == 0) return '';$xml = "<xml>";foreach ($arr as $key=>$val){if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">";}else{$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";}}$xml.="</xml>";return $xml;}public function XmlToArr($xml){if($xml == '') return '';libxml_disable_entity_loader(true);$arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);return $arr;}}// 获取订单号$orderdata = D('foodorder')->where(['id'=>$_SESSION['orderid']])->find();// 传值$data = ['transaction_id' => $orderdata['wx_number'], //微信交易号'out_refund_no' => $orderdata['wx_number'], //退款单号'total_fee' => $orderdata['cash_fee'], //原订单金额'refund_fee' => $orderdata['cash_fee'] //退款金额];// 实例化退款类$obj = new Refund($data);// 调用退款方法$res = $obj->orderRefund();// 退款微信返回数据$refunddata = $obj->XmlToArr($res);if($refunddata['return_code'] == 'SUCCESS'){$data['wx_refundorder'] = $orderdata['wx_number'];$data['user_id'] = $orderdata['userid'];$data['refund_fee'] = $orderdata['cash_fee'];$data['refund_time'] = time();$refundorder = D('refundorder')->add($data);if(!$refundorder){$log_name= "./Public/Pay/refund_url.log";//log文件路径file_put_contents($log_name,"【退款成功 , 数据库添加失败通知", FILE_APPEND);}}else{$log_name= "./Public/Pay/refund_url.log";//log文件路径file_put_contents($log_name,"【退款失败", FILE_APPEND);}
4.控制器文件
5.控制器代码
// 退款public function refundmoney() {$order_id = I('orderid');session('orderid',$order_id);vendor('WxPayPubHelper.refund');// 查询订单表$orderdata = D('foodorder')->where(['id'=>$order_id])->find();// 查询退款后的数据库$refunddata = D('refundorder')->where(['wx_refundorder'=>$orderdata['wx_number']])->find();// 判断是否存在if($orderdata){// 修改退款的refund状态$orderedit = D('foodorder')->where(['id'=>session('orderid')])->setInc('refund');// 清除订单idsession('orderid',null);__success('退款成功',U('/addon/WeiuidDeit/web/foodorderindex'));}else{__error('退款失败');}}
