Приём оплаты через СБП: как это устроено и что учесть в интеграции
· 5 мин чтения
Как проходит платёж по QR-коду СБП, почему подтверждение приходит с задержкой, чем это отличается от карт и какие из этого следуют требования к интеграции.
Система быстрых платежей заметно отличается от карточной оплаты — и различия эти не косметические, они меняют то, как должна быть устроена ваша интеграция. Разберём, что происходит после того, как плательщик увидел QR-код.
Чаще всего СБП подключают первым — и особенно часто те, кому банк отказал в эквайринге: картам нужен договор с банком, а здесь достаточно шлюза.
Как проходит платёж
- Вы создаёте платёж и получаете адрес страницы оплаты.
- Плательщик открывает её и выбирает СБП.
- Формируется QR-код НСПК. На телефоне вместо сканирования работает переход по ссылке в приложение банка.
- Плательщик подтверждает перевод в своём банковском приложении — не на вашем сайте и не на нашей странице.
- Деньги уходят со счёта плательщика на счёт получателя напрямую, минуя карточную инфраструктуру.
- Вы получаете webhook с итоговым статусом.
Ключевой момент — шаг 4. Плательщик уходит в другое приложение, и ваш сайт в этот момент про него ничего не знает.
Чем это отличается от карт
Нет 3-D Secure. Подтверждение — сам факт того, что плательщик нажал кнопку в банковском приложении, куда он уже вошёл. Отдельного кода из SMS нет, отдельного редиректа на страницу банка тоже.
Практически нет оспариваний. СБП — это перевод, а не карточная операция, и механизма chargeback в привычном виде здесь нет. Для продавца это главное экономическое отличие: возврат возможен, но только по вашей инициативе.
Деньги приходят быстрее. Перевод исполняется почти мгновенно, тогда как карточная операция сначала холдируется и списывается позже.
Нет callback от плательщика к вам. И вот это меняет техническую часть.
Почему подтверждение приходит не сразу
У карточной оплаты есть возврат браузера: плательщик проходит 3-D Secure и его редиректит обратно — есть событие, за которое можно зацепиться. В СБП такого события нет вовсе. Плательщик подтвердил перевод в приложении банка, и физически некому сообщить об этом вашему сайту.
Поэтому единственный канал подтверждения — опрос платёжного шлюза на стороне процессора. Отсюда два практических следствия.
Первое: статус меняется с задержкой. Обычно это секунды, но интеграция обязана быть к этому готова и не считать отсутствие подтверждения через две секунды отказом.
Второе: платёж нельзя гасить по таймауту вслепую. Если платёж уже начали проводить, гасить его
по expires_at без финального опроса нельзя — иначе поздняя оплата, которую процессор уже
подтвердил, потеряется. На стороне шлюза это учтено, но то же правило касается и вашей стороны: не
закрывайте заказ как неоплаченный только потому, что прошло полчаса.
Что из этого следует для интеграции
Не полагайтесь на return_url. Возврат плательщика на ваш сайт — не подтверждение оплаты.
Плательщик может закрыть вкладку сразу после подтверждения в банке, и деньги всё равно придут.
Подтверждение — только webhook.
Не стройте поллинг вместо webhook. Запрос статуса платежа существует для восстановления состояния, когда уведомление не дошло, а не как основной канал. Опрос по каждому заказу раз в секунду создаёт нагрузку и всё равно проигрывает webhook по задержке.
Сделайте обработчик идемпотентным. Уведомление о переходе в succeeded может прийти дважды —
это штатное поведение при повторе после сетевого таймаута.
Проверяйте подпись. Раз подтверждение оплаты приходит по сети, а не от плательщика, оно и есть единственное основание отгрузить товар — значит, подделав его, можно получить товар бесплатно. Разбор того, как проверять подпись webhook, — отдельной статьёй.
Читайте expires_at из ответа, а не зашивайте константу. У СБП окно 30 минут, но у других
способов оплаты оно другое: у криптовалюты, например, час, потому что перевод должен успеть
подтвердиться сетью. Значение приходит в ответе на создание платежа.
В takemypay это устроено так же: HMAC-SHA256 на теле, защита от replay, ретраи до 2xx по расписанию. Ключ стартует в тестовом режиме, поэтому всю интеграцию можно собрать на симулированных платежах и не ждать активации.
Открыть документацию →Когда СБП не подходит
Плательщику нужен российский банк, подключённый к СБП, и его приложение под рукой. Для аудитории за пределами России это не работает — там нужны карты или криптовалюта. Поэтому способ оплаты и не задаётся в запросе на создание: вы создаёте платёж, а плательщик выбирает то, чем реально может заплатить.
Как выглядит запрос на создание — в разделе Создание платежа.
Частые вопросы
Нужен ли плательщику QR-код, если он платит с телефона?
Нет. На телефоне вместо сканирования работает переход по ссылке, которая открывает приложение банка сразу с заполненным платежом. QR нужен, когда страницу оплаты смотрят с компьютера, а платят с телефона.
Через сколько приходят деньги по СБП?
Сам перевод исполняется почти мгновенно — в отличие от карточной операции, которая сначала холдируется. Но статус на вашей стороне меняется не в тот же миг: подтверждение приходит опросом процессора, обычно за секунды.
Есть ли по СБП оспаривания?
В привычном карточном виде нет: СБП — это перевод, а не карточная операция, и механизма chargeback здесь не существует. Возврат возможен, но только по вашей инициативе. Для продавца это главное экономическое отличие от карт.
Можно ли считать подтверждением возврат плательщика на return_url?
Нет. Плательщик может закрыть вкладку сразу после подтверждения в приложении банка, и деньги всё равно придут; и наоборот — вернуться на сайт, ничего не подтвердив. Единственное подтверждение оплаты — webhook.
Что делать, если webhook не дошёл?
Запросить статус платежа через API. Это канал восстановления состояния, а не замена уведомлениям: опрос по каждому заказу раз в секунду создаёт нагрузку и всё равно проигрывает webhook по задержке.
Сколько живёт платёж по СБП?
Окно — 30 минут, но зашивать его константой нельзя: у других способов оно другое, у криптовалюты,
например, час. Значение приходит в expires_at в ответе на создание платежа. И платёж, который
процессор уже начал проводить, нельзя закрывать по таймауту без финального опроса — иначе поздняя
оплата потеряется.
takemypay — платёжный шлюз для тех, кому не дали эквайринг. СБП, карты Мир, Visa/Mastercard и USDT по одному API, комиссия 18%, выплаты в USDT TRC20 от $100. Регистрация — по ссылке из письма, ключ сразу в тестовом режиме. Вопросы — в поддержку.
Получить ключ →Читать дальше
· 6мин чтения
Комиссия, конвертация и выплаты: сколько стоит приём платежей через шлюз
Как из суммы платежа получается сумма на балансе: комиссия 18% с gross, кто её платит, конвертация по курсу ЦБ с наценкой, порог выплаты и сбор за перевод.
· 5мин чтения
Банк отказал в эквайринге: почему так происходит и что делать дальше
Разбор типичных причин отказа в подключении интернет-эквайринга и работающие способы принимать оплату, пока вопрос с банком не решён.
· 5мин чтения
Как проверить подпись webhook: HMAC-SHA256 на практике
Зачем подписывают уведомления о платежах, как устроена подпись HMAC-SHA256, четыре ошибки, из-за которых она не сходится, и защита от повторной отправки.