完整的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;
}
}
