
Клиент нажал «Оплатить», деньги списались, а статус заказа не обновился. Вебхук не пришёл, пришёл трижды или пришёл с несовпадающей подписью. Покупатель ждёт подтверждения, менеджер не видит заказа, а вы разбираетесь, что пошло не так.
В документации платёжных сервисов обычно описывают только идеальный сценарий. А что делать, когда запросы дублируются, клиент закрыл страницу до редиректа или платёж завис в статусе PENDING? В статье — об архитектуре приёма платежей: от создания заказа до фискального чека. С примерами кода, схемами и разбором граничных случаев, которые не описаны в документации.
Интеграция оплаты на сайте для интернет-магазина через API или CMS-модуль — задача с чёткой документацией: создать заказ, отправить запрос, обработать вебхук, обновить статус. С точки зрения разработки — ряд штатных HTTP-вызовов. Но в документации провайдеров редко описывают, что делать, когда вебхук приходит трижды, клиент закрыл страницу до редиректа, а подпись уведомления не совпадает с ожидаемой.
В статье — пошаговый разбор архитектуры приёма платежей в интернет-магазине: от создания заказа до фискального чека. Рассматриваем, как хранить order_id и payment_id, почему проверка подписи — единственная защита от поддельных уведомлений и как спроектировать обработку вебхука так, чтобы повторные запросы не обновляли статус дважды. С примерами кода, схемами и разбором граничных сценариев, о которых молчит документация.
Как выстроен процесс оплаты на сайте
Процесс оплаты на сайте для интернет-магазина — это последовательность взаимодействий между сайтом, платёжным сервисом и системами учёта, где происходит обмен данными. Ошибки в процессе приводят к сбоям: потерянным заказам, двойным списаниям, отсутствию подтверждения для клиента.
Что происходит после нажатия кнопки «Оплатить»
Процесс выглядит так:
Создание заказа. Когда покупатель нажимает кнопку «Оплатить», бэкенд интернет-магазина обрабатывает POST-запрос с данными формы. На основе них ORM создаёт запись в БД, где фиксирует состав заказа, сумму и данные покупателя. Кроме того, бэкенд генерирует уникальный идентификатор заказа (order_id) на уровне базы данных. Этот идентификатор передаётся во все последующие запросы к платёжному сервису, чтобы связать платёж с конкретным заказом.
Создание платежа. Бэкенд сайта формирует HTTP-запрос к API платёжного сервиса, с которым заключён договор, и передаёт сумму, идентификатор заказа, описание и получателя. Сервис создаёт платёж со своим идентификатором (payment_id) и возвращает ссылку на платёжную страницу или открывает виджет. Платёжный сервис может быть любым, в нашем примере это инструмент от Монеты.
Переход на платёжную страницу. Покупатель вводит данные карты или выбирает СБП на странице платёжного сервиса.
Авторизация. Платёжный сервис отправляет запрос банку-эквайеру, тот — платёжной системе (Visa/Mastercard/МИР) и банку-эмитенту. Банк-эмитент проверяет карту и блокирует сумму.
Подтверждение. После того как банк-эмитент проверил карту, он возвращает код авторизации (approval code) — это означает, что платёж одобрен. Платёжный сервис получает этот код и в ответ на запрос авторизации отправляет команду на финальное списание средств (capture). Если используется двухстадийная модель, деньги сначала блокируются (холд), а списание происходит после команды от мерчанта. Если одностадийная, средства списываются сразу. После получения подтверждения от банка-эквайера платёжный сервис меняет статус транзакции на SUCCESS и готовит данные для отправки вебхук-уведомления на сайт мерчанта. Подтверждение может включать дополнительные данные: сумму списания, валюту, номер авторизации, временную метку. Все эти параметры сохраняются в логах платёжного сервиса для последующей сверки.
Отправка вебхука. Платёжный сервис отправляет на указанный вами URL уведомление о том, что платёж успешно завершён. Например, https://ваш-сайт.ru/api/payment-webhook.
Обновление заказа. Ваш сайт принимает вебхук и меняет статус заказа с «Ожидает оплаты» на «Оплачен».
Отправка чека. Платёжный сервис передаёт данные о платеже (номенклатуру товаров, сумму, ставку НДС, систему налогообложения) в подключённую онлайн-кассу. Касса формирует фискальный чек, передаёт его в ОФД, а оттуда — в ФНС. Чек отправляется покупателю на email или по СМС.
Почему не стоит хранить данные карт на своём сервере
PCI DSS — это международный стандарт безопасности, разработанный платёжными системами Visa, Mastercard и МИР. Он устанавливает правила работы с данными банковских карт и обязателен для всех компаний, принимающих карточные платежи.
Требования PCI DSS зависят от двух факторов: объёма транзакций и способа приёма платежей.
По объёму транзакций:
Если компания обрабатывает до 1 миллиона карточных транзакций в год, она не обязана проходить полноценный QSA-аудит. Вместо этого необходимо подтверждать соответствие стандарту через заполнение листов самооценки (SAQ, Self-Assessment Questionnaire).
Если объём превышает 1 миллион транзакций в год, требования становятся существенно строже. Компания обязана проходить внешний аудит с привлечением сертифицированного аудитора (QSA, Qualified Security Assessor). Он проверяет инфраструктуру, процессы и системы на соответствие PCI DSS: от защиты сетей до правил работы с данными карт.
По способу приёма платежей. Тип анкеты SAQ зависит от того, как именно вы принимаете онлайн-платежи для интернет-магазина:
используете готовую платёжную страницу провайдера (редирект) — минимальный набор требований;
встраиваете виджет (iframe) с обработкой на стороне провайдера — также минимальные требования;
собираете данные карт на своём сайте и передаёте их через API провайдера — требования выше;
храните данные карт на своём сервере — требования максимальные, фактически полная сертификация.
Подробная схема для выбора листа самооценки опубликована на сайте Национальной системы платёжных карт.
Что это значит для бизнеса:
Самостоятельная сертификация — сложный и дорогой процесс. QSA-аудит требует выстроить внутренние процессы безопасности.
Штрафы за несоответствие. Если ваш сайт обрабатывает данные карт без сертификации, платёжные системы могут наложить штрафы — от 50 тысяч долларов ежемесячно до устранения несоответствия.
Риск утечки данных. Хранение карточных данных на вашем сервере — это прямая угроза: при взломе сайта злоумышленники получат доступ к номерам карт клиентов.
На практике компании стремятся минимизировать зону ответственности за обработку карточных данных, передавая её платёжному провайдеру и оставаясь в более простом контуре соответствия через SAQ. При работе через платёжный сервис данные карт не проходят через сервер магазина, и тогда не требуется проходить полную сертификацию PCI DSS.
Технические варианты реализации и уровень требований PCI DSS:
Способ обработки карт | Уровень требований PCI DSS | Риски |
Платёжная страница провайдера (редирект) | Минимальный (SAQ) | Минимальные |
Встроенный виджет (iframe) с обработкой на стороне провайдера | Минимальный (SAQ) | Минимальные |
Сбор данных на своём сайте с передачей через API провайдера | Высокий | Высокие |
Хранение данных карт на своём сервере | Максимальный (QSA-аудит) | Критические |
Прохождение QSA-аудита — это сложный и дорогой процесс, поэтому большинство интернет-магазинов выбирают работу через платёжного провайдера и остаются в контуре SAQ. Это позволяет принимать карты без необходимости проходить полную сертификацию и брать на себя ответственность за хранение данных карт.
Чем отличается приём платежей от учёта заказов
Приём платежей и учёт заказов — это два разных процесса. Разберём каждый из них.
Приём платежей — это финансовая операция: деньги списываются с карты покупателя и зачисляются на счёт продавца. Техническую сторону процесса: авторизацию, обработку и проведение платежа — обеспечивают платёжный сервис и банки. Однако успешное проведение платежа не гарантирует, что заказ в системе магазина автоматически обновится: для этого требуется синхронизация статусов.
Если ваш сайт не получит уведомление от платёжного сервиса (вебхук) или не обработает его корректно, заказ останется в статусе «Ожидает оплаты», хотя деньги уже списаны. Клиент будет ждать товар, а вы — не видеть оплаченного заказа.
Учёт заказов — это логистическая часть: заказ появляется в CRM или CMS, ему присваивается статус «Ожидает оплаты» или «Новый». После получения подтверждения об оплате система автоматически меняет статус на «Оплачен» и запускает триггеры для передачи заказа на склад (в WMS или через API) и в службу доставки.
Например, после обновления статуса может отправляться запрос в 1С или ERP-систему для резервирования товара и формирования задания на сборку. Это внутренняя логика магазина, которая не зависит от платёжного сервиса, но использует его уведомления как триггер для запуска процессов.
Почему важно синхронизировать статусы оплаты с CRM, CMS, складом и доставкой
Когда проходит онлайн-оплата для интернет-магазина, статус заказа должен обновляться мгновенно во всех системах: в интерфейсе заказа у клиента, CRM, на складе и в службе доставки. Если платформы не синхронизируются между собой:
Менеджеры тратят время на ручную сверку. Если статус не обновился в CRM, менеджер не знает, что заказ оплачен, и не начинает его обработку.
Склад не видит заказа к сборке. Если статус не передан на склад, товар не резервируется и не отгружается.
Клиент не получает уведомления. Если статус не обновлён в интерфейсе заказа, клиент не видит, что его заказ обрабатывается, и начинает звонить в поддержку.
Служба доставки не получает адрес. Если статус не передан в логистическую систему, курьер не получает заказ к отправке.
Как это реализовать. Настройте вебхуки (callbacks) от платёжного сервиса: после успешной оплаты сервис отправляет уведомление в систему. Подробнее о вебхуках расскажем ниже. Ваш сайт обрабатывает это уведомление и меняет статус заказа в CMS, а CMS, в свою очередь, передаёт обновление в CRM, на склад и в службу доставки через API или интеграционные модули.
При получении вебхук-уведомления от платёжного сервиса вы можете обрабатывать его асинхронно: не обновлять статус заказа и отправлять данные в CRM и на склад синхронно, а ставить задачу в очередь (например, RabbitMQ, Redis или Amazon SQS). Это означает, что вы сразу подтверждаете получение вебхука, а обработка обновления статуса и вызова API CRM выполняется отдельным воркером.
Как это работает:
При получении вебхука бэкенд публикует сообщение в очередь (например, в Redis через LPUSH или в RabbitMQ через basic_publish). Сообщение содержит payment_id, order_id, статус и другие данные, необходимые для обработки.
Отдельный воркер (процесс, который слушает очередь) забирает сообщение, обновляет статус заказа в базе данных, отправляет запросы в CRM и склад, а затем подтверждает обработку (в RabbitMQ — ack, в Redis — удаляет из очереди).
Если какая-то система временно недоступна (например, CRM не отвечает), воркер может повторить попытку через заданный интервал (retry) или вернуть сообщение в очередь. Это гарантирует, что уведомление не потеряется.
Пример сценария. Покупатель оплатил заказ. Платёжный сервис отправляет вебхук на https://ваш-сайт/api/payment-webhook. Ваш бэкенд принимает уведомление, проверяет подпись, чтобы убедиться, что запрос от сервиса, а не от злоумышленника, обновляет статус заказа в базе данных и отправляет запрос в CRM через REST API. CRM меняет статус сделки, а затем через интеграционный модуль отправляет задание на склад в системе WMS.
В запросе на создание платежа вы передаёте свой order_id. В ответ платёжный сервис возвращает свой payment_id. Сохраняйте оба идентификатора. При обработке вебхук-уведомлений используйте payment_id для поиска заказа — это надёжнее, чем полагаться на order_id, переданный в уведомлении. Так вы исключите ошибки при повторных уведомлениях и сможете точно сопоставить платёж с заказом.
Комментарий команды Монеты
В следующем разделе разберём, какие способы оплаты стоит подключать интернет-магазину в первую очередь.
Онлайн-оплата для интернет-магазинов: какие способы можно подключить
От набора способов оплаты напрямую зависит конверсия. Если пользователь не видит привычного ему способа, он может отложить покупку или передумать: в момент оформления у него не будет стимула искать карту. Это не всегда приводит к уходу, но повышает риск отказа от покупки. Вместо того чтобы подключать все возможные методы, стоит выбрать те, что соответствуют вашей целевой аудитории, среднему чеку и модели продаж. Ниже кратко разберём, с помощью чего и как принимать платежи на сайте, подробнее читайте в нашем блоге.
Банковские карты
Карты — универсальный способ оплаты, который занимает бо́льшую часть рынка. В 2026 году 73% россиян оплачивают покупки именно картой.
Как это технически реализовано. Для приёма карт на сайте требуется эквайринг — услуга банка-эквайера, который проводит транзакции через платёжные системы. Бизнес может подключить онлайн-оплату на сайт напрямую через банк или платёжный сервис.
Кроме того, с помощью платёжного сервиса можно подключить сразу несколько способов оплаты через один договор.
Кому подключать. Всем, кто принимает онлайн-платежи, так как доля оплат картами остаётся на высоком уровне.
СБП
СБП позволяет клиенту оплачивать покупки в пару кликов через мобильное приложение банка. Покупателю не нужно вводить данные карты — достаточно подтвердить платёж.
Постепенно этот способ оплаты набирает популярность: в 2026 году 39% клиентов отмечают, что стали регулярно использовать QR-код при оплате покупок. По данным ЦБ РФ, каждый второй пользуется оплатой товаров и услуг с помощью СБП.
Комиссия в 3–5 раз ниже, чем у банковского эквайринга, а деньги зачисляются на счёт продавца сразу. Если для СБП ставка комиссии — 0,4–0,7%, то для оплаты картой — это 3–5% в среднем с учётом появившегося в 2026 году НДС.
Кому подключать. Если доля мобильного трафика растёт, стоит подключить СБП. Кроме того, СБП понадобится бизнесу с частыми небольшими платежами: так комиссия ниже, а зачисление проходит мгновенно.
У части ретейлеров он уже выведен на первое место в платёжной форме: например, в «ЛЭТУАЛЬ» СБП стоит по умолчанию. Это показывает, что для многих покупателей СБП становится привычным способом, а не альтернативой картам.
Pay-сервисы
Это кнопки оплаты от крупных банков: SberPay, T-Pay, Alfa Pay. Покупатель выбирает знакомый логотип — система переводит его в приложение банка, где он подтверждает платёж без ввода реквизитов. Данные карты уже привязаны в банковском приложении, поэтому оплата занимает 5–10 секунд. Для клиента это способ сохранить кэшбэк, которого при оплате через СБП не будет. Для бизнеса — дополнительный канал, повышающий конверсию среди пользователей конкретных банков.
Кому подключать. Магазинам с высокой долей клиентов Сбера, «Т-Банка» или «Альфа-Банка». Особенно эффективны для повторных покупок и мобильного трафика. Если ваша аудитория активно пользуется приложениями этих банков, Pay-сервисы повышают конверсию и удерживают клиентов, которые хотят платить быстро и получать кэшбэк.
Кто и как участвует в обработке платежа на сайте интернет-магазина
В процессе приёма онлайн-платежей на сайте участвуют несколько систем — от платёжного сервиса до оператора фискальных данных. Понимание ролей каждого участника помогает правильно настроить интеграцию и избежать ошибок, когда платёж прошёл, а статус заказа не обновился или чек не ушёл клиенту.
Интернет-магазин как мерчант
Роль. Инициатор платежа и получатель средств.
Сайт или приложение, на котором покупатель выбирает товары и инициирует оплату. Мерчант создаёт заказ, передаёт платёжному сервису данные о сумме и идентификаторе заказа, а затем обрабатывает уведомления об успешной оплате и меняет статус заказа в своей системе. Так магазин разбирается, как принимать оплату на сайте, и подключает нужные способы.
Технический аспект. Мерчант хранит order_id (свой идентификатор заказа) и получает от платёжного сервиса payment_id. Он обязан правильно обрабатывать вебхук-уведомления и проверять цифровую подпись каждого запроса.
Покупатель
Роль. Инициатор платежа, владелец карты или счёта.
Покупатель выбирает товары, переходит к оплате, вводит данные карты или подтверждает платёж в приложении банка (для СБП и Pay-сервисов). Именно он предоставляет платёжные данные и даёт согласие на списание средств.
Технический аспект. Взаимодействие с платёжным сервисом происходит через браузер или мобильное приложение. Покупатель не общается напрямую с сервером магазина после момента передачи данных на платёжную страницу провайдера.
Платёжный провайдер или сервис
Роль. Технологический посредник, который связывает интернет-магазин с банками и платёжными системами.
Платёжный провайдер, например Монета, принимает запрос на оплату от сайта, создаёт платёж, направляет его в банк-эквайер, обрабатывает ответ банка и отправляет уведомление мерчанту. Кроме того, он предоставляет платёжную страницу или виджет, где покупатель вводит данные карты, и управляет токенизацией.
Основные функции:
Приём карт на странице без хранения платёжных данных на стороне магазина.
Маршрутизация платежа — автоматический выбор банка-эквайера для каждой транзакции. Например, если один банк недоступен или даёт высокий процент отказов, платёж направляется через другой. Это повышает надёжность и конверсию.
Возврат статуса платежа: например, SUCCESS, FAIL, PENDING.
Отправка вебхук-уведомлений на сайт мерчанта.
Токенизация карт для повторных оплат.
Поддержка рекуррентных платежей, холдирования, сплитования.
Технический аспект. Провайдер предоставляет API для создания платежей, SDK для интеграции и документацию по обработке уведомлений. Он обязан соответствовать стандарту PCI DSS и обеспечивать безопасность данных карт.
Банк-эквайер
Роль. Банк, который проводит транзакции по картам и зачисляет средства на счёт продавца.
В схеме через платёжный сервис продавец не взаимодействует с банком-эквайером напрямую. Все операции: авторизация, обработка платежей, зачисление средств — происходят через платёжный сервис, у которого уже есть договоры с несколькими банками-эквайерами. Продавцу не нужно заключать отдельный договор с банком, настраивать техническую интеграцию или разбираться в тарифах каждого эквайера.
Функции:
принимает запросы на авторизацию от платёжного сервиса;
передаёт запросы в платёжные системы (Visa/Mastercard/МИР);
получает ответ от банка-эмитента;
после подтверждения транзакции зачисляет средства на счёт продавца, указанный им при регистрации в платёжном сервисе.
Все эти действия происходят без участия продавца. Единственное, что требуется от бизнеса, — подключить платёжный сервис и указать реквизиты для зачисления. Остальное сервис делает сам: выбирает банк с наилучшими условиями, переключает транзакции при сбоях, обеспечивает соблюдение требований ЦБ РФ и платёжных систем.
Банк-эмитент
Роль. Банк, который выпустил карту покупателя.
Банк-эмитент проверяет достаточность средств на карте, блокирует сумму при авторизации и списывает её при подтверждении. Он также может запросить дополнительную аутентификацию через 3D Secure.
Функции:
проверка карты на действительность и отсутствие блокировок;
блокировка суммы при авторизации;
снятие блокировки при отмене или списание при подтверждении;
возврат средств при отмене операции (void) или возврате (refund).
Оператор фискальных данных
Роль. Оператор, который передаёт фискальные чеки в налоговую.
ОФД — это организация, аккредитованная ФНС, которая принимает фискальные данные от онлайн-касс и передаёт информацию в налоговую. Кроме того, ОФД отправляет чек покупателю (на email или по СМС).
CMS, CRM и учётные системы
Роль. Системы, которые управляют заказами, клиентской базой, складом и бухгалтерией.
После успешной оплаты статус заказа должен меняться в CMS и CRM, а заказ — отправляться на склад и в службу доставки. Без синхронизации менеджеры тратят время на ручную сверку, а клиент не видит статуса заказа.
Технический аспект. Интеграция с учётными системами строится на вебхук-уведомлениях. При получении уведомления об оплате бэкенд сайта должен не только обновить статус заказа, но и отправить данные в CRM (через REST API или очередь задач), а затем в складскую систему для запуска сборки и отправки заказа.
Чтобы вам было проще понять суть взаимодействия между участниками операции, мы собрали подробную блок-схему:

