Как подключить локальные физические онлайн-кассы 54-ФЗ без статического белого IP через веб-сервис

Программист Торговля и дистрибуция
← На главную

При автоматизации розничной торговли, интернет-магазинов или курьерских служб разработчики часто сталкиваются со следующей проблемой: физические онлайн-кассы (ККТ) подключены к локальным компьютерам в точках продаж, на складах или в офисах, где отсутствует выделенный статический IP-адрес (компьютеры находятся за NAT провайдера). При этом центральная учетная система (например, облачная 1С или CRM) развернута на сервере с публичным IP-адресом и должна отправлять команды на пробитие чеков напрямую на эти кассы.

Стандартная «Push-модель», при которой облачный сервер пытается сам инициировать соединение с локальной кассой, в таких условиях не работает без покупки дорогостоящих «белых» IP-адресов или сложной настройки VPN/SSH-туннелей. В этой статье мы подробно разберем, как решить эту задачу с помощью «Pull-модели» (обратного вызова), готовых облачных мостов и современных облегченных туннелей.

Архитектурный подход: Push-модель против Pull-модели

Для начала проанализируем разницу в архитектурных подходах передачи команд на ККТ:

  1. Push-модель (классическая): Облачный веб-сервер генерирует чек и отправляет HTTP-запрос на IP-адрес кассового компьютера. Этот способ требует наличия статического публичного IP-адреса на стороне кассы и проброса портов на роутере. Любая смена IP у провайдера или сбой маршрутизации приводят к остановке печати чеков.
  2. Pull-модель (обратный вызов / Callback): Локальный кассовый сервер сам выступает в роли клиента. Он регулярно отправляет исходящие запросы к облачному веб-сервису, спрашивая: «Есть ли для меня новые чеки в очереди?». Если чеки есть, веб-сервис отдает их в ответе на запрос, локальный сервер печатает чек и следующим запросом возвращает статус фискализации (успех или ошибка). Этот метод работает из-под любого серого IP-адреса и не требует настройки сетевого оборудования.

Рассмотрим подробнее три основных практических сценария реализации такой схемы.

Решение 1. Использование KkmServer в режиме «Обратного вызова»

Популярный программный продукт KkmServer поддерживает штатный режим работы по Pull-модели, который называется «Обратный вызов». При такой настройке локально установленный кассовый сервер сам опрашивает центральную базу данных.

Разберем по шагам, как организовать очередь чеков на стороне 1С (или любого другого веб-сервиса) для работы с обратным вызовом:

Шаг 1. Создание HTTP-сервиса на стороне 1С (или веб-сервера)

Вам необходимо реализовать API-эндпоинт, который будет принимать запросы от KkmServer. Локальный сервер кассы будет периодически присылать POST-запрос с данными о своем состоянии.

Посмотрим на пример реализации обработки такого запроса в HTTP-сервисе 1С:


// Метод HTTP-сервиса для обработки обратного вызова KkmServer
Функция ПолучитьКомандуДляККМ(Запрос)
    
    // Читаем JSON, пришедший от локального KkmServer (содержит статус кассы)
    СтрокаJSON = Запрос.ПолучитьТелоКакСтроку("UTF-8");
    ДанныеКассы = ДесериализоватьJSON(СтрокаJSON);
    ИдентификаторКассы = ДанныеКассы.УникальныйИдентификаторККМ;
    
    ОтветСтруктура = Новый Структура;
    
    // Ищем в нашей базе подготовленные к печати чеки для этой конкретной кассы
    ЗапросОчереди = Новый Запрос;
    ЗапросОчереди.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	ОчередьЧеков.Ссылка КАК Ссылка,
        |	ОчередьЧеков.ТелоКоманды KkmServer КАК ДанныеЧека
        |ИЗ
        |	Справочник.ОчередьЧековККМ КАК ОчередьЧеков
        |ГДЕ
        |	ОчередьЧеков.ИдентификаторКассы = &ИдентификаторКассы
        |	И ОчередьЧеков.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЧековОчереди.Подготовлен)";
    
    ЗапросОчереди.УстановитьПараметр("ИдентификаторКассы", ИдентификаторКассы);
    РезультатЗапроса = ЗапросОчереди.Выполнить();
    
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        
        // Помещаем JSON-команду пробития чека в ответ KkmServer'у
        ДанныеКоманды = ДесериализоватьJSON(Выборка.ДанныеЧека);
        ОтветСтруктура.Вставить("Command", ДанныеКоманды);
        
        // Фиксируем транзакцию: меняем статус чека в очереди на "Отправлен"
        ОбъектОчереди = Выборка.Ссылка.ПолучитьОбъект();
        ОбъектОчереди.Статус = Перечисления.СтатусыЧековОчереди.ОтправленВККМ;
        ОбъектОчереди.Записать();
    Иначе
        // Если команд на печать нет, возвращаем пустой ответ
        ОтветСтруктура.Вставить("Command", Неопределено);
    КонецЕсли;
    
    // Формируем HTTP-ответ
    ТелоОтвета = СериализоватьВJSON(ОтветСтруктура);
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.УстановитьТелоИзСтроки(ТелоОтвета, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    Ответ.Заголовки.Вставить("Content-Type", "application/json");
    
    Возврат Ответ;
КонецФункции

Шаг 2. Настройка KkmServer на локальном компьютере

В настройках локального KkmServer в разделе «Обратный вызов» необходимо указать URL вашего HTTP-сервиса (например, https://my-server.ru/hs/kkm-api/v1/poll) и интервал опроса (например, каждые 3–5 секунд). Теперь локальный сервер будет самостоятельно стучаться в вашу 1С, забирать команды на фискализацию и возвращать результаты выполнения.

Решение 2. Использование готовых облачных шлюзов и мостов

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

Решение 3. Обход NAT с помощью легковесных туннелей (Альтернатива VPN)

Если вам все же необходимо сохранить классическую Push-модель (когда облачный сервер мгновенно отправляет POST-запрос на локальный IP-адрес кассы), но вы не хотите настраивать сложные корпоративные сети IPSec или OpenVPN, отличным выходом будет использование современных легковесных туннелей приложений.

Проанализируем работу бесплатного и безопасного инструмента — Cloudflare Tunnel (cloudflared):

  1. На локальный кассовый компьютер (где запущен KkmServer на порту 5893) устанавливается консольный агент cloudflared.
  2. Агент создает защищенное исходящее соединение (туннель) до ближайшей точки присутствия сети Cloudflare.
  3. В панели управления Cloudflare вы привязываете этот туннель к вашему доменному имени (например, kassa1.yourfirm.ru).
  4. Все входящие HTTPS-запросы на адрес https://kassa1.yourfirm.ru будут автоматически, безопасно и с минимальной задержкой перенаправляться внутри туннеля на локальный адрес http://localhost:5893 кассового компьютера.

Этот способ полностью решает проблему «серого» IP-адреса, обеспечивает сквозное шифрование трафика и избавляет от необходимости администрировать сложные сетевые маршруты. Аналогичным образом можно использовать легковесную утилиту с открытым исходным кодом FRP (Fast Reverse Proxy), развернув ее клиентскую часть на кассовом ПК, а серверную — на вашем VPS с белым IP.

Резюме и рекомендации

Выбор конкретного решения зависит от квалификации вашей команды разработки и архитектуры системы:

← На главную