Deduction Refund API
HTTP Request
POST /v5/bybitpay/agreement/refund
Initiate refund for a successful deduction transaction. Supports full and partial refunds.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchant_id | string | Yes | Merchant ID |
| user_id | string | Yes | Platform user ID |
| agreement_type | string | Yes | Sign type: CYCLE / NON_CYCLE / SINGLE |
| trade_no | string | Either | Platform trade number |
| out_trade_no | string | Either | Merchant order number |
| out_refund_no | string | Yes | Merchant refund number (unique) |
| refund_amount | object | Yes | Refund amount |
| refund_amount.total | string | Yes | Refund amount (minimum unit) |
| refund_amount.currency | string | Yes | Currency code |
| refund_amount.currency_type | string | Yes | FIAT or CRYPTO |
| refund_amount.chain | string | No | Chain network (required for crypto) |
| refund_reason | string | No | Refund reason |
| notify_url | string | Yes | Refund result webhook URL |
info
Either trade_no or out_trade_no must be provided.
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| retCode | int | Response code |
| retMsg | string | Response message |
| result | object | Response data |
| result.refund_no | string | Platform refund number |
| result.out_refund_no | string | Merchant refund number |
| result.trade_no | string | Original trade number |
| result.status | string | Refund status: PROCESSING / SUCCESS / FAILED |
| result.refund_amount | object | Refund amount |
| result.refund_time | string | Refund success time (on success) |
| result.failure_reason | string | Failure reason (on failure) |
Request Example
Full Refund
POST /v5/bybitpay/agreement/refund HTTP/1.1
Host: api2.bybit.com
Content-Type: application/json
X-BAPI-API-KEY: xxxxxxxxxxxxxxxxxx
X-BAPI-TIMESTAMP: 1736233200000
X-BAPI-SIGN: {signature}
X-BAPI-RECV-WINDOW: 5000
{
"merchant_id": "M123456789",
"user_id": "U_123456789",
"agreement_type": "CYCLE",
"trade_no": "PAY202601070001",
"out_refund_no": "REFUND20260107001",
"refund_amount": {
"total": "2350",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"refund_reason": "User requested cancellation",
"notify_url": "https://merchant.com/notify/refund"
}
Partial Refund
POST /v5/bybitpay/agreement/refund HTTP/1.1
Host: api2.bybit.com
Content-Type: application/json
X-BAPI-API-KEY: xxxxxxxxxxxxxxxxxx
X-BAPI-TIMESTAMP: 1736233200000
X-BAPI-SIGN: {signature}
X-BAPI-RECV-WINDOW: 5000
{
"merchant_id": "M123456789",
"user_id": "U_123456789",
"agreement_type": "CYCLE",
"out_trade_no": "ORDER20260107001",
"out_refund_no": "REFUND20260107002",
"refund_amount": {
"total": "1000",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"refund_reason": "Partial service not provided",
"notify_url": "https://merchant.com/notify/refund"
}
Response Examples
Refund Success
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"refund_no": "RF202601070001",
"out_refund_no": "REFUND20260107001",
"trade_no": "PAY202601070001",
"status": "SUCCESS",
"refund_amount": {
"total": "2350",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"refund_time": "2026-01-07T11:30:00Z"
}
}
Refund Processing
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"refund_no": "RF202601070002",
"out_refund_no": "REFUND20260107002",
"trade_no": "PAY202601070001",
"status": "PROCESSING",
"refund_amount": {
"total": "1000",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
}
}
}
Refund Failed
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"refund_no": "RF202601070003",
"out_refund_no": "REFUND20260107003",
"trade_no": "PAY202601070001",
"status": "FAILED",
"refund_amount": {
"total": "5000",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"failure_reason": "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
out_refund_noreturns 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