Deduction Refund API
HTTP Request
POST /v5/pay/agreement/refund
Initiate refund for a successful deduction transaction. Supports full and partial refunds.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantId | string | Yes | Merchant ID |
| userId | string | Yes | Platform user ID |
| agreementType | string | Yes | Sign type: CYCLE / NON_CYCLE / SINGLE |
| tradeNo | string | Either | Platform trade number |
| outTradeNo | string | Either | Merchant order number |
| outRefundNo | string | Yes | Merchant refund number (unique) |
| refundAmount | object | Yes | Refund amount |
| refundAmount.total | string | Yes | Refund amount (minimum unit) |
| refundAmount.currency | string | Yes | Currency code |
| refundAmount.currencyType | string | Yes | FIAT or CRYPTO |
| refundReason | string | No | Refund reason |
| notifyUrl | string | Yes | Refund result webhook URL |
info
Either tradeNo or outTradeNo must be provided.
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| retCode | int | Response code |
| retMsg | string | Response message |
| result | object | Response data |
| result.refundNo | string | Platform refund number |
| result.outRefundNo | string | Merchant refund number |
| result.tradeNo | string | Original trade number |
| result.status | string | Refund status: PROCESSING / SUCCESS / FAILED |
| result.refundAmount | object | Refund amount |
| result.refundTime | string | Refund success time (on success) |
| result.failureReason | string | Failure reason (on failure) |
Request Example
Full Refund
POST /v5/pay/agreement/refund HTTP/1.1
Host: api.bybit.com
Content-Type: application/json
X-Request-Id: 550e8400-e29b-41d4-a716-446655440000
X-Timestamp: 1736233200000
X-Signature: {signature}
Authorization: Bearer {access_token}
{
"merchantId": "M123456789",
"userId": "U_123456789",
"agreementType": "CYCLE",
"tradeNo": "PAY202601070001",
"outRefundNo": "REFUND20260107001",
"refundAmount": {
"total": "2350",
"currency": "USDT",
"currencyType": "CRYPTO"
},
"refundReason": "User requested cancellation",
"notifyUrl": "https://merchant.com/notify/refund"
}
Partial Refund
POST /v5/pay/agreement/refund HTTP/1.1
Host: api.bybit.com
Content-Type: application/json
X-Request-Id: 550e8400-e29b-41d4-a716-446655440000
X-Timestamp: 1736233200000
X-Signature: {signature}
Authorization: Bearer {access_token}
{
"merchantId": "M123456789",
"userId": "U_123456789",
"agreementType": "CYCLE",
"outTradeNo": "ORDER20260107001",
"outRefundNo": "REFUND20260107002",
"refundAmount": {
"total": "1000",
"currency": "USDT",
"currencyType": "CRYPTO"
},
"refundReason": "Partial service not provided",
"notifyUrl": "https://merchant.com/notify/refund"
}
Response Examples
Refund Success
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"refundNo": "RF202601070001",
"outRefundNo": "REFUND20260107001",
"tradeNo": "PAY202601070001",
"status": "SUCCESS",
"refundAmount": {
"total": "2350",
"currency": "USDT",
"currencyType": "CRYPTO"
},
"refundTime": "2026-01-07T11:30:00Z"
}
}
Refund Processing
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"refundNo": "RF202601070002",
"outRefundNo": "REFUND20260107002",
"tradeNo": "PAY202601070001",
"status": "PROCESSING",
"refundAmount": {
"total": "1000",
"currency": "USDT",
"currencyType": "CRYPTO"
}
}
}
Refund Failed
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"refundNo": "RF202601070003",
"outRefundNo": "REFUND20260107003",
"tradeNo": "PAY202601070001",
"status": "FAILED",
"refundAmount": {
"total": "5000",
"currency": "USDT",
"currencyType": "CRYPTO"
},
"failureReason": "REFUND_AMOUNT_EXCEED"
}
}
Refund Rules
- Refundable Amount: Cannot exceed original transaction amount minus already refunded amount
- Multiple Refunds: Same transaction supports multiple partial refunds
- Quota Restoration: Used agreement quota is restored after successful refund
- Agreement State: Refund is allowed even after agreement is unsigned/expired
Error Scenarios
| Error Code | Description | Handling |
|---|---|---|
| REFUND_AMOUNT_EXCEED | Refund amount exceeds refundable amount | Check refunded amount |
| REFUND_NOT_ALLOW | Transaction status does not support refund | Transaction must be successful |
| REFUND_PROCESSING | Another refund is in progress | Wait for completion |
| TRADE_NOT_EXIST | Original transaction not found | Check trade number |
Notes
- Idempotency: Same
outRefundNoreturns result of first request - Currency Matching: Refund currency must match original transaction currency
- Async Processing:
PROCESSINGstatus requires waiting for webhook or query - Timeout Handling: Set 30-second timeout, query if timeout occurs