Appearance
退款查询接口
接口说明
退款查询接口用于查询退款订单的状态和详细信息。可通过商户退款单号或平台退款号进行查询。
接口信息
- 接口地址:
POST /v1/pay/refundQuery - Content-Type:
application/json - 字符编码: UTF-8
- 签名方式: RSA-SHA256
请求参数
认证信息
请在 HTTP Header 中携带 Authorization 字段,格式详见 接口概览
业务参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| merchant_no | String | 是 | 商户号 |
| out_refund_no | String | 二选一 | 商户退款单号 |
| refund_no | String | 二选一 | 平台退款号 |
提示
out_refund_no 和 refund_no 至少提供一个,优先使用 refund_no 查询。
请求示例
使用商户退款单号查询
http
POST /v1/pay/refundQuery
Content-Type: application/json
Authorization: RSA service_id=SVC1234567890,timestamp=1704067200,nonce_str=abc123,sign=签名值
{
"merchant_no": "1234567890",
"out_refund_no": "REFUND20240101120000"
}使用平台退款号查询
http
POST /v1/pay/refundQuery
Content-Type: application/json
Authorization: RSA service_id=SVC1234567890,timestamp=1704067200,nonce_str=abc123,sign=签名值
{
"merchant_no": "1234567890",
"refund_no": "RF20240101120000001"
}响应参数
成功响应
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | String | 响应码,00000 表示成功 |
| msg | String | 响应消息 |
| data | Object | 退款详细信息 |
| data.pay_trade_no | String | 原商户单号 |
| data.out_trade_no | String | 原商户订单号 |
| data.refund_no | String | 平台退款号 |
| data.out_refund_no | String | 商户退款单号 |
| data.pay_trade_no | String | 原支付交易号 |
| data.transaction_id | String | 支付宝交易号(仅支付宝) |
| data.total_amount | Integer | 原订单总金额,单位:分 |
| data.refund_amount | Integer | 退款金额,单位:分 |
| data.status | String | 退款状态:PROCESSING/SUCCESS/FAILED |
| data.pay_method | String | 支付方式:wechat/alipay |
| data.refund_reason | String | 退款原因 |
| data.refund_time | String | 退款申请时间,格式:yyyyMMddHHmmss |
| data.refund_success_time | String | 退款成功时间,格式:yyyyMMddHHmmss |
响应示例
退款处理中
json
{
"code": "00000",
"msg": "success",
"data": {
"pay_trade_no": "MF20240101120000001",
"out_trade_no": "ORDER20240101120000",
"refund_no": "RF20240101120000001",
"out_refund_no": "REFUND20240101120000",
"pay_trade_no": "WX20240101120000001",
"total_amount": 100,
"refund_amount": 100,
"status": "PROCESSING",
"pay_method": "wechat",
"refund_reason": "用户申请退款",
"refund_time": "20240101130000",
"refund_success_time": ""
}
}退款成功
json
{
"code": "00000",
"msg": "success",
"data": {
"pay_trade_no": "MF20240101120000001",
"out_trade_no": "ORDER20240101120000",
"refund_no": "RF20240101120000001",
"out_refund_no": "REFUND20240101120000",
"pay_trade_no": "ALI20240101120000001",
"transaction_id": "2024010122001234567890",
"total_amount": 200,
"refund_amount": 200,
"status": "SUCCESS",
"pay_method": "alipay",
"refund_reason": "商品质量问题",
"refund_time": "20240101130000",
"refund_success_time": "20240101130500"
}
}退款状态说明
| 状态 | 说明 |
|---|---|
| PROCESSING | 退款处理中,等待支付渠道处理 |
| SUCCESS | 退款成功,资金已退回用户账户 |
| FAILED | 退款失败,需重新发起或联系客服 |
代码示例
Java
java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
public class RefundQueryExample {
public static void main(String[] args) throws Exception {
// 1. 构建请求参数
Map<String, Object> params = new HashMap<>();
params.put("service_id", "SVC1234567890");
params.put("merchant_no", "1234567890");
params.put("out_refund_no", "REFUND20240101120000");
params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
params.put("nonce_str", generateNonceStr());
// 2. 生成签名
String sign = SignUtil.sign(params, privateKey);
params.put("sign", sign);
// 3. 发送请求
String jsonBody = objectMapper.writeValueAsString(params);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.meepay.org/v1/pay/refundQuery"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
// 4. 处理响应
System.out.println(response.body());
}
private static String generateNonceStr() {
return UUID.randomUUID().toString().replace("-", "");
}
}PHP
php
<?php
function queryRefund($outRefundNo) {
// 1. 构建请求参数
$params = [
'service_id' => 'SVC1234567890',
'merchant_no' => '1234567890',
'out_refund_no' => $outRefundNo,
'timestamp' => time(),
'nonce_str' => bin2hex(random_bytes(16))
];
// 2. 生成签名
$params['sign'] = SignUtil::sign($params, $privateKey);
// 3. 发送请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.meepay.org/v1/pay/refundQuery');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception('请求失败: ' . $error);
}
return json_decode($response, true);
}
// 使用示例
try {
$result = queryRefund('REFUND20240101120000');
if ($result['code'] === '00000') {
echo "退款状态: " . $result['data']['status'] . PHP_EOL;
echo "退款金额: " . $result['data']['refund_amount'] . PHP_EOL;
} else {
echo "查询失败: " . $result['msg'] . PHP_EOL;
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . PHP_EOL;
}查询流程
使用场景
1. 退款状态轮询
提交退款申请后,定时查询退款状态:
javascript
async function pollRefundStatus(outRefundNo) {
for (let i = 0; i < 10; i++) {
const result = await queryRefund(outRefundNo);
if (result.data.status === 'SUCCESS') {
return { success: true, data: result.data };
} else if (result.data.status === 'FAILED') {
return { success: false, reason: '退款失败' };
}
// 等待 5 秒后再次查询
await sleep(5000);
}
return { success: false, reason: '查询超时' };
}2. 退款对账
每日对账时,查询退款记录与本地数据核对:
java
// 查询当日退款记录
List<RefundOrder> refunds = refundService.getTodayRefunds();
for (RefundOrder refund : refunds) {
RefundQueryResult result = queryRefund(refund.getOutRefundNo());
if (result.getData().getStatus().equals("SUCCESS")) {
// 退款成功,更新本地状态
refundService.updateRefundStatus(refund.getId(), "REFUNDED");
}
}注意事项
- 查询参数:
out_refund_no和refund_no至少提供一个 - 查询频率: 建议查询间隔不低于 2 秒
- 数据延迟: 退款状态可能有延迟,建议稍后重试
- 权限控制: 只能查询本商户的退款订单
- 状态轮询: 建议使用异步通知 + 定时查询结合
错误码
| 错误码 | 说明 | 处理建议 |
|---|---|---|
| 00000 | 成功 | - |
| 10001 | 参数错误 | 检查是否提供了退款单号 |
| 10002 | 签名失败 | 检查签名算法 |
| 50001 | 退款订单不存在 | 检查退款单号是否正确 |
| 50002 | 退款不属于该商户 | 确认商户号是否正确 |