- Динамический QR на сайте
- Пользователь выбирает «Оплатить через СБП» → ваш бэкенд создаёт платеж → получаете
qr_payload и картинку SVG/PNG → показываете на витрине → клиент сканирует камерой банка → банк инициирует перевод → провайдер присылает webhook об успешной оплате.
- Deep link СБП в приложении
- Клиент кликает «Оплатить в приложении банка» → открывается банковское приложение через deep link → подтверждение платежа → возврат по
return_url → фиксация оплаты по webhook. Подробнее — мобильный приём.
- Оплата по ссылке
- Формируете платёж через API → получаете
payment_url → отправляете клиенту по SMS/email/мессенджеру → он открывает страницу с выбором банка и QR/deep link. Подробнее — оплата по ссылке и интернет‑эквайринг СБП.
Основные эндпоинты и модель данных
Ниже типовой набор методов (конкретные пути и поля могут отличаться у вашего провайдера; примеры — иллюстративные):
| Метод |
Путь |
Назначение |
| POST |
/api/sbp/v1/payments |
Создать платёж (динамический QR + deep link) |
| GET |
/api/sbp/v1/payments/{id} |
Получить платёж и статус |
| POST |
/api/sbp/v1/refunds |
Создать возврат по оплате |
| GET |
/api/sbp/v1/banks |
Получить список банков СБП |
| POST |
/api/sbp/v1/qrs/{id}/close |
Принудительно закрыть QR |
| POST |
/api/sbp/v1/test/webhook |
Отправить тестовый webhook |
Особенности модели:
- Суммы — в копейках (целое число), валюта — RUB.
- Идентификаторы — строки:
payment_id, order_id (ваш), refund_id.
- Идемпотентность — по заголовку
Idempotency-Key или X-Idempotency-Key.
- Срок жизни QR — ограничен (например, 15–30 минут) и передаётся как
expires_at.
qr_payload sbp и deep_link включаются в ответ при создании платежа.
Смотрите также: QR‑платежи СБП и общий обзор СБП‑эквайринга.
Пример создания платежа и получение QR/deep link
Запрос (создание платежа):
{
"order_id": "ORD-100500",
"amount": 125000,
"currency": "RUB",
"description": "Оплата заказа #100500",
"expires_at": "2025-12-31T23:59:00+03:00",
"return_url": "https://shop.ru/thanks",
"callback_url": "https://shop.ru/webhooks/sbp",
"customer": { "phone": "+79990001122" },
"qr": { "format": "svg", "size": 256 },
"features": { "deep_link": true },
"metadata": { "cart_id": "c_789" }
}
Ответ (усечённый):
{
"payment_id": "pay_abc123",
"status": "created",
"qr_payload": "https://qr.nspk.ru/XXXXYYYY?sum=125000&cur=RUB&purpose=ORD-100500",
"qr_svg": "data:image/svg+xml;base64,PHN2ZyB...",
"deep_link": "sbp://pay?amount=125000&order=ORD-100500&ref=pay_abc123",
"payment_url": "https://pay.example.ru/p/pay_abc123",
"expires_at": "2025-12-31T23:59:00+03:00"
}
Покажите QR на веб‑странице, а в мобильном сценарии предложите «Оплатить в приложении банка» через deep link. Возврат статуса выполняйте по webhook; опрашивать GET рекомендуется только как резервный механизм.
Webhooks СБП: события, ретраи и HMAC подпись
Webhooks СБП — основной источник финальных статусов. Типовые события:
payment.paid — клиент оплатил, денежные средства зачислены;
payment.expired — QR просрочен;
payment.failed — оплата не удалась;
refund.succeeded / refund.failed — результат возврата.
Пример уведомления:
Headers:
Content-Type: application/json
X-SBP-Event: payment.paid
X-SBP-Timestamp: 1730978451
X-SBP-Delivery: dlvry_6fj2
X-SBP-Signature: t=1730978451,v1=2f4a... (hmac подпись уведомлений)
Body:
{
"event": "payment.paid",
"payment_id": "pay_abc123",
"order_id": "ORD-100500",
"amount": 125000,
"status": "paid",
"paid_at": "2025-11-07T12:01:02+03:00",
"metadata": { "cart_id": "c_789" }
}
Проверка подписи HMAC SHA‑256 (пример Node.js):
// rawBody — неизменённая строка JSON из запроса
// secret — ваш webhook_secret из личного кабинета
const crypto = require('crypto');
function verifySignature(rawBody, signatureHeader, timestamp, secret) {
const base = `${timestamp}.${rawBody}`;
const digest = crypto.createHmac('sha256', secret).update(base, 'utf8').digest('hex');
const expected = `t=${timestamp},v1=${digest}`;
return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}
Python (альтернатива):
import hmac, hashlib
def verify_signature(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool:
base = timestamp.encode() + b'.' + raw_body
digest = hmac.new(secret.encode(), base, hashlib.sha256).hexdigest()
expected = f"t={timestamp},v1={digest}"
return hmac.compare_digest(signature, expected)
Рекомендации:
- Отвечайте 200 OK за <1–2 сек, обработку делайте асинхронно.
- Повторные доставки возможны — используйте
X-SBP-Delivery и идемпотентную запись событий.
- Храните сырое тело запроса для корректной валидации HMAC.
Подробнее о возвратах и спорах — на странице возвраты и споры.
Deep link СБП: мобильный сценарий
Deep link СБП открывает выбранное банковское приложение сразу на платёж, минуя сканирование QR. Полезно в:
- мобильных приложениях магазина;
- адаптивной мобильной веб‑витрине (кнопка «Оплатить в банке»).
Типичное поведение:
- Создаёте платёж через API с флагом
deep_link: true.
- Получаете
deep_link и/или bank_choice_url (страница выбора банка).
- Открываете ссылку в мобильном браузере/приложении; пользователь подтверждает и возвращается на
return_url.
Сценарии глубже раскрыты в разделах мобильный приём и оплата по ссылке СБП.
![Пример QR и deep link (placeholder)]()
QR payload SBP: что внутри кода
QR payload SBP — это строка (обычно URL с параметрами), которую банки распознают и инициируют перевод по СБП. Динамический payload содержит идентификатор платежа, сумму, назначение и срок жизни. Пример (сокращённый):
https://qr.nspk.ru/XXXXYYYY?type=01&sum=125000&cur=RUB&purpose=ORD-100500
Практические моменты:
- Динамический QR создаётся per‑order и истекает по
expires_at.
- Размер и формат: SVG предпочтительнее для веба, PNG — для печати.
- Избегайте перекодирования payload (не меняйте регистр/экранирование значений).
Подробнее о форматах — в разделе QR‑платежи СБП.
Возвраты, статусы и идемпотентность
Статусы платежа:
| Статус |
Описание |
Финальный |
| created |
Платёж создан, QR выдан |
нет |
| processing |
Банк обрабатывает перевод |
нет |
| paid |
Оплачено (получен webhook) |
да |
| expired |
Время действия истекло |
да |
| failed |
Ошибка при оплате |
да |
| refunded / partial_refunded |
Возврат проведён |
да |
Пример возврата:
{
"payment_id": "pay_abc123",
"refund_id": "rfd_555",
"amount": 125000,
"reason": "Отмена заказа"
}
Идемпотентность:
- Передавайте уникальный
Idempotency-Key для create/refund.
- На стороне бэкенда связывайте ключ с результатом, чтобы безопасно повторять запросы.
Развёрнуто про кейсы и споры — на странице возвраты и споры.
Безопасность, 54-ФЗ и хранение данных
Минимальные требования:
- TLS 1.2+, строгая проверка сертификатов.
- Валидация HMAC подписи уведомлений и allowlist публичных IP провайдера (если доступно).
- Храните только необходимые атрибуты, персональные данные маскируйте/шифруйте.
- Логи webhooks — без чувствительных токенов, но с
X-SBP-Delivery и временными метками.
Если требуется фискализация чеков, смотрите раздел касса 54‑ФЗ. Дополнительно о методах защиты — в разделе безопасность и юридических вопросах — договор и право.
Инструменты, плагины и тарифы
Не обязательно писать интеграцию «с нуля»:
Best practices и чеклист интеграции
Лучшие практики:
- Обязательно принимайте финальный статус из webhooks; опрос API используйте как fallback.
- Суммы храните как integer (копейки), избегая float.
- Таймауты HTTP 5–10 секунд, повтор запросов при сетевых ошибках с backoff и идемпотентностью.
- Показывайте пользователю выбор: QR и «Оплатить в приложении банка» (deep link), определяя устройство.
- Кэшируйте список банков на 24 часа, обновляйте по расписанию.
- Закрывайте QR при отмене заказа, чтобы не было «заблудившихся» оплат.
- Обновляйте UI по событиям: paid/expired/failed с понятными подсказками.
- Логируйте
order_id, payment_id, X-SBP-Delivery и хэш тела webhook.
- Пройдите песочницу: тест вебхуков, обработка ретраев, HMAC‑проверка на «битых телах».
- Документируйте статусы и SLA внутри команды поддержки.
Чеклист перед запуском:
- Создание платежа выдаёт корректный
qr_payload и deep_link.
- Веб‑страница рендерит QR (SVG/PNG) и проверена на Retina/Android камеры.
- Webhook обработчик проверяет HMAC и хранит сырое тело.
- Повторная доставка событий не ломает бизнес‑логику (идемпотентность по
delivery_id).
- Возвраты работают, статусы отображаются в админке.
- Интеграционные логи доступны и ротация настроена.
Вывод и следующий шаг
Интеграция СБП через API — быстрый способ повысить конверсию платежей и снизить комиссию. Используйте динамический QR и deep link, принимайте статусы через webhooks СБП с HMAC‑подписью и внедряйте практики идемпотентности и безопасности.
Готовы подключиться или хотите демо? Посмотрите как подключить и тарифы и комиссии, а затем выберите подходящий сценарий: СБП‑эквайринг или интернет‑эквайринг СБП. Мы поможем с пилотом и ответим на вопросы.