完整的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;//商户退款单号商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@
private $total_fee;//total_fee订单总金额,单位为分,只能为整数
private $refund_fee;//退款金额
private $refund_desc='接单员暂时都没有空,麻烦您提价,或稍后再发一次';//退款原因;
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';
}
//发出退款请求
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两个数
之间的一个随机整数 } return $str; } /** 创建签名 例如: appid: wxd111665abv58f4f mch_id: 10000100 device_info: 1000 Body: test nonce_str: ibuaiVcKdpRxkhJA 第一步:对参数按照 key=value 的格式,并按照参数名 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获取请求文本内容
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);//设置头文件的信息作为数据流输出
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);//执行命令
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;
}
}
