Как передать дополнительные виды оплаты (бонусы) в ККТ АТОЛ из 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Налоговый учет Торговля и дистрибуция
← На главную

При доработке нетиповых конфигураций (например, на базе УТ 10.3) под требования 54-ФЗ программисты часто сталкиваются с необходимостью отражения специфических видов оплат, таких как «Бонусы», «Подарочные карты» или «Баллы». Несмотря на то, что драйверы ККТ АТОЛ (начиная с версий ДТО 9 и 10) позволяют использовать до 10 типов оплат, стандартные механизмы 1С накладывают жесткие ограничения на структуру передаваемых данных. Разберем детально, почему не получается передать шестой тип оплаты через XML и как решить эту задачу правильно с технической и юридической точек зрения.

Анализ проблемы: почему CashLessType6 не работает

Проанализируем ситуацию, с которой сталкивается разработчик при попытке расширить узел Payments в XML-пакете. Стандартная функция ПолучитьXMLПакетДляФискализацияЧека формирует структуру, которая затем передается компоненте драйвера. В типовом коде мы видим следующее наполнение:


ЗаписьXML.ЗаписатьНачалоЭлемента("Payments");
Если ВерсияФФД > 0 Тогда 
    // Атрибуты согласно ФФД 1.05
    ЗаписьXML.ЗаписатьАтрибут("Cash", XMLСтрока(СуммаНаличными));
    ЗаписьXML.ЗаписатьАтрибут("ElectronicPayment", XMLСтрока(СуммаЭлектронными));
    ЗаписьXML.ЗаписатьАтрибут("Credit", XMLСтрока(СуммаПостоплатой));
    ЗаписьXML.ЗаписатьАтрибут("AdvancePayment", XMLСтрока(СуммаПредоплатой));
    ЗаписьXML.ЗаписатьАтрибут("CashProvision", XMLСтрока(СуммаПредоставлением));
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();

Разберем, почему добавление произвольного атрибута, например CashLessType6, приводит к тому, что ККТ перестает печатать подвал чека или выдает ошибку. Проблема заключается в том, что БПО (Библиотека подключаемого оборудования) и сами драйверы (DLL), поставляемые фирмой 1С, работают строго по определенной XSD-схеме. В этой схеме узел Payments имеет фиксированный набор атрибутов, соответствующих пяти типам оплаты, разрешенным ФФД 1.05 и 1.1/1.2:

  1. Cash (Тег 1031) — Наличные.
  2. ElectronicPayment (Тег 1081) — Безналичные (ранее — электронные).
  3. AdvancePayment (Тег 1215) — Предоплата (Аванс).
  4. Credit (Тег 1216) — Постоплата (Кредит).
  5. CashProvision (Тег 1217) — Иная форма оплаты (Встречное предоставление).

Любой другой атрибут, не входящий в этот список, просто игнорируется парсером внутри драйвера или вызывает исключение при проверке XML на соответствие схеме. Именно поэтому попытка «попасть» в шестую строку таблицы оплат ККТ через XML-пакет в рамках стандартного вызова СформироватьЧек обречена на неудачу.

Юридический аспект и ФФД

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

Решение №1: Использование 5-го типа оплаты (рекомендуемое)

Рассмотрим самый простой и надежный способ реализации. Поскольку атрибут CashProvision (Встречное предоставление) уже поддерживается 1С, мы можем направить сумму бонусов в него. Чтобы в чеке вместо надписи «Иная форма оплаты» выводилось слово «БОНУС», необходимо выполнить настройку на стороне самой кассы.

Выполним следующие шаги:

  1. Запустим Тест драйвера ККТ (ДТО 9 или 10).
  2. Перейдем в раздел Настройки (или Параметры ККТ).
  3. Найдем Таблицу 12 «Наименования типов оплаты».
  4. Для 5-го типа оплаты изменим стандартное наименование на «БОНУС».
  5. В коде 1С передадим сумму бонусов в атрибут CashProvision.

Пример модифицированного кода в 1С:


// СуммаБонусы — расчетное значение суммы, оплаченной баллами
ЗаписьXML.ЗаписатьАтрибут("CashProvision", XMLСтрока(СуммаБонусы));

Этот метод позволяет остаться в рамках стандартного обмена 1С и драйвера, обеспечивая при этом корректное отображение информации в чеке и передачу данных в ОФД под тегом 1217.

Решение №2: Распределение бонусов как скидки

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

Выясним общую сумму чека до применения бонусов. Допустим, она составляет 1000 рублей, а бонусов — 100. Это значит, что на каждую позицию нужно применить скидку в 10%. Важно следить за округлением, чтобы сумма скидок по строкам совпала с общей суммой бонусов. После этого в XML-пакет в узел Positions передаются цены уже с учетом скидки, а узел Payments содержит только ElectronicPayment или Cash на сумму 900 рублей.

Преимущество метода: Полное отсутствие проблем с типами оплат и 100% соответствие любым версиям ФФД.

Решение №3: Прямое использование методов драйвера (для продвинутых)

Если вам критически важно использовать именно 6-й, 7-й или последующие типы оплат (например, если 5-й уже занят под подарочные сертификаты), стандартный XML-интерфейс 1С использовать не получится. В этом случае придется отказаться от функции МенеджерОборудованияВызовСервера.СформироватьЧек и взаимодействовать с драйвером напрямую через COM-объект или Native-компоненту.

Рассмотрим пример логики для ДТО 10 (фрагмент кода):


// Инициализация драйвера и открытие чека
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_RECEIPT_TYPE, Драйвер.LIBFPTR_RT_SELL);
Драйвер.openReceipt();

// Регистрация позиций...
// ...

// Регистрация оплаты 6-го типа (например, Бонусы)
Драйвер.setParam(Драйver.LIBFPTR_PARAM_PAYMENT_TYPE, 6); // Номер типа оплаты из Таблицы 12
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_PAYMENT_SUM, СуммаБонусов);
Драйвер.payment();

// Закрытие чека
Драйвер.closeReceipt();

При таком подходе вы полностью обходите ограничения XML-схемы 1С, так как напрямую командуете драйверу использовать конкретный индекс из таблицы типов оплат ККТ. Однако это потребует значительной переработки модуля обмена с оборудованием, так как вам придется вручную обрабатывать открытие смены, регистрацию каждой позиции и ошибки печати.

Выясним причину выбора конкретного метода

Выбор решения зависит от архитектуры вашей системы. Для большинства задач Решение №1 (использование CashProvision) является оптимальным балансом между трудозатратами и результатом. Оно не требует взлома логики БПО и легко поддерживается при обновлениях драйверов. Если же ваша компания ведет строгий учет бонусов как маркетинговых скидок, выбирайте Решение №2. Прямая работа с драйвером (Решение №3) оправдана только в исключительных случаях в высоконагруженных или сильно кастомизированных фронт-офисных решениях.

Помните, что при использовании дополнительных типов оплат (6–10) в АТОЛ, их наименования в Таблице 12 должны быть запрограммированы заранее, иначе в чеке будет печататься стандартный текст вроде «ТИП ОПЛАТЫ 6».

← На главную