Оплата и фискализация — связанные, но разные операции. Банк может подтвердить списание в момент, когда кассовый сервис недоступен. Если приложение ждет чек в одном синхронном запросе, заказ остается в неопределенном статусе, пользователь повторяет оплату, а оператор не понимает, получены ли деньги. Надежная схема отдельно фиксирует платеж и гарантированно доводит чек до результата.

Для конкретного заказа сравните transaction ID банка, статус платежа, запись кассового задания, номер попытки и ответ оператора фискальных данных. Не запускайте оплату заново, пока не проверили подтверждение эквайринга. Сначала сохраните успешный платеж, затем безопасно восстановите очередь чеков.

Что проверить в первую очередь

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

  • Проверьте финальный статус платежа напрямую у эквайера по transaction ID.
  • Найдите кассовое задание и его idempotency key, привязанный к заказу и типу чека.
  • Уточните доступность кассы, срок действия токена, состояние смены и очередь провайдера.
  • Сравните сумму, НДС, позиции, тип оплаты и контакт покупателя с требованиями кассового API.

Почему возникает проблема

Внешний симптом часто появляется дальше по цепочке, чем первичная ошибка. Интерфейс может показывать неверное состояние из-за backend, очереди, кеша, прав доступа, фоновой задачи или внешнего API. Поэтому важно проследить данные от источника до результата и найти первую точку расхождения, а не исправлять только последнее сообщение об ошибке.

  • Приложение считает платеж завершенным только после синхронного ответа кассы.
  • Таймаут произошел после приема чека провайдером, а повтор создает второй документ.
  • Кассовая смена закрыта, закончились ресурсы устройства или истек сертификат.
  • В заказе есть неподдерживаемая ставка налога, способ расчета или маркированная позиция.
  • Фоновый worker остановлен и задания остаются в статусе pending без алерта.

Пошаговая диагностика

Диагностику проводите на тестовой записи или отдельном окружении. В журналах скрывайте токены, пароли, персональные данные и содержимое документов. Для каждого шага сохраняйте измеримый результат: код ответа, версию записи, идентификатор события, состояние процесса, контрольную сумму или время выполнения. Так можно отличить подтвержденную причину от случайного совпадения.

  • Постройте временную шкалу: создание заказа, платеж, callback банка, постановка чека, ответ кассы.
  • Проверьте журнал исходящего payload без полного телефона, email и платежных реквизитов.
  • Получите статус операции у кассового провайдера по внешнему ID до повторной отправки.
  • Посмотрите возраст очереди, число retry и последнюю ошибку каждого задания.
  • Создайте тестовый заказ с минимальным набором позиций и отдельно проверьте сложные налоги и маркировку.

Как разделить платеж и фискализацию

Финансовый статус заказа должен опираться на подтверждение эквайера, а статус чека — на отдельный надежный процесс. Между ними нужна транзакционная запись задания, чтобы сбой после оплаты не потерял обязанность сформировать документ.

  • Payment хранит provider transaction ID и подтвержденную сумму.
  • Fiscal job имеет уникальный ключ order ID plus receipt type и неизменяемый payload.
  • Worker выполняет ограниченные retry с паузой и проверкой уже созданного чека.
  • Заказ показывает оператору раздельные статусы оплаты и фискализации, не скрывая задержку.

Как исправить проблему

Исправление делите на небольшие обратимые изменения. Сначала устраните подтвержденную причину, затем повторите исходный сценарий и проверьте соседние функции. Массовое обновление данных запускайте на ограниченной выборке с отчетом и только после сверки расширяйте на весь объем. Не отключайте авторизацию, проверку сертификатов, валидацию или аудит ради быстрого исчезновения симптома.

  • Фиксируйте успешный callback оплаты до обращения к кассе и ставьте чек в durable queue.
  • Добавьте идемпотентный ключ и запрос статуса перед повтором после таймаута.
  • Разделите временные ошибки транспорта и постоянные ошибки состава чека.
  • Создайте операторский экран для повторной обработки после исправления данных.
  • Настройте алерт по возрасту нефискализированных оплаченных заказов и окончательным отказам.

