В разборе про приём оплаты я оставил фискальную часть на потом — она не помещалась, а материала на самостоятельный текст хватает с запасом. Вот он.
Главная мысль сразу, потому что на ней держится всё остальное: на один заказ приходится два чека, и второй пробивается не в момент оплаты, а когда товар передан покупателю — то есть через дни после того, как деньги пришли. Первый чек уходит вместе с платежом, и про него не забывают. Второй — такая же обязанность продавца, но в момент оплаты его пробить нельзя, а через неделю о нём уже никто не помнит.
Ошибка здесь не выглядит как ошибка: у клиента всё хорошо, деньги ушли, товар приехал, чек об оплате он видел. Не хватает двух вещей — второго чека и кодов маркировки в нём. И узнают об этом не от системы, а от проверяющих.
Про коды стоит сказать отдельно, потому что их роль часто понимают как лишнюю отчётность. Честный Знак — это подтверждение, что товар легальный, а не контрафакт: у каждой единицы свой код, и он ведёт её от производителя до покупателя. Выбывает единица из оборота чеком — тем самым, вторым. Пока он не пробит с кодом внутри, проданная и уехавшая клиенту единица по документам всё ещё лежит у вас на складе. А значит, и контроль не работает: код числится живым, хотя товар давно у покупателя, — и именно за такие «живые» коды цепляется контрафакт, которому нужен легальный номер, чтобы им прикрыться. Смысл маркировки ровно в том, чтобы этого не происходило, и держится он на последнем шаге — на чеке.

