完整的PHP 微信 退款類操作,詳細如下,完整頁面下載在底部:
use think\Config; //微信申請退款類 class Refund{ protected $config = null; private $appid;//公眾賬號appid private $mch_id;//商戶號 private $nonce_str;//隨機字符串,不長于32位 private $sign; // 簽名 private $transaction_id;//微信生成的訂單號,在支付通知中有返回 private $out_refund_no;//商戶退款單號商戶系統(tǒng)內(nèi)部的退款單號,商戶系統(tǒng)內(nèi)部唯一,只能是數(shù)字、大小寫字母_-|*@ private $total_fee;//total_fee訂單總金額,單位為分,只能為整數(shù) private $refund_fee;//退款金額 private $refund_desc='接單員暫時都沒有空,麻煩您提價,或稍后再發(fā)一次';//退款原因; private $api_password; //商戶平臺設置的密鑰key private $refundurl = "https://api.mch.weixin.qq.com/secapi/pay/refund"; /** 公鑰*/ private $apiclient_cert; /** 私鑰*/ private $apiclient_key; /** ca證書*/ private $rootca; public function __construct(){ $this->config = Config::get(); //初始化紅包設置信息 $this->appid = $this->config["wechat"]["app_id"]; $this->mch_id = $this->config["wechat"]["payment"]["mch_id"]; $this->api_password = $this->config["wechat"]["payment"]["key"]; $this->nonce_str = $this->create_nonce_str(32); $this->apiclient_cert = EXTEND_PATH . 'wxcert' . DS . 'apiclient_cert.pem'; $this->apiclient_key = EXTEND_PATH . 'wxcert' . DS . 'apiclient_key.pem'; $this->rootca = EXTEND_PATH . 'wxcert' . DS . 'rootca.pem'; } //發(fā)出退款請求 public function send_post($transaction_id="",$out_refund_no='',$refund_fee=0,$total_fee=0){ $sign = $this->create_sign($transaction_id, $out_refund_no, $refund_fee, $total_fee); $send_array = array( 'appid' => $this->appid, 'mch_id' => $this->mch_id, 'nonce_str' => $this->nonce_str, 'out_refund_no' => $out_refund_no, 'refund_desc' => $this->refund_desc, 'refund_fee' => $refund_fee, 'total_fee' => $total_fee, 'transaction_id'=> $transaction_id , 'sign' => $sign, ); $send_xml = $this->toxml($send_array); $result = $this->get_curl_contents($this->refundurl, $send_xml); if($result){ $data = $this->xmlToArray($result); return $data; } else{ return null; } } //生成隨機字符串 public function create_nonce_str($length){ $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol)-1; for($i=0;$i<$length;$i++){ $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max兩個數(shù)
之間的一個隨機整數(shù) } return $str; } /** 創(chuàng)建簽名 例如: appid: wxd111665abv58f4f mch_id: 10000100 device_info: 1000 Body: test nonce_str: ibuaiVcKdpRxkhJA 第一步:對參數(shù)按照 key=value 的格式,并按照參數(shù)名 ASCII 字典序排序如下: stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_i d=10000100&nonce_str=ibuaiVcKdpRxkhJA"; 第二步:拼接支付密鑰: stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d" sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A 9CF3B7" */ private function create_sign($transaction_id="",$out_refund_no='',$refund_fee=0,
$total_fee=0){ $string_array = array( 'appid' => $this->appid, 'mch_id' => $this->mch_id, 'nonce_str' => $this->nonce_str, 'out_refund_no' => $out_refund_no, 'refund_desc' => $this->refund_desc, 'refund_fee' => $refund_fee, 'total_fee' => $total_fee, 'transaction_id'=> $transaction_id ); $stringA = ""; foreach($string_array as $key =>$value){ if(!empty($value)){ $stringA .= "$key=$value"; if($key != 'transaction_id'){$stringA .= '&';} } } $stringSignTemp="$stringA&key=$this->api_password"; $sign = MD5($stringSignTemp); $sign = strtoupper($sign); return $sign; } public function toxml($arr){ $xml = "<xml>"; foreach ($arr as $key=>$val) { $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } $xml.="</xml>"; return $xml; } private function xmlToArray($postStr){ $msg = array(); $msg = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); return $msg; } //curl獲取請求文本內(nèi)容 public function get_curl_contents($url, $data = null) { $curl = curl_init(); //初始化 curl_setopt($curl, CURLOPT_URL, $url);//設置抓取的url 為 $requesturl curl_setopt($curl, CURLOPT_HEADER, 0);//設置頭文件的信息作為數(shù)據(jù)流輸出 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //設置獲取的信息以文件流的形式返回,而不是直接輸出。 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //跳過證書驗證 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 從證書中檢查SSL加密算法是否存在 curl_setopt($curl,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($curl,CURLOPT_SSLCERT,$this->apiclient_cert); curl_setopt($curl,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($curl,CURLOPT_SSLKEY,$this->apiclient_key); curl_setopt($curl,CURLOPT_SSLKEYTYPE,'PEM'); //echo $this->rootca; curl_setopt($curl,CURLOPT_CAINFO,$this->rootca); if (!empty($data)){ curl_setopt($curl, CURLOPT_POST, 1); //POST請求 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } $data = curl_exec($curl);//執(zhí)行命令 curl_close($curl);//關閉URL請求 return $data; } public function get_server_ip(){ if('/'==DIRECTORY_SEPARATOR){ $server_ip=$_SERVER['SERVER_ADDR']; }else{ $server_ip=@gethostbyname($_SERVER['SERVER_NAME']); } return $server_ip; } }