Безопасный порядок внедрения

  • Сохраните затрагиваемые данные, конфигурацию и текущие журналы, затем проверьте возможность реального восстановления.
  • Повторите проблему на тестовом объекте без реальных списаний, рассылок и необратимых изменений клиентских данных.
  • Зафиксируйте изменение в системе контроля версий или журнале работ вместе с причиной, ожидаемым эффектом и планом отката.
  • Проведите тест на нормальном сценарии, ошибочном вводе, повторном запросе, параллельной операции и временной недоступности зависимости.
  • После выпуска наблюдайте полный пользовательский путь, логи и метрики, а не только один успешный запрос.

Как проверить результат

Разовый успешный тест недостаточен. Повторите операцию, проверьте крайние значения, одновременные действия и восстановление после перезапуска или временного сбоя. Для важного сценария сохраните автоматический тест либо короткий регрессионный чек-лист. Итог должен подтверждаться не только интерфейсом, но и состоянием базы, очереди, внешнего сервиса и журналом действий.

  • Успешная оплата сохраняется даже при искусственно отключенной кассе.
  • После восстановления кассы создается ровно один чек с правильной суммой и позициями.
  • Повтор callback банка и повтор worker не создают второй платеж или чек.
  • Постоянная ошибка данных видна оператору и не повторяется бесконечно.

Типичные ошибки при исправлении

  • Предлагать клиенту оплатить повторно, не сверив transaction ID.
  • Повторно отправлять чек после любого таймаута без запроса его статуса.
  • Менять оплаченный заказ до фиксации исходного состава фискального документа.
  • Считать HTTP 200 кассы окончательным признаком регистрации без проверки результата.

Как предотвратить повторение

Профилактика строится вокруг явных контрактов, повторяемых релизов и наблюдаемости. Система должна не только работать сейчас, но и позволять быстро увидеть нарушение правила при следующем обновлении, росте нагрузки или сбое внешнего сервиса. Проверки особенно полезно автоматизировать там, где ошибка уже привела к потере времени, данных, денег или заявок.

  • Мониторьте оплаченные заказы без зарегистрированного чека и возраст очереди.
  • Регулярно проверяйте сертификаты, смены и лимиты кассового оборудования.
  • Тестируйте ставки налогов, скидки, частичную оплату, возврат и маркированные товары.
  • Проводите ежедневную сверку эквайринга, заказов и фискальных документов.

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

  • Количество успешных и ошибочных операций в разрезе версии, канала и типа сценария.
  • Возраст необработанных записей, длину очередей, число повторных попыток и долю окончательных отказов.
  • Расхождение между пользовательским статусом и фактическим состоянием в базе или внешней системе.
  • Появление новых кодов ошибок после релиза и изменение времени выполнения ключевой операции.
  • Сигналы от поддержки и бизнес-метрики, которые могут показать скрытый частичный сбой.

Что подготовить для технического разбора

  • Описание ожидаемого и фактического поведения с точной последовательностью действий.
  • Время проблемы, идентификатор тестового объекта и версии затронутых компонентов.
  • Фрагменты журналов до и после ошибки без секретов и персональных данных.
  • Перечень последних изменений и уже выполненных проверок.
  • Безопасный доступ к тестовой среде либо способ воспроизвести сбой без влияния на клиентов.

Частые вопросы

Можно ли считать заказ неоплаченным, пока нет чека?

Нет, если эквайер подтвердил списание. Платеж и фискализация требуют отдельных статусов и процедур восстановления.

Что делать после таймаута кассового API?

Сначала запросить статус по внешнему идентификатору. Повтор допустим только с тем же идемпотентным ключом и после подтверждения отсутствия чека.

Когда нужна помощь специалиста

Если из-за недоступной кассы зависают оплаченные заказы, я могу разделить платежный и кассовый контуры, восстановить очередь чеков без дублей и настроить сверку и мониторинг.