Справка
hw-connector · локальный веб-сервис для торгового оборудования
Swagger UI ← На сайт

hw-connector

Локальный веб-сервис, через который веб-приложения работают с торговым оборудованием компьютера: ККТ, банковскими терминалами, принтерами и сканерами штрихкодов.

Сервис запускается на компьютере, к которому подключено оборудование, и принимает запросы только с этого компьютера: http://localhost:7790. У него две стороны:

Сервис работает в фоне, показывает значок в трее Windows и запускается вместе с Windows.

Быстрый старт

  1. Установите ПО оборудования, если оно нужно (см. Оборудование): драйвер ДТО10 x64 для ККТ АТОЛ, программу банка для терминала.
  2. Откройте страницу настройки: значок в трее → «Открыть интерфейс» или http://localhost:7790/.
  3. На вкладке «Оборудование» нажмите «Подключить устройство», выберите тип, заполните поля и нажмите «Сохранить и проверить». Карточка устройства покажет «на связи» или что исправить.
  4. На вкладке «Принтеры» назначьте принтеры для билетов и документов, задайте бумагу и напечатайте тестовую страницу.
  5. На вкладке «Рабочее место» укажите кассира и, если нужно, почту отправителя, место расчётов и СНО.
  6. Подключите веб-приложение к API (см. API).

Язык интерфейса переключается кнопками RU / EN в заголовке страницы, справки и в меню значка в трее.

Карточки устройств: ККТ, терминалы, принтеры без драйвера, дисплеи покупателя, сканеры, считыватели карт, денежные ящики, порты. Номер в углу карточки (№1, №2…) — номер устройства в API.

Значения по умолчанию для операций ККТ. Сервис подставляет их, только если в запросе их нет; переданное в запросе всегда важнее.

Ниже на той же вкладке — доступ к агенту и печать PDF. Изменения действуют сразу, без перезапуска, и сохраняются в data\access.json; «Как в файле настроек» возвращает значения из config\application.yml.

Все операции с устройствами: статус, что происходит сейчас, результат или ошибка. Обновляется вживую (зелёная точка у вкладки — события подключены). Щелчок по строке показывает операцию целиком. Хранятся 1000 последних операций, в том числе после перезапуска.

Значок показывает, что сервис работает; подсказка и верхние строки меню — версия, число включённых устройств и порт. Двойной щелчок открывает интерфейс. Меню (правая кнопка):

Поддерживаемое оборудование

УстройствоКак подключаетсяЧто нужно на компьютере
ККТ АТОЛ (платформа 5)COM-порт, USB, сетьДрайвер ДТО10 x64
ККТ Штрих-М, Меркурий в режиме ФР, Ритейл, ЭЛВЕС, PaykioskСеть или USB (RNDIS, порт 7778), COM-порт; протокол обмена версии 1 или 2Ничего: сервис работает с ККТ напрямую
ККТ Пирит 2Ф, Вики Принт 57/80, Дримкас-ФCOM-порт (по умолчанию 57600), сеть через модуль Wi-FiНичего; режим ФФД 1.2
ККТ КИТ (КАСБИ): КИТ Онлайн-Ф, Терминал-ФАСеть (порт 50003) или COM-порт; ФФД 1.05 и 1.2Ничего; денежный ящик к КИТ не подключается
Терминал INPAS (Verifone, PAX)Через DualConnectorINPAS DualConnector
Терминал СбербанкаЧерез UPOS (sb_pilot.exe)Дистрибутив UPOS, порт пинпада — в его pinpad.ini
Терминал ARCUS 2 (Ingenico)Через Аркус-2 (CommandLineTool.exe)ПО Аркус-2
Терминал UCSКабель (COM-порт) или сетьНичего
Терминал с протоколом ТТК2Сеть (обычно порт 888)Ничего; на терминале включить приём команд от кассы
Оплата по QR через СБП: Т-Банк, СбербанкИнтернет-эквайринг банка по HTTPSНичего; ключи из договора эквайринга с подключённым СБП
Принтер чеков ESC/POS (Epson, Xprinter, Posiflex, АТОЛ, Штрих…)Сеть (порт 9100), COM-порт, принтер Windows в режиме RAWНичего; для USB без COM — принтер в Windows (подойдёт Generic / Text Only)
Принтер этикеток и билетов ZPL (Zebra), TSPL (TSC), EZPL (Godex)Сеть (9100), COM-порт, принтер Windows в режиме RAWТак же
Билетный принтер Boca Systems (FGL)Сеть (9100), COM-порт, принтер Windows в режиме RAW; 200 или 300 dpiТак же
Любой принтер WindowsДрайвер WindowsДрайвер принтера
Дисплей QR-кодов Mertech QR-PA, QR-ScreenCOM-порт (USB как виртуальный COM)Драйвер виртуального COM дисплея
Дисплей покупателя VFD/LCD (Epson ESC/POS, CD5220)COM-порт (USB как виртуальный COM)Драйвер виртуального COM дисплея
Дисплей покупателя на втором монитореСтраница display.html?device=N во весь экранБраузер
Денежный ящикЧерез ККТ, через принтер ESC/POS или свой COM-портНичего
Сканер штрихкодовCOM-порт (USB как виртуальный COM) или USB HID POSДля COM — драйвер виртуального COM сканера
Считыватель карт NFC/RFID (ACR122U, ACR1252, Omnikey…)USB, PC/SCДрайвер CCID считывателя (обычно ставится сам), служба «Смарт-карта»
ИБПUSB, Windows видит его как батареюНичего
Другое устройство на COM-порту или в сети«Порт устройства»: байты отправляет и получает приложениеНичего

