При организации работы кассовой техники в крупных компаниях, распределенных сетях или на терминальных серверах (RDP) системные администраторы и программисты часто сталкиваются с технической задачей: можно ли физически подключить ККТ АТОЛ к одному компьютеру, а базу «1С:Бухгалтерия» запускать на другом компьютере (или в облаке), избежав при этом установки локального драйвера кассы на рабочее место пользователя?
В этой статье мы подробно разберем, как устроена сетевая архитектура взаимодействия «1С:Предприятие» и ККТ АТОЛ через драйвер 10-й версии (ДТО 10). Мы проанализируем два принципиальных подхода к решению этой задачи, рассмотрим конкретные примеры программного кода, а также разберем критически важные лицензионные ограничения современных версий программного обеспечения АТОЛ.
---
В рамках стандартного функционала «1С» и возможностей ДТО 10 у нас есть два пути реализации такой схемы. Они принципиально отличаются как по сложности реализации, так и по требованиям к наличию локального программного обеспечения на стороне пользователя.
Рассмотрим оба варианта подробнее.
---
Этот способ позволяет реализовать схему, при которой на компьютере пользователя с запущенной «1С» действительно не устанавливается никаких драйверов, утилит или динамических библиотек (DLL) от компании АТОЛ.
Архитектурная схема решения выглядит следующим образом:
16732.Основная сложность данного подхода заключается в том, что штатная библиотека подключаемого оборудования (БПО), встроенная в «1С:Бухгалтерия 3.0», не умеет «из коробки» отправлять JSON-запросы на веб-сервер АТОЛ. Стандартный механизм БПО всегда требует наличия локальной компоненты. Поэтому для реализации этой схемы программисту необходимо написать собственный код интеграции.
Давайте разберем по шагам, как устроен этот процесс программно.
Взаимодействие с веб-сервером АТОЛ является асинхронным. Процесс печати чека состоит из двух этапов:
Ниже представлен пример кода на языке «1С:Предприятие» для отправки задания на веб-сервер АТОЛ:
// Функция отправляет задание на печать чека продажи на веб-сервер ККТ
Функция ОтправитьЧекНаВебСервер(АдресСервера, Порт, ДанныеЧека, Логин = "", Пароль = "") Экспорт
// Создаем HTTP-соединение с компьютером, к которому подключена касса
HTTPСоединение = Новый HTTPСоединение(АдресСервера, Порт);
// Формируем запрос к API веб-сервера АТОЛ (версия API v10)
HTTPЗапрос = Новый HTTPЗапрос("/api/v10/tasks");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
// Если на веб-сервере включена авторизация (обязательно для ДТО 10.9.4.0+)
Если ЗначениеЗаполнено(Логин) Тогда
СтрокаАвторизации = Логин + ":" + Пароль;
// Кодируем учетные данные в формат Base64
ТокенАвторизации = ПолучитьBase64СтрокуИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки(СтрокаАвторизации, КодировкаТекста.UTF8));
HTTPЗапрос.Заголовки.Вставить("Authorization", "Basic " + ТокенАвторизации);
КонецЕсли;
// Генерируем уникальный идентификатор задачи
UUIDЗадачи = Строка(Новый УникальныйИдентификатор);
// Формируем тело запроса в формате JSON по спецификации АТОЛ
ТекстJSON =
"{
| ""uuid"": """ + UUIDЗадачи + """,
| ""request"": [
| {
| ""type"": ""sell"",
| ""operator"": {
| ""name"": """ + ДанныеЧека.Кассир + """
| },
| ""items"": [
| {
| ""type"": ""position"",
| ""name"": """ + ДанныеЧека.НаименованиеТовара + """,
| ""price"": " + Формат(ДанныеЧека.Цена, "ЧГ=0; ЧДЦ=2") + ",
| ""quantity"": " + Формат(ДанныеЧека.Количество, "ЧГ=0; ЧДЦ=3") + ",
| ""amount"": " + Формат(ДанныеЧека.Сумма, "ЧГ=0; ЧДЦ=2") + ",
| ""department"": 1,
| ""tax"": {
| ""type"": ""none""
| }
| }
| ],
| ""payments"": [
| {
| ""type"": ""electronically"",
| ""amount"": " + Формат(ДанныеЧека.Сумма, "ЧГ=0; ЧДЦ=2") + "
| }
| ],
| ""total"": " + Формат(ДанныеЧека.Сумма, "ЧГ=0; ЧДЦ=2") + "
| }
| ]
|}";
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8);
Попытка
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если Ответ.КодСостояния = 201 Или Ответ.КодСостояния = 200 Тогда
Возврат UUIDЗадачи; // Задание успешно принято сервером
Иначе
ВызватьИсключение "Сервер вернул код ошибки: " + Ответ.КодСостояния;
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("ККТ_ВебСервер", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Не удалось связаться с веб-сервером ККТ.";
КонецПопытки;
КонецФункции
После отправки задания нам необходимо запустить цикл ожидания фискализации чека. Рассмотрим пример кода для получения статуса задачи:
// Функция ожидает выполнение задачи фискализации кассой
Функция ОжидатьВыполнениеЧека(АдресСервера, Порт, UUIDЗадачи, Логин = "", Пароль = "") Экспорт
HTTPСоединение = Новый HTTPСоединение(АдресСервера, Порт);
HTTPЗапрос = Новый HTTPЗапрос("/api/v10/tasks/" + UUIDЗадачи);
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
Если ЗначениеЗаполнено(Логин) Тогда
СтрокаАвторизации = Логин + ":" + Пароль;
ТокенАвторизации = ПолучитьBase64СтрокуИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки(СтрокаАвторизации, КодировкаТекста.UTF8));
HTTPЗапрос.Заголовки.Вставить("Authorization", "Basic " + ТокенАвторизации);
КонецЕсли;
// Опрашиваем сервер в течение максимум 15 секунд
Для Итератор = 1 По 15 Цикл
Попытка
Ответ = HTTPСоединение.Получить(HTTPЗапрос);
Если Ответ.КодСостояния = 200 Тогда
СтрокаJSON = Ответ.ПолучитьТелоИзСтроки(КодировкаТекста.UTF8);
// Читаем полученный JSON
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Результат = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
СтатусЗадачи = Результат.results.status;
Если СтатусЗадачи = "ready" Тогда
Возврат Истина; // Чек успешно напечатан и фискализирован!
ИначеЕсли СтатусЗадачи = "error" Тогда
ВызватьИсключение "Ошибка ККТ: " + Результат.results.errorDescription;
КонецЕсли;
КонецЕсли;
Исключение
ВызватьИсключение "Ошибка при проверке статуса чека: " + ОписаниеОшибки();
КонецПопытки;
// Делаем небольшую паузу перед повторным запросом
#Если Клиент Тогда
СигналыОповещения = Новый ОписаниеОповещения;
ПодключитьОбработчикОжидания("ПустаяПроцедураДляПаузы", 1, Истина);
#КонецЕсли
КонецЦикла;
ВызватьИсключение "Таймаут ожидания печати чека.";
КонецФункции
---
Если вы хотите настроить систему стандартным путем, используя встроенное в «1С:Бухгалтерия 3.0» меню «Администрирование -> Подключаемое оборудование», то полностью отказаться от установки драйверов на компьютер пользователя не получится.
Для сетевой работы БПО использует механизм удаленного вызова процедур — RPC-сервер АТОЛ:
Почему в этой схеме нельзя обойтись без локального драйвера?
Штатная обработка обслуживания «1С» использует локальную внешнюю компоненту (файл FprnM1C.dll), которая обращается к системным библиотекам ДТО 10, установленным на Компьютере Б. Именно эта локальная библиотека упаковывает команды 1С в XML-пакеты и отправляет их на удаленный RPC-сервер. Без локальной установки драйвера компонента просто не сможет инициализироваться на рабочем месте пользователя, и «1С» выдаст ошибку.
---
Если вы решили использовать первый сценарий (работа по HTTP API через веб-сервер), необходимо учитывать жесткие изменения в политике лицензирования АТОЛ, которые произошли за последнее время:
atol-fptr-web-server-users.exe, расположенной в папке установленного драйвера, и передавать данные авторизации в заголовках каждого HTTP-запроса (как показано в примере кода выше).---
Если покупка дополнительных лицензий АТОЛ для службы Web Request не укладывается в бюджет проекта, ИТ-специалисты используют проверенные альтернативные варианты решения:
Версия драйвера 10.9.2.3 является последним релизом, где старая служба веб-сервера работает полностью бесплатно, без ограничений по количеству подключаемых IP-адресов и без обязательного лицензирования. Вы можете развернуть этот драйвер на Компьютере А. Однако помните о рисках: старые версии драйверов со временем перестают поддерживать новые требования ФНС (например, новые реквизиты маркировки или изменения в форматах фискальных данных ФФД 1.2).
Для этого используются сторонние программные утилиты (например, HW VSP, Tibbo Virtual Serial Port, USR-VCOM). Схема работы выглядит так:
---
Подводя итог нашему анализу, ответим на вопрос автора: Да, реализовать такую схему можно.
Если вы хотите настроить систему абсолютно «чисто» без установки драйверов на ПК с 1С — используйте Вариант 1 (HTTP API / Web Request) и пишите интеграцию в 1С через HTTPСоединение. Но будьте готовы приобрести платную лицензию АТОЛ для работы веб-службы по сети.
Если вы хотите настроить ККТ стандартными средствами 1С из коробки — используйте Вариант 2 (RPC-сервер), но помните, что на компьютере пользователя вам всё равно придется установить локальный драйвер ККТ АТОЛ для корректной работы БПО.