Skip to Content
Разовые платежиКарты, СБП, SberPay

Оплата банковской картой

Сценарий оплаты картой не требует предварительного создания контракта. Достаточно создать счёт и перенаправить пользователя на полученный URL для оплаты.

5.1 Создание счёта (карта)

POST /api/v3/projects/{projectId}/invoices

Тело запроса
{ "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 } } }
ПолеТипОбязательноеОписание
customer.typestringДа"undefined_bank_card" — реквизиты вводит плательщик на платёжной странице
customer.sourcestring (max 64)ДаУникальный идентификатор ресурса / бренда мерчанта. Гарантирует глобальную уникальность пары source + merchant_customer_id
customer.countrystring (ISO 3166)ДаСтрана клиента
customer.merchant_customer_idstring (max 128)ДаУникальный ID клиента в системе мерчанта
customer.emailstringНет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.

Ответ — 201 Created
{ "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.url в JSON, <AuthorizationUrl> в XML.

Челлендж 3-D Secure — не константа. Показывается ли после формы карты страница подтверждения, зависит от эквайера, типа интеграции и фрод-правил, поэтому интеграция должна работать в обоих режимах. На состав ответа этого сценария наличие челленджа не влияет: адрес для редиректа приходит всегда. Прогнать оба режима можно в песочнице — там 3-D Secure переключается настройкой проекта, см. Сценарий: 3-D Secure.

Возврат клиента на сайт

Закончив оплату — успешно или нет, — клиент возвращается на адрес возврата, настроенный у вашего проекта. Платформа дописывает к нему параметры результата:

ПараметрЗначение
invoiceIdИдентификатор счёта в системе платформы
merchantOrderIdИдентификатор заказа в вашей системе
successtrue — оплата прошла; false — ошибка или отмена
Пример адреса возврата
https://your-site.com/payment/result?invoiceId=1aa2b436-0031-0028-1a54-8abd8eb88c40&merchantOrderId=order_123&success=true

success годится для экрана результата, но не для выдачи товара. Параметры приходят из браузера клиента и подписью не защищены, а до вашего сайта клиент может и не доехать — закрыть вкладку, потерять сеть. Источник состояния платежа — вебхук и GET /invoices/{invoice_id}.

POST /invoices — карта, с редиректом

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

Отдельного запроса у СБП и SberPay нет. Счёт создаётся ровно так же, как в §5.1, а способ оплаты выбирается параметрами к адресу из ответа (authorization.url в JSON, <AuthorizationUrl> в XML) — платформа перешла на эту схему в v2.78.0.

Параметры к адресу оплатыЧто откроется
(без параметров)Форма банковской карты
?useSbp=trueСБП — QR-код
?payType=Sber&deviceType=DesktopSberPay для десктопа
?payType=Sber&deviceType=MobileSberPay для мобильных устройств
Адрес оплаты с выбранным способом
https://pay.callisto.pay/checkout/1aa2b436003100281a548abd8eb88c40?useSbp=true

Поле payment_method в теле запроса — deprecated. Селектор способа оплаты был в редакции спеки от мая 2026 и платформой снят. Поле принимается ещё одну minor-версию, снятие — в 3.0.0; на состав ответа оно не влияет — вернётся тот же authorization.url, только с уже дописанными параметрами из таблицы выше.

Один счёт открывается любым способом, пока не оплачен. Плательщик может вернуться на адрес оплаты и выбрать другой способ — отдельный счёт под каждый способ создавать не нужно.

Привязки СБП пока недоступны. Повторные списания по СБП через контракт — в дорожной карте, в протоколе этого сценария сейчас нет. Для списаний без повторного подтверждения доступны два пути: контракт по номеру телефона с подтверждением PIN-кодом (DCB) и привязка карты (§5.3).

5.3 Привязка карты (card-on-file)

Требуется сертификация PCI DSS. В этом сценарии карточные данные проходят через продавца, и спека ставит это жёстким условием.

Без сертификации используйте сценарий «Оплата через банковскую платёжную форму» — это §5.1 выше: счёт создаётся без карточных данных, клиент вводит их на стороне платформы, куда уходит по адресу оплаты из ответа.

Данные карты вводятся на стороне продавца и передаются блоком <BankCard> внутри <BankCardCustomer> (XML) или объектом customer.bank_card при customer.type = "bank_card" (JSON). Карта привязывается контрактом CreateCustomerContract / POST /contracts (ответ — AuthorizationType: SKIP, PIN-подтверждения нет), дальнейшие списания идут обычным созданием счёта с ссылкой на контракт, без повторного ввода реквизитов. Наличие блока карточных данных в запросах регулируется типом интеграции и индивидуальными требованиями эквайера — включается индивидуально.

Поле customer.bank_cardОбязательноеОписание
panДаНомер карты, 16 цифр
expiration_monthДаМесяц окончания срока действия, 1–12
expiration_yearДаГод окончания срока действия, 2 или 4 цифры
security_codeДаCVV/CVC, 3–4 цифры. Не сохраняется нигде и ни в каком виде
cardholderНетДержатель карты, до 128 символов

Блок допустим только вместе с contract.merchant_contract_id — контур всегда работает через контракты. Карта не возвращается ни в одном ответе и не сохраняется: от неё остаются только последние 4 цифры номера, а в журнал запросов тело попадает уже замаскированным.

Карточные данные принимает отдельный хост. Спецификация отводит под контур PCI DSS выделенный адрес: customer.bank_card принимают только создание счёта и создание контракта на нём, всё остальное — авторизация, отмена, возвраты, чтение счёта — обслуживает основной хост, и отправка карты туда отклоняется. Адрес контура запрашивайте у команды платформы.

Пошаговый разбор и правила эмуляции в тестовой среде — Сценарий: привязка карты; формат метода — Создать контракт.