https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
微信官方文档
微信退款接口地址
https://api.mch.weixin.qq.com/secapi/pay/refund
/**
我写在一个类中,文中 $this-> 那啥,自己替换下
*/
/**
传入订单信息,这里只要传入订单信息即可
*/
function refund($res = array("id" => "224", "total_price" => "1", "addtime" => "1527588085")) {
if (empty($this->config1)) {
$this->config1['appid'] = '';
$this->config1['mch_id'] = '';
$this->config1['api_key']='';
}
$pay_no=$res['id'] . "a" . $res['addtime'] . "b" . "RepairOrder";//微信支付返回的 out_trade_no (pay_no)
$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
$data = array(
"appid" => $this->config1['appid'], //公众账号ID
"mch_id" => $this->config1['mch_id'], //商户号
"nonce_str" => $this->createNoncestr(), //随机字符串
"out_trade_no" => $pay_no, //商户订单号
"out_refund_no" =>$pay_no.rand(0,20), //商户退款单号--多次退款则添加不同退款单号
"total_fee" => ($res['total_price'] * 100), //订单总金额,单位为分,只能为整数
"refund_fee" => ($res['total_price'] * 100), //退款金额,单位 分
"refund_desc" => "订单已取消", //若商户传入,会在下发给用户的退款消息中体现退款原因
"notify_url" => "http://xxx/Wxapppay/refundcallback", //回调函数
);
$sign = $this->getSign($data); //签名
$data["sign"] = $sign;
$xml = $this->arrayToXml($data);
$response = $this->postXmlCurl2($xml, $url);
//将微信返回的结果xml转成数组
$response = $this->xmlToArray($response);
if ($response['return_code'] == "SUCCESS") {
$this->data_log("微信申请退款成功~~~ {$pay_no}","Wxapppay.txt");
}else{
$this->data_log("微信申请退款失败~~~~ {$pay_no}","Wxapppay.txt");
$this->data_log($response,"Wxapppay.txt");
}
}
/* 生成签名 */
public function getSign($Obj) {
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//echo '【string1】'.$String.'';
//签名步骤二:在string后加入KEY
$String = $String . "&key=" . $this->config1['api_key'];
//echo "【string2】".$String."";
//签名步骤三:MD5加密
$String = md5($String);
//echo "【string3】 ".$String."";
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
//echo "【result】 ".$result_."";
return $result_;
}
//数组转xml
public function arrayToXml($arr) {
$xml = "
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml.="<" . $key . ">" . $val . "" . $key . ">";
} else {
$xml.="<" . $key . ">" . $key . ">";
}
}
$xml.="
return $xml;
}
/**
* 作用:以post方式提交xml到对应的接口url
* 微信退款
*/
public function postXmlCurl2($xml, $url, $second = 30) {
//初始化curl
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
/**
* 微信证书
*/
curl_setopt($ch, CURLOPT_SSLCERT, dirname(__FILE__) . '/apiclient_cert.pem');
curl_setopt($ch, CURLOPT_SSLKEY, dirname(__FILE__) . '/apiclient_key.pem');
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
echo "curl出错,错误码:$error" . "
";
curl_close($ch);
return false;
}
}
/**
* 作用:将xml转为array
*/
public function xmlToArray($xml) {
//将XML转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
//数据效验
function data_log($msg = "error", $filename = "error.txt", $files = "./error") {
if (!file_exists($files)) {
mkdir(iconv("UTF-8", "GBK", $files), 0777, true);
}
if (is_array($msg)) {
foreach ($msg as $key => $val) {
if (is_array($val)) {
$this->data_log($val, $filename, $files);
} else {
$this->data_log($key . "=>" . $val, $filename, $files);
}
}
die();
}
$fp = fopen($files . "/" . $filename, "a+");
flock($fp, LOCK_EX + LOCK_NB);
fwrite($fp, $msg . "\r\n");
flock($fp, LOCK_UN);
fclose($fp);
}