Для проверки без оборудования есть эмуляторы ККТ и терминала (группа «Для разработки»).

Совместимые ККТ

Многие ККТ других марок внутри работают по протоколу Штрих-М или Пирит. Для них не нужен отдельный драйвер: в окне «Подключить устройство» у каждой есть свой пункт, а настройки те же, что у ККТ с этим протоколом.

ККТПротоколКак подключить
Ритейл-01Ф, Ритейл-02Ф, Ритейл-Комбо-01ФШтрих-МПункт «Ритейл»: USB (RNDIS, 192.168.137.111, порт 7778) или COM-порт; пароли кассира и администратора по умолчанию 30
ЭЛВЕС-ФР-ФШтрих-МПункт «ЭЛВЕС»: так же, как Штрих-М
Paykiosk PayOnline-01-ФА, Pay VKP-80К-ФАШтрих-МПункт «Paykiosk»: обычно USB как виртуальный COM-порт — выберите «COM-порт» и нажмите «Найти порты»
РР-01Ф, РР-02Ф, РР-03Ф, РР-04Ф (РР-Электро)Штрих-М, обычно обмен версии 2Пункт «РР-Электро»: так же, как Штрих-М; версия протокола 2 выбрана по умолчанию
Меркурий в режиме ФРШтрих-МПункт «Штрих-М, Меркурий»
Вики Принт 57Ф, 57+Ф, 80+Ф (Дримкас)ПиритПункт «Вики Принт»: COM-порт (USB как виртуальный COM, 57600) или сеть через модуль Wi-Fi; пароль связи PIRI
Пирит 1Ф, 2Ф, 2СФ (Кристалл Сервис)ПиритПункт «Пирит»

Если связи нет, проверьте на самой ККТ скорость COM-порта и версию протокола обмена: обычно они печатаются в тесте ККТ при включении с нажатой кнопкой протяжки.

Оплата по QR (СБП). «СБП по QR» подключается как банковский терминал и вызывается теми же методами /terminals/{id}/…. При оплате приложение создаёт платёж в банке и показывает QR-код: в окне приложения, на дисплее покупателя, номер которого указан в настройке (второй монитор, дисплей QR-кодов Mertech или QR-Screen), и событием qr для вашей программы. Покупатель сканирует QR в приложении своего банка, приложение каждые 2 секунды спрашивает банк о статусе. Не оплатили за время ожидания — платёж отменяется. Номер платежа в банке возвращается в paymentRef.idProcessing, по нему делается возврат. Сверка итогов для СБП не нужна.

API

Принципы

Методы