Как технически работает онлайн-оплата на сайте для интернет-магазина
В этом разделе разберём по шагам, что происходит на каждом этапе оплаты и как это работает.
Создание заказа
Что происходит. Покупатель заполняет корзину, переходит к оформлению, вводит данные для доставки и нажимает кнопку «Оформить заказ». Бэкенд интернет-магазина создаёт запись заказа в базе данных со статусом pending — «Ожидает оплаты».
Как работает:
Интернет-магазин генерирует уникальный идентификатор заказа (order_id). Он используется для связки заказа с платежом и для обратных вызовов (вебхуков).
В базе фиксируются: состав заказа, сумма, валюта, данные покупателя (email, телефон, адрес доставки).
Статус заказа: pending или waiting_for_payment.
Что важно. order_id должен быть уникальным в рамках вашей системы. Не используйте автоинкрементные ID без проверки коллизий.
Создание платежа
Что происходит. Бэкенд магазина отправляет запрос в платёжный сервис, например от Монеты, с параметрами платежа: сумма, валюта, описание, order_id и реквизиты мерчанта.
Как работает:
запрос отправляется через REST API платёжного сервиса;
в ответе приходит payment_id — идентификатор платежа в системе провайдера;
сохраняете payment_id в базе, привязав его к order_id.
Схематичный пример запроса:
POST /api/v1/payment/create { "amount": 1000.00, "currency": "RUB", "order_id": "ORD-12345", "description": "Заказ №ORD-12345 в интернет-магазине", "customer": { "email": "customer@example.com", "phone": "+79001234567" }, "success_url": "https://example.com/success", "fail_url": "https://example.com/fail" }
Что важно. Убедитесь, что сумма передаётся с правильной точностью в два знака после запятой. Некорректный формат — частая причина ошибок.
Переход на платёжную форму или открытие виджета
Что происходит. Платёжный сервис возвращает ссылку на платёжную страницу. Сайт перенаправляет покупателя на неё или открывает платёжный виджет внутри сайта магазина, если используется встроенный SDK.
Как работает:
для редиректа: 302 Redirect на URL, полученный от провайдера;
для виджета: JavaScript-скрипт инициализирует платёжную форму внутри контейнера на странице магазина.
Покупатель видит страницу с выбором способов оплаты и полями для ввода данных.
Что важно. Платёжная страница должна загружаться не дольше 2–3 секунд. Задержки на этом этапе увеличивают вероятность того, что покупатель закроет страницу.
Авторизация
Что происходит. Покупатель вводит данные карты или выбирает другой способ оплаты и подтверждает её. Платёжный сервис отправляет запрос банку-эквайеру, тот — платёжной системе (Visa/Mastercard/МИР), а затем банку-эмитенту, который проверяет карту и блокирует сумму.
Как работает:
время авторизации зависит от банка и типа карты, обычно 2–3 секунды;
при успехе возвращается код авторизации;
при ошибке — код отказа с пояснением, например недостаточно средств, неверный CVV-код, карта заблокирована и т. д.
Покупатель видит процесс подтверждения — например, запрос 3D Secure, где требуется код из СМС. Если это первая оплата картой, банк может запросить дополнительную аутентификацию.
Что важно. Если платёж требует 3D Secure, платёжный сервис должен корректно обрабатывать этот сценарий и уведомлять вас о результате (успех/отказ).
Подтверждение
Что происходит. Банк-эмитент возвращает ответ: Approved (одобрено) или Declined (отклонено). В случае одобрения платёжный сервис подтверждает списание средств.
Как работает:
платёж переходит из статуса pending в successful (на стороне провайдера);
если используется двухстадийная модель (холд + подтверждение), авторизация и подтверждение могут быть разделены во времени;
в случае отклонения платёж покажет статус failed.
Важно. При двухстадийной модели (холд) средства блокируются, но не списываются до вашего подтверждения (capture). Это полезно для сценариев с бронированием.
Отправка вебхука
Что происходит. После подтверждения платежа платёжный сервис отправляет HTTP-запрос (вебхук) на заранее указанный URL вашего сайта. В запросе содержатся данные о платеже: сумма, payment_id, order_id, статус и подпись для проверки.
Платёжный сервис подписывает каждое уведомление с использованием HMAC-SHA256 или аналогичного алгоритма. Подпись вычисляется на основе тела запроса и секретного ключа, известного только вам и провайдеру.
Как работает:
URL для вебхука указывается в настройках мерчанта в личном кабинете провайдера;
платёжный сервис может отправлять несколько попыток при ошибке получения (Retry);
вебхук содержит подпись (HMAC), которую нужно проверить, чтобы убедиться, что запрос пришёл именно от провайдера.
Как схематично может выглядеть пример вебхук-запроса:
POST /api/payment-webhook { "payment_id": "PAY-67890", "order_id": "ORD-12345", "amount": 1000.00, "status": "success", "signature": "abc123def456..." }
Помните о том, что вебхук — асинхронный. Не полагайтесь на синхронный ответ от платёжной страницы при обновлении статуса заказа. Клиент может закрыть страницу до завершения редиректа.
Комментарий команды Монеты
Вебхук-уведомления приходят на ваш сервер из внешней сети. Без проверки подписи поддельный запрос может изменить статус заказа на «Оплачен». Единственный способ защититься — проверять цифровую подпись каждого уведомления.
Как проверить. Ваш бэкенд должен вычислить подпись по тому же правилу и сравнить с той, что пришла в запросе. Если совпадают — уведомление легитимно. Алгоритм и формат подписи описаны в документации провайдера.
Храните секретный ключ в переменных окружения. Добавьте middleware, который проверяет подпись для всех вебхук-запросов до их обработки. Это исключит риск поддельных уведомлений.
На практике в документации провайдера должен быть точно описан формат подписи и порядок её вычисления. Например, в PayAnyWay подпись формируется по алгоритму, описанному в документации Merchant API. На практике мы рекомендуем вынести проверку подписи в отдельный middleware — чтобы все вебхук-запросы проходили через него до попадания в бизнес-логику. Так вы точно не пропустите поддельное уведомление.
Комментарий команды Монеты
Обновление заказа
Что происходит. Ваш бэкенд получает вебхук, проверяет подпись, ищет заказ по order_id и обновляет его статус с pending на paid.
Как работает:
на этом этапе также может быть запущен триггер для отправки заказа в CRM, на склад и в службу доставки;
обновление статуса должно быть атомарным, чтобы избежать двойной обработки одного вебхука.
Что важно. Обрабатывайте идемпотентность. Если вебхук придёт несколько раз (например, из-за сетевого сбоя), обновление статуса не должно выполняться дважды. Используйте проверку текущего статуса: если заказ уже paid, повторная обработка не требуется.
Отправка чека
Что происходит. Платёжный сервис или подключённая онлайн-касса формирует фискальный чек и отправляет его покупателю на email или по СМС, указанные при заказе.
Как работает:
чек должен содержать наименование товара, количество, цену, ставку НДС и систему налогообложения магазина;
если данные переданы корректно, ОФД фискализирует чек, передаёт его в ФНС и возвращает фискальный признак;
чек отправляется клиенту в течение нескольких секунд после подтверждения оплаты.
Если вы передаёте неполные данные, например без наименования товара, чек может быть отклонён ОФД. Проверяйте запрос к платёжному сервису — в нём должны передаваться все обязательные реквизиты для фискализации.
Комментарий команды Монеты
Основная задача интеграции — правильно обработать вебхук. Если сайт не получает уведомление или не проверяет подпись, заказ остаётся в статусе pending. Клиент платит, но вы не видите оплаты. Настройка вебхуков и обработка повторных уведомлений — самый важный этап при внедрении онлайн-оплаты.
В следующем разделе разберём варианты подключения оплаты: виджет, CMS-модуль или API.
Варианты подключения оплаты: платёжный виджет, CMS-модуль или API
Выбор способа интеграции зависит от архитектуры сайта, технических ресурсов и требуемых сценариев. Три основных варианта: платёжный виджет, готовый модуль для CMS и прямая интеграция через API. Рассмотрим их особенности, сильные стороны и ограничения.
Платёжный виджет
Виджет — это JavaScript-компонент, который встраивается на страницу оформления заказа и открывает платёжную форму внутри сайта, без перенаправления на внешнюю страницу провайдера.
Как это работает:
На странице размещается контейнер (div) с указанием data-* атрибутов или вызывается функция инициализации.
При нажатии кнопки «Оплатить» виджет отправляет запрос к платёжному сервису, получает параметры платежа и открывает форму.
Покупатель вводит данные карты или выбирает СБП внутри виджета.
После оплаты виджет закрывается, а на ваш сайт приходит вебхук-уведомление.
Из плюсов — пользователю не нужно покидать сайт, чтобы оплатить покупку, а для интеграции понадобится добавить только несколько строчек кода. Кроме того, дизайн самой формы уже реализован провайдером — ничего придумывать с нуля не придётся.
Минусы. Для внешнего вида формы кастомизация ограничена, а платёж зависит от скрипта — пока тот не запустится, платёж не пройдёт.
Когда и кому подходит. Виджет чаще используют интернет-магазины без сложной логики оплаты и те, кому нужен быстрый запуск без программистов. Например, Монета предоставляет виджет, который можно встроить на сайт и начать принимать оплату в тот же день.
CMS-модуль
Готовый плагин или модуль для популярных систем управления сайтом: WordPress (WooCommerce), 1С-Битрикс, Tilda, Joomla (VirtueMart), OpenCart и других.
Как это работает:
Скачиваете модуль из каталога расширений или маркетплейса CMS.
Устанавливаете архив через админку сайта.
В настройках модуля указываете API-ключи: номер счёта, секретный ключ.
Модуль добавляет платёжную форму на страницу оформления заказа.
После оплаты модуль обрабатывает вебхук и обновляет статус заказа.
Среди плюсов — всё настраивается через интерфейс CMS, пользователь получает сразу готовый функционал с обновлением статусов, фискализацией и возвратами.
Минусы. Сложные сценарии, например холдирование или сплитование, через модуль настроить не получится.
Когда и кому подходит. Большинству магазинов на популярных CMS, которым нужен быстрый запуск без разработчиков. PayAnyWay предоставляет модули для всех популярных CMS, включая WordPress, 1С-Битрикс, Tilda, Joomla, OpenCart и другие. Модули поддерживают карты, СБП.
API-интеграция
Прямая интеграция через API платёжного сервиса. Сайт самостоятельно формирует запросы на создание платежа, обрабатывает ответы и управляет статусами через вебхук.
Как это работает:
Бэкенд магазина отправляет запрос к API провайдера с параметрами платежа (сумма, order_id, описание).
В ответе получает payment_id и ссылку на платёжную страницу или токен для виджета.
Сайт перенаправляет покупателя на страницу оплаты или открывает виджет.
После оплаты провайдер отправляет вебхук на указанный URL.
Бэкенд обрабатывает вебхук, проверяет подпись, обновляет статус заказа, запускает логистику.
Из плюсов — вы можете полностью реализовать и контролировать любые сценарии оплаты: рекуррентные платежи, сплитование, холдирование, кастомные платёжные формы, интеграцию с мобильными приложениями через SDK.
Минусы. Для подключения потребуется помощь разработчиков, чтобы реализовать создание платежей, обработку вебхуков, проверку подписи, управление статусами. В целом API-интеграция занимает больше времени, чем подключение готового CMS-модуля.
Когда и кому использовать. Кастомные сайты, мобильные приложения, сложные сценарии (маркетплейсы, подписки, холдирование, сплитование). Монета предоставляет детальную документацию Merchant API, SDK для мобильных приложений и тестовую среду (sandbox). API поддерживает все расширенные функции: рекуррентные платежи, сохранение карт, сплитование, безопасные сделки, массовые выплаты.
Что лучше выбрать:
Если у вас сайт на популярной CMS и нет программиста, выбирайте готовый модуль. Подключение от одного рабочего дня.
Если есть разработчик, но нет сложных сценариев, виджет будет быстрее и проще.
Если вы строили свой сайт с нуля или нужны сложные сценарии (подписки, сплитование, холдирование, маркетплейс), берите API.
Теперь, когда вы знаете, как подключить онлайн-оплату на сайт, разберёмся, что может пойти не так.
Как не потерять заказ: работа с order_id, payment_id и вебхуками
При интеграции через API корректная обработка платежей и статусов заказов зависит от того, как вы реализовали взаимодействие с платёжным сервисом. Платёжный сервис предоставляет инструменты, но конечная логика: создание платежей, обработка вебхуков, обновление статусов — остаётся на вашей стороне. Ошибки в этой логике (например, неправильная проверка подписи или игнорирование повторных уведомлений) приводят к проблемам с заказами.
Как хранить order_id и payment_id
На этом этапе возникают ошибки у многих интеграций. Что важно:
order_id — ваш внутренний идентификатор заказа. Вы генерируете его сами и передаёте в запросе на создание платежа (например, в Монете это MNT_TRANSACTION_ID).
payment_id — идентификатор платежа в системе провайдера. Вы получаете его в ответе на запрос создания платежа.
Сохраняйте оба идентификатора в базе данных и связывайте их между собой. При получении вебхук-уведомления вы должны найти заказ по payment_id (или по order_id, если провайдер передаёт его в уведомлении). Хранить нужно оба, потому что в вебхуках может прийти только payment_id. Если вы не сохранили его, вы не сможете найти заказ.
При повторных уведомлениях ищите заказ по payment_id, чтобы избежать дублирования.
Комментарий команды Монеты
Приведём пример:
CREATE TABLE orders ( id SERIAL PRIMARY KEY, order_id VARCHAR(255) UNIQUE NOT NULL, -- ваш ID payment_id VARCHAR(255), -- ID от провайдера status VARCHAR(50) DEFAULT 'pending', amount DECIMAL(10,2), -- другие поля );
Почему нужно проверять подпись уведомлений
Вебхук-уведомления приходят на ваш сервер из внешней сети. Любой может отправить запрос на ваш URL с поддельными данными. Чтобы отличить легитимное уведомление от подделки, платёжные сервисы подписывают запросы.
Разберём, как это работает, на примере платёжного сервиса от Монеты.
Подпись (signature) формируется по алгоритму: md5(operation + secret), где operation — это строка с параметрами уведомления, а secret — ваш секретный код. Без проверки подписи вы рискуете:
Сменой статуса заказа по поддельному запросу. Злоумышленник может отправить уведомление об успешной оплате и получить товар бесплатно.
Потерей данных. Если вы не проверяете подпись, вы не можете доверять ни одному уведомлению.
Как обрабатывать повторные уведомления
Платёжные сервисы могут отправлять одно и то же уведомление несколько раз. Причины:
ваш сервер не ответил 200 OK в течение тайм-аута;
сетевая проблема на стороне провайдера;
платёжный сервис повторяет уведомления для гарантии доставки.
Если вы не обрабатываете повторные уведомления корректно, это приведёт к двойному обновлению статуса, повторной отправке чеков и путанице в логистике.
Решение — идемпотентность. Если ваш обработчик вебхуков многократно применяет одно и то же уведомление, это не должно менять состояние системы больше одного раза.
Как это реализовать практически:
Проверка статуса. Перед обновлением заказа проверьте его текущий статус. Если он уже paid, не выполняйте повторные действия (отправку уведомлений, запуск логистики).
Хранение ID уведомления. Если провайдер передаёт уникальный ID уведомления (notification_id), сохраняйте его в отдельной таблице обработанных уведомлений. При получении нового уведомления проверяйте, не обрабатывали ли вы его ранее.
Блокировка на уровне БД. Используйте SELECT FOR UPDATE или оптимистичную блокировку, чтобы два параллельных запроса не обновили статус одновременно.
Пример логики, как это может выглядеть:
def handle_webhook(request): # 1. Проверка подписи if not verify_signature(request): return HttpResponse(status=400) payment_id = request.POST.get('payment_id') status = request.POST.get('status') # 2. Поиск заказа order = Order.objects.filter(payment_id=payment_id).first() if not order: return HttpResponse(status=404) # 3. Идемпотентность: проверка текущего статуса if order.status == 'paid': return HttpResponse(status=200) # Уже обработано # 4. Блокировка записи with transaction.atomic(): order = Order.objects.select_for_update().get(pk=order.pk) if order.status == 'paid': return HttpResponse(status=200) # Повторная проверка после блокировки # 5. Обновление статуса и запуск логистики order.status = 'paid' order.save() start_logistics(order) return HttpResponse(status=200)
Важно. Всегда отвечайте 200 OK на вебхук, даже если произошла ошибка на вашей стороне, кроме случаев, когда она критическая. Иначе провайдер будет повторять отправку, что создаст лишнюю нагрузку.
Как выбрать платёжный сервис для интернет-магазина
Важно подобрать инструмент, который будет работать с вашей архитектурой, масштабироваться вместе с бизнесом и не создавать проблем при интеграции. Ошибка на этом этапе оборачивается потерей заказов, двойными списаниями и невозможностью подключить новые способы оплаты без переписывания кода сайта. Ниже — сжатый чек-лист параметров для оценки провайдера:
Способы оплаты. Базовый набор: карты и СБП. Для роста — Pay-сервисы (SberPay, T-Pay), рассрочка/BNPL и другие. Все методы должны быть в одном API.
Комиссия и тарифы. Запрашивайте детальный расчёт, смотрите на отсутствие минимальных фиксированных комиссий и включён ли НДС в сумму.
Скорость подключения. Платёжные сервисы чаще всего подключают за 1–3 дня, банки — за 1–2 недели. Для быстрого старта можно выбрать первый вариант.
Тестовый режим (sandbox). Обязателен для отладки без риска для реальных денег.
API-документация. Должна быть актуальной, с примерами кода и описанием вебхуков. Если не обновлялась годами — интеграция будет очень сложной.
Антифрод. Уточните, как провайдер обрабатывает транзакции, какие сценарии считает подозрительными и как он на них реагирует (запрос дополнительной верификации, автоматическая блокировка). Узнайте, можно ли настраивать правила фильтрации под ваш бизнес — это снижает риск чарджбэков и мошеннических списаний без участия вашей команды.
Логируйте все попытки оплаты, даже неуспешные, вместе с IP-адресами и user-agent. Кроме того, настройте оповещения о подозрительной активности: резкий рост отказов, необычно крупные суммы, множественные попытки с одного IP. Это позволит снизить риск мошенничества.
Комментарий команды Монеты
Готовые CMS-модули. Для WordPress, 1С-Битрикс, Tilda, Joomla и других. Экономят время и деньги на разработчиках.
Расширенные сценарии. Рекуррентные платежи, сохранение карт (токенизация), холдирование, сплитование — если они нужны, убедитесь, что провайдер их поддерживает (обычно только через API).
Безопасность. Лицензия ЦБ РФ, сертификат PCI DSS, 3D Secure, антифрод — это база. Если провайдер скрывает информацию, отказывайтесь.
Стабильность. Узнайте, какой уровень доступности сервиса прописан в договоре — это SLA (Service Level Agreement). Стандарт для платёжных сервисов — 99,9% («три девятки»). Запросите у провайдера отчёт о фактической доступности за последние 3–6 месяцев, чтобы проверить информацию.
Отчёты и личный кабинет. Фильтрация, выгрузка в Excel, детализация по каждой транзакции.
Масштабирование. Проверьте, есть ли у провайдера опыт работы с крупными проектами, сможет ли он подключить международные платежи, дать SDK для мобильных приложений. Уточните, предусмотрена ли автоматическая балансировка нагрузки и горизонтальное масштабирование шлюзов.
Главное, что стоит запомнить
Данные карт не должны проходить через ваш сервер. Используйте платёжную страницу провайдера или виджет — это снимает с вас ответственность за PCI DSS.
Статус заказа обновляется только по вебхукам. Редирект не гарантирует получение подтверждения — клиент может закрыть страницу.
Проверяйте подпись уведомлений. Без этого любой может отправить поддельный запрос и изменить статус заказа.
Храните order_id и payment_id. Оба идентификатора нужны для корректной обработки уведомлений и поиска заказа.
Обрабатывайте повторные уведомления идемпотентно. Платёжный сервис может отправить одно и то же уведомление несколько раз — убедитесь, что это не приведёт к двойной обработке.
Тестируйте все сценарии: успех, отказ, возврат, повторную попытку — до запуска.
Интеграция оплаты на сайте для интернет-магазина — это создание архитектуры: как принимать вебхуки, как не потерять заказ при повторном уведомлении и как проверить, что платёж действительно прошёл, а не является подделкой.
P. S. Примеры API-запросов, сценарии подключения платёжной формы и параметры для приёма платежей можно посмотреть в документации Монеты.

