Skip to main content

Recurring Payments Introduction

Note

This API is not yet publicly available. Please contact Bybit Pay team if you need access to Recurring Payments.

Overview

Recurring Payments (Auto-deduction) enables merchants to automatically deduct funds from users' Bybit accounts after users pre-authorize the agreement. No manual confirmation is required for each transaction.

Document Version: v2.10

Update History:

  • v2.10 (2026-03-29): Added merchant settlement configuration error code MERCHANT_SETTLEMENT_CONFIG_ERROR (139006004); Added merchant quota limit error code EXCEED_MERCHANT_QUOTA_LIMIT (139004008); Added chain_address field to amount and limit config in sign/deduction/sign-and-pay APIs
  • v2.9 (2026-02-24): Added Agreement Type Description section detailing usage scenarios and limit configuration differences for CYCLE/NON_CYCLE/SINGLE types; Fixed missing NON_CYCLE in documentation
  • v2.8 (2026-02-11): Expanded deduction API supported scene codes from 6 to 17, added FOOD, ENTERTAINMENT, EDUCATION, MEMBERSHIP, RENT, FITNESS, TELECOM, CLOUD, INSURANCE, LOAN, OTHERS
  • v2.7: Updated response format (retCode/retMsg/result), fixed field type descriptions, adjusted document structure

Applicable Scenarios:

  • Ride-hailing contactless payment
  • Membership auto-renewal / Subscriptions
  • Utility bill payment
  • Parking lot automatic deduction
  • Recurring service payments

Security Mechanism:

  • Strong authentication for signing (SMS/Face/Password)
  • Single and period limit controls
  • Real-time risk control interception
  • Async notification for every deduction

Core Concepts

Agreement Lifecycle

                                    ┌─────────────────────────────────────┐
│ │
▼ │
┌──────┐ Sign Request ┌──────┐ User Scan ┌─────────┐ Confirm Sign ┌────────┐
│ │ ─────────────→ │ │ ───────────→ │ │ ─────────────→ │ │
│ Start│ │ INIT │ │ PENDING │ │ SIGNED │◀──┐
│ │ │ │ │ │ │ │ │
└──────┘ └──────┘ └─────────┘ └────────┘ │
│ │ │ │ │ │ │
│ Timeout │ │ Failed/Rejected │ │ │ │
▼ ▼ │ │ │ │ │
┌─────────┐ ┌────────┐ │ │ │ │
│ TIMEOUT │ │ FAILED │ │ │ │ │
└─────────┘ └────────┘ │ │ │ │
│ │ │ │
┌──────────────────────────────────────────────┘ │ │ │
│ Unsign │ │ │
▼ │ │ │
┌──────────┐ │ │ │
│ UNSIGNED │ │ │ │
└──────────┘ │ │ │
│ │ │
┌────────────────────────────────────────────────┘ │ │
│ Expired │ │
▼ │ │
┌─────────┐ │ │
│ EXPIRED │ │ │
└─────────┘ │ │
│ │
┌───────────────────────────────────────────────────┘ │
│ Risk/Abnormal │
▼ │
┌───────────┐ Resume │
│ SUSPENDED │ ────────────────────────────────────────────────┘
└───────────┘

Agreement States

StatusDescriptionDeduction Allowed
INITSign request created, waiting for user scanNo
PENDINGUser scanned, waiting to complete verificationNo
SIGNEDAgreement activeYes
SUSPENDEDTemporarily paused (can be resumed)No
UNSIGNEDAgreement terminated (final)No
EXPIREDAgreement expired (final)No
FAILEDSign failed (final)No
TIMEOUTSign link expired (final)No

Integration Flow

1. Sign Flow (One-time Setup)

Merchant Server                  Platform                         User App
│ │ │
│ 1.Sign Request │ │
│ (user_id + │ │
│ merchant_user_id) │ │
│ ──────────────────────→ │ │
│ │ │
│ 2.Return Sign QR Code │ │
│ (qr_code/sign_url) │ │
│ ←────────────────────── │ │
│ │ │
│ Display QR Code │ 3.Scan │
│ - - - - - - - - - - - - │ ←──────────────────────── │
│ │ │
│ │ 4.Login/Register │
│ │ ←─────────────────────────→│
│ │ │
│ │ 5.Identity Verification│
│ │ (SMS/Face/Password) │
│ │ ←─────────────────────────→│
│ │ │
│ │ 6.Confirm Sign Auth │
│ │ ←──────────────────────── │
│ │ │
│ 7.Webhook Notification │ │
│ (agreement_no) │ │
│ ←────────────────────── │ │
│ │ │

2. Deduction Flow (Automatic Payment)

Merchant Server → Deduction Request(agreement_no) → Platform

┌─────────────────┐
│ 1. Agreement │
│ validity check│
│ 2. Limit check │
│ 3. Risk check │
│ 4. Execute │
│ deduction │
└─────────────────┘

←←←←←←← Sync return result + Async notification ←←←←

User receives deduction notification (Push/SMS)

3. Refund Flow

Merchant Server → Refund Request(trade_no + refund_amount) → Platform

┌─────────────────┐
│ 1. Transaction │
│ validity check│
│ 2. Refundable │
│ amount check │
│ 3. Execute refund│
└─────────────────┘

←←←←←←← Sync return result + Async notification ←←←←←←←←

User receives refund notification (Push/SMS)

API List

API NameMethodEndpointDescription
Sign RequestPOST/v5/bybitpay/agreement/signCreate sign request, get QR code
UnsignPOST/v5/bybitpay/agreement/unsignTerminate agreement
DeductionPOST/v5/bybitpay/agreement/payExecute automatic deduction
RefundPOST/v5/bybitpay/agreement/refundRefund deduction transaction
Query AgreementGET/v5/bybitpay/agreement/queryQuery single agreement status
List AgreementsGET/v5/bybitpay/agreement/listList merchant agreements
Query TransactionGET/v5/bybitpay/agreement/pay/queryQuery single transaction/refund
List TransactionsGET/v5/bybitpay/agreement/pay/listList transactions under agreement

Quick Start

Step 1: Create Sign Request

POST /v5/bybitpay/agreement/sign
{
"merchant_id": "M123456789",
"agreement_type": "CYCLE",
"merchant_user_id": "merchant_user_123",
"scene_code": "SUBSCRIPTION",
"external_agreement_no": "MERCHANT_AGR_001",
"single_limit": {
"amount": "100000",
"currency": "USDT",
"currency_type": "CRYPTO"
},
"notify_url": "https://merchant.com/notify/sign"
}

Step 2: User Completes Sign

Display the returned qr_code or sign_url to the user. User scans and completes identity verification.

Step 3: Receive Sign Webhook

{
"notifyType": "AGREEMENT_SIGN",
"data": {
"agreementNo": "AGR202312230001",
"status": "SIGNED",
"userId": "U_123456789"
}
}

Step 4: Execute Deduction

POST /v5/bybitpay/agreement/pay
{
"merchant_id": "M123456789",
"user_id": "U_123456789",
"agreement_type": "CYCLE",
"agreement_no": "AGR202312230001",
"out_trade_no": "ORDER20231223001",
"scene_code": "SUBSCRIPTION",
"amount": {
"total": "2350",
"currency": "USDT",
"currency_type": "CRYPTO"
},
"order_info": {
"order_title": "Monthly subscription"
},
"notify_url": "https://merchant.com/notify/pay"
}