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

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

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

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

  • Проверьте статус первого чека и его тип оплаты, а не только наличие номера в интерфейсе.
  • Зафиксируйте дату и событие фактической передачи товара или завершения услуги.
  • Посмотрите очередь кассы, число попыток, последний ответ API и внешний идентификатор документа.
  • Уточните, не был ли заказ частично выдан, возвращен, переоформлен или разбит на несколько отгрузок.
  • Сверьте настройки системы налогообложения, ставки НДС и номенклатуру на момент расчета.

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

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

  • Событие shipment_completed или service_delivered не связано с созданием чека полного расчета.
  • Обработчик срабатывает только при онлайн-оплате и пропускает ручную смену статуса.
  • Первый чек ошибочно создан с признаком полного расчета, поэтому второй блокируется.
  • Очередь потеряла задачу после таймаута, а локальный статус преждевременно стал sent.
  • Идемпотентный ключ совпадает у чека предоплаты и закрывающего документа.

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

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

  • Постройте хронологию заказа по времени: payment captured, receipt prepaid, delivery completed, final receipt queued и fiscalized.
  • Проверьте payload первого и ожидаемого второго документа, особенно payment_method и payment_subject.
  • Найдите запись outbox или очереди по order ID и типу кассовой операции.
  • Сопоставьте локальный request ID с ответом кассы и результатом запроса статуса.
  • Проверьте обработку повторной доставки webhook и восстановления воркера после перезапуска.

Как связать исполнение заказа и кассовый документ

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

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

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

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

  • Добавьте явный переход к состоянию final_receipt_required при передаче товара или завершении услуги.
  • Формируйте payload из зафиксированного состава исполнения и суммы зачтенной предоплаты.
  • Разведите ключи идемпотентности по типу документа и этапу расчета.
  • Верните зависшие задачи в очередь только после проверки статуса у кассового провайдера.
  • Создайте контролируемую команду восстановления для заказов без закрывающего чека с предварительным dry-run отчетом.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Можно ли сформировать чек вручную?

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

Почему чек появляется с задержкой?

Возможны очередь, асинхронный ответ кассы или повтор после временной ошибки. Важно контролировать допустимый срок и конечный статус.

Нужно ли менять первый чек?

Не всегда. Решение зависит от его фактических реквизитов и состояния расчета; исторический документ нельзя просто переписать в базе.

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

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