Оплата по QR через Систему быстрых платежей (СБП) — популярный безналичный способ на кассе: покупатель сканирует динамический QR, деньги мгновенно уходят продавцу, а чек закрывается по подтверждению банка. Разберём архитектуру платёжной интеграции, генерацию QR, отслеживание статуса и привязку платежа к розничной продаже.
Как устроена оплата по QR
QR-оплата через СБП — это трёхсторонний процесс: касса формирует запрос на оплату, банк-эквайер генерирует QR и проводит платёж, покупатель подтверждает его в своём банковском приложении. Есть два типа QR:
| Тип QR | Особенности |
|---|---|
| Динамический | Генерируется на конкретную сумму и заказ, оплата в один тап |
| Статический | Один QR на точку, покупатель вводит сумму вручную |
Для кассы нужен динамический QR: он привязан к сумме чека и конкретному платежу, что позволяет автоматически сопоставить оплату с продажей. Статический подходит скорее для приёма произвольных платежей.
Архитектура платёжной интеграции
В связке участвуют касса (POS), сервер интеграции, банк-эквайер и МойСклад. Сервер интеграции — оркестратор: он инициирует платёж в банке и синхронизирует результат с учётной системой.
- касса запрашивает оплату на сумму чека;
- сервер интеграции создаёт платёж у эквайера и получает QR (ссылку/изображение);
- QR показывается покупателю, тот оплачивает в банковском приложении;
- банк уведомляет о статусе, интеграция закрывает продажу в МойСклад.
Для записи продажи используется JSON API 1.2: создаётся retaildemand с признаком безналичной оплаты. Авторизация — по access_token аккаунта, как и в остальном розничном контуре.
Генерация динамического QR
QR формируется у банка-эквайера по данным платежа. Минимальный набор параметров запроса:
- сумма — в копейках, строго равна итогу чека;
- идентификатор заказа — ваш уникальный номер платежа для сверки;
- назначение — описание платежа;
- срок жизни QR — тайм-аут, после которого QR становится недействительным.
В ответ приходит qrId и payload — строка СБП вида https://qr.nspk.ru/..., которую касса кодирует в изображение QR.
Отслеживание статуса платежа
После показа QR нужно узнать, оплачен ли он. Есть два подхода, и надёжнее использовать оба:
| Механизм | Когда применять |
|---|---|
| Вебхук | Основной канал: банк присылает статус сразу после оплаты |
| Поллинг | Страховка: касса опрашивает статус по qrId с интервалом |
Типичные статусы платежа:
CREATED— QR сгенерирован, ожидает оплаты;CONFIRMED/ACCEPTED— деньги получены, можно закрывать чек;REJECTED/EXPIRED— платёж не прошёл, чек не закрываем.
Закрывайте продажу только по подтверждённому статусу. Показ QR — не гарантия оплаты; кассир не должен отпускать товар до подтверждения от банка.
Привязка платежа к продаже и сверка
Каждый QR-платёж должен однозначно сопоставляться с чеком. Для этого связывайте свой идентификатор платежа с продажей в МойСклад.
- храните пару «qrId ↔ retaildemand» на сервере интеграции;
- при подтверждении фиксируйте безналичную оплату в чеке;
- ежедневно сверяйте свои платежи с реестром эквайера.
Сверка (реконсиляция) ловит расхождения: платёж прошёл в банке, но чек не закрылся из-за сбоя, или наоборот. Автоматический отчёт по несведённым платежам экономит часы ручного разбора.
retailsalesreturn в МойСклад. Частичный возврат должен уменьшать и учётную продажу, и сумму к возврату в банке.QR-оплата на сайте и в заказах
QR через СБП работает не только на кассе, но и в онлайн-заказах. На сайте (например, магазин на 1С-Битрикс, связанный с МойСклад) покупатель видит QR прямо на странице оплаты и платит из банковского приложения.
- заказ на сайте создаёт покупательский заказ (
customerorder) в МойСклад; - сервер генерирует динамический QR на сумму заказа;
- по подтверждению платежа заказ переводится в статус «оплачен», создаётся входящий платёж;
- статус оплаты отражается и на сайте, и в учётной системе.
Отличие от кассы — в источнике суммы: не итог чека, а сумма заказа. Но требования те же: динамический QR, подтверждённый статус, идемпотентность и сверка. Для near-real-time обновления статуса на сайте удобно использовать вебхуки МойСклад по платежам и заказам.
Надёжность и 54-ФЗ
Платёжная интеграция обязана быть устойчивой к сбоям сети и дублям уведомлений. Ключевые правила:
- Идемпотентность вебхуков — одно уведомление банка может прийти дважды, обрабатывайте по
qrIdбез повторного закрытия чека; - Тайм-ауты — если статус не пришёл, поллинг добирает его; не «зависайте» на вебхуке;
- Идемпотентная фискализация — фискальный чек по 54-ФЗ пробивается один раз, с признаком «безналичными».
Безналичная оплата по QR тоже требует фискального чека. Здесь платёжный контур смыкается с Фискальным API: после подтверждения оплаты чек фискализируется на ККТ с корректным способом расчёта.
Итог
Оплата по QR через СБП — это генерация динамического QR на сумму чека, ожидание подтверждённого статуса (вебхук + поллинг), закрытие продажи в МойСклад и ежедневная сверка с эквайером. Критично: не отпускать товар до подтверждения, аннулировать QR при изменении суммы и держать идемпотентность на вебхуках и фискализации.
Мы разрабатываем платёжные интеграции для касс и сайтов на 1С-Битрикс: генерацию QR СБП, обработку статусов, привязку к заказам МойСклад и автоматическую сверку. Спроектируем отказоустойчивый платёжный контур, который не теряет и не задваивает оплаты.
Частые вопросы
Какой QR нужен для кассы — статический или динамический?
Динамический: он привязан к сумме чека и конкретному платежу, что позволяет автоматически сопоставить оплату с продажей. Статический подходит для приёма произвольных сумм.
Где реально проходит платёж?
На стороне банка-эквайера через СБП. Задача интеграции — сгенерировать QR на сумму чека, дождаться статуса и корректно закрыть розничную продажу в МойСклад.
Когда можно закрывать чек?
Только по подтверждённому статусу платежа от банка (например, CONFIRMED). Показ QR не гарантирует оплату, поэтому товар нельзя отпускать до подтверждения.
Что делать, если сумма чека изменилась после генерации QR?
Аннулировать старый динамический QR и сгенерировать новый на актуальную сумму. Иначе покупатель оплатит не ту сумму, что была в чеке.
Как надёжно узнавать статус платежа?
Использовать вебхук как основной канал и поллинг по qrId как страховку. Двойной механизм защищает от потери уведомления при сбоях сети.
Как сопоставить платёж с продажей?
Хранить связку qrId и retaildemand на сервере интеграции, фиксировать безналичную оплату в чеке при подтверждении и ежедневно сверять платежи с реестром эквайера.
Как оформить возврат по QR?
Возврат делается операцией refund у эквайера и retailsalesreturn в МойСклад. При частичном возврате уменьшается и учётная продажа, и сумма к возврату в банке.
Нужен ли фискальный чек при оплате по QR?
Да. Безналичная оплата по 54-ФЗ требует фискального чека с признаком расчёта безналичными. Фискализация выполняется один раз после подтверждения оплаты.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.