Create Payment
Creates a new payment and returns the requisites for payment.
Endpoint
POST /v1/payments
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ext_id | string | Yes | Unique order ID in your system (max 255 chars) |
amount | number | Yes | Payment amount in RUB (100 – 300,000) |
method | string | No | Payment method: SBP, CARD, SBP_QR, CROSS_BORDER, CROSS_BORDER_CARD, SIM, VIET_QR (see Payment Methods). Default CARD |
bank | string | No | Bank code (filter) |
country | string | No | Country code for CROSS_BORDER: TJ, KZ, UZ, KG |
client_id | string | No | Client/payer ID in your system |
notify_url | string | No | URL for webhook notifications |
notification_token | string | No | Token for webhook validation (see Webhooks) |
Notification Token
The notification_token parameter lets you pass an arbitrary token that will be returned in the X-Notification-Token header when sending a webhook. Use it to validate incoming notifications.
Request Example (SBP)
curl -X POST https://api.bopay.io/v1/payments \
-H "Content-Type: application/json" \
-H "X-Identity: your-api-key" \
-H "X-Signature: calculated-signature" \
-d '{
"ext_id": "order_12345",
"amount": 5000,
"method": "SBP",
"client_id": "user_789",
"notify_url": "https://your-site.com/webhook",
"notification_token": "your-secret-token"
}'
Client ID
The client_id parameter lets you track payments of a specific client. Use the user ID from your system (email, phone number, internal ID).
Response (SBP/Card)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"ext_id": "order_12345",
"amount": 5000,
"currency": "RUB",
"rate": 80.95,
"payin_rate": 11,
"terminal_id": "6f15ad5b-325f-44ca-8f36-233379dcaf4c",
"terminal_name": "Sber Deep RUB",
"status": "PENDING",
"method": "SBP",
"requisites": {
"type": "sbp",
"value": "+79001234567",
"bank": "Сбербанк",
"bank_code": "sberbank",
"holder": "Ivan I."
},
"payment_url": "https://pay.bopay.io/invoice?id=550e8400-e29b-41d4-a716-446655440000",
"valid_until": "2026-01-30T12:30:00Z",
"created_at": "2026-01-30T12:15:00Z"
}
Payment URL
The payment_url field contains a link to the payment page. You can redirect the client to this page, where they will see the requisites and can confirm the transfer.
Response (Cross-Border)
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"ext_id": "order_67890",
"amount": 10000,
"currency": "RUB",
"rate": 80.95,
"payin_rate": 11,
"terminal_id": "6f15ad5b-325f-44ca-8f36-233379dcaf4c",
"terminal_name": "Sber Deep RUB",
"status": "PENDING",
"method": "CROSS_BORDER",
"requisites": {
"type": "phone",
"value": "+992901234567",
"bank": "vasl_bank",
"bank_name": "Vasl Bank",
"holder": "Ivan I.",
"country": "TJ",
"currency": "TJS",
"amount_local": 1237.39
},
"payment_url": "https://pay.bopay.io/invoice?id=660e8400-e29b-41d4-a716-446655440001",
"valid_until": "2026-01-30T12:30:00Z",
"created_at": "2026-01-30T12:15:00Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique payment ID (UUID) |
ext_id | string | Your order ID |
amount | number | Payment amount in RUB |
currency | string | Currency (RUB) |
rate | number | RUB/USDT rate fixed for this deal |
payin_rate | number | Your pay-in rate for this deal, % |
terminal_id | string | ID of the terminal the payment went through (UUID) |
terminal_name | string | Terminal name |
status | string | Payment status |
method | string | Payment method |
requisites | object | Requisites for payment |
requisites.type | string | Type: sbp, card, phone, or qr (for VIET_QR — value = EMV string) |
requisites.value | string | Phone number or card number |
requisites.bank | string | Bank name |
requisites.bank_code | string | Bank code (e.g.: sberbank, tinkoff, alfabank) |
requisites.bank_name | string | Bank name (for CROSS_BORDER) |
requisites.holder | string | Recipient name |
requisites.country | string | Country code (for CROSS_BORDER) |
requisites.currency | string | Requisites currency (for CROSS_BORDER) |
requisites.amount_local | number | Amount in local currency (for CROSS_BORDER) |
payment_url | string | null | Payment page URL (if any) |
valid_until | string | Payment expiration time (ISO 8601) |
created_at | string | Creation time (ISO 8601) |
Payment Methods
| Method | Description |
|---|---|
CARD | Bank card |
SBP | Faster Payments System (transfer by phone number) |
SBP_QR | SBP via QR code |
SIM | Payment to a phone number (mobile operator) |
CROSS_BORDER | Cross-border transfer by requisites (TJ, KZ, UZ, KG) |
CROSS_BORDER_CARD | Cross-border transfer to a card |
Payment Statuses
| Status | Description |
|---|---|
PENDING | Awaiting payment |
PROCESSING | Client confirmed the transfer, awaiting verification |
COMPLETED | Successfully completed |
COMPLETED_APPEAL | Successfully completed via appeal (including for an amount different from the order amount) |
CANCELLED | Cancelled (timeout or manual) |
CANCELLED_APPEAL | Cancelled via appeal |
DISPUTE | Dispute opened |
Errors
| Code | HTTP | Description |
|---|---|---|
PAY_001 | 500 | Internal error |
PAY_002 | 400 | Invalid parameters (ext_id, amount, method) |
PAY_003 | 409 | Order with this ext_id already exists |
PAY_004 | 503 | No available requisites |
PAY_005 | 429 | Too many payments with the same amount |
Error Response Example
{
"error": "PAY_003",
"message": "Payment order already exists",
"data": {
"ext_id": "order_12345"
}
}