Оплаты и вебхуки при сбое сервера: как не потерять заказы

Октябрьские аварии в облаке заставили многих владельцев интернет-магазинов и ботов заметить неочевидную проблему. Покупатель оплатил заказ, деньги списались, а магазин об этом не знает: сервер, который должен был принять уведомление от платёжного сервиса, в этот момент не работал. Автор разбора аварии на Хабре отдельно советует держать буфер для вебхуков у независимого оператора. Разбираем, как устроены повторные уведомления и что сделать, чтобы оплаты не терялись.
Как работают уведомления об оплате
Когда покупатель платит, платёжный сервис отправляет на сервер магазина уведомление — вебхук. Магазин принимает его, отмечает заказ оплаченным, пробивает чек и запускает доставку. Если сервер магазина недоступен, уведомление не доходит.
Платёжные сервисы это предусматривают, но не бесконечно. Например, по документации ЮKassa, уведомление отправляется повторно, пока сервер магазина не ответит кодом HTTP 200, и попытки продолжаются в течение 24 часов с момента события. Telegram хранит обновления для ботов, пока бот их не заберёт, но не дольше 24 часов, а вебхук повторяет запрос при ошибке «разумное число раз».
| Сервис | Поведение по документации | Риск |
|---|---|---|
| ЮKassa | Повторы до ответа 200, в течение 24 часов | Сбой дольше суток — уведомления потеряны |
| Telegram Bot API | Обновления хранятся до получения, не дольше 24 часов | То же для сообщений и платежей в боте |
| Ваш сервер | Должен ответить 200 и обработать событие | Ответ 200 без обработки — заказ «завис» |

Где теряются оплаты
Сбой дольше суток. В октябре часть сервисов не работала двое-трое суток. Уведомления за этот период могли не дойти вовсе.
Сервер ответил 200, но не обработал. Если приложение сначала отвечает «принято», а потом падает при обработке, платёжный сервис считает уведомление доставленным и больше не повторяет. Заказ остаётся неоплаченным в магазине.
База в режиме только чтения. Сервер принял уведомление, но записать статус заказа не смог. Если в этой ситуации отвечать 200, событие потеряется.
Дубли. Повторные уведомления приходят несколько раз. Если обработка не проверяет, был ли платёж уже учтён, возможны двойные чеки и двойная отгрузка.
Что настроить
- Отвечайте 200 только после записи события. Сначала сохраните уведомление в надёжное место — базу или очередь, — потом отвечайте. Если сохранить не удалось, верните ошибку: сервис повторит попытку.
- Обрабатывайте идемпотентно. Проверяйте идентификатор платежа: если он уже учтён, ничего не делайте повторно.
- Проверяйте статус через API. Документация ЮKassa рекомендует перед обработкой запросить текущий статус объекта — это защищает и от подделок, и от устаревших уведомлений.
- Настройте сверку. Раз в несколько часов запрашивайте у платёжного сервиса список платежей за период и сравнивайте с заказами. Это ловит всё, что не дошло уведомлениями.
- Вынесите приём уведомлений. Для критичных проектов имеет смысл принимать вебхуки на отдельном лёгком сервисе у другого провайдера, который только складывает события в очередь. Основное приложение заберёт их после восстановления.
- Мониторьте «тишину». Если за час при обычном трафике не пришло ни одного уведомления, это сигнал проверить приём.
Как проверить приём уведомлений без сбоя
Отключать сервер ради теста не обязательно. Достаточно на тестовом окружении временно возвращать ошибку на адрес вебхука, провести тестовую оплату и убедиться, что после возврата нормального ответа уведомление пришло повторно и заказ отметился оплаченным. Второй тест — отправить одно и то же уведомление дважды и проверить, что заказ не задвоился и чек не пробит повторно. Оба теста занимают полчаса и показывают, как магазин поведёт себя в реальном сбое.
Что делать после сбоя
Если ваш сервер был недоступен, после восстановления выгрузите из личного кабинета платёжного сервиса все платежи за период сбоя и сверьте с заказами. Оплаченные, но не отмеченные заказы обработайте вручную: отметьте оплату, пробейте чек, если он не был пробит, и свяжитесь с покупателем. Так же стоит проверить бота: сообщения, пришедшие больше суток назад, Telegram уже не отдаст.
Особый случай: чеки
Если оплата прошла, а уведомление не дошло, чек тоже мог не пробиться — особенно когда облачная касса запускается по сигналу от сайта. После сбоя проверьте чеки за весь период: для оплаченных заказов без чека нужно оформить чек коррекции. Чем раньше это сделать, тем меньше вопросов у налоговой.
Отдельно предупредите поддержку: в дни после сбоя покупатели будут писать «деньги списались, а заказа нет». Короткая инструкция для операторов — где проверить платёж, как отметить заказ и что ответить покупателю — сэкономит время и нервы обеим сторонам.
Если у вас бот с оплатой
Для Telegram-ботов с приёмом платежей действуют те же правила: отвечать на вебхук только после записи события, проверять статус платежа и делать сверку. Дополнительно стоит предусмотреть, что бот, вернувшийся после долгого простоя, не получит обновления старше суток. Если покупатель за это время оплатил заказ и написал боту, оплату нужно найти сверкой, а сообщение — восстановить по истории чата или попросить покупателя повторить.
Наше мнение
Мы советуем каждому магазину с онлайн-оплатой проверить две вещи: когда сервер отвечает платёжному сервису «принято» и есть ли регулярная сверка платежей с заказами. Первое часто устроено неправильно, второго часто нет вовсе. Обе доработки небольшие, а спасают именно те заказы, за которые покупатель уже заплатил.
Материалы для проверки
Если нужна реализация
Состав работ зависит от текущего проекта и подтверждённой причины. Можно обсудить диагностику или разработку подходящего решения.
Вопросы и ответы
Сколько времени платёжный сервис повторяет уведомления?
Зависит от сервиса. По документации ЮKassa — пока сервер не ответит 200, в течение 24 часов с момента события.
Сколько Telegram хранит обновления для бота?
До получения ботом, но не дольше 24 часов.
Что делать с оплатами, которые пришли во время сбоя?
Выгрузить платежи за период из личного кабинета платёжного сервиса, сверить с заказами и обработать недостающие вручную, включая чеки.
Почему приходят дубли уведомлений?
Сервис повторяет отправку, если не получил подтверждение. Обработка должна проверять идентификатор платежа и не учитывать его дважды.
Нужен ли отдельный сервер для приёма вебхуков?
Для большинства магазинов достаточно правильного порядка обработки и сверки. Отдельный приёмник у другого провайдера имеет смысл для проектов, где сбой на сутки и больше критичен.