退款
对已成功的支付发起部分或全额退款。资金从商户待结算余额退回付款人钱包,可多次退款,累计不超过原支付金额。
POST/api/v1/payments/:id/refund需要 API Key
请求参数
| 参数 | 类型 | 说明 |
|---|---|---|
amount可选 | string | 退款金额,默认退剩余全部。不能超过 refundable_cents |
reason可选 | string | 退款原因,付款人可见,建议填写 |
请求示例
curl "https://your-domain/api/v1/payments/pay_1/refund" \
-X POST \
-H "Authorization: Bearer $SPACEPAY_KEY" \
-H "Content-Type: application/json" \
-d '{"amount":"2.34","reason":"部分退单"}'
import os
import requests
resp = requests.post(
"https://your-domain/api/v1/payments/pay_1/refund",
headers={"Authorization": f"Bearer {os.environ['SPACEPAY_KEY']}"},
json={"amount": "2.34", "reason": "部分退单"},
timeout=15,
)
print(resp.json())
const resp = await fetch('https://your-domain/api/v1/payments/pay_1/refund', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SPACEPAY_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ amount: '2.34', reason: '部分退单' }),
});
const data = await resp.json();
响应示例
{
"ok": true,
"refund": {
"id": "ref_1",
"payment_id": 1,
"amount_cents": 234,
"amount": "2.34",
"reason": "部分退单",
"status": "SUCCEEDED",
"created_at": 1762800200000
},
"payment": {
"id": "pay_1",
"status": "PARTIALLY_REFUNDED",
"refunded_cents": 234,
"refundable_cents": 1000
}
}
退款规则
- 只有
SUCCEEDED或PARTIALLY_REFUNDED的支付可以退款;未支付、已过期、已取消的支付返回PAYMENT_NOT_REFUNDABLE。 - 累计退款不能超过原支付金额;超额返回
REFUND_EXCEEDS_REMAINING,并在details.refundable_cents中给出可退金额。 - 退款从商户可结算余额扣除。若已发起结算提现导致余额不足,返回
INSUFFICIENT_MERCHANT_BALANCE。 - 退款成功后付款人钱包立即入账,支付状态变为
PARTIALLY_REFUNDED或REFUNDED。
退款事件
每次退款成功都会推送 payment.refunded,data 是最新的支付单快照(含 refunded_cents 与 status)。请以事件驱动退款状态,而不是轮询。
常见错误
| code | 原因 |
|---|---|
PAYMENT_NOT_FOUND | 支付单不存在或不属于当前商户 |
PAYMENT_NOT_REFUNDABLE | 支付尚未成功或已进入不可退款状态 |
REFUND_EXCEEDS_REMAINING | 退款金额超过剩余可退金额 |
INSUFFICIENT_MERCHANT_BALANCE | 商户可结算余额不足 |
AMOUNT_INVALID | 金额格式错误或小于等于 0 |
✓退款同样建议带
Idempotency-Key:网络超时后用同一个键重试,不会重复退款。