МетодЧто делает
GET/api/v1/healthСервис работает: версия, время запуска, питание (сеть или батарея)
GET/api/v1/devicesУстройства: номер, вид, тип, название
GET/api/v1/registers/{id}/shiftСостояние смены ККТ
POST/api/v1/registers/{id}/shift/openОткрыть смену {operator}*
POST/api/v1/registers/{id}/shift/closeЗакрыть смену (Z-отчёт) {operator}*
POST/api/v1/registers/{id}/reports/xX-отчёт {operator}*
POST/api/v1/registers/{id}/reports/calculation-stateОтчёт о текущем состоянии расчётов {operator}*
GET/api/v1/registers/{id}/countersСчётчики ККТ: число чеков и суммы по признакам расчёта за смену и за всё время ФН (АТОЛ, Штрих-М, Пирит)
GET/api/v1/registers/{id}/fn-documents/{n}Документ из ФН по номеру (АТОЛ, Штрих-М)
POST/api/v1/registers/{id}/fn-documents/{n}/printНапечатать копию документа из ФН (АТОЛ, Пирит)
POST/api/v1/registers/{id}/cash/inВнесение наличных {operator*, amount}
POST/api/v1/registers/{id}/cash/outВыплата наличных {operator*, amount}
POST/api/v1/registers/{id}/cash-drawer/openОткрыть денежный ящик
POST/api/v1/registers/{id}/receiptsПробить чек
POST/api/v1/registers/{id}/correctionsЧек коррекции {receipt, correction: {type: SELF|INSTRUCTION, baseDate, baseNumber}} — АТОЛ, Штрих-М, Пирит
POST/api/v1/registers/{id}/documentsНапечатать нефискальный текст {lines}
POST/api/v1/terminals/{id}/paymentsОплата картой {amount}
POST/api/v1/terminals/{id}/refundsВозврат на карту {amount, paymentRef}
POST/api/v1/terminals/{id}/cancellationsОтмена оплаты в тот же день {amount, paymentRef}
POST/api/v1/terminals/{id}/settlementsСверка итогов
POST/api/v1/terminals/{id}/emergency-reversalsАварийная отмена последней операции, если касса не получила её результат {amount, paymentRef?}
POST/api/v1/terminals/{id}/reports?full=falseОтчёт терминала по операциям смены без сверки: краткий или полный (full=true)
GET/api/v1/terminals/{id}/last-slipСлип последней успешной операции из журнала — чтобы напечатать ещё раз
GET/api/v1/qr?text=…&size=400Картинка QR-кода PNG, например для payload из события qr
POST/api/v1/checkoutsПродажа или возврат целиком: карта → чек → слип; если чек не напечатан — оплата отменяется
GET/api/v1/printersПринтеры Windows, назначения, настройки
POST/api/v1/print-jobsПечать: urls, document (PDF base64), images, raw, report или text (строки, только для принтера без драйвера); printer, device (принтер без драйвера) или role, copies
POST/api/v1/cash-drawers/{id}/openОткрыть денежный ящик: id — ККТ, принтер ESC/POS или ящик на COM-порту
POST/api/v1/displays/{id}Показать строки на дисплее покупателя {lines}; пустой список — очистить
POST/api/v1/displays/{id}/qrПоказать QR-код на дисплее QR-кодов или втором мониторе {payload, top, bottom}; пустой payload — убрать
GET/api/v1/displays/{id}Что показано на дисплее
POST/api/v1/channels/{id}/exchangeОтправить байты в порт устройства и получить ответ {hex | base64 | text, readTimeoutMs, until}
GET/api/v1/reportsШаблоны отчётов с параметрами и полями
POST/api/v1/reports/{name}/renderPDF по шаблону {parameters, rows} — сразу, не операция
GET/api/v1/operations/{id}Операция; с Prefer: wait=N ждёт окончания
GET/api/v1/operations?limit=50Последние операции
GET/api/v1/eventsСобытия (SSE)

* operator можно не передавать, если кассир задан на вкладке «Рабочее место». Тело запроса тогда тоже не нужно.

Методы /api/v1/setup/… обслуживают страницу настройки и доступны только с неё.

Чек

{
  "type": "SELL",                       // SELL, SELL_RETURN, BUY, BUY_RETURN
  "taxation": "USN_INCOME",             // OSN, USN_INCOME, USN_INCOME_OUTCOME, ESHN, PATENT; нет — из «Рабочего места» или СНО ККТ
  "operator": {"name": "Иванова И.И.", "inn": "770123456789"},   // нет — кассир из «Рабочего места»
  "customer": {"contact": "+79991234567"},   // для электронного чека
  "header": [
    {"kind": "TEXT", "text": "Заказ 123", "align": "CENTER"},
    {"kind": "PAIR", "text": "Дата:", "right": "01.11.2026 19:00"},
    {"kind": "SEPARATOR"}
  ],
  "items": [
    {"name": "Услуга", "price": 150000, "quantity": 1, "amount": 150000,
     "vat": "NONE", "paymentMethod": "FULL_PAYMENT", "paymentObject": "SERVICE"}
  ],
  "payments": [{"type": "CARD", "amount": 150000}],   // CASH, CARD, PREPAID, CREDIT, OTHER
  "footer": [],
  "electronic": false,                  // true — не печатать, отправить покупателю
  "senderEmail": "kassa@example.ru",    // тег 1117; нет — из «Рабочего места»
  "settlementPlace": "Касса"            // тег 1187; нет — из «Рабочего места»
}

Сумма оплат должна быть равна сумме позиций, стоимость позиции — цене × количество. Строки текста переносятся по ширине ленты ККТ автоматически.

Примеры

Продажа с оплатой картой — оплата, чек и слип одной операцией:

POST /api/v1/checkouts
Content-Type: application/json
Idempotency-Key: 3f6c1d9e-1b2a-4c55-9e0d-6a1f0c2b7d11
Prefer: wait=170

{"registerId": 1, "terminalId": 2, "receipt": { … }, "printSlip": true}