Шесть шагов. Последний нужен потому, что «чек принят» от платёжного сервиса приходит раньше, чем чек становится чеком.
Почему чеков два
Покупатель заплатил на сайте — товар он получит через несколько дней. С точки зрения закона это предоплата, и она закрывается двумя чеками:
- Чек аванса — в момент оплаты. Он говорит: деньги получены, товар пока не передан.
- Чек полного расчёта с зачётом аванса — когда товар передан покупателю. Он говорит: обязательство закрыто, ранее полученный аванс зачтён.
Различает их признак способа расчёта в каждой позиции. В первом чеке позиции идут как предоплата, во втором — как полный расчёт, и вместо денег в реквизитах стоит зачтённая сумма аванса: новых денег не поступало, поэтому «электронными» ноль, а вся сумма — зачёт.
Первый чек почти всегда делает платёжный сервис вместе с оплатой. Второй не сделает никто, кроме вашей системы: чтобы его собрать, нужно знать, что товар доехал, и — если товар маркированный — какие именно коды уехали покупателю. Ни того, ни другого у платёжного сервиса нет.
Чек аванса: уходит вместе со ссылкой
Первый чек мы не пробиваем отдельно — он передаётся вместе с созданием оплаты, отдельным блоком данных. Что в нём:
- позиции — название, цена, количество, сумма;
- доставка отдельной строкой — в заказе она не позиция, а в чеке обязана быть строкой, причём услугой, а не товаром. Считаем её как разницу между итогом заказа и суммой позиций: строка появляется ровно тогда, когда доставка платная, и никогда не расходится с итогом;
- система налогообложения и ставка НДС — не «галочки для бухгалтерии», от них зависит, примет ли касса чек;
- почта и телефон покупателя — чек электронный, его надо куда-то отправить.
Что возвращается обратно
Пробитый чек — не только ссылка «посмотреть чек». Платёжный сервис присылает нам уведомление с фискальным документом целиком, и мы сохраняем его весь: номер фискального документа, фискальный признак, номер накопителя, смену, сумму, признак расчёта, кассу.
Зачем хранить это у себя, если есть личный кабинет сервиса: во-первых, ссылка на чек нужна в карточке заказа и в личном кабинете клиента; во-вторых, это готовые данные для бухгалтерии и учётной системы — их не придётся выгружать руками; в-третьих, кабинет чужой, а данные наши.
⚠️ Уведомление о чеке может прийти дважды — от повторной доставки не застрахован никто. Дубли отсекаются на уровне базы уникальным признаком, а не проверкой в коде: проверка в коде проигрывает гонку, когда два одинаковых уведомления приходят одновременно.
Финальный чек: зачёт аванса и коды маркировки
Финальный чек — то, чего готовый модуль на витрине не сделает никогда: у него нет ни статуса доставки, ни кодов маркировки. Финальный чек собирает система.
Зачёт аванса. Позиции идут как полный расчёт, сумма аванса ставится в отдельный реквизит, новых денег в чеке нет.
Коды маркировки. Если товар маркированный, во втором чеке должны быть коды тех самых единиц, которые уехали покупателю, — именно с этого чека код выбывает из оборота, уходя в Честный Знак через ОФД. Это и есть конец пути единицы: она подтверждённо продана конкретному покупателю и больше не может всплыть где-то ещё. Коды мы получаем от склада вместе с отгрузкой и раскладываем по позициям заказа. Почему они приезжают неполными и что проверять до отгрузки — в статье про Честный Знак при отгрузке со склада.
Два правила, без которых чек не пройдёт:
- Одна единица — одна строка — один код. Позиция «две штуки» разбивается на две строки по одной. Иначе коды некуда положить.
- Кодов меньше, чем единиц, — чек не пробиваем. Не «пробьём что есть», не «пробьём без кодов»: система останавливается и зовёт человека. Неполный чек по маркированному товару — это проблема, которая всплывёт позже и уже в отчётности.
⚠️ Правило двух терминалов. Если у вас, как у нас, два платёжных терминала — один для сайта, другой для заказов менеджера, — финальный чек обязан уйти на тот же терминал, где прошла предоплата. Иначе касса не свяжет зачёт с авансом: технически чек пробьётся, а по документам аванс так и останется незакрытым.
Превью перед пробитием. Чек — необратимая операция, поэтому сначала система показывает, что именно уйдёт: терминал, суммы, позиции, коды. Человек смотрит и подтверждает. Кнопка «пробить» без предварительного показа — это кнопка «сделать необратимое вслепую».
Автоматика: чек через час после доставки
Пробивать финальные чеки руками на потоке невозможно: менеджер должен каждый день просматривать доставленные заказы, искать коды и пробивать. Поэтому чек пробивается сам — через час после того, как заказ стал доставленным.
Почему именно час, а не сразу: это окно на вмешательство человека. Клиент может отказаться прямо у двери, курьер — ошибиться со статусом, менеджер — увидеть проблему с кодами. Весь этот час кнопка ручного пробития работает как обычно, и если чек пробили руками, автомат такой заказ уже не тронет.
Что автоматика не трогает вовсе: заказы с уже пробитым чеком, тестовые и нулевые суммы.
⚠️ Инженерная деталь, которая экономит месяцы: автомат не содержит своей копии логики — он дёргает тот же самый внутренний маршрут, что и кнопка менеджера. Скопировать двести строк выбора терминала, зачёта аванса и разбивки по кодам — значит завести вторую версию правды, которая разъедется с первой на первой же правке.
Чек возврата: операция, которую нельзя отменить
Покупатель вернул товар — нужен чек возврата. И здесь важное, что стоит знать заранее: пробитие такого чека само возвращает деньги покупателю. Отдельной операции возврата средств делать не нужно, и отменить сделанное нельзя.
Отсюда всё остальное устройство: обязательное превью, повторное пробитие заблокировано, а в интерфейсе прямо написано, что деньги уйдут клиенту.
Состав берём из документа возврата, а не из заказа: в чек должно попасть то, что реально вернулось на склад. При частичном возврате состав заказа вернул бы лишнее. Коды маркировки — из того же документа, полные, с криптоподписью: без них Честный Знак не примет товар обратно в оборот. Если возврат в системе не зафиксирован, состав берётся из заказа, но превью честно говорит, на чём он основан.
Терминал — по тому же правилу: чек возврата уходит туда, где прошла оплата.
«Чек принят» ≠ «чек пробит»
Самая дорогая часть статьи.
Платёжный сервис отвечает «успешно» на запрос пробития — и делает это до фискализации. Если касса чек не примет (например, ей не хватает нужного режима для маркированных товаров), он тихо осядет в личном кабинете, во вкладке с ошибками. По API этих ошибок не достать — мы проверили все правдоподобные адреса, все отвечают «нет такого метода». А система при этом показывает зелёную галочку «чек пробит».
Именно так один заказ у нас сутки считался закрытым, хотя чека не было.
Лечится это сверкой: документы из ОФД приезжают к нам сами, и по каждому заказу с отметкой «чек пробит» система ищет соответствующий фискальный документ. Нашла — заказ помечается «подтверждён в ОФД». Не нашла дольше отведённого срока — уведомление администраторам, один раз на заказ.
⚠️ Сопоставлять приходится по сумме и времени: у документов из ОФД нет номера заказа. Там, где чек поймал вебхук платёжного сервиса, есть номер счёта — по нему точнее. Это компромисс, и он честно описан в коде, чтобы следующий человек не считал совпадение по сумме надёжным опознанием.
Общее правило, ради которого стоило всё это писать: ответ «успешно» от чужого сервиса — это ответ о приёме запроса, а не о результате. Между ними бывает целая касса.
Что выяснить до запуска
- Сколько у вас чеков на заказ и кто пробивает второй.
- Что происходит, если товар не доехал — чек аванса уже пробит, обязательство закрыто чем?
- Маркированный ли товар и откуда придут коды: от склада, из своей системы или руками.
- Сколько у вас терминалов и связываются ли чеки с авансом на каждом.
- Как вы узнаете, что чек не прошёл фискализацию. Если ответ «увидим в кабинете» — вы не узнаете.
- Что происходит при возврате и понимает ли менеджер, что нажатие вернёт деньги.
Если у вас та же задача
Фискальная часть — не то, что делается «заодно с оплатой»: два чека, коды маркировки, правило терминалов, автоматика после доставки, возвраты и сверка с ОФД уже пройдены на боевом проекте, и эти наработки применимы там, где такая же схема: предоплата на сайте, отгрузка позже, маркированный товар.
Что обычно входит в такую работу:
- разбор вашей схемы расчётов: предоплата, постоплата, частичные возвраты;
- чек аванса и чек зачёта — с правильными признаками и составом;
- коды маркировки в чеке и проверки полноты до пробития;
- автоматика после доставки — с окном, в которое человек успевает вмешаться;
- чеки возврата: превью, защита от повторного пробития, состав по документу;
- сверка с ОФД и сигнал, когда чек не дошёл.
Хотите такую же связку у себя — расскажите о задаче.
Коротко: частые вопросы
- Почему при предоплате нужно два чека?
- Первый — на аванс, в момент оплаты. Второй — на полный расчёт с зачётом аванса, когда товар передан покупателю. Второй забывают чаще всего: в момент оплаты его пробить нельзя, а через неделю о нём никто не помнит.
- Кто пробивает финальный чек?
- Ваша система. Платёжный модуль на сайте этого не сделает: у него нет ни статуса доставки, ни кодов маркировки, которые должны попасть в чек.
- Как узнать, что чек действительно пробит?
- Только сверкой с оператором фискальных данных: платёжный сервис отвечает «успешно» на приём запроса, а не на фискализацию чека. Частая причина расхождения — маркировка: перед пробитием касса отправляет код Честного Знака на проверку, и если код неполный, уже выбывший из оборота или не проходит проверку по другой причине, фискализация останавливается, а чек уходит в ошибки личного кабинета. Со стороны это незаметно: деньги списаны, заказ закрыт, система показывает «чек пробит» — а чека нет.