В процессе интеграции и эксплуатации контрольно-кассовой техники (ККТ) семейства Атол (в частности, популярной модели Атол 11Ф) технические специалисты часто сталкиваются со специфическим поведением кассового аппарата при оформлении чеков возврата. Типичный сценарий: касса успешно пробивает чеки прихода (продажи), однако при попытке выполнить операцию «Возврат прихода» чек распечатывается ровно наполовину и аннулируется. При этом на чековой ленте печатается строка «ЧЕК АННУЛИРОВАН», а драйвер возвращает неочевидный код ошибки.
Вторая распространенная проблема, с которой сталкиваются ритейлеры после обновления фискальных документов (ФФД 1.05 или 1.2) и программного обеспечения кассы, — это подмена типа оплаты. Клиент расплачивается картой (безналичный расчет), а в пробитом чеке вместо привычной надписи «Безналичными» (или «Электронными») красуется формулировка «Последующая оплата (кредит)» или «В кредит». В рамках данной статьи мы подробно разберем обе проблемы, выясним их истинные причины и пошагово реализуем рабочие технические решения.
Рассмотрим ситуацию, когда при выполнении программного кода возврата чек выходит наполовину и прерывается. Разберем исходный код, написанный с использованием устаревшего драйвера версии 8 (компонента AddIn.FPrnM45), который очень часто встречается в старых интеграциях:
' Создаем объект драйвера ККТ Атол DTO 8
Set ECR = CreateObject("AddIn.FPrnM45")
' Настраиваем параметры подключения
ECR.Model = 67 ' Код модели Атол 11Ф
ECR.PortNumber = 1016 ' Номер COM-порта
ECR.BaudRate = 18 ' Скорость подключения
ECR.DeviceEnabled = 1
' Входим в режим регистрации
ECR.Password = "30" ' Пароль кассира по умолчанию
ECR.NewDocument
ECR.Mode = 1
ECR.SetMode
' Передаем ИНН кассира (атрибут 1021)
ECR.AttrNumber = 1021
ECR.AttrValue = "123456789012"
ECR.WriteAttribute
' Открываем чек возврата прихода
ECR.CheckType = 2 ' 2 — Возврат прихода
ECR.CheckMode = 1
ECR.OpenCheck
' Передаем СНО (атрибут 1055)
ECR.AttrNumber = 1055
ECR.AttrValue = 8 ' Например, УСН Доход минус Расход
ECR.WriteAttribute
' Регистрируем позицию в чеке
ECR.BeginItem()
ECR.ItemType = 1
ECR.Name = "Возвратный товар"
ECR.Price = 40
ECR.Quantity = 1
ECR.Summ = 40
ECR.Department = 1
ECR.TaxTypeNumber = 4 ' Без НДС
ECR.PaymentMode = 1 ' Полный расчет
ECR.EndItem()
' Закрываем чек комбинированной оплатой
ECR.TypeClose = 0 ' 0 — Наличные
ECR.Summ = 20
ECR.Payment()
ECR.TypeClose = 1 ' 1 — Безналичные
ECR.Summ = 20
ECR.Payment()
ECR.CloseCheck()
ECR.DeviceEnabled = 0
На первый взгляд программная логика выглядит абсолютно корректно. Однако при выполнении метода ECR.CloseCheck() кассовый аппарат обрывает печать. Почему так происходит? Дело в том, что в коде присутствует комбинированная оплата: часть суммы (20 рублей) возвращается наличными (ECR.TypeClose = 0), а часть — безналичным путем (ECR.TypeClose = 1).
Если в этот момент мы обратимся к логам драйвера или попытаемся считать результат выполнения метода закрытия чека, то обнаружим ошибку с кодом -3800 (внутренний код ККТ E000-152), которая расшифровывается как «В ККМ недостаточно денег для выплаты».
В ККТ Атол по умолчанию включен жесткий контроль наличности в виртуальном денежном ящике. Кассовый аппарат не может выдать из кассы больше наличных денег, чем в ней числится на текущий момент смены. Если перед проведением возврата за текущую смену не было совершено продаж за наличный расчет на сумму не менее 20 рублей (либо не была проведена операция внесения денег), касса заблокирует закрытие фискального документа прямо посреди процесса, аннулировав его.
Проанализировав ситуацию, мы можем предложить три надежных способа устранения этой проблемы в зависимости от бизнес-процессов вашей организации.
Способ 1. Программное внесение наличных средств. Перед проведением возврата наличными необходимо выполнить нефискальную операцию внесения денег в кассу. Для этого в коде драйвера ККТ используется метод внесения (для старого драйвера DTO 8 это свойство Summ и метод CashIncome):
' Переводим кассу в режим администратора/сервисный режим
ECR.Mode = 4
ECR.SetMode()
' Задаем сумму вносимых средств (с запасом для возврата)
ECR.Summ = 100
ECR.CashIncome() ' Выполняем операцию внесения наличных
' Возвращаем ККТ в режим регистрации для оформления чека возврата
ECR.Mode = 1
ECR.SetMode()
После проведения транзакции внесения в виртуальном денежном ящике появится необходимая сумма, и ККТ Атол без проблем закроет чек возврата наличными.
Способ 2. Отключение контроля наличности в параметрах кассы. Если кассовая дисциплина вашего предприятия допускает проведение возвратов без жесткой проверки остатка наличных в денежном ящике ККТ, эту опцию можно отключить в системных таблицах кассы. Разберем по шагам, как это сделать через утилиту «Тест драйвера ККТ»:
После отключения этого контроля ККТ Атол перестанет сверять сумму наличного возврата с накопленной выручкой в текущей смене, и чеки возврата больше не будут аннулироваться на середине печати.
Способ 3. Перевод возврата полностью на безналичный расчет. Если покупатель оплачивал товар картой, возврат должен производиться исключительно безналичным путем. В предоставленном автором коде ошибочно указан тип закрытия 0 (наличные). Нам необходимо скорректировать программную логику так, чтобы вся сумма закрывалась типом 1 (электронные/безналичные оплаты):
' Правильное закрытие безналичного возврата на всю сумму товара (40 рублей)
ECR.TypeClose = 1 ' 1 — Электронные/Безналичные
ECR.Summ = 40
ECR.Payment()
ECR.CloseCheck()
Теперь разберем вторую проблему, упомянутую в обсуждении: после планового обновления формата фискальных документов (ФФД) или обновления внутреннего ПО кассового аппарата (перехода на Платформу 5.0) чеки за безналичный расчет стали пробиваться с типом оплаты «В кредит» (или «Последующая оплата»).
Выясним причину этой системной путаницы. В старых стандартах ФФД (1.0) и старых версиях драйверов Атол (включая DTO 8 и ранние сборки DTO 9) разработчики могли настраивать типы оплаты произвольно. Очень часто в настройках касс под индексом 2 программировался «Талон», под индексом 3 — «Кредит», а под индексом 4 или другим свободным номером настраивали «Оплату картой» или «Безналичные».
С введением жестких требований ФФД 1.05 и ФФД 1.2 на уровне фискального законодательства РФ типы оплат были строго стандартизированы. В современных версиях прошивок ККТ Атол (Платформа 5.0) и актуальном драйвере 10-й версии (AddIn.Fptr10) индексы типов оплат жестко зафиксированы разработчиками оборудования на аппаратном уровне:
Когда вы обновили ККТ, касса стала строго подчиняться этой новой спецификации. Ваша учетная система (например, 1С), работающая по старым алгоритмам или использующая устаревшие настройки сопоставления оплат, при отправке безналичного чека передает старый индекс (например, 3). Но на новой прошивке ККТ индекс 3 зарезервирован исключительно под «Последующую оплату (Кредит)». Касса послушно выполняет команду и печатает в чеке «В кредит», вводя в заблуждение покупателей и искажая фискальную отчетность для налоговой службы.
Для исправления этой коллизии нам необходимо синхронизировать типы оплат в базе данных 1С и настройках драйвера кассы. Выполним следующие шаги:
Дополнительно рекомендуется проверить настройки таблиц оплат в самой ККТ через утилиту «Тест драйвера ККТ». Перейдите в раздел «Свойства» -> «Параметры ККТ» -> «Настройки оплат» и убедитесь, что под индексом 1 зафиксирован тип оплаты «Безналичные».
Важно понимать, что старый драйвер DTO 8 (компонента AddIn.FPrnM45) официально признан устаревшим (deprecated) компанией Атол и больше не поддерживается. Он не умеет корректно работать со многими обязательными тегами новых форматов ФФД 1.05 и 1.2 (такими как маркировка товаров «Честный Знак», ИНН поставщика, агентские реквизиты и др.). Чтобы избежать регулярных технических сбоев, настоятельно рекомендуется переписать программную интеграцию на современный 10-й драйвер.
Проанализируем пример того, как аналогичная операция регистрации товара и закрытия чека возврата выглядит в среде 1С:Предприятие при использовании современного кроссплатформенного драйвера DTO 10 (AddIn.Fptr10):
// Инициализируем современный драйвер Атол v10
Попытка
Драйвер = Новый COMОбъект("AddIn.Fptr10");
Исключение
Предупреждение("Не удалось загрузить драйвер ККТ Атол 10-й версии!");
Возврат;
КонецПопытки;
// Настройка соединения с кассой
Драйвер.setSingleSetting("Model", "67"); // Атол 11Ф
Драйвер.setSingleSetting("Port", "1"); // COM-порт (системный индекс)
Драйвер.setSingleSetting("BaudRate", "115200");
Драйвер.applySingleSettings();
// Соединение с ККТ
Драйвер.connect();
Если Не Драйвер.isOpened() Тогда
Сообщить("Ошибка подключения к ККТ: " + Драйвер.errorDescription());
Возврат;
КонецЕсли;
// Авторизация кассира (Обязательный реквизит по ФФД)
Драйвер.setParam(1021, "Иванов И.И."); // Имя кассира
Драйвер.setParam(1203, "123456789012"); // ИНН кассира
Драйвер.operatorLogin();
// Открытие чека возврата прихода
// LIBFPTR_CHEQUE_RETURN_BUY - константа для возврата прихода (значение 2)
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_RECEIPT_TYPE, Драйвер.LIBFPTR_RT_BUY_RETURN);
Драйвер.openReceipt();
// Регистрация позиции товара
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_COMMODITY_NAME, "Возвратный товар");
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_PRICE, 40.00);
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_QUANTITY, 1.000);
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_TAX_TYPE, Драйвер.LIBFPTR_TAX_NO); // Без НДС
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_USE_ONLY_TAX_TYPE, Истина);
Драйвер.registerPosition();
// Проводим оплату безналичным типом (Электронными)
// LIBFPTR_PT_ELECTRONICALLY - константа безналичной оплаты (индекс 1)
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_PAYMENT_TYPE, Драйвер.LIBFPTR_PT_ELECTRONICALLY);
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_PAYMENT_SUM, 40.00);
Драйвер.payment();
// Финализация и закрытие чека
Драйвер.closeReceipt();
// Проверка корректности закрытия чека
Если Драйвер.getParamBool(Драйвер.LIBFPTR_PARAM_DOCUMENT_CLOSED) Тогда
Сообщить("Чек возврата успешно пробит и закрыт!");
Иначе
// Если чек не закрылся (например, из-за ошибки ФН или связи)
Сообщить("Ошибка закрытия чека: " + Драйвер.errorDescription());
Драйвер.cancelReceipt(); // Отменяем зависший документ
КонецЕсли;
// Отключение от устройства
Драйвер.disconnect();
Переход на DTO 10 решает большинство проблем совместимости ККТ с новыми требованиями законодательства. Драйвер 10-й версии самостоятельно контролирует передачу обязательных фискальных тегов, имеет встроенные механизмы проверки валидности данных и информативные описания ошибок на русском языке, что значительно упрощает отладку кода для программиста 1С.