Ответ: операция с result.receipt (номер ФД, ФП, смена, QR-код) и result.payment (paymentRef, карта, RRN, код авторизации, слип). paymentRef нужен для возврата.

Печать PDF на принтер билетов:

POST /api/v1/print-jobs
Idempotency-Key: …

{"urls": ["https://example.com/tickets/1.pdf"], "role": "tickets", "copies": 1}

Отчёт по шаблону — сразу PDF или на принтер:

POST /api/v1/reports/ACT/render
{"parameters": {"NUMBER": "15", "DATE": "2026-11-01"},
 "rows": [{"NAME": "Позиция 1", "PRICE": 1500}]}

POST /api/v1/print-jobs
{"report": {"name": "ACT", "parameters": { … }, "rows": [ … ]}, "role": "documents"}

Билеты по шаблону TICKET — по билету на строку, на принтер билетов:

POST /api/v1/print-jobs
Idempotency-Key: …

{"report": {"name": "TICKET", "rows": [
  {"top_line": "ООО Концерты", "pos_line": "Большой зал", "addr_line": "ул. Тверская, 1",
   "service_line": "Концерт (12+)", "date_line": "Дата: 01.11.2026 Время начала: 19:00",
   "place_line": "Партер ряд 5 место 12", "price_line": "Стоимость услуги: 1500.00 р.",
   "sold_line": "31.10.2026 10:00 Кассир: Иванова И.И.", "sale_line": "1911-000123"}
 ]}, "role": "tickets"}

Команды принтера как есть (ESC/POS, ZPL) — например, этикетка ZPL:

POST /api/v1/print-jobs
{"raw": "XlhBXkZPNTAsNTBeQTBOLDUwXkZESGVsbG9eRlNeWFo=", "printer": "Zebra ZD220"}

Ожидание операции и события в браузере:

const events = new EventSource('http://localhost:7790/api/v1/events');
events.addEventListener('operation', e => {
  const op = JSON.parse(e.data);
  console.log(op.type, op.status, op.stage);    // «Приложите карту к терминалу»
});
events.addEventListener('barcode', e => console.log(JSON.parse(e.data).code));

Ошибки

Ошибки запроса — ответ в формате RFC 9457 (application/problem+json) с полем code:

HTTPcodeКогда
400INVALID_REQUEST или нетНеверный JSON, нет Idempotency-Key, нарушены ограничения полей (тогда code: INVALID_REQUEST и поля в detail)
404DEVICE_NOT_FOUND, REPORT_NOT_FOUNDНет такого устройства или шаблона
409IDEMPOTENCY_KEY_REUSED, DEVICE_BUSYКлюч уже использован для другой операции; устройство занято
422VALIDATION_ERROR, REPORT_ERRORСуммы не сходятся, не указан кассир, неверное значение параметра, шаблон с ошибкой

Ошибки устройства приходят в самой операции: status: FAILED, error: {code, message, details}.

codeЧто произошло
DEVICE_ERRORОшибка ККТ, терминала или принтера; текст — в message
PAYMENT_CANCELLEDЧек не напечатан после оплаты картой; оплата отменена на терминале
PAYMENT_NOT_CANCELLEDЧек не напечатан, отменить оплату не удалось; данные оплаты — в details
RECEIPT_FAILED_AFTER_REFUNDДеньги на карту возвращены, чек возврата не напечатан
INTERRUPTEDСервис перезапустился во время операции

Настройки и файлы

Устройства, назначения и настройки принтеров, рабочее место, доступ и ограничения печати меняются на странице настройки (значения со страницы важнее файла). Остальное — в файле config\application.yml в папке программы:

ПараметрЧто задаёт
server.portПорт агента, по умолчанию 7790; нужен перезапуск
hw.allowed-originsАдреса веб-приложений, которым разрешено обращаться к сервису из браузера
hw.api-tokenТокен: если задан, запросы к API должны нести Authorization: Bearer <токен> (для событий — ?access_token=)
hw.printer.allowed-url-prefixesАдреса, с которых разрешено скачивать PDF для печати
hw.reports.dir, hw.reports.fontПапка шаблонов отчётов и шрифт с кириллицей для PDF
hw.trayfalse — без значка в трее
hw.power-monitorfalse — не следить за питанием
ПапкаЧто в ней
data\devices.jsonУстройства
data\printers.jsonНазначения и настройки принтеров
data\ui.jsonЯзык интерфейса
data\workplace.jsonРабочее место: кассир и реквизиты по умолчанию
data\access.jsonДоступ и печать, заданные на странице настройки
data\operations.jsonlЖурнал операций
reports\Шаблоны отчётов, картинки, подотчёты
logs\Логи, 30 дней

Безопасность