01.08.2026

Уведомления от платёжки теряются: как не терять статусы оплаты

Оплата прошла, заказ завис в ожидании — клиент злится, поддержку правят вручную. Нет надёжной обработки уведомлений от платёжки.

Клиент пишет: «деньги списались, заказ всё ещё ждёт оплаты». В личном кабинете платёж успешен. В вашей CRM — pending. Поддержка вручную переводит статус, пока менеджер извиняется. К вечеру таких тикетов пять. К чёрной пятнице — очередь.

Почти всегда корень в обработке уведомлений платёжки: webhook не дошёл, дошёл дважды, пришёл раньше, чем заказ создался, или обработчик упал на полпути без идемпотентности. Деньги есть. Состояние заказа — нет.

Это не «глюк эквайринга». Это дыра в договорённости между платёжным контуром и вашим бэкендом.

Типичные сценарии потери

Эндпоинт был недоступен минуту — провайдер повторил позже, но ваш код не умеет принимать опоздания и дубли. Или наоборот: дубль создал повторное начисление бонусов.

На тестовый контур URL остался в кабинете платёжки после релиза. Боевые уведомления улетают в пустоту.

Обработчик проверяет подпись кое как или не проверяет. После «улучшения» безопасности начинают отбрасываться легитимные события — или наоборот, принимается мусор.

Статус меняют и админка, и webhook, и крон сверки — без единого источника истины. Гонки гарантированы.

Ошибки, которые дорого стоят

Полагаться только на редирект «успех» в браузере. Пользователь закрыл вкладку — редиректа нет, webhook был единственным шансом.

Обрабатывать уведомление долго внутри HTTP-запроса. Провайдер получает таймаут и шлёт снова; у вас полторы проводки логики.

Не иметь сверки реестров. Webhook — быстрый путь, сверка — страховочная сетка.

Практичная схема обработки

Принцип простой: уведомление принять быстро, зафиксировать, обработать устойчиво, уметь повторять без вреда.

Эндпоинт проверяет подпись, пишет событие в журнал/очередь с ключом идемпотентности (id платежа + статус) и отвечает успехом. Дальше воркер меняет заказ, инициирует выдачу, письма, фискализацию.

Повтор того же события не должен второй раз закрывать заказ «по новому» или дважды начислять. Повтор с новым статусом — отдельная ветка с понятными переходами.

Обязательный контур рядом:

  • мониторинг ошибок и числа «оплачен у провайдера / не оплачен у нас»;
  • периодическая сверка реестров;
  • ручной инструмент поддержки: подтянуть статус платежа по id без правки SQL «на глаз»;
  • алерты, если webhook молчит подозрительно долго при живых оплатах.

Что сделать после серии ручных правок

Соберите 20 последних инцидентов «деньги есть — статуса нет» и разметьте причины. Обычно всплывает один два системных бага, а не «просто так». Закройте их до следующей акции — иначе поддержка снова станет кассой статусов.

Сверка как страховочная сетка

Даже идеальный webhook иногда опаздывает или теряется на сети. Ночная сверка реестра провайдера с вашей таблицей платежей закрывает хвосты до того, как клиент напишет в поддержку.

Сделайте для поддержки безопасный инструмент «подтянуть статус»: без прямого редактирования базы и без выдачи лишних прав. Ручной SQL в инциденте плодит новые ошибки.

Отдельно протестируйте дубли и перестановки событий: оплачен → возврат, два успеха подряд, успех после таймаута. Эти кейсы редки в демо и часты в проде.

Перед акциями проверяйте не только витрину, но и очередь обработки уведомлений: хватает ли воркеров, нет ли накопленного лага, живы ли алерты на расхождения.

Идемпотентность на пальцах

Каждое событие платежа должно иметь устойчивый ключ. Повтор с тем же ключом не создаёт вторую выдачу товара и второе письмо «спасибо». Новое состояние — обрабатывается как переход, а не как новый мир.

Храните сырое уведомление. Когда через неделю спорят «что прислала платёжка», сырой журнал заканчивает дискуссию быстрее, чем воспоминания разработчика.

Отделяйте фискализацию и пост обработку от факта «платёж успешен». Если чек временно не пробился, это не повод потерять сам статус оплаты — но и не повод молчать в мониторинге.

Нагрузочно проверьте пик: очередь растёт, воркеры живы, пользователи не висят в pending дольше оговорённого SLA. Акции без этой проверки регулярно заканчиваются ручными правками статусов.

Полезно ввести внутренний SLA: сколько минут заказ может висеть в pending после успешной оплаты у провайдера. Превышение — инцидент, а не «подождём, само догонит». Так поддержка и разработка получают общий язык.

Проверьте часовые пояса и форматы сумм в уведомлениях. Казалось бы мелочь, но из-за неё падают разборы подписи и сверки, а статусы снова правят руками.

Если подключено несколько платёжных методов, унифицируйте внутреннюю модель событий. Иначе каждый провайдер плодит свой зоопарк обработчиков и свой сорт потери webhooks.

Заведите дашборд расхождений: оплачено у провайдера / не подтверждено у нас, и наоборот. Это главный индикатор здоровья платёжного контура — понятнее любых абстрактных графиков.

И не чините статусы «тихо» без записи. Каждая ручная правка должна оставлять след: кто, когда, почему. Иначе вы лечите симптомы и теряете статистику системных дыр.

Перед крупными акциями прогоните тест двойных уведомлений и задержки. Именно эти кейсы в пике создают очередь тикетов «оплатил, заказа нет». Лучше сломать тест, чем витрину.

И закрепите владельца платёжного контура: кто смотрит дашборд расхождений ежедневно. Без владельца даже идеальный код деградирует незаметно.

Пока статусы правят вручную, вы платите дважды: поддержкой сегодня и повторным инцидентом на следующей акции. Автоматическая идемпотентная обработка дешевле.

Сверка реестров и идемпотентный обработчик — минимальный набор, после которого «оплата есть, заказа нет» перестаёт быть еженедельным ритуалом поддержки.

Итог

Когда webhooks теряются, страдает не «интеграция», а доверие клиента и нагрузка на поддержку. Идемпотентная обработка, очередь, сверка реестров и мониторинг расхождений превращают хаос в управляемый процесс.

Если сейчас статусы правят руками — это уже сигнал. Почините путь уведомлений до пиковой нагрузки, а не во время неё.

Нужна помощь с похожей задачей?

Опишите ситуацию — предложим решение на основе нашего опыта.

Заявка

Имя, Email, телефон и комментарий — остальное обсудим после заявки