Agreement Deduction API
HTTP Request
POST /v5/bybitpay/agreement/pay
Execute automatic deduction from user's account using a signed agreement. This is the core API for agreement payment.
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 |
| agreement_no | string | Yes | Platform agreement number |
| out_trade_no | string | Yes | Merchant order number (unique) |
| scene_code | string | Yes | Scene code - Supports 17 scenarios including TAXI, PARKING, SUBSCRIPTION, FOOD, ENTERTAINMENT, EDUCATION, etc. |
| amount | object | Yes | Deduction amount |
| amount.total | string | Yes | Amount (minimum unit) |
| amount.currency | string | Yes | Currency code |
| amount.currency_type | string | Yes | FIAT or CRYPTO |
| amount.chain | string | No | Chain network (required for crypto) |
| amount.chain_address | string | No | Chain address (required for dynamic on-chain settlement) |
| order_info | object | Yes | Order information |
| order_info.order_title | string | Yes | Order title (displayed to user) |
| order_info.order_desc | string | No | Order description |
| order_info.goods_name | string | No | Goods name |
| order_info.goods_id | string | No | Goods ID |
| order_info.goods_category | string | No | Goods category |
| scene_info | object | No | Scene information |
| scene_info.device_id | string | No | Device ID |
| scene_info.device_ip | string | No | Device IP |
| scene_info.location | object | No | Location information |
| scene_info.location.latitude | string | No | Latitude |
| scene_info.location.longitude | string | No | Longitude |
| scene_info.location.address | string | No | Detailed address |
| notify_url | string | Yes | Deduction result webhook URL |
| risk_info | object | No | Risk control information |
| risk_info.user_ip | string | No | User IP address |
| risk_info.device_fingerprint | string | No | Device fingerprint |
| risk_info.user_agent | string | No | User agent string |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| retCode | int | Response code |
| retMsg | string | Response message |
| result | object | Response data |
| result.order_no | string | Platform order number |
| result.trade_no | string | Platform trade number |
| result.out_trade_no | string | Merchant order number |
| result.status | string | Transaction status: PROCESSING / SUCCESS / FAILED / TIMEOUT |
| result.amount | object | Requested amount |
| result.crypto_payment | object | Actual crypto payment info (for fiat orders) |
| result.crypto_payment.currency | string | Cryptocurrency (e.g., USDT) |
| result.crypto_payment.amount | string | Cryptocurrency amount |
| result.crypto_payment.chain | string | Chain network |
| result.crypto_payment.exchange_rate | string | Exchange rate |
| result.crypto_payment.rate_time | string | Rate lock time |
| result.pay_time | string | Payment time (on success) |
| result.failure_reason | string | Failure reason (on failure) |
Request Examples
Cryptocurrency Order
POST /v5/bybitpay/agreement/pay 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",
"agreement_no": "AGR202601070001",
"out_trade_no": "ORDER20260107001",
"scene_code": "SUBSCRIPTION",
"amount": {
"total": "2350",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"order_info": {
"order_title": "Monthly subscription - January 2026",
"order_desc": "Premium membership",
"goods_name": "Premium Plan",
"goods_id": "PREMIUM_001"
},
"notify_url": "https://merchant.com/notify/pay"
}
Fiat Currency Order
POST /v5/bybitpay/agreement/pay 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",
"agreement_no": "AGR202601070001",
"out_trade_no": "ORDER20260107002",
"scene_code": "TAXI",
"amount": {
"total": "10000",
"currency": "USD",
"currency_type": "FIAT"
},
"order_info": {
"order_title": "Ride fare",
"order_desc": "Trip from A to B"
},
"scene_info": {
"device_id": "DEVICE_001",
"device_ip": "192.168.1.1",
"location": {
"latitude": "39.9042",
"longitude": "116.4074",
"address": "Beijing, China"
}
},
"risk_info": {
"user_ip": "203.0.113.45",
"device_fingerprint": "fp_abc123xyz"
},
"notify_url": "https://merchant.com/notify/pay"
}
Response Examples
Crypto Order Success
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"order_no": "ORD202601070001",
"trade_no": "PAY202601070001",
"out_trade_no": "ORDER20260107001",
"status": "SUCCESS",
"amount": {
"total": "2350",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"pay_time": "2026-01-07T10:30:00Z"
}
}
Fiat Order Success (with Crypto Payment)
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"order_no": "ORD202601070002",
"trade_no": "PAY202601070002",
"out_trade_no": "ORDER20260107002",
"status": "SUCCESS",
"amount": {
"total": "10000",
"currency": "USD",
"currency_type": "FIAT"
},
"crypto_payment": {
"currency": "USDT",
"amount": "10005.50",
"chain": "TRC20",
"exchange_rate": "1.00055",
"rate_time": "2026-01-07T10:29:55Z"
},
"pay_time": "2026-01-07T10:30:00Z"
}
}
Processing Status
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"order_no": "ORD202601070003",
"trade_no": "PAY202601070003",
"out_trade_no": "ORDER20260107003",
"status": "PROCESSING",
"amount": {
"total": "5000",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
}
}
}
Deduction Failed
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"order_no": "ORD202601070004",
"trade_no": "PAY202601070004",
"out_trade_no": "ORDER20260107004",
"status": "FAILED",
"amount": {
"total": "5000",
"currency": "USDT",
"currency_type": "CRYPTO",
"chain": "TRC20"
},
"failure_reason": "BALANCE_NOT_ENOUGH"
}
}
Verification Steps
Platform performs the following checks before executing deduction:
- Agreement Validity: Agreement must be in
SIGNEDstatus - Single Limit Check: Amount does not exceed single transaction limit
- Period Limit Check: Cumulative amount does not exceed period limit
- Balance Check: User account has sufficient balance
- Risk Check: Transaction passes risk control rules
Notes
- Idempotency: Same
out_trade_noreturns result of first request - Async Processing:
PROCESSINGstatus requires waiting for webhook or query - Timeout Handling: Set 30-second timeout, query if timeout occurs
- Fiat Orders: User pays with cryptocurrency;
crypto_paymentshows actual payment details