Refund
Description
Issue a refund for a successfully paid order.
Notes:
- Supports partial and full refunds
- Refund amount cannot exceed the order's refundable balance (
refundableBalancefrom order query) - For multiple refunds on the same order,
bizRefundNomust be unique (auto-generated if omitted)
Endpoints
Refund endpoints belong to the Management API (/mch/*), authenticated via Sa-Token session. Responses use Result wrapper (field name message, not msg).
vs Payment API
Payment API (/unipay/*) uses RSA signature auth and DaxResult responses; refund endpoints use Accesstoken header auth and Result responses.
Request
POST /mch/order/refund/refund
- Auth: Sa-Token (
Accesstokenheader) - Response:
Result<RefundOrderResult>
Headers
| Header | Required | Description |
|---|---|---|
| Accesstoken | Yes | Sa-Token session token |
| Content-Type | Yes | application/json |
Parameters
RefundParam:
| Parameter | Type | Required | Description |
|---|---|---|---|
| tradeNo | string | No* | Original fund trade number (platform tradeNo) |
| bizOrderNo | string | No* | Merchant order number |
| amount | long | Yes | Refund amount in cents (@Positive, must be > 0) |
| bizRefundNo | string | No | Merchant refund number (auto-generated if omitted) |
| reason | string | No | Refund reason |
*At least one of
tradeNo/bizOrderNorequired;tradeNopreferred. IftradeNois not found by fund number, the system falls back to looking up by gateway containerorderNo.
Example
{
"bizOrderNo": "ORDER20241201001",
"amount": 100,
"bizRefundNo": "REFUND20241201001",
"reason": "Customer requested refund"
}Response
Result<RefundOrderResult>, data fields (main fields; full 27 fields in source RefundOrderResult):
| Field | Type | Description |
|---|---|---|
| id | long | Refund order ID |
| mchNo | string | Merchant number |
| mchName | string | Merchant name (translated) |
| appId | string | Application ID |
| refundNo | string | System refund number |
| bizRefundNo | string | Merchant refund number |
| relationOrderNo | string | Actual relation number sent to channel |
| title | string | Title |
| tradeNo | string | Original fund trade number |
| tradeType | string | Original trade type |
| bizOrderNo | string | Original merchant order number |
| outOrderNo | string | Channel payment order number |
| outRefundNo | string | Channel refund流水 number |
| amount | long | Refund amount (cents) |
| orderAmount | long | Original order total amount (cents) |
| currency | string | Currency |
| reason | string | Refund reason |
| status | string | Refund status (RefundOrderStatusEnum) |
| finishTime | string | Refund completion time (UTC) |
| channel | string | Payment channel |
| product | string | Payment product |
| channelMchNo | string | Channel merchant number |
| channelAppId | string | Channel App ID |
| notifyUrl | string | Async notification URL |
| attach | string | Merchant custom data |
| clientIp | string | Client IP |
| storeNo | string | Store number |
| errorMsg | string | Error message (on failure) |
Refund Status (RefundOrderStatusEnum)
| status | Description |
|---|---|
| progress | Refund processing (created and channel invoked, awaiting result) |
| success | Refund successful |
| fail | Refund failed |
| close | Refund closed (timeout, etc.) |
Example
{
"code": 0,
"message": "success",
"data": {
"id": "1853123456789012345",
"refundNo": "R2024120112345700001",
"bizRefundNo": "REFUND20241201001",
"bizOrderNo": "ORDER20241201001",
"tradeNo": "T2024120112345700001",
"amount": 100,
"orderAmount": 100,
"status": "progress",
"reason": "Customer requested refund"
}
}Refund Callback
After a successful refund, the platform sends an async notification with event=refund.success to the original payment order's notifyUrl. See Async Callback.