Оплата банковской картой
Сценарий оплаты картой не требует предварительного создания контракта. Достаточно создать счёт и перенаправить пользователя на полученный URL для оплаты.
5.1 Создание счёта (карта)
JSON API v3
POST /api/v3/projects/{projectId}/invoices
JSON API v3
{
"client_ip": "10.20.30.40",
"customer": {
"type": "undefined_bank_card",
"source": "my_app",
"country": "RU",
"merchant_customer_id": "client_12345",
"email": "test@test.com"
},
"order": {
"merchant_order_id": "order_123",
"price": {
"amount": "20.00",
"currency": "RUB",
"vat_included": true
}
}
}JSON API v3
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
customer. | string | Да | "undefined_bank_card" — реквизиты вводит плательщик на платёжной странице |
customer. | string (max 64) | Да | Уникальный идентификатор ресурса / бренда мерчанта. Гарантирует глобальную уникальность пары source + merchant_customer_id |
customer. | string (ISO 3166) | Да | Страна клиента |
customer. | string (max 128) | Да | Уникальный ID клиента в системе мерчанта |
customer. | string | Нет | Email клиента |
undefined_bank_card и bank_card — разные сценарии. undefined_bank_card означает «карту вводит плательщик на платёжной странице» и подходит для всего, что описано в §5.1 и §5.2; контракты этим типом не создаются — блок contract вместе с ним отклоняется 400 BAD_REQUEST. bank_card по спеке — приём карты на форме продавца (контур PCI DSS, §5.3). В новых интеграциях платёжной страницы используйте undefined_bank_card: bank_card остаётся deprecated-алиасом и будет снят в 3.0.0.
JSON API v3
{
"success": true,
"data": {
"invoice_id": "1aa2b436-0031-0028-1a54-8abd8eb88c40",
"status": "Created",
"payment_status": "NOT_PAID",
"authorization": {
"type": "AUTH_PAGE",
"is_authorized": false,
"url": "https://pay.callisto.pay/checkout/1aa2b436003100281a548abd8eb88c40"
},
"price": {
"amount": "20.00",
"currency": "RUB",
"vat_included": true
},
"merchant_order_id": "order_123",
"created_at": "2025-10-04T08:46:45Z",
"expires_at": "2025-10-04T10:46:45Z",
"billing_channel": "BankRtp",
"customer": {
"type": "undefined_bank_card",
"source": "my_app",
"country": "RU",
"merchant_customer_id": "client_12345",
"email": "test@test.com"
}
}
}После получения ответа мерчант перенаправляет клиента по адресу из ответа: authorization. в JSON, <AuthorizationUrl> в XML.
Челлендж 3-D Secure — не константа. Показывается ли после формы карты страница подтверждения, зависит от эквайера, типа интеграции и фрод-правил, поэтому интеграция должна работать в обоих режимах. На состав ответа этого сценария наличие челленджа не влияет: адрес для редиректа приходит всегда. Прогнать оба режима можно в песочнице — там 3-D Secure переключается настройкой проекта, см. Сценарий: 3-D Secure.
Возврат клиента на сайт
Закончив оплату — успешно или нет, — клиент возвращается на адрес возврата, настроенный у вашего проекта. Платформа дописывает к нему параметры результата:
| Параметр | Значение |
|---|---|
invoiceId | Идентификатор счёта в системе платформы |
merchantOrderId | Идентификатор заказа в вашей системе |
success | true — оплата прошла; false — ошибка или отмена |
https://your-site.com/payment/result?invoiceId=1aa2b436-0031-0028-1a54-8abd8eb88c40&merchantOrderId=order_123&success=truesuccess годится для экрана результата, но не для выдачи товара. Параметры приходят из браузера клиента и подписью не защищены, а до вашего сайта клиент может и не доехать — закрыть вкладку, потерять сеть. Источник состояния платежа — вебхук и GET /invoices/{invoice_id}.
JSON API v3
POST /invoices — карта, с редиректом
curl
RESPONSE=$(curl -sS -X POST "$BASE/api/v3/projects/$PROJECT_ID/invoices" \
-H "Content-Type: application/json" \
-H "X-Login: $LOGIN" \
-H "X-Timestamp: $TS" \
-H "X-Signature-Version: 3" \
-H "X-Signature: $SIG" \
-d '{
"client_ip": "10.20.30.40",
"customer": {
"type": "undefined_bank_card",
"source": "my_app",
"country": "RU",
"merchant_customer_id": "client_12345"
},
"order": {
"merchant_order_id": "order_123",
"price": { "amount": "20.00", "currency": "RUB", "vat_included": true }
}
}')
echo "$RESPONSE" | jq -r '.data.authorization.url'5.2 СБП и SberPay
JSON API v3
Отдельного запроса у СБП и SberPay нет. Счёт создаётся ровно так же, как в §5.1, а способ оплаты выбирается параметрами к адресу из ответа (authorization. в JSON, <AuthorizationUrl> в XML) — платформа перешла на эту схему в v2.78.0.
| Параметры к адресу оплаты | Что откроется |
|---|---|
| (без параметров) | Форма банковской карты |
?useSbp=true | СБП — QR-код |
?payType=Sber&deviceType=Desktop | SberPay для десктопа |
?payType=Sber&deviceType=Mobile | SberPay для мобильных устройств |
https://pay.callisto.pay/checkout/1aa2b436003100281a548abd8eb88c40?useSbp=trueПоле payment_method в теле запроса — deprecated. Селектор способа оплаты был в редакции спеки от мая 2026 и платформой снят. Поле принимается ещё одну minor-версию, снятие — в 3.0.0; на состав ответа оно не влияет — вернётся тот же authorization., только с уже дописанными параметрами из таблицы выше.
Один счёт открывается любым способом, пока не оплачен. Плательщик может вернуться на адрес оплаты и выбрать другой способ — отдельный счёт под каждый способ создавать не нужно.
Привязки СБП пока недоступны. Повторные списания по СБП через контракт — в дорожной карте, в протоколе этого сценария сейчас нет. Для списаний без повторного подтверждения доступны два пути: контракт по номеру телефона с подтверждением PIN-кодом (DCB) и привязка карты (§5.3).
5.3 Привязка карты (card-on-file)
Требуется сертификация PCI DSS. В этом сценарии карточные данные проходят через продавца, и спека ставит это жёстким условием.
Без сертификации используйте сценарий «Оплата через банковскую платёжную форму» — это §5.1 выше: счёт создаётся без карточных данных, клиент вводит их на стороне платформы, куда уходит по адресу оплаты из ответа.
Данные карты вводятся на стороне продавца и передаются блоком <BankCard> внутри <BankCardCustomer> (XML) или объектом customer. при customer.type = "bank_card" (JSON). Карта привязывается контрактом CreateCustomerContract / POST /contracts (ответ — AuthorizationType: SKIP, PIN-подтверждения нет), дальнейшие списания идут обычным созданием счёта с ссылкой на контракт, без повторного ввода реквизитов. Наличие блока карточных данных в запросах регулируется типом интеграции и индивидуальными требованиями эквайера — включается индивидуально.
Поле customer. | Обязательное | Описание |
|---|---|---|
pan | Да | Номер карты, 16 цифр |
expiration_month | Да | Месяц окончания срока действия, 1–12 |
expiration_year | Да | Год окончания срока действия, 2 или 4 цифры |
security_code | Да | CVV/CVC, 3–4 цифры. Не сохраняется нигде и ни в каком виде |
cardholder | Нет | Держатель карты, до 128 символов |
Блок допустим только вместе с contract. — контур всегда работает через контракты. Карта не возвращается ни в одном ответе и не сохраняется: от неё остаются только последние 4 цифры номера, а в журнал запросов тело попадает уже замаскированным.
Карточные данные принимает отдельный хост. Спецификация отводит под контур PCI DSS выделенный адрес: customer. принимают только создание счёта и создание контракта на нём, всё остальное — авторизация, отмена, возвраты, чтение счёта — обслуживает основной хост, и отправка карты туда отклоняется. Адрес контура запрашивайте у команды платформы.
Пошаговый разбор и правила эмуляции в тестовой среде — Сценарий: привязка карты; формат метода — Создать контракт.