Help
hw-connector · local web service for point-of-sale hardware
Swagger UI ← To the website

hw-connector

A local web service through which web applications work with the computer's point-of-sale hardware: fiscal registers, payment terminals, printers, customer displays, scanners and card readers.

The service runs on the computer the hardware is connected to and accepts requests only from that computer: http://localhost:7790. It has two sides:

The service runs in the background, shows an icon in the Windows tray and starts with Windows.

Quick start

  1. Install the hardware software if needed (see Hardware): the DTO10 x64 driver for ATOL registers, the bank software for the terminal.
  2. Open the setup page: tray icon → “Open interface” or http://localhost:7790/.
  3. On the Devices tab click “Add device”, choose the type, fill in the fields and click “Save and check”. The device card shows “online” or what to fix.
  4. On the Printers tab assign printers for tickets and documents, set the paper and print a test page.
  5. On the Workplace tab enter the cashier and, if needed, the sender email, place of settlement and tax system.
  6. Connect the web application to the API (see API).

The interface language is switched with the RU / EN buttons in the page header, in the help and in the tray icon menu.

Device cards: fiscal registers, terminals, driverless printers, customer displays, scanners, card readers, cash drawers, ports. The number in the card corner (No. 1, No. 2…) is the device number in the API.

Default values for register operations. The service uses them only when the request does not contain them; what is passed in the request always wins.

Further down the same tab — access to the agent and PDF printing. Changes apply at once, without a restart, and are saved in data\access.json; “As in the settings file” returns the values from config\application.yml.

All device operations: status, what is happening now, result or error. Updates live (the green dot by the tab means events are connected). Clicking a row shows the whole operation. The last 1000 operations are kept, including after a restart.

The icon shows that the service is running; the tooltip and the top menu lines show the version, the number of enabled devices and the port. Double-click opens the interface. Menu (right click):

Supported hardware

DeviceConnectionNeeded on the computer
ATOL fiscal registers (platform 5)COM port, USB, networkDTO10 x64 driver
Shtrih-M registers, Mercury in fiscal printer mode, Retail, ELVES, PaykioskNetwork or USB (RNDIS, port 7778), COM port; exchange protocol version 1 or 2Nothing: the service talks to the register directly
Pirit 2F, Viki Print 57/80, Dreamkas-F registersCOM port (57600 by default), network via the Wi-Fi moduleNothing; FFD 1.2 mode
KIT registers (KASBI): KIT Online-F, Terminal-FANetwork (port 50003) or COM port; FFD 1.05 and 1.2Nothing; a cash drawer cannot be connected to KIT
INPAS terminal (Verifone, PAX)Via DualConnectorINPAS DualConnector
Sberbank terminalVia UPOS (sb_pilot.exe)UPOS distribution, the PIN pad port is in its pinpad.ini
ARCUS 2 terminal (Ingenico)Via Arcus-2 (CommandLineTool.exe)Arcus-2 software
SBP QR payment: T-Bank, SberbankThe bank's internet acquiring over HTTPSNothing; keys from an acquiring contract with SBP enabled
Terminal with the TTK2 protocolNetwork (usually port 888)Nothing; enable commands from the POS on the terminal
UCS terminalCable (COM port) or networkNothing
ESC/POS receipt printer (Epson, Xprinter, Posiflex, ATOL, Shtrih…)Network (port 9100), COM port, Windows printer in RAW modeNothing; for USB without COM — the printer installed in Windows (Generic / Text Only works)
Label and ticket printer ZPL (Zebra), TSPL (TSC), EZPL (Godex)Network (9100), COM port, Windows printer in RAW modeThe same
Boca Systems ticket printer (FGL)Network (9100), COM port, Windows printer in RAW mode; 200 or 300 dpiThe same
Any Windows printerWindows driverPrinter driver
QR code display Mertech QR-PA, QR-ScreenCOM port (USB as a virtual COM)The display's virtual COM driver
VFD/LCD customer display (Epson ESC/POS, CD5220)COM port (USB as a virtual COM)The display's virtual COM driver
Customer display on a second monitorPage display.html?device=N full screenA browser
Cash drawerVia the register, via an ESC/POS printer or its own COM portNothing
Barcode scannerCOM port (USB as a virtual COM) or USB HID POSFor COM — the scanner's virtual COM driver
NFC/RFID card reader (ACR122U, ACR1252, Omnikey…)USB, PC/SCThe reader's CCID driver (usually installs itself), the Smart Card service
UPSUSB, Windows sees it as a batteryNothing
Another device on a COM port or the network“Device port”: the application sends and receives the bytesNothing

To test without hardware there are register and terminal emulators (the “For development” group).

Compatible fiscal registers

Many registers of other brands use the Shtrih-M or Pirit protocol inside. They need no separate driver: each has its own item in the “Add a device” window, and the settings are the same as for registers with that protocol.

RegisterProtocolHow to connect
Retail-01F, Retail-02F, Retail-Combo-01FShtrih-M“Retail” item: USB (RNDIS, 192.168.137.111, port 7778) or COM port; cashier and administrator passwords are 30 by default
ELVES-FR-FShtrih-M“ELVES” item: same as Shtrih-M
Paykiosk PayOnline-01-FA, Pay VKP-80K-FAShtrih-M“Paykiosk” item: usually USB as a virtual COM port — choose “COM port” and press “Find ports”
RR-01F, RR-02F, RR-03F, RR-04F (RR-Electro)Shtrih-M, usually exchange version 2“RR-Electro” item: same as Shtrih-M; protocol version 2 is chosen by default
Mercury in fiscal printer modeShtrih-M“Shtrih-M, Mercury” item
Viki Print 57F, 57+F, 80+F (Dreamkas)Pirit“Viki Print” item: COM port (USB as a virtual COM, 57600) or network via the Wi-Fi module; link password PIRI
Pirit 1F, 2F, 2SF (Crystal Service)Pirit“Pirit” item

If there is no connection, check the COM port speed and the exchange protocol version on the register itself: they are usually printed in the self-test when it is switched on with the paper feed button held.

SBP QR payment. “SBP QR payment” is added as a payment terminal and called with the same /terminals/{id}/… methods. On payment the application creates a payment at the bank and shows the QR code: in the application window, on the customer display whose number is set in the settings (a second monitor, a Mertech or QR-Screen QR code display), and as the qr event for your program. The customer scans the QR in their bank app; the application asks the bank for the status every 2 seconds. If it is not paid within the wait time, the payment is cancelled. The bank payment ID is returned in paymentRef.idProcessing and is used for refunds. No settlement is needed for SBP.

API

Principles

Methods

MethodWhat it does
GET/api/v1/healthThe service is running: version, start time, power (mains or battery)
GET/api/v1/devicesDevices: number, kind, type, name
GET/api/v1/languageInterface language: ru or en
GET/api/v1/registers/{id}/shiftRegister shift state
POST/api/v1/registers/{id}/shift/openOpen shift {operator}*
POST/api/v1/registers/{id}/shift/closeClose shift (Z report) {operator}*
POST/api/v1/registers/{id}/reports/xX report {operator}*
POST/api/v1/registers/{id}/reports/calculation-stateCurrent calculation state report {operator}*
GET/api/v1/registers/{id}/countersRegister counters: receipt count and sums by calculation sign for the shift and the whole fiscal drive (ATOL, Shtrih-M, Pirit)
GET/api/v1/registers/{id}/fn-documents/{n}A document from the fiscal drive by number (ATOL, Shtrih-M)
POST/api/v1/registers/{id}/fn-documents/{n}/printPrint a copy of a document from the fiscal drive (ATOL, Pirit)
POST/api/v1/registers/{id}/cash/inCash in {operator*, amount}
POST/api/v1/registers/{id}/cash/outCash out {operator*, amount}
POST/api/v1/registers/{id}/cash-drawer/openOpen the cash drawer
POST/api/v1/registers/{id}/receiptsPrint a receipt
POST/api/v1/registers/{id}/correctionsCorrection receipt {receipt, correction: {type: SELF|INSTRUCTION, baseDate, baseNumber}} — ATOL, Shtrih-M, Pirit
POST/api/v1/registers/{id}/documentsPrint non-fiscal text {lines}
POST/api/v1/terminals/{id}/paymentsCard payment {amount}
POST/api/v1/terminals/{id}/refundsRefund to card {amount, paymentRef}
POST/api/v1/terminals/{id}/cancellationsSame-day payment cancellation {amount, paymentRef}
POST/api/v1/terminals/{id}/settlementsSettlement
POST/api/v1/terminals/{id}/emergency-reversalsEmergency reversal of the last operation when the POS did not get its result {amount, paymentRef?}
POST/api/v1/terminals/{id}/reports?full=falseTerminal report on the shift's operations without settlement: short or full (full=true)
GET/api/v1/terminals/{id}/last-slipThe slip of the last successful operation from the journal — to print it again
GET/api/v1/qr?text=…&size=400QR code PNG image, e.g. for the payload from the qr event
POST/api/v1/checkoutsA whole sale or refund: card → receipt → slip; if the receipt fails, the payment is cancelled
GET/api/v1/printersWindows printers, roles, settings
POST/api/v1/print-jobsPrinting: urls, document (PDF base64), images, raw, report or text (lines, driverless printer only); printer, device (driverless printer) or role, copies
POST/api/v1/cash-drawers/{id}/openOpen a cash drawer: id — register, ESC/POS printer or a drawer on a COM port
POST/api/v1/displays/{id}Show lines on the customer display {lines}; an empty list clears it
POST/api/v1/displays/{id}/qrShow a QR code on a QR code display or second monitor {payload, top, bottom}; an empty payload removes it
GET/api/v1/displays/{id}What is shown on the display
POST/api/v1/channels/{id}/exchangeSend bytes to a device port and get the reply {hex | base64 | text, readTimeoutMs, until}
GET/api/v1/reportsReport templates with parameters and fields
POST/api/v1/reports/{name}/renderPDF by template {parameters, rows} — immediate, not an operation
GET/api/v1/operations/{id}An operation; with Prefer: wait=N waits for completion
GET/api/v1/operations?limit=50Recent operations
GET/api/v1/eventsEvents (SSE)

* operator can be omitted if the cashier is set on the Workplace tab. Then the request body is not needed either.

The /api/v1/setup/… methods serve the setup page and are available only from it.

Receipt

{
  "type": "SELL",                       // SELL, SELL_RETURN, BUY, BUY_RETURN
  "taxation": "USN_INCOME",             // OSN, USN_INCOME, USN_INCOME_OUTCOME, ESHN, PATENT; absent — from Workplace or the register default
  "operator": {"name": "Ivanova I.I.", "inn": "770123456789"},   // absent — the cashier from Workplace
  "customer": {"contact": "+79991234567"},   // for an electronic receipt
  "header": [
    {"kind": "TEXT", "text": "Order 123", "align": "CENTER"},
    {"kind": "PAIR", "text": "Date:", "right": "01.11.2026 19:00"},
    {"kind": "SEPARATOR"}
  ],
  "items": [
    {"name": "Service", "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 — do not print, send to the customer
  "senderEmail": "kassa@example.ru",    // tag 1117; absent — from Workplace
  "settlementPlace": "Cash desk"        // tag 1187; absent — from Workplace
}

The sum of payments must equal the sum of items, an item amount — price × quantity. Text lines are wrapped to the register paper width automatically.

Examples

Sale with a card payment — payment, receipt and slip in one operation:

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}

Response: an operation with result.receipt (FD number, fiscal sign, shift, QR code) and result.payment (paymentRef, card, RRN, authorization code, slip). paymentRef is needed for a refund.

Printing a PDF on the ticket printer:

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

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

Report by template — a PDF right away or to a printer:

POST /api/v1/reports/ACT/render
{"parameters": {"NUMBER": "15", "DATE": "2026-11-01"},
 "rows": [{"NAME": "Item 1", "PRICE": 1500}]}

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

Tickets by the TICKET template — one ticket per row, on the ticket printer:

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

{"report": {"name": "TICKET", "rows": [
  {"top_line": "Concerts LLC", "pos_line": "Grand hall", "addr_line": "1 Tverskaya St.",
   "service_line": "Concert (12+)", "date_line": "Date: 01.11.2026 Start: 19:00",
   "place_line": "Stalls row 5 seat 12", "price_line": "Price: 1500.00",
   "sold_line": "31.10.2026 10:00 Cashier: Ivanova I.I.", "sale_line": "1911-000123"}
 ]}, "role": "tickets"}

Printer commands as is (ESC/POS, ZPL) — e.g. a ZPL label:

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

Waiting for an operation and events in the browser:

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);    // e.g. "tap the card on the terminal"
});
events.addEventListener('barcode', e => console.log(JSON.parse(e.data).code));

Errors

Request errors — RFC 9457 responses (application/problem+json) with a code field:

HTTPcodeWhen
400INVALID_REQUEST or noneInvalid JSON, no Idempotency-Key, field constraints violated (then code: INVALID_REQUEST and the fields in detail)
404DEVICE_NOT_FOUND, REPORT_NOT_FOUNDNo such device or template
409IDEMPOTENCY_KEY_REUSED, DEVICE_BUSYThe key was used for another operation; the device is busy
422VALIDATION_ERROR, REPORT_ERRORTotals do not match, no cashier, invalid parameter value, template with errors

Device errors arrive in the operation itself: status: FAILED, error: {code, message, details}. Error texts from devices are in Russian.

codeWhat happened
DEVICE_ERRORRegister, terminal or printer error; the text is in message
PAYMENT_CANCELLEDThe receipt failed after a card payment; the payment was cancelled on the terminal
PAYMENT_NOT_CANCELLEDThe receipt failed and the payment could not be cancelled; payment data is in details
RECEIPT_FAILED_AFTER_REFUNDMoney was refunded to the card, the refund receipt was not printed
INTERRUPTEDThe service restarted during the operation

Settings and files

Devices, printer roles and settings, the workplace, access, printing limits and the language are changed on the setup page (values from the page win over the file). Everything else is in config\application.yml in the program folder:

ParameterWhat it sets
server.portAgent port, 7790 by default; needs a restart
hw.allowed-originsWeb application addresses allowed to call the service from the browser
hw.api-tokenToken: if set, API requests must carry Authorization: Bearer <token> (for events — ?access_token=)
hw.printer.allowed-url-prefixesAddresses PDFs may be downloaded from for printing
hw.reports.dir, hw.reports.fontReport template folder and the Cyrillic font for PDFs
hw.trayfalse — no tray icon
hw.power-monitorfalse — do not monitor power
FolderContents
data\devices.jsonDevices
data\printers.jsonPrinter roles and settings
data\ui.jsonInterface language
data\workplace.jsonWorkplace: default cashier and receipt details
data\access.jsonAccess and printing set on the setup page
data\operations.jsonlOperation journal
reports\Report templates, images, subreports
logs\Logs, 30 days

Security