【微信支付】退款


  微信支付文档申请退款的详细介绍,建议大家先把文档看一遍,然后有什么不明白的再百度。这里记录的是我用php进行微信支付退款

1. 下载商户证书

  登录上商户平台,依次【账户中心】-->【账户设置】-->【API安全】-->【证书下载】,解压,把apiclient_cert.pem和apiclient_key.pem两个文件放到项目目录中,分别用常量SSLCERT_PATHSSLKEY_PATH表示文件路径。

define(SSLCERT_PATH, "apiclient_cert.pem的路径");
define(SSLKEY_PATH, "apiclient_key.pem的路径");

2. 组装参数

$params = array(
'out_trade_no' => $out_trade_no, //商户订单号
'total_fee' => $total_fee, //订单总金额,以分为单位
'refund_fee' => $refund_fee, //退款金额,以分为单位
'out_refund_no' => $mch_id. date("YmdHis"),
'op_user_id' => $mch_id, //商户Id
'appid' => $appId, //AppId
'mch_id' => $mch_id,
'nonce_str' => getNonceStr(),//生成随机字符串
);
//生成签名
$params['sign'] = makeSign($params, $key); //$key微信支付Key
//转为XML格式
$xml = toXml($params);
/***************工具函数***************/
/**
* 生成指定长度的随机字符串
*/
function getNonceStr($length = 32){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
/**
* 生成签名
* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
private function makeSign($values, $key)
{
//签名步骤一:按字典序排序参数
ksort($values);
$string = $this->toUrlParams($values);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 格式化参数格式化成url参数
*/
function toUrlParams($values){
$buff = "";
foreach ($values as $k => $v){
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 输出xml字符
* @throws WxPayException
**/
function toXml($values){
if(!is_array($values) || count($values) <= 0){
throw new WxPayException("数组数据异常!");
}
$xml = "<xml>";
foreach ($values as $key=>$val) {
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}

3. 发送HTTPS请求

$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
$response = postXmlCurl($xml, $url, true, 6);
/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间,默认30s
* @throws Exception
*/
function postXmlCurl($xml, $url, $useCert = false, $second = 30) {
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if($useCert == true){
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, SSLCERT_PATH);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, SSLKEY_PATH);
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new Exception("curl出错,错误码:$error");
}
}

4. 接收HTTPS响应数据

//Https请求返回的数据是XML格式的,要先转为数组
$result = fromXml($response);
if($result['return_code'] == 'SUCCESS'){
//检查签名
checkSign($result, $Key);
}
/**
* xml数据转为数组
*/
function fromXml($xml){
if(!$xml){
throw new Exception("xml数据异常!");
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
/**
* 检查返回数据的签名
*/
function checkSign($values, $key){
//fix异常
if(!array_key_exists('sign', $values)){
throw new Exception("签名错误!");
}
$sign = makeSign($values, $key);
if($values['sign'] == $sign){
return true;
}
throw new Exception("签名错误!");
}

总结

  微信支付退款和其他普通的API请求一样,只不过是多了证书而已。

posted @   刘一二  阅读(715)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示