PHP后台实现退款功能(原路原回)

以前对于退款并没有什么研究,因为项目需要用到退款,就研究了下,现在分享出来

PS:后台功能,接口的话可以进行相应的修改

 if($order['payment_type'] == 1)//微信{$refundNo=time().rand(10000,999999).'100001';$wxOrderNo='';$orderNo=$order['order_no'];$result=$this->doRefund($order['pay_money'],$order['pay_money'],$refundNo,$wxOrderNo,$orderNo);if($result===true){if($order_refund !==false){return $data=array('code'=>1);}else{return $data=array('code'=>-1);}}else{echo 'refund fail';}}if($order['payment_type'] == 2)//支付宝{$alipay = new \think\Alipay();$out_trade_no=$order['order_no'];     //订单号$wepay_serial="";     //唯一订单号$totalFee=$order['pay_money'];     //退款金额$array = $alipay ->alipayRefund($out_trade_no,$wepay_serial,$totalFee);if(!empty($array)&&$array == 10000){if($order_refund !==false){return $data=array('code'=>1);}else{return $data=array('code'=>-1);}}}

此处首先判断是微信还是支付宝 ,根据判断原路原回

微信引用方法:

 /*** 退款* @param float $totalFee 订单金额 单位元* @param float $refundFee 退款金额 单位元* @param string $refundNo 退款单号* @param string $wxOrderNo 微信订单号* @param string $orderNo 商户订单号* @return string*/public function doRefund($totalFee, $refundFee, $refundNo, $wxOrderNo='',$orderNo=''){$config = array('mch_id' => '**************','appid' => '*************','key' => '**************',);$unified = array('appid' => $config['appid'],'mch_id' => $config['mch_id'],'nonce_str' => self::createNonceStr(),'total_fee' => intval($totalFee * 100),    //订单金额  单位 转为分'refund_fee' => intval($refundFee * 100),    //退款金额 单位 转为分'sign_type' => 'MD5',      //签名类型 支持HMAC-SHA256和MD5,默认为MD5'transaction_id'=>$wxOrderNo,        //微信订单号'out_trade_no'=>$orderNo,    //商户订单号'out_refund_no'=>$refundNo,    //商户退款单号'refund_desc'=>'商品已售完',   //退款原因(选填));$unified['sign'] = self::getSign($unified, $config['key']);$responseXml = $this->curlPost('https://api.mch.weixin.qq.com/secapi/pay/refund', self::arrayToXml($unified));$unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);if ($unifiedOrder === false) {die('parse xml error');}if ($unifiedOrder->return_code != 'SUCCESS') {die($unifiedOrder->return_msg);}if ($unifiedOrder->result_code != 'SUCCESS') {die($unifiedOrder->err_code);}return true;}public static function curlGet($url = '', $options = array()){$ch = curl_init($url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_TIMEOUT, 30);if (!empty($options)) {curl_setopt_array($ch, $options);}//https请求 不验证证书和hostcurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);$data = curl_exec($ch);curl_close($ch);return $data;}public function curlPost($url = '', $postData = '', $options = array()){if (is_array($postData)) {$postData = http_build_query($postData);}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数if (!empty($options)) {curl_setopt_array($ch, $options);}//https请求 不验证证书和hostcurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//第一种方法,cert 与 key 分别属于两个.pem文件//默认格式为PEM,可以注释curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/******/apiclient_cert.pem');//默认格式为PEM,可以注释curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/******/apiclient_key.pem');//第二种方式,两个文件合成一个.pem文件
//    curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');$data = curl_exec($ch);curl_close($ch);return $data;}public static function createNonceStr($length = 16){$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';$str = '';for ($i = 0; $i < $length; $i++) {$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);}return $str;}public static function arrayToXml($arr){$xml = "";foreach ($arr as $key => $val) {if (is_numeric($val)) {$xml .= "<" . $key . ">" . $val . "";} else$xml .= "<" . $key . ">";}$xml .= "";return $xml;}public static function getSign($params, $key){ksort($params, SORT_STRING);$unSignParaString = self::formatQueryParaMap($params, false);$signStr = strtoupper(md5($unSignParaString . "&key=" . $key));return $signStr;}protected static function formatQueryParaMap($paraMap, $urlEncode = false){$buff = "";ksort($paraMap);foreach ($paraMap as $k => $v) {if (null != $v && "null" != $v) {if ($urlEncode) {$v = urlencode($v);}$buff .= $k . "=" . $v . "&";}}$reqPar = '';if (strlen($buff) > 0) {$reqPar = substr($buff, 0, strlen($buff) - 1);}return $reqPar;}

orderrefund()方法中key参数是商户平台的key秘钥,同时还需要商户的俩个证书,放入项目中
支付宝退款方法

 /*** 支付宝退货处理* 退货前提是必须支付成功* @param type $orderId* @return bool*/public function alipayRefund($out_trade_no,$wepay_serial,$totalFee) {Loader::import('.alipay.aop.AopClient', '', '.php');Loader::import('.alipay.aop.request.AlipayTradeRefundRequest', '', '.php');Loader::import('.alipay.aop.SignData', '', '.php');$aop = new \AopClient ();$aop->gatewayUrl = Config::get('alipay')['gatewayUrl'];$aop->appId = Config::get('alipay')['appId'];$aop->rsaPrivateKey = Config::get('alipay')['rsaPrivateKey'];$aop->alipayrsaPublicKey=Config::get('alipay')['alipayrsaPublicKey'];$aop->apiVersion = '1.0';$aop->signType =Config::get('alipay')['signType'];$aop->postCharset='UTF-8';$aop->format=Config::get('alipay')['format'];$request = new \AlipayTradeRefundRequest();$bizcontent = json_encode(['out_trade_no'=>$out_trade_no,'trade_no'=> $wepay_serial,'refund_amount'=> $totalFee,'refund_reason'=>'正常退款']);$request->setBizContent($bizcontent);$result = $aop->execute($request);$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";$resultCode = $result->$responseNode->code;return $resultCode;}

退款方法已测试能用


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部