Введение

Данный документ является Руководством Программиста, а так же Руководством Пользователя по использованию Программной Кассы.


В данной документации описан протокол, типы и ошибки, которые могут возникать при использовании протокола tsrv.

Данная документация будет дополняться в процессе доработок.

Сам по себе протокол взаимодействия предполагает схему "запрос-ответ", с сообщениями в JSON формате.


На текущий момент tsrv поддерживает взаимодействие по:

Однако в планах находится добавление поддержки взаимодействия по:

  • WebSocket
  • TCP

Типы данных, в частности сообщений, при этом, не будут иметь отличий, однако в зависимости от протокола могут быть некоторые нюансы.

Все типы данных описаны в отдельном разделе данной документации

Message

Базовой сущностью протокола является Message. Структура Message представляет собой JSON следующего формата:

{
  "type": MessageType,
  "address": String,
  "reply_address": String?,
  "data": Any?,
  "headers": Map<String, String>
}

MessageType передается как строка и может иметь следующие значения:

  • send - вызов метода
  • ping - запрос на проверку связи
  • pong - ответ на запрос проверки связи
  • error - сообщение сервера об ошибке

Поле type служит для объявления типа передаваемого сообщения. Список поддерживаемых сообщений со временем может расширяться.

Поле address имеет два значения в рамках протокола:

  • В случае клиентского сообщения, данное поле требуется для идентификации сервиса (dispatcher), который будет обслуживать данное сообщение
  • В случае серверного сообщения, данное поле заполняется значением из поля reply_address клиентского запроса, чтобы клиентская часть могла определить, на какое свое сообщение она получила ответ.

Поле reply_address является опциональным и служит для передачи "адреса", на котором будет ожидать ответа клиентская часть. Сервер, в свою очередь, данное поле оставляет всегда в значении null и после успешной/неуспешной обработки клиентского сообщения помещает значение данного поля в address серверного сообщения.

Поле data содержит тело запроса. Тело запроса меняется в зависимости от обслуживающего сервиса, а так же исполняемой функции.

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

Заголовок action может иметь значение с использованием любой политики наименования, например:

  • getTokenBySerial
  • get_token_by_serial
  • GET_TOKEN_BY_SERIAL
  • GetTokenBySerial

являются полностью поддерживаемыми и валидными значения вызова одного и того же метода.

Важно: для всех запросов, кроме тех, что находятся в сервисе ik.service.app требуется передавать дополнительный заголовок sid - идентификатор текущей сессии. Таким образом гарантируется 1 активная сессия работы с сервисом. Подробнее о сессиях написано в разделе Сессии

Важно: для уменьшения передаваемых данных следует передавать minified JSON (без переносов строк, пробелов между полями и т.п.), например:

{"type":"send","address":"ik.service.token","headers":{"action":"getTokenBySerial","token":"AVQ11031010703","refresh_tokens":"true"}}

Примеры

Валидный клиентский Message:

{
  "type": "send",
  "address": "ik.service.token",
  "headers": {
    "action": "getTokenBySerial",
    "token": "AVQ11031010703",
    "refresh_tokens": "true"
  }
}

Валидный успешный серверный Message:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": {
    "device_id": 131010703,
    "operator_code": 5,
    "organization": "ИП Моров А.М.",
    "pin_code_length": 5,
    "puk_code_length": 8,
    "serial": "AVQ11031010703",
    "tax_number": 191832203
  },
  "headers": null
}

Валидный неуспешный серверный Message:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "dispatcher not found",
    "name": "TSRV_DISPATCHER_NOT_FOUND"
  },
  "headers": null
}

Ошибки

В случае возникновения ошибки, сервер отправит сообщение типом error и полем data следующего вида:

{
  "description": String,
  "name": String,
  "op_data": Any?
}

Для идентификации ошибки на клиентской стороне требуется ориентироваться на поле name, т.к. оно является гарантированно уникальным в рамках протокола.

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

Так же, текстовое описание ошибок description может меняться/дополняться в рамках работы сервиса и, как следствие, полагаться на него как на уникальное значение запрещается.

Перечень ошибок, возможных в рамках протокола ошибок:

[errors]
AVQFR_INVALID_COMMAND = 'подана команда с неизвестным кодом или нарушен порядок подачи команд'
AVQFR_UNSUPPORTED_VERSION = 'версия протокола взаимодействия с устройством не поддерживается'
AVQFR_ACCESS_DENIED = 'неверно указана роль при авторизации (отличная от PIN, PUK или REG)'
AVQFR_BAD_SERIAL_NUMBER = 'неверно задан серийный номер устиойства'
AVQFR_BAD_DEVICE_MODE = 'команда не может быть выполнена в текущем режиме устройства'
AVQFR_INTERNAL_ERROR = 'внутренняя ошибка (возможная причина - аппаратный сбой)'
AVQFR_TIMEOUT = 'превышено время ожидания ответа при синхронизации времени'
AVQFR_BAD_FW_UPGRADE_KEY = 'отсутствует ключ обновления прошивки или его целостность нарушена'
AVQFR_NOT_MOUNTED = 'файловая система на смонтирована (внутренняя ошибка, устройство неисправно)'
AVQFR_NOT_FORMATTED = 'носитель на отформатирован (внутренняя ошибка, устройство неисправно)'
AVQFR_INSUFFICIENT_SPACE = 'недостаточно места для записи данных'
AVQFR_FILE_IS_TOO_BIG = 'превышен размер файла (внутренняя ошибка, устройство неисправно)'
AVQFR_FILE_NOT_EXIST = 'файл не найден, необходимые данные отсутствуют'
AVQFR_FILE_ALREADY_EXISTS = 'файл уже имеется (внутренняя ошибка, устройство неисправно)'
AVQFR_INVALID_OFFSET = 'неверное смещение (внутренняя ошибка, устройство неисправно)'
AVQFR_PROGRAM_ERROR = 'ошибка записи во флеш-память (внутренняя ошибка, устройство неисправно)'
AVQFR_BAD_ADDRESS = 'неверно задан адрес блока памяти (внутренняя ошибка, устройство неисправно)'
AVQFR_ERASE_ERROR = 'ошибка стирания флеш-памяти (внутренняя ошибка, устройство неисправно)'
AVQFR_NO_CIPHER_CALLBACKS = 'функции шифрования файловой системы недоступны (внутренняя ошибка, устройство неисправно)'
AVQFR_MAC_NOT_FOUND = 'у файла отсутствует имитовставка (внутренняя ошибка, устройство неисправно)'
AVQFR_NOT_ACTUAL_KEY = 'срок действия ключа не наступил или истек'
AVQFR_BAD_SIGN = 'подпись не верна'
AVQFR_INCORRECT_PARAM_SIZE = 'неверный размер параметра (один из параметров команды имеет неверную длину)'
AVQFR_BAD_SYNC_REQUEST_ID = 'неверный идентификатор запроса синхронизации времени'
AVQFR_BAD_FILE_INDEX = 'недопустимое имя файла (внутренняя ошибка, устройство неисправно)'
AVQFR_NO_DATA = 'запрашиваемые данные отсутствуют (попытка получить внутренний или отсутствующий документ)'
AVQFR_INTEGRITY_ERROR = 'нарушение целостности данных, хранящихся в устройстве (устройство неисправно)'
AVQFR_PRNG_NOT_INITIALIZED = 'генератор СЧП не инициализирован, инициализация устройства не завершена'
AVQFR_BAD_SIGN_CTR = 'неверное значение счетчика подписей'
AVQFR_BAD_STATUS_CODE = 'неверное значение кода завершения обработки запроса сервером'
AVQFR_INVALID_MODE = 'неверно задан режим алгоритма (внутренняя ошибка, устройство неисправно)'
AVQFR_INCORRECT_PARAM = 'один из переданных параметров имеет недопустимое значение'
AVQFR_SELF_TEST_FAILURE = 'ошибка самотестирования (устройство неисправно)'
AVQFR_SHIFT_IDLE_TIMEOUT = 'превышено время бездействия, требуется синхронизация времени'
AVQFR_BAD_KEY_AUTH_DATA = 'неверные данные для авторизации сессии (неверное значение PIN, PUK или REG)'
AVQFR_INVALID_ATTR_ID = 'неверный идентификатор атрибута устройства (атрибут, не поддерживается устройством)'
AVQFR_BAD_KEY_TOKEN = 'токен ключа сформирован некорректно'
AVQFR_FILE_BACKUP_ERROR = 'ошибка дублирования файла (внутренняя ошибка, устройство неисправно)'
AVQFR_BAD_KEY_ID = 'идентификатор ключа отсутствует или имеет неверный размер'
AVQFR_BAD_KEY = 'ключ отсутствует, имеет неверный размер или неверный формат набора ключей'
AVQFR_ASN1_PARSE_ERROR = 'невозможно разобрать ASN1-структуру (нарушена структура сертификата или ответа сервера)'
AVQFR_INCORRECT_DATA_SIZE = 'неверный общий размер данных команды (передана команда неподдерживаемой длины)'
AVQFR_SESSIONS_LIMIT_EXCEEDED = 'слишком много одновременно открытых сессий'
AVQFR_INVALID_SESSION_ID = 'неверный идентификатор сессии'
AVQFR_SHIFT_IS_PENDING = 'необходимо закрыть смену'
AVQFR_RECEIPT_IS_PENDING = 'в устройстве присутствуют кассовые документы, которые необходимо передать на сервер'
AVQFR_RECEIPT_SUM_OVERFLOW = 'переполнение счетчиков, необходимо закрыть смену'
AVQFR_RECEIPT_NEGATIVE_VALUE = 'задано отрицательное значение суммы'
AVQFR_NEGATIVE_SHIFT_BALANCE = 'получен отрицательный сменный баланс'
AVQFR_SESSION_ALREADY_AUTHORIZED = 'сессия уже авторизована (попытка повторной авторизации уже авторизованной сессии)'
AVQFR_SESSION_NOT_AUTHORIZED = 'сессия не авторизована (команда требует обязательной авторизации)'
AVQFR_SESSION_EXISTS = 'имеется открытая сессия (выполнение команды возможно только в монопольном режиме)'
AVQFR_SHIFT_IS_OPENED = 'смена открыта (команда возможна только при закрытой смене)'
AVQFR_SHIFT_IS_CLOSED = 'смена закрыта (команда возможна только при открытой смене)'
AVQFR_BAD_DATE_TIME = 'неверный формат или значение даты или времени (операция выполняется "задним" числом)'
AVQFR_BAD_CASH_REG_NUMBER = 'неверный номер кассового аппарата (номер КСА в СККО)'
AVQFR_BAD_CURRENCY_NAME = 'неверное наименование кода валюты'
AVQFR_BAD_RECEIPT_TYPE = 'неверный тип кассового документа'
AVQFR_BAD_RECEIPT_NUMBER = 'номер кассового документа отличается от значения внутренего счетчика кассовых документов'
AVQFR_BAD_RECEIPT_COST = 'рассогласование по полю "Итого общая стоимость"'
AVQFR_BAD_RECEIPT_DISCOUNT = 'рассогласование по полю "Сумма скидки (надбавки)"'
AVQFR_BAD_RECEIPT_TOTAL = 'рассогласование по полю "Итого к оплате"'
AVQFR_BAD_RECEIPT_CENTS = 'неправильное значение дробной части денежного поля'
AVQFR_BAD_TAXPAYER_NUMBER = 'задан неверный УНП'
AVQFR_BAD_CORRECTION_VALUE = 'задана ненулевая сумма коррекции при отсутствии коррекций'
AVQFR_TOTAL_TRADE_OVERFLOW = 'переполнение счетчика суммарного торгового оборота'
AVQFR_UNKNOWN = 'неизвестная ошибка'

TR_EMPTY_INPUT = 'неверные входные данные (данные отсутствуют)'
TR_INVALID_TYPE = 'неверный тип данных'
TR_INSUFFICIENT_BYTES = 'недостаточно данных для считывания информации'

USB_IO = "Input/Output Error"
USB_INVALID_PARAM = "Invalid parameter"
USB_ACCESS = "Access denied (insufficient permissions)"
USB_NO_DEVICE = "No such device (it may have been disconnected)"
USB_NOT_FOUND = "Entity not found"
USB_BUSY = "Resource busy"
USB_TIMEOUT = "Operation timed out"
USB_OVERFLOW = "Overflow"
USB_PIPE = "Pipe error"
USB_INTERRUPTED = "System call interrupted (perhaps due to signal)"
USB_NO_MEM = "Insufficient memory"
USB_NOT_SUPPORTED = "Operation not supported or unimplemented on this platform"
USB_BAD_DESCRIPTOR = "Malformed descriptor"
USB_OTHER = "Other error"

CRT_MISSING_DEVICE_ID = "missing device id"
CRT_MISSING_OWNER_TAX_NUMBER = "missing owner tax number"
CRT_MISSING_OPERATOR_CODE = "missing operator code"
CRT_MISSING_SERIAL_NUMBER = "missing serial number"
CRT_MISSING_OWNER_NAME = "missing owner name in certificate"
CRT_MISSING_CERT_SERIAL = "missing cert serial"
CRT_INVALID = "invalid certificate"

AVTPCR_ATTR_NOT_FOUND = 'missing required attribute'

TIN_CODE_LEN = "invalid code length"
TIN_EMPTY_NAME = "empty name"
TIN_NAME_LEN = "invalid name length"
TIN_INVALID_GTIN = "invalid gtin/ean"
TIN_ZERO_SUM = "invalid sum: can't be 0"
TIN_NEGATIVE_SUM = "invalid sum: can't be negative"
TIN_SUM_OVERFLOW = "sum overflow"
TIN_QUANTITY_OVERFLOW = "quantity overflow"
TIN_ZERO_QUANTITY = "invalid quantity: 0"
TIN_EMPTY_CASHIER = "empty cashier name"
TIN_NO_ITEMS = "invalid items array: no items"
TIN_MAX_ITEMS = "too many items"
TIN_NOT_ENOUGH_MONEY = "not enough payed"
TIN_CASHLESS_OVERFLOW = "too much cashless payment"
TIN_CASH_OVERFLOW = "too much cash"
TIN_NEGATIVE_CHANGE = "invalid change: can't be negative"
TIN_CASHIER_LEN = "invalid cashier length"
TIN_NOT_ENOUGH_CASH_IN = "not enough money in cash box"

TSRV_APP_WAS_NOT_CONFIGURED = "application was not configured properly"
TSRV_EMPTY_ADDRESS = "no address provided"
TSRV_DISPATCHER_NOT_FOUND = "dispatcher not found"
TSRV_DESERIALIZE_ERROR = "failed to deserialize value"
TSRV_EMPTY_MSG_DATA = "data field is required but was not provided"
TSRV_ACTION_NOT_FOUND = "'action' was not found"
TSRV_INVALID_HEADER = "invalid header value"
TSRV_TOKEN_NOT_FOUND = "token was not found"
TSRV_INVALID_SUM_DEC_PART = "invalid sum decimal part. should always have 2 digits after dot"
TSRV_INVALID_QUANTITY_DEC_PART = "invalid quantity decimal part. should always have 3 digits after dot"
TSRV_NEGATIVE_CHEQUE_DISCOUNT = "cheque discount can't be negative"
TSRV_TOKEN_NOT_ACTIVE = "token is not active"
TSRV_ITEM_NOT_FOUND = "item was not found in storage"

PR_IO_ERROR = "printer I/O error"
PR_NOT_FOUND = "printer was not found"
PR_USB_ERROR = "usb printer error"

SM_SESSION_EXISTS = "session already exists. remove existing session or restart app"
SM_INVALID_SESSION = "invalid session id"
SM_SID_NOT_FOUND = "session id was not found"

TORD_FAILED_TO_REMOVE = "failed to remove prev order"
TORD_FAILED_TO_DESER = "failed to deserialize prev order (file may be corrupted)"
TORD_READ_FAILED = "failed to read order"
TORD_WRITE_FAILED = "failed to write order"
TORD_NOT_FOUND = "order was not found"

Что делать если была возвращена ошибка...

  • AVQFR_NOT_ACTUAL_KEY - требуется проверить срок действия СКО и обратиться в тех. поддержку

  • AVQFR_BAD_KEY_AUTH_DATA - PIN/PUK код имеются неверные значения - проверить их правильность в соответствии с паспортом СКО

  • AVQFR_SHIFT_IDLE_TIMEOUT - требуется проверить подключение к интернету и попытаться открыть смену. При открытии смены осуществляется попытка синхронизации времени

  • AVQFR_INSUFFICIENT_SPACE - слишком много неотправленных документов - подключиться к интернету, проверить, что пройдена авторизация по PIN коду. Максимальное кол-во документов - около 4000

  • AVQFR_SESSIONS_LIMIT_EXCEEDED - Программная касса завершала свою работу некорректно какое-то кол-во раз. Требуется обратиться в тех. поддержку предоставив лог-файл и для продолжения работы - достать и вернуть СКО в устройство с запущенной программной кассой

  • AVQFR_SHIFT_IS_PENDING - требуется закрытие смены.

  • AVQFR_RECEIPT_IS_PENDING - требуется проверка наличия интернета на устройстве и убедиться, что пройдена авторизация по PIN коду, а так же дождаться, пока документы будут отправлены на сервер. Кол-во неотправленных документов можно получить с помощью метода get_stored_documents

  • AVQFR_RECEIPT_SUM_OVERFLOW - прибыль вашей компании за смену достигла невероятных объемов. Требуется закрыть смену и сообщить в тех. поддержку о данной ошибке

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

  • AVQFR_SESSION_ALREADY_AUTHORIZED - уже пройдена авторизация в СКО

  • AVQFR_SESSION_NOT_AUTHORIZED - требуется прохождение авторизации в СКО

  • AVQFR_SHIFT_IS_OPENED - требуется закрыть смену

  • AVQFR_SHIFT_IS_CLOSED - требуется открыть смену

  • AVQFR_BAD_DATE_TIME - требуется проверить время на устройстве

  • TIN_CODE_LEN - требуется проверить длину кода. Длина кода не должна превышать 13 знаков.

  • TIN_EMPTY_NAME - имя является обязательным полем, требуется проверить, что оно заполнено

  • TIN_NAME_LEN - неверная длина имени тов. позиции. Не должна превышать 128 символов

  • TIN_INVALID_GTIN - не пройдена валидация кода GTIN (проверочный знак неверный)

  • TIN_ZERO_SUM - значение цены/суммы не может быть равно 0 в одном из полей

  • TIN_NEGATIVE_SUM - значение цены/суммы не может быть отрицательным

  • TIN_SUM_OVERFLOW - слишком большое/маленькое значение цены/суммы. Об ограничениях написано в описании типа Sum

  • TIN_QUANTITY_OVERFLOW - слишком большое значение кол-во. Об ограничениях написано в описании типа Quantity

  • TIN_ZERO_QUANTITY - кол-во не может быть равно 0.

  • TIN_EMPTY_CASHIER - имя кассира не может быть пустым. Это обязательное поле

  • TIN_NO_ITEMS - попытка совершения продажи без товарных позиций

  • TIN_MAX_ITEMS - слишком много товарных позиций в чеке

  • TIN_NOT_ENOUGH_MONEY - недостаточная сумма при попытке оплаты чека

  • TIN_CASHLESS_OVERFLOW - слишком много безналичных средств. Ошибка возникает если значение способов безналичной оплаты и других способов оплаты превышает сумму. С данных способов оплаты невозможно выдать сдачу

  • TIN_CASH_OVERFLOW - слишком много наличных средств. Возникает если сумма безналичных и других способов оплаты полностью покрываем сумму по чеку, а наличные не равны 0

  • TIN_NEGATIVE_CHANGE - Отрицательная сдача.

  • TIN_CASHIER_LEN - неверная длина кассира. Превышает 16 символов

  • TIN_NOT_ENOUGH_CASH_IN - недостаточно наличных в кассе для совершения операции. Например, для выдачи сдачи

  • TSRV_APP_WAS_NOT_CONFIGURED - ошибка инициализации ПО. Требуется обратиться в тех. поддержку

  • TSRV_EMPTY_ADDRESS - не указано значение поля address в запросе, либо пустое значение

  • TSRV_DISPATCHER_NOT_FOUND - неверное значение address в запросе

  • TSRV_DESERIALIZE_ERROR - ошибка обработки входных данных. Требуется проверка правильности формата и указание обязательных полей

  • TSRV_EMPTY_MSG_DATA - требуемое тело запроса (поле data) отсутствует

  • TSRV_ACTION_NOT_FOUND - неверное значение заголовка action , либо address указан неверно

  • TSRV_INVALID_HEADER - неверное значение одного из заголовков

  • TSRV_TOKEN_NOT_FOUND - СКО не найдено

  • TSRV_INVALID_SUM_DEC_PART - неверное значение суммы (передано не в формате X.XX)

  • TSRV_INVALID_QUANTITY_DEC_PART - неверное значение кол-ва (передано не в формате X.XXX)

  • TSRV_NEGATIVE_CHEQUE_DISCOUNT - отрицательная скидка по чеку (надбавка на чек недоступна)

  • TSRV_TOKEN_NOT_ACTIVE - СКО заблокировано

  • TSRV_ITEM_NOT_FOUND - товар отсутствует в БД товаров

  • PR_IO_ERROR - ошибка чтения/записи принтера

  • PR_NOT_FOUND - принтер с указанными данными не найден

  • PR_USB_ERROR - ошибки при работе с принтером по USB

  • SM_SESSION_EXISTS - сессия уже существует. Описание работы с сессиями

  • SM_INVALID_SESSION - неизвестная сессия. Требуется либо пересоздание, либо перезапуск

  • SM_SID_NOT_FOUND - отсутствует заголовок sid в запросе

  • TORD_FAILED_TO_REMOVE - ошибка удаления предыдущего заказа

  • TORD_FAILED_TO_DESER - файл заказа поврежден либо не может быть обработан. Требуется пересоздать заказ предварительно удалив

  • TORD_READ_FAILED - ошибка чтения заказа из ФС. Требуется обратиться в тех. поддержку

  • TORD_WRITE_FAILED - ошибка записи заказа в ФС. Требуется обратиться в тех. поддержку

  • TORD_NOT_FOUND - заказ с данным идентификатором не найден. Требуется создание заказа

Сессии

Для работы со всеми сервисами, за исключением сервиса ik.service.app, требуется передача активной сессии в заголовке sid запроса.

Для инициализации новой сессии требуется совершать запрос на ее инициализацию.

При создании сессии может возникнуть ошибка SM_SESSION_EXISTS, которая говорит о наличии уже активной сессии. В данном случае имеется 2 варианта решения этой проблемы:

  • Очистка текущей сессии методом clear_session
  • Перезапуск приложения

В целях безопасности отсутствует возможность очистить текущую активную сессию без передачи ее идентификатора, т.к. сервис может быть запущен в незащищенной публичной сети, к которой имеется доступ у клиентов (потенциальные злоумышленники).

В случае, если произошло непредвиденное поведение на клиентской стороне и сессионный ключ был утерян по тем или иным причинам, требуется перезапуск сервера.

Если сессионный ключ известен, но требуется проверить его верность, то имеется возможность запросить хэш-значение идентификатора текущей активной сессии методом get_active_session_hash, который отдаст значение в виде HEX(MD5(session_id)). Данное значение может быть проверено на клиентской стороне

Список поддерживаемых заголовков

СКО

  • token - серийный номер СКО
  • tokens.refresh - обновление списка СКО

Работа с принтерами и отрисовкой чеков

  • printer.[usb|dummy] - заголовки и подзаголовки для работы с принтерами
  • printer.spl - spl - symbols per line. Указание кол-ва символов в ширину на бумаге, на которой будет происходить печать. По умолчанию: 48
  • printer.code.policy - правило печати кодов товарных позиций. По умолчанию: only_gtin
    • no_plain - все, кроме типа кода без GTIN/EAN (тип кода - 0)
    • only_gtin - только GTIN/EAN (тип кода - 1)
    • all - печатать коды товарных позиций всех типов
  • printer.cp866 - указание номера таблицы символов в принтере соответствующий кодировке CP866. По умолчанию - 17
  • printer.feed - указание кол-во строк прокрутки бумаги после печати. По умолчанию: 5
  • printer.cut - принудительное отрезание бумаги после завершения печати. По умолчанию: true
  • printer.prefix - данные для печати перед печатью основного чека. Может быть использовано для печати лого или изменении шрифта для последующей печати
  • printer.style - вид печати чека. по умолчанию - default, печатает полный чек. При указании значения qr будет напечатан чек с QR кодом, в котором содержится ссылка на эл. чек
  • DEPRECATED printer.escpos.required - требуется ли передача escpos представления чека в ответе. В случае, если значение true, escpos команды в base64 формате будут помещены в поле extra ответов.

Электронные чеки

  • dreceipt.emails - перечень email'ов на которые требуется отправить эл. чек. В случае указании нескольких email разделителем является запятая. Например: "[email protected],[email protected]"

Представление чеков

  • repr.html - отдавать в объекте фискального документа дополнительный объект repr с полем html, в котором находится html представление чека
  • repr.esc_pos - отдавать в объекте фискального документа дополнительный объект repr с полем esc_pos, в котором находится esc_pos (base64) представление чека
  • repr.text - отдавать в объекте фискального документа дополнительный объект repr с полем text, в котором находится текстовое представление чека
  • repr.link - отдавать в объекте фискального документа дополнительный объект repr с полем link, в котором находится ссылка на эл. чек

Важно!

Печатать чеки для клиентов, отданные в repr.html, repr.text, repr.link категорически запрещается, из-за отсутствия в них QR кода с УИ!

Работа с принтером

Для использования принтера требуется передать наборы заголовков, в зависимости от желаемого способа использования принтера.


Общее

Печать осуществляется путем построчного формирования для последующей печати, добавлением стилей, преобразованием в набор EscPos команд и отправкой на принтер данных.

Т.к. позиционирование построчное и основано на максимальном кол-ве символов в строке, имеется возможность передать кол-во символов для правильного формирования чека под конкретные размеры путем передачи заголовка printer.spl. Значение по умолчанию для данного заголовка - 48

Процесс вывода на печать выглядит следующим образом:

  • Осуществляется подключение к печатающему устройству
  • Совершается запрашиваемая операция
  • Осуществляется вывод на печать сформированных данных

В случае возникновения ошибки на последнем этапе (вывод на печать), возвращается ошибка со всеми данными по совершенной операцией в поле op_data структуры.

Все данные передаются в кодировке CP866 и для корректного отображения данных на бумажном чеке, требуется, чтобы в принтере кодировкой по умолчанию была установлена кодировка CP866, либо требуется передача заголовка printer.cp866

Принтер выбирается на основе printer.* заголовков в следующей приоритетности:

  • USB
  • Dummy

Если заголовки первого принтера не были найдены - будет попытка найти следующий принтер. Dummy принтер всегда имеет низший приоритет.


USB-принтер

Для работы с USB принтером требуется передача двух заголовков:

  • printer.usb.vendor - строковое представление vendorId устройства
  • printer.usb.product - строковое представление productId устройства

Перед любой операцией печати с использованием USB принтера, программная касса "забирает" контроль над USB устройством. В случае, если программной кассе не удалось этого сделать, будет возвращена ошибка с префиксом USB_

В случае, если требуется вывести какую-то информацию на принтер до или после печати - USB устройство доступно для подключения соответственно ДО выполняемой операции и после ее завершения


Очередь печати Windows

Данный способ работает только на ОС Windows с принтерами, которые поддерживают печать через очередь печати.

Для отправки чека в очередь печати требуется передача заголовка printer.spool.name с указанием наименования принтера/очереди печати.


Dummy-принтер

Данный тип принтера не выводит ничего на печать. Для задействования требуется передача заголовка printer.dummy с любым значением


Delayed принтер

Данный тип принтера не выводит ничего на печать на принтер, а вместо этого помечает документ для отложенной печати.

Для использования этого типа принтера требуется передать заголовок printer.delayed с тем же идентификатором, что будет передан в printer.delayed.id

При использовании данного способа требуется передача дополнительного заголовка: printer.delayed.id c идентификатором для последующей печати. В качестве идентификатора можно использовать номер следующего документа в смене.

Печать отложенного чека может быть совершена с помощью метода print_delayed

Работа с СКО

Для корректного запуска приложения и работы с СКО, требуется объявление переменной окружения OPERATOR_CODE с указанием кода оператора. На основании кода оператора будут доступны устройства с соответствующим кодом оператора.

Доступные коды оператора:

  • 5 - dev окружение iKassa
  • 910000001 - stage окружение iKassa, используемое Республиканским Унитарным Предприятием "Информационно-Издательский Центр Министерства по Налогам и Сборам" (РУП ИИЦ МНС)
  • 1 - prod окружение iKassa, используемое на реальных торговых точках

В случае компрометации устройства, либо по решению РУП ИИЦ МНС или Оператора Программной Кассы СКО может быть заблокировано для совершения всех фискальных операций, кроме операции изъятия и закрытия смены. Все операции, в случае блокировки, будут отдавать ошибку TSRV_TOKEN_NOT_ACTIVE

Запросить текущий статус СКО можно с помощью метода get_status

Важно: статус СКО по умолчанию - unknown и, если нет подключения к интернету, либо сервера iKassa недоступны, из текущей сети, использование СКО невозможно и требуется подключение к интернету.

Важно: на старте приложения осуществляется поиск доступного СКО.


Приложение работает и принимает запросы в асинхронном режиме, однако работа с СКО осуществляется в синхронном режиме, соответственно любое действие с СКО блокирует возможность выполнения других действий с ним.

По причине, описанной выше, скорость при выполнении команд может падать при некоторых обстоятельствах. Ниже описаны способы ускорения работы


Приостановка отправки документов

Приложение опрашивает все СКО на предмет наличия неотправленных документов 1 раз в 3 секунды. Процесс удаления документов состоит из трех этапов:

  • Запрос документа из СКО
  • Попытка отправки документа
  • В случае успешной отправки - запрос в СКО на удаление документа

Соответственно в момент отправки происходит 2 блокировки.

В ряде случае может потребоваться максимальная производительность при совершении операций и для этого имеется метод приостановки отправки документов и соответственно метод возобновления отправки документов.

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


Обновление списка СКО

Важно помнить, что список доступных СКО обновляется в ручном режиме, путем передачи заголовка tokens.refresh со значением "true".

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

Исходя из изложенного выше, стоит передавать tokens.refresh исключительно в том случае, если СКО не было найдено, либо по какой-то причине команда отдала ошибку TSRV_TOKEN_NOT_FOUND


Кэширование данных

Мы очень заботимся о скорости выполнения операций и потому существует кэширование части информации для максимально быстрых запросов без обращения к СКО. Список методов, которые отдают кэшированные данные:

Переменные окружения

  • TSRV_ADDR - адрес, который будет слушаться HTTP сервером. По умолчанию - 0.0.0.0:1828
  • TSRV_REST_MODE - переменная окружения для переключения режима работы Программной Кассы в режим обслуживания за столиками. Должно иметь значение true или false. Значение по умолчанию false
  • OPERATOR_CODE - код оператора. Описано в разделе Работа с СКО

Логирование

По умолчанию установлен INFO уровень логирования всех модулей в stdout (консоль).

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

refresh_rate: 15 seconds 
appenders:              
  stdout:
    kind: console

  receipts:               # (1) Дополнительное правило логирования 
    kind: console         # В консоль (stdout)
    encoder:    
      pattern: "{m}{n}"   # Шаблон. {m} - сообщение, {n} - перенос
root:
  level: info             # Уровень логирования для всех модулей
  appenders:
    - stdout

loggers:
  tsrv_renderer::esc_pos: # Данный модуль отвечает за преобразование в EscPos команды
    level: trace          # Уровень логирования
    appenders:
      - receipts          # (1)
    additive: false      

  actix_server::worker:
    level: warn
    appenders:
      - stdout

Путь конфигурационного файла зависит от ОС:

ОСПутьПример
Linux$XDG_CONFIG_HOME или $HOME/.config/home/alice/.config/.tsrv/log.yaml
Windows%AppData%C:\Users\Alice\AppData\Roaming\.tsrv\log.yaml

Конфигурация Менеджера СКО

Менеджер СКО отслеживает новые подключения СКО и может совершать над ними какие-либо операции, например - автоматическая авторизация

Пример конфигурационного файла:

tokens:
  AVQ11071080687:
    auto_login: true
    pin_code: 20740

В разделе tokens описываются СКО и конфигурации к ним.

  • auto_login - требуется ли автоматический вход (по умолчанию - false)
  • pin_code - PIN-код СКО. Если значение отсутствует - вход не будет выполнен.
    • В случае неверного pin-кода в лог будет выведена ошибка и потребуется совершать вход согласно протокола

Путь конфигурационного файла зависит от ОС:

ОСПутьПример
Linux$XDG_CONFIG_HOME или $HOME/.config/home/alice/.config/.tsrv/token_manager_conf.yaml
Windows%AppData%C:\Users\Alice\AppData\Roaming\.tsrv\token_manager_conf.yaml

Настройки ПК

Пример файла настроек:

headers:
  defaults:
    repr.html: true
    repr.esc_pos: true
    repr.text: true
    repr.link: true
    token: AVQ11031010705
    printer.dummy: ''

Путь конфигурационного файла зависит от ОС:

ОСПутьПример
Linux$XDG_CONFIG_HOME или $HOME/.config/home/alice/.config/.tsrv/settings.yaml
Windows%AppData%C:\Users\Alice\AppData\Roaming\.tsrv\settings.yaml

Установка TSRV как сервиса (службы) Windows

  • Установить tsrv как сервис
    • Рядом с tsrv.exe создать файл по имени install.bat со следующим содержимым:
    cd %~dp0
    .\tsrv.exe --install-service --test
    pause
    
    • Запустить install.bat от администратора
  • Альтернативный способ:
    • Запустить cmd.exe от Администратора
    • Выполнить c:\путь\к\tsrv.exe --install-service --test
  • Проверить, что сервис успешно запустился:
    • sc query tsrv-native
    • В случае, если сервис не в статусе RUNNING необходимо посмотреть логи сервиса
  • ⚠️ При переходе из тестовой зоны в боевую необходимо вызывать инсталлер с ключом --prod вместо --test. Это заведёт правильную переменную окружения для работы кассы.

Логи сервиса

  • Логи складываются в %AppData%\.tsrv\.logs
  • Так как сервис запускается под пользователем LocalSystem, логи можно найти по пути C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming\.tsrv\.logs
  • [необязательно] Чтобы логи и файлы конфигурации складывались в не-системного пользователя, необходимо сменить пользователя в service.msc для сервиса TSRVNative, это поддерживается

Общее описание принципов взаимодействия

Пример взаимодействия с СКО

Обработка ошибок

Ошибки разделяются на подтипы, на основании используемых префиксов:

  • AVQFR_ - ошибки СКО
  • TR_ - ошибки обработки ответов СКО. Практически в 100% случаев обрабатываются на уровне Программной Кассы. Клиентская обработка не требуется. Данные ошибки могут фигурировать в лог-файлах
  • USB_ - ошибка взаимодействия по USB с устройством. При возникновении таких ошибок при работе с СКО, последнее помечается как неактивное и удаляется из списка доступных
  • CRT_ - ошибки чтения данных из сертификата в СКО. Данная ошибка не передается на текущий момент на клиентскую часть, т.к. при ошибке чтения данных СКО считается невалидным и не помещается в список доступных к использованию. Данные ошибки могут фигурировать в лог-файлах
  • AVTPCR_ - аналогично CRT_, но относится к аттрибутам устройства
  • TIN_ - ошибки валидации входных данных. Данные ошибки не должны возникать при валидной передаче данных и их обработка заключается в исправлении входных данных
  • TSRV_ - общие сервисные ошибки, должны обрабатываться в соответствии с их описанием
  • PR_ - ошибки связанные с взаимодействием с принтером. При возникновении данного типа ошибок на этапе фискализации передается поле op_data с фискальным чеком
  • SM_ - ошибки сессий. Ошибки описаны в разделе Сессии
  • TORD_ - ошибки работы с заказами в ресторанном режиме. В режиме ритейла данные ошибки отсутствуют

Более подробно об ошибках описано в описании методов и в разделе Ошибки данной документации.

Транспортный уровень

Данный раздел будет дополняться поддерживаемыми транспортными протоколами.

HTTP

Обмен сообщения происходит по адресу: host:port/tsrv

По умолчанию HTTP сервер стартует на 0.0.0.0:1828, однако это можно поменяв, установив переменную окружения TSRV_ADDR в значение формата host:port

Все запросы совершаются методом POST

Заголовок Content-Type должен иметь значение application/json

Пример:

> POST /tsrv HTTP/1.1
> Host: localhost:1828
> User-Agent: insomnia/2021.5.3
> Content-Type: application/json
> Accept: */*
> Content-Length: 109

| {
|   "address": "ik.service.app",
|   "headers": {
|     "action": "init_session"
|   },
|   "data": null,
|   "type": "send"
| }

Альтернативный способ взаимодействия по HTTP

Возможен так же вариант взаимодействия по следующему URL методом POST: /tsrv/{address}/{action}.

В данном варианте все заголовки (поле headers сообщения) могут быть помещены в заголовки HTTP запроса, а заголовок action может быть опущен, т.к. находится внутри пути запроса. В тело HTTP запроса помещается поле data сообщения.

В данном случае пример инициализации сессии выглядит следующим образом:

> POST /tsrv/ik.service.app/init_session HTTP/1.1
> Host: localhost:1828
> User-Agent: insomnia/2021.5.3
> Content-Type: application/json
> Accept: */*
> Content-Length: 0

В то же время запрос на авторизацию (с телом запроса) выглядит следующим образом:

> POST /tsrv/ik.service.token.authority/authorize HTTP/1.1
> Host: localhost:1828
> User-Agent: insomnia/2021.5.3
> Content-Type: application/json
> sid: 630862a0-30cb-4743-82c9-c42a875beeba
> token: AVQ11071080687
> tokens.refresh: true
> Accept: */*
> Content-Length: 19

| {
|   "pin": "47702"
| }

Требуется обратить внимание на HTTP заголовки sid, token и tokens.refresh - они находятся в HTTP запросе

Проверка имени кассира

Важно: перед началом проверки удаляются пробелы в начале и конце строки.

Список проверок

  • Длина поля cashier не равна 0, иначе ошибка TIN_EMPTY_CASHIER
  • Длина поля cashier не превышает 16 символов, иначе ошибка TIN_CASHIER_LEN

Проверка суммы

Список проверок

  • value имеет не более 2 знаков после запятой, иначе ошибка TSRV_INVALID_SUM_DEC_PART
  • value является положительным числом, иначе ошибка TIN_NEGATIVE_SUM
  • value не превышает максимального значения

Проверка скидки тов. позиции

Список проверок

  • discount имеет не более 2 знаков после запятой, иначе ошибка TSRV_INVALID_SUM_DEC_PART
  • discount находится в интервале от -549755813887.99 до 549755813887.99 включительно

Проверка наименования тов. позиции

Важно: перед началом проверки удаляются пробелы в начале и конце строки.

Осуществляемые проверки

  • Длина name не равна 0, иначе ошибка TIN_EMPTY_NAME
  • Длина name не превышает 128 символов, иначе ошибка TIN_NAME_LEN

Проверка способов оплат и сдачи

Осуществляемые проверки

  • cash + cashless + other больше, либо равно сумме К оплате по чеку, иначе ошибка TIN_NOT_ENOUGH_MONEY
  • cashless + other меньше, либо равно сумме К оплате по чеку, иначе ошибка TIN_CASHLESS_OVERFLOW
  • cashless + other равно сумме К оплате по чеку и сумма оплат наличными равна 0, иначе ошибка TIN_CASH_OVERFLOW. Обьяснение: если сумма наличных и безналичных платежей равна требуемой сумме к оплате, то нет возможности дать сдачу, а значит сумма наличных должна быть равна 0.
  • change (сдача) должна быть больше либо равна 0, иначе ошибка TIN_NEGATIVE_CHANGE

Правила округления

Все значения, имеющий тип Sum и требующие округления, округляются в 2 этапа:

  • Округление до 3 знаков в сторону 0 (было: 1.2356, стало: 1.235)
  • Округление до 2 знаков, по правилам математики
    • Пример 1. было: 1.235, стало: 1.24
    • Пример 2. было: 1.234, стало: 1.23

Все поля, требующие округления, описаны в соответствующих запросах, либо описании полей.

Сервисы

Сервисы представляют собой наборы функций, агрегированные по назначению.

Название каждого сервиса (например - app) передается в поле address клиентского сообщения. Сервер, в свою очередь, передает обработку данного сообщения "сервису", с указанным наименованием, который в свою очередь пытается найти функцию для вызова на основании заголовка action. Стандартные сервисы, описанные в данном документе, преобразуют значение поля action в camel_case вне зависимости от переданного значения.

Напоминание: поле action может быть передано с любой политикой наименования, для сервисов, описанных в данной документации.

Важно: термин "возвращаемое значение" подразумевает под собой данные, передающиеся в поле data ответа сервера.

Все сервисы в данном разделе, которые взаимодействуют с конкретным СКО, принимают следующие заголовки:

  • token (обязательный) - серийный номер СКО
  • tokens.refresh (необязательный) - "true" / "false"

ik.service.app

Данный сервис предназначен для работы с операциями управления и получения информации о приложении.

version

Вызов данной функции возвращает информацию о версии протокола приложения.

В случае выполнения данной функции, поле data отсутствует. Возвращаемое значение: Version


Примеры

Запрос:

{
  "type": "send",
  "address": "ik.service.app",
  "reply_address": "version-msg",
  "data": null,
  "headers": {
    "action": "version"
  }
}

Ответ:

{
  "type": "send",
  "address": "version-msg",
  "reply_address": null,
  "data": {
    "version": "1.0.0"
  },
  "headers": null
}

init_session

Вызов данного метода инициализирует новую сессию, если это возможно.

В случае выполнения данной функции, поле data отсутствует. Возвращаемое значение: String

В случае, если на текущий момент существует активная сессия, будет возвращена ошибка SM_SESSION_EXISTS


Примеры

Запрос:

{
  "type": "send",
  "address": "ik.service.app",
  "reply_address": null,
  "data": null,
  "headers": {
    "action": "init_session"
  }
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": "44a31146-2bda-4ba7-bfb3-ca064b45e4ae",
  "headers": null
}

get_active_session_hash

Данный метод предназначен для получения хэш-значения текущей активной сессии, если таковая присутствует.

Входные данные: отсутствуют

Возвращаемые данные:

  • null - в случае, если сессия отсутствует
  • String - MD5 хэш-сумма текущей активной сессии в HEX представлении

Примеры

Запрос:

{
  "type": "send",
  "address": "ik.service.app",
  "reply_address": null,
  "data": null,
  "headers": {
    "action": "get_active_session_hash"
  }
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": "DEEBB93965F12F2AF219FB56129042BE",
  "headers": null
}

clear_session

Данный метод очищает активную сессию.

Входные данные: String - идентификатор сессии Возвращаемые данные:

  • null в случае успеха
  • ошибка SM_INVALID_SESSION, если передан неверный идентификатор сессии

Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.app",
  "reply_address": null,
  "data": "a9258dc0-9c8e-4fb2-88b3-d4871a2c6b84",
  "headers": {
    "action": "clear_session"
  }
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": null,
  "headers": null
}

Ошибка SM_INVALID_SESSION

Запрос:

{
  "type": "send",
  "address": "ik.service.app",
  "reply_address": null,
  "data": "123",
  "headers": {
    "action": "clear_session"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "invalid session id",
    "name": "SM_INVALID_SESSION",
    "op_data": null
  },
  "headers": null
}

pause_receipts_sending

Данный метод позволяет приостановить отправку документов.


Входные данные: отсутствуют

Возвращаемые данные: Отсутствуют


Для возобновления отправки документов требуется вызов метода resume_receipt_sending.


Примеры

Запрос

{
  "address": "ik.service.app",
  "headers": {
    "action": "pause_receipts_sending",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  },
  "type": "send"
}

Ответ

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": null,
  "headers": null
}

resume_receipts_sending

Данный метод позволяет возобновить отправку документов.


Входные данные: отсутствуют

Возвращаемые данные: Отсутствуют


Запрос

{
  "address": "ik.service.app",
  "headers": {
    "action": "resume_receipts_sending",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  },
  "type": "send"
}

Ответ

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": null,
  "headers": null
}

Работа с принтерами

request

Метод позволяет послать данные на принтер и опционально ожидать ответа на ту или иную команду.


Входные данные: EscPosReq

Возвращаемые данные:

  • Error - если произошла ошибка чтения/записи при работе с принтером
  • String - base64 представление ответа, если имеется
  • null - если в поле reply_size запроса отсутствует или имеет значение 0

print_delayed

Метод позволяет распечатать "отложенный" чек


Входные данные:

{
  "id": String
}

ik.service.token

Данный сервис предназначен для получения информации об СКО.

get_tokens

Данный метод предназначен для получения информации о доступных СКО.

Данный метод не требует передачи поля data в сообщении.

Возвращаемое значение: Массив значений TokenInformation

Важно: данный метод сканирует список USB-устройств автоматически при вызове, вне зависимости от того, было ли найдено СКО или нет. После сканирования СКО попадает в список доступных к использованию.


Примеры

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "get_tokens"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": [
    {
      "device_id": 131010703,
      "operator_code": 5,
      "organization": "ИП Моров А.М.",
      "pin_code_length": 5,
      "puk_code_length": 8,
      "serial": "AVQ11031010703",
      "tax_number": 191832203
    }
  ],
  "headers": null
}

get_token_by_serial

Данный метод предназначен для получения информации об СКО по серийному номеру.

Необходимость во входных данных отсутствует, однако серийный номер требуется к передаче в заголовке token.

Так же, опционально может быть передан заголовок tokens.refresh со следующими значениями:

  • "true" - будет совершено обновление сканирование USB-устройств
  • "false" (по умолчанию) - сканирование USB-устройств совершено не будет
  • В случае, если передано иное значение, будет возвращена ошибка TSRV_INVALID_HEADER

Возвращаемое значение: TokenInformation, либо ошибка TSRV_TOKEN_NOT_FOUND, если СКО не было найдено

Важно: если этот метод был вызван без передачи заголовка tokens.refresh, либо со значением "false", а СКО не было помечено как доступное к использованию, например методом get_tokens, то будет отдана ошибка TSRV_TOKEN_NOT_FOUND


Примеры

Пример с ошибкой

Запрос, без tokens.refresh:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "token": "AVQ11031010703",
    "action": "get_token_by_serial"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "token was not found. available: [])",
    "name": "TSRV_TOKEN_NOT_FOUND"
  },
  "headers": null
}

Пример успешного выполнения

Запрос с заголовком tokens.refresh:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "get_token_by_serial",
    "tokens.refresh": "true",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": {
    "device_id": 131010703,
    "operator_code": 5,
    "organization": "ИП Моров А.М.",
    "pin_code_length": 5,
    "puk_code_length": 8,
    "serial": "AVQ11031010703",
    "tax_number": 191832203
  },
  "headers": null
}

Пример неверного значения tokens.refresh

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "get_token_by_serial",
    "token": "AVQ11031010703",
    "tokens.refresh": "truefalse"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "invalid header value. header: 'tokens.refresh', error: provided string was not `true` or `false`",
    "name": "TSRV_INVALID_HEADER"
  },
  "headers": null
}

get_cash_in_token

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

Входные данные:

  • null.
  • либо строковое значение Currency

Возвращаемые данные:

  • В случае, если во входных данных был передан null, будет возвращен массив значений CashIn, со всеми поддерживаемыми валютами
  • В случае, если было передано значение Currency, будет возвращен массив с 1 элементом CashIn, соответствующий переданной валюте
  • В случае, если было передано неверное значение Currency, будет возвращена ошибка TSRV_DESERIALIZE_ERROR

Важно: должны быть соблюдены следующие условия:

  1. В СКО должна быть произведения авторизация по PIN-коду, иначе будет отдана ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: в случае, если смена закрыта, будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED


Примеры

Ошибка (сессия не авторизована)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "get_cash_in_token",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

Успех (все валюты)

Запрос

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "get_cash_in_token",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": [
    {
      "cash": "0.00",
      "currency": "BYN"
    },
    {
      "cash": "0.00",
      "currency": "USD"
    },
    {
      "cash": "0.00",
      "currency": "EUR"
    },
    {
      "cash": "0.00",
      "currency": "RUB"
    }
  ],
  "headers": null
}

Успех (указание валюты)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": "BYN",
  "headers": {
    "token": "AVQ11031010703",
    "action": "get_cash_in_token"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": [
    {
      "cash": "0.00",
      "currency": "BYN"
    }
  ],
  "headers": null
}

Ошибка (неверная валюта)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": "TRY",
  "headers": {
    "token": "AVQ11031010703",
    "action": "get_cash_in_token"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "failed to deserialize value. unknown variant `TRY`, expected one of `BYN`, `USD`, `EUR`, `RUB`",
    "name": "TSRV_DESERIALIZE_ERROR"
  },
  "headers": null
}

next_cheque_number

Данный метод предназначен для получения номера следующего документа.

Входные данные: null

Возвращаемые данные: u32 - номер следующего чека

Важно: должны быть соблюдены следующие условия:

  1. В СКО должна быть произведения авторизация по PIN-коду, иначе будет отдана ошибка AVQFR_SESSION_NOT_AUTHORIZED
  2. Смена в СКО должна быть открыта, иначе будет отдана ошибка AVQFR_SHIFT_IS_CLOSED

Примеры

Успешный (пройдена авторизация)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "next_cheque_number",
    "tokens.refresh": "true",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": 5782,
  "headers": null
}

Ошибка (авторизация не пройдена)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "next_cheque_number",
    "token": "AVQ11031010703",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

Ошибка (смена закрыта)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "next_cheque_number",
    "tokens.refresh": "true",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "смена закрыта (команда возможна только при открытой смене)",
    "name": "AVQFR_SHIFT_IS_CLOSED"
  },
  "headers": null
}

get_stored_documents

Данный метод предназначен для получения информации, о количестве неотправленных документов.

С клиентской стороны отсутствует возможность повлиять на количество отправленных или неотправленных документов и этот метод хоть и может вводить в панику числом, отличным от 0, является лишь справочным для проверки, что документы (не)отправляются на сервер Оператора Программной Кассы.

Входные данные: null

Возвращаемые данные: u16 - количество неотправленных документов на сервер.

Важно: должно быть соблюдено следующее условие:

  1. В СКО должна быть произведения авторизация по PIN-коду, иначе будет отдана ошибка AVQFR_SESSION_NOT_AUTHORIZED

Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "token": "AVQ11031010703",
    "tokens.refresh": "true",
    "action": "get_stored_documents"
  }
}

Ответ:

{
   "type": "send",
   "address": "example",
   "reply_address": null,
   "data": 100,
   "headers": null
}

Ошибка (не пройдена авторизация)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "token": "AVQ11031010703",
    "action": "get_stored_documents",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

get_oldest_document

Данный метод предназначен для получения самого "старого" неотправленного документа на сервер Оператора Программной Кассы.

Входные данные: null

Возвращаемые данные: OldestDocument

Важно: должны быть соблюдены следующие условия:

  1. В СКО должна быть произведения авторизация по PIN-коду, иначе будет отдана ошибка AVQFR_SESSION_NOT_AUTHORIZED

Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "token": "AVQ11031010703",
    "action": "get_oldest_document",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": {
    "date": "2021-09-13T10:17:35+03:00",
    "uid": "A50B7A727894C03707CF108F"
  },
  "headers": null
}

Ошибка (авторизация не пройдена)

Запрос:

{
  "type": "send",
  "address": "ik.service.token",
  "reply_address": "example",
  "data": null,
  "headers": {
    "token": "AVQ11031010703",
    "action": "get_oldest_document",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

get_token_state

Данный метод позволяет получить сохраненную информацию об СКО.


Входные данные: отсутствуют

Возвращаемые данные:

  • null если авторизация не пройдена
  • State, если авторизация пройдена

get_total_income


Входные данные: Currency

Возвращаемые данные: Sum


get_status

Получение статуса СКО.

Статус unknown означает то, что приложение не смогло узнать статус кассы.

Статус blocked означает, что касса была заблокирована.

Статус active означает, что все хорошо и касса может работать.


Входные данные: отсутствуют

Возвращаемые данные: Status


set_trade_point_name

Указание наименования торговой точки, для отображения на чеках.


Входные данные: String

Возвращаемые данные: null


get_minmax_receipts

Получение информации о первом и последнем известном документе в рамках текущей, либо одной из предыдущих смен.


Входные данные:

  • null - получение чеков в текущей смене
  • u16 - номер смены, из которой требуется получение номеров первого и последнего документа

Возвращаемые данные:

  • AVQFR_SHIFT_IS_CLOSED - если передано null во входных данных и смена закрыта
  • AVQFR_SESSION_NOT_AUTHORIZED - если не пройдена авторизация в СКО
  • MinMaxReceipts - в случае успеха

get_receipt

Получение информации по ранее фискализированному чеку в текущей/предыдущей смене.


Входные данные: ReceiptRequest

Возвращаемые данные:

  • null - если чек не найден
  • Receipt - если чек найден

Важно: Данный метод требует авторизации в СКО. В случае, если авторизация в СКО не пройдена будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: если data.shift_number передано значение null требуется наличие открытой смены, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

print_prev_receipt

Получение и печать ранее фискализированного документа.


Входные данные: ReceiptRequest

Возвращаемые данные:

  • null - если чек не найден
  • Receipt - если чек найден

Важно: Данный метод требует авторизации в СКО. В случае, если авторизация в СКО не пройдена будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: если data.shift_number передано значение null требуется наличие открытой смены, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

Важно: для данного запроса требуются заголовки для работы с принтером

ik.service.token.authority

Данный сервис предназначен для совершения операций с СКО - связанных с PIN/PUK кодами.

authorize

Данный метод предназначен для совершения авторизации в СКО.

Входные данные: Pin

Возвращаемые данные:

  • null в случае успеха.
  • ошибка AVQFR_BAD_KEY_AUTH_DATA в случае, если указан неверный PIN-код.
  • ошибка TIN_CODE_LEN в случае, если длина PIN-кода неверна.

Важно: после каждой неверной попытки авторизации задержка ответа увеличивается. После 3 попытки время ожидания ответа авторизации составляет 10 секунд. После ввода успешного PIN-кода задержка сбрасывается.


Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": "example",
  "data": {
    "pin": "16522"
  },
  "headers": {
    "tokens.refresh": "true",
    "token": "AVQ11031010703",
    "action": "authorize",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": null,
  "headers": null
}

Ошибка: Неверный PIN (неверная длина)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": null,
  "data": {
    "pin": "1652"
  },
  "headers": {
    "action": "authorize",
    "token": "AVQ11031010703",
    "tokens.refresh": "true",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "invalid code length. current: 4, required: 5",
    "name": "TIN_CODE_LEN"
  },
  "headers": null
}

Ошибка: неверный PIN

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": null,
  "data": {
    "pin": "16523"
  },
  "headers": {
    "token": "AVQ11031010703",
    "tokens.refresh": "true",
    "action": "authorize",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "неверные данные для авторизации сессии (неверное значение PIN, PUK или REG)",
    "name": "AVQFR_BAD_KEY_AUTH_DATA"
  },
  "headers": null
}

change_pin_code

Данный метод предназначен для изменения PIN-кода СКО.

Входные данные: ChangePin

Возвращаемые данные:

  • null в случае успеха
  • ошибка AVQFR_BAD_KEY_AUTH_DATA в случае, если указан неверный PIN-код
  • ошибка TIN_CODE_LEN в случае, если длина PIN-кода или PUK-кода неверна

Данный метод совершает следующие операции:

  1. Попытка совершить logout
  2. Авторизация по PUK-коду
  3. Смена PIN-кода
  4. logout

Как следствие, после совершения данного метода, если была авторизованная сессия, сессия авторизованной не является.


Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": null,
  "data": {
    "pin": "16522",
    "puk": "17307748"
  },
  "headers": {
    "tokens.refresh": "true",
    "token": "AVQ11031010703",
    "action": "change_pin_code",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": null,
  "headers": null
}

Ошибка (неверный PUK-код)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": null,
  "data": {
    "pin": "16522",
    "puk": "17307749"
  },
  "headers": {
    "token": "AVQ11031010703",
    "tokens.refresh": "true",
    "action": "change_pin_code",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "неверные данные для авторизации сессии (неверное значение PIN, PUK или REG)",
    "name": "AVQFR_BAD_KEY_AUTH_DATA",
  },
  "headers": null
}

Ошибка (неверная длина PUK-кода)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": null,
  "data": {
    "pin": "16522",
    "puk": "1730774"
  },
  "headers": {
    "token": "AVQ11031010703",
    "action": "change_pin_code",
    "tokens.refresh": "true",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "invalid code length. current: 7, required: 8",
    "name": "TIN_CODE_LEN"
  },
  "headers": null
}

Ошибка (неверная длина PIN-кода)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": null,
  "data": {
    "pin": "1652",
    "puk": "17307748"
  },
  "headers": {
    "token": "AVQ11031010703",
    "action": "change_pin_code",
    "tokens.refresh": "true",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "invalid code length. current: 4, required: 5",
    "name": "TIN_CODE_LEN"
  },
  "headers": null
}

logout

Данный метод предназначен для совершения выхода из авторизованной сессии.

Входные данные: null

Возвращаемые данные:

  • null в случае успеха
  • ошибка AVQFR_SESSION_NOT_AUTHORIZED в случае, если текущая сессия на авторизована

Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "token": "AVQ11031010703",
    "action": "logout",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": null,
  "headers": null
}

Ошибка: сессия на авторизована

Запрос:

{
  "type": "send",
  "address": "ik.service.token.authority",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "logout",
    "token": "AVQ11031010703",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

ik.service.token.shift

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

open_shift

Данный метод предназначен для открытия смены.

Входные данные: null

Возвращаемые данные:

  • null в случае успеха.
  • ошибка AVQFR_SESSION_NOT_AUTHORIZED в случае, если сессия не авторизована.
  • ошибка AVQFR_SHIFT_IS_OPENED в случае, если смена уже открыта.
  • ошибка AVQFR_RECEIPT_IS_PENDING в случае, если в СКО находятся документы. которые не были отправлены на сервер в течение последних 7 дней.

Важно: смена может быть открыта не более 24 часов.

Важно: в случае, если имеются неотправленные документы на сервер требуется:

  1. Проверить соединение с интернетом.
  2. Сессия в СКО должна быть авторизована для отправки документов.
  3. Проверить, что сервера Оператора Программной Кассы доступны из текущей сети.
  4. В случае, если предыдущие пункты выполнены, обратиться к представителям Оператора Программной Кассы, предоставив серийный номер СКО, а так же лог-файл.

Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "openShift",
    "token": "AVQ11031010703",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": null,
  "headers": null
}

Ошибка (сессия не авторизована)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "openShift",
    "token": "AVQ11031010703",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

Ошибка (смена уже открыта)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "token": "AVQ11031010703",
    "action": "openShift"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "смена открыта (команда возможна только при закрытой смене)",
    "name": "AVQFR_SHIFT_IS_OPENED"
  },
  "headers": null
}

Ошибка (требуется отправка документов)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "token": "AVQ11031010703",
    "action": "openShift"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "в устройстве присутствуют кассовые документы, которые необходимо передать на сервер",
    "name": "AVQFR_RECEIPT_IS_PENDING"
  },
  "headers": null
}

get_x_report

Данный метод предназначен для получения X-отчета.

Входные данные: null

Возвращаемые данные:

  • Report в случае успеха
  • ошибка AVQFR_SESSION_NOT_AUTHORIZED в случае, если сессия не авторизована
  • ошибка AVQFR_SHIFT_IS_CLOSED в случае, если смена закрыта

Важно: данный метод НЕ отдает документ на печать. Для отправки на печать следует использовать метод печати X-отчёта


Примеры

Успех

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "action": "get_x_report",
    "token": "AVQ11031010703",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": {
    "cashier": null,
    "close_date": null,
    "company_name": "ИП Моров А.М.",
    "counters": [],
    "device_id": 131010703,
    "first_sale_number": 0,
    "last_sale_number": 0,
    "number": 159,
    "open_date": "2021-09-13T22:16:33+03:00",
    "sales_count": 0,
    "tax_number": 191832203,
    "uid": null
  },
  "headers": null
}

Ошибка (сессия не авторизована)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "token": "AVQ11031010703",
    "tokens.refresh": "true",
    "action": "get_x_report"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

Ошибка (смена закрыта)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "get_x_report",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "смена закрыта (команда возможна только при открытой смене)",
    "name": "AVQFR_SHIFT_IS_CLOSED"
  },
  "headers": null
}

print_x_report

Данный метод предназначен для получения X-отчета.

Входные данные: ReportComments или null

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

Возвращаемые данные:

  • Report в случае успеха
  • ошибка AVQFR_SESSION_NOT_AUTHORIZED в случае, если сессия не авторизована
  • ошибка AVQFR_SHIFT_IS_CLOSED в случае, если смена закрыта

Важно: в случае, если в операции не совершалось никаких операций, массив счетчиков (data.counters) будет пустым, однако на печать в любом случае уйдут счетчики с нулевыми значениями по валюте BYN

Примеры

Примеры аналогичны получению Х-отчета, за исключением необходимых заголовков для работы с принтером

close_shift

Данный метод предназначен для закрытия смены с последующим получением Z-отчета.

Входные данные:

  • null
  • либо CloseShiftRequest, если требуется сохранить и распечатать имя кассира, закрывшего смену.

Возвращаемые данные:

  • Report в случае успеха.
  • ошибка AVQFR_SESSION_NOT_AUTHORIZED в случае, если сессия не авторизована.
  • ошибка AVQFR_SHIFT_IS_CLOSED в случае, если смена закрыта.
  • ошибка AVQFR_NEGATIVE_SHIFT_BALANCE в случае, если имеются наличные в кассе.

Важно: для закрытия смены, требуется полное изъятие наличных.


Примеры

Успех (с именем кассира)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": {
    "cashier": "Администратор"
  },
  "headers": {
    "action": "closeShift",
    "token": "AVQ11031010703",
    "tokens.refresh": "true"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": {
    "cashier": "Администратор",
    "close_date": "2021-09-13T22:31:24+03:00",
    "company_name": "ИП Моров А.М.",
    "counters": [
      {
        "cancels_count": 0,
        "cancels_sum": "0.00",
        "corrections_count": 0,
        "corrections_sum": "0.00",
        "currency": "BYN",
        "deposits_count": 0,
        "deposits_sum": "0.00",
        "extended_counters": null,
        "income": "4161.40",
        "money_backs_count": 0,
        "money_backs_sum": "0.00",
        "rollbacks_count": 0,
        "rollbacks_sum": "0.00",
        "sales_cash_sum": "0.00",
        "sales_cashless_sum": "0.00",
        "sales_count": 0,
        "sales_sum": "0.00",
        "withdraws_count": 0,
        "withdraws_sum": "0.00"
      }
    ],
    "device_id": 131010703,
    "first_sale_number": 0,
    "last_sale_number": 0,
    "number": 159,
    "open_date": "2021-09-13T22:16:33+03:00",
    "sales_count": 0,
    "tax_number": 191832203,
    "uid": "ACB32AEF876DFDD307CF108F"
  },
  "headers": null
}

Успех (без имени кассира)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "closeShift",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "send",
  "address": "example",
  "reply_address": null,
  "data": {
    "cashier": null,
    "close_date": "2021-09-13T22:32:44+03:00",
    "company_name": "ИП Моров А.М.",
    "counters": [
      {
        "cancels_count": 0,
        "cancels_sum": "0.00",
        "corrections_count": 0,
        "corrections_sum": "0.00",
        "currency": "BYN",
        "deposits_count": 0,
        "deposits_sum": "0.00",
        "extended_counters": null,
        "income": "4161.40",
        "money_backs_count": 0,
        "money_backs_sum": "0.00",
        "rollbacks_count": 0,
        "rollbacks_sum": "0.00",
        "sales_cash_sum": "0.00",
        "sales_cashless_sum": "0.00",
        "sales_count": 0,
        "sales_sum": "0.00",
        "withdraws_count": 0,
        "withdraws_sum": "0.00"
      }
    ],
    "device_id": 131010703,
    "first_sale_number": 0,
    "last_sale_number": 0,
    "number": 160,
    "open_date": "2021-09-13T22:32:44+03:00",
    "sales_count": 0,
    "tax_number": 191832203,
    "uid": "369DF290AC86E05D07CF108F"
  },
  "headers": null
}

Ошибка (сессия не авторизована)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "closeShift",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED"
  },
  "headers": null
}

Ошибка (смена закрыта)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "closeShift",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "смена закрыта (команда возможна только при открытой смене)",
    "name": "AVQFR_SHIFT_IS_CLOSED"
  },
  "headers": null
}

Ошибка (Имеются наличные в СКО)

Запрос:

{
  "type": "send",
  "address": "ik.service.token.shift",
  "reply_address": "example",
  "data": null,
  "headers": {
    "tokens.refresh": "true",
    "action": "closeShift",
    "token": "AVQ11031010703"
  }
}

Ответ:

{
  "type": "error",
  "address": "example",
  "reply_address": null,
  "data": {
    "description": "получен отрицательный сменный баланс",
    "name": "AVQFR_NEGATIVE_SHIFT_BALANCE"
  },
  "headers": null
}

Пример запроса с комментариями

{
	"type": "send",
	"address": "ik.service.token.shift",
	"data": {
		"cashier": "Администратор",
		"comments": {
			"top": {
				"before": "Магазин ASD"
			}
		}
	},
	"headers": {
		"action": "closeShift",
		"token": "AVQ11071080699",
		"tokens.refresh": "true",
		"sid": "f46dfb7b-2124-4790-ad89-32f3adbe2edf",
		"printer.usb.vendor": "1137",
		"printer.usb.product": "85"
	}
}

get_z_report_copy

Данный метод предназначен для печати копии Z-отчета.

Входные данные:

Возвращаемые данные:

  • Report в случае успеха.
  • ошибка AVQFR_SESSION_NOT_AUTHORIZED в случае, если сессия не авторизована.

Важно: требуется авторизация

create_deposit

Входные данные: NewSumChequeRequest

Возвращаемые данные: Deposit


Важно: Для совершения данной операции требуется Авторизация в СКО, иначе будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: Для совершения данной операции требуется открытая смена, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

Важно: Для совершения данной операции смена должна быть открыта менее 24 часов, иначе будет возвращена ошибка AVQFR_SHIFT_IS_PENDING


Осуществляемые действия перед операцией внесения


Примеры запросов

Успех

Запрос:

{
  "address": "ik.service.token.deposit",
  "headers": {
    "action": "create_deposit",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": {
    "extra": null,
    "header": {
      "cashier": "Test",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2021-09-25T14:07:07.523495+03:00",
      "device_id": 131010703,
      "number": 5918,
      "serial_number": "AVQ11031010703",
      "shift_number": 206,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "deposit",
      "uid": "0C7D6E36464C9F4A07CF108F"
    },
    "sum": "1.00"
  },
  "headers": null
}

Ошибка AVQFR_SESSION_NOT_AUTHORIZED

Запрос:

{
  "address": "ik.service.token.deposit",
  "headers": {
    "action": "create_deposit",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED",
    "op_data": null
  },
  "headers": null
}

Ошибка AVQFR_SHIFT_IS_CLOSED

Запрос:

{
  "address": "ik.service.token.deposit",
  "headers": {
    "action": "create_deposit",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "смена закрыта (команда возможна только при открытой смене)",
    "name": "AVQFR_SHIFT_IS_CLOSED",
    "op_data": null
  },
  "headers": null
}

Ошибка AVQFR_SHIFT_IS_PENDING

Запрос:

{
  "address": "ik.service.token.deposit",
  "headers": {
    "action": "create_deposit",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "необходимо закрыть смену",
    "name": "AVQFR_SHIFT_IS_PENDING",
    "op_data": null
  },
  "headers": null
}

create_withdraw

Входные данные: NewSumChequeRequest

Возвращаемые данные: Withdraw


Важно: Для совершения данной операции требуется Авторизация в СКО, иначе будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: Для совершения данной операции требуется открытая смена, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

Важно: Для совершения данной операции смена должна быть открыта менее 24 часов, либо сумма изъятия должна быть на сумму всех наличных в кассе по указанной валюте, иначе будет возвращена ошибка AVQFR_SHIFT_IS_PENDING.


Осуществляемые действия перед операцией внесения


Примеры запросов

Успех

Запрос:

{
  "address": "ik.service.token.withdraw",
  "headers": {
    "action": "create_withdraw",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": {
    "extra": null,
    "header": {
      "cashier": "Test",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2021-09-25T14:08:57.072357+03:00",
      "device_id": 131010703,
      "number": 5919,
      "serial_number": "AVQ11031010703",
      "shift_number": 206,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "withdraw",
      "uid": "2636BF4D0E0E524F07CF108F"
    },
    "sum": "1.00"
  },
  "headers": null
}

Ошибка AVQFR_SESSION_NOT_AUTHORIZED

{
  "address": "ik.service.token.withdraw",
  "headers": {
    "action": "create_withdraw",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "сессия не авторизована (команда требует обязательной авторизации)",
    "name": "AVQFR_SESSION_NOT_AUTHORIZED",
    "op_data": null
  },
  "headers": null
}

Ошибка AVQFR_SHIFT_IS_CLOSED

Запрос:

{
  "address": "ik.service.token.withdraw",
  "headers": {
    "action": "create_withdraw",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "смена закрыта (команда возможна только при открытой смене)",
    "name": "AVQFR_SHIFT_IS_CLOSED",
    "op_data": null
  },
  "headers": null
}

Ошибка AVQFR_SHIFT_IS_PENDING

Запрос:

{
  "address": "ik.service.token.withdraw",
  "headers": {
    "action": "create_withdraw",
    "sid": "47dc1757-3b51-4bae-b300-6acd71799426",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sum_cheque_data": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "sum": "1.00"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "необходимо закрыть смену",
    "name": "AVQFR_SHIFT_IS_PENDING",
    "op_data": null
  },
  "headers": null
}

store

Сохранение товарной позиции во внутреннее хранилище.


Входные данные: StorageItem

Возвращаемые данные:

  • null - если товар был успешно сохранен и ранее товар с данным идентификатором отсутствовал.
  • StorageItem - ранее существующий товар с данным идентификатором.

remove

Удаление товарной позиции из хранилища


Входные данные: String - идентификатор товара

Возвращаемые данные:

  • null - если товар не был найден
  • StorageItem - удаленный товар

get

Получение информации о товаре из хранилища.


Входные данные: String - идентификатор товара.

Возвращаемые данные:

  • null - если товар не найден в хранилище.
  • StorageItem - если товар был найден.

get_ids

Получение идентификаторов всех сохраненных товаров.


Входные данные: отсутствуют.

Возвращаемые данные: массив String ([ *String ]) идентификаторов товаров.

Продажа

Сервис ритейла: ik.service.token.sales.retail

create_sale

Данный метод предназначен для совершения операции продажи.

Входные данные: SaleRequest

Возвращаемые данные: Sale


Важно: Для совершения данной операции требуется Авторизация в СКО, иначе будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: Для совершения данной операции требуется открытая смена, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

Важно: Для совершения данной операции смена должна быть открыта менее 24 часов, иначе будет возвращена ошибка AVQFR_SHIFT_IS_PENDING

Важно: После совершения продажи, сформированный объект Sale сохраняется, для дальнейшего возможного совершения операции аннулирования.


Осуществляемые действия перед операцией продажи

Важно: если скидка на товарную позицию имеет отрицательное значение, скидка считается надбавкой


Примеры

Успех

Запрос:

{
  "address": "ik.service.token.sales.retail",
  "headers": {
    "action": "create_sale",
    "sid": "ed046722-8f66-4709-b087-3af224514802",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "sale": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "items": [
        {
          "price": "1.00",
          "quantity": "1.000",
          "code": {
            "type": 3,
            "value": 9999999999
          },
          "name": "длинное наименование товара на большом и маленьком чеках 11111",
          "discount": "-1.02",
          "tax_rate": "tax10"
        }
      ],
      "payments": [
        {
          "payment_type": "cash",
          "value": "2.01"
        }
      ],
      "cheque_discount": "0.01"
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": {
    "change": "0.00",
    "extra": null,
    "header": {
      "cashier": "Test",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2021-09-27T18:25:23.523915+03:00",
      "device_id": 131010703,
      "number": 5979,
      "serial_number": "AVQ11031010703",
      "shift_number": 209,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "sale",
      "uid": "D940E3560F346BAC07CF108F"
    },
    "items": [
      {
        "item": {
          "code": {
            "type": 3,
            "value": 9999999999
          },
          "comment": null,
          "discount": "-1.02",
          "id": null,
          "name": "длинное наименование товара на большом и маленьком чеках 11111",
          "price": "1.00",
          "quantity": "1.000",
          "tax_rate": "tax10"
        },
        "values": {
          "discount": "-1.02",
          "raw_sum": "1.00",
          "sum": "2.02",
          "tax": "0.18"
        }
      }
    ],
    "payments": [
      {
        "name": null,
        "payment_type": "cash",
        "ref": null,
        "value": "2.01"
      }
    ],
    "rolled_back_by": null,
    "sub_totals": {
      "cheque_discount": "0.01",
      "sum": "2.02",
      "taxes": [
        {
          "sum": "0.18",
          "tax_rate": "tax10"
        }
      ]
    },
    "totals": {
      "discount": "-1.01",
      "sum": "3.03"
    }
  },
  "headers": null
}

create_sale_ex

Данный метод предназначен для совершения операции продажи на основании товаров из внутренней БД товаров.


Входные данные: ExSaleRequest

Возвращаемые данные: Sale


Все проверки и действия идентичны методу create_sale после получения всех товарных позиций

on_cancel

Данный метод предназначен для регистрации отмены платежного док-та


Входные данные: CancelRequest

Возвращаемые данные: null


Пример запроса

{
  "address": "ik.service.token.sales.retail",
  "headers": {
    "action": "on_cancel",
    "sid": "{{ _.sid }}",
    "token": "AVQ11071080687",
    "printer.dummy": ""
  },
  "data": {
    "currency": "BYN",
    "sum": "1.00",
    "corrections_sum": "1.00",
    "corrections_count": 1
  },
  "type": "send"
}

save_order

Метод сохранения/обновления заказа.


Входные данные: OrderRequest

Возвращаемые данные:

  • null - если заказ был успешно создан.
  • Order - замененный заказ (тот, что имел тот же идентификатор и был заменен заказом в запросе).

Важно: для вызова данного метода требуется пройденная авторизация в СКО.

Важно: для вызова данного метода требуется открытая смена в СКО.

Осуществляемые действия перед сохранением заказа


Примеры

Запрос:

{
  "address": "ik.service.token.sales.rest",
  "headers": {
    "action": "save_order",
    "sid": "{{ _.sid }}",
    "token": "AVQ11071080687"
  },
  "data": {
    "order_id": "123",
    "order": {
      "number": 111,
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "items": [
        {
          "price": "1.00",
          "quantity": "1.000",
          "code": {
            "type": 0,
            "value": 9999999999
          },
          "name": "блюдо 1",
          "discount": "-1.02"
        }
      ],
      "cheque_discount": "1.22",
      "table": 1,
      "place": 1
    }
  },
  "type": "send"
}

remove_order

Удаление заказа.


Входные данные: String

Возвращаемые данные:

  • null - если заказ отсутствовал.
  • Order - удаленный заказ.

Важно: для вызова данного метода требуется пройденная авторизация в СКО.

Важно: для вызова данного метода требуется открытая смена в СКО.

print_order

Печать счёта на основании заказа


Входные данные: PrintBillRequest

Возвращаемые данные:

  • null - если заказ был успешно распечатан

Важно: для вызова данного метода требуется пройденная авторизация в СКО

Важно: для вызова данного метода требуется открытая смена в СКО

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


pay_order

Оплата заказа.


Входные данные: PayOrderRequest

Возвращаемые данные: Sale


Важно: для вызова данного метода требуется пройденная авторизация в СКО.

Важно: для вызова данного метода требуется открытая смена в СКО.

Важно: после оплаты заказа заказ удаляется из хранилища заказов.


Примеры

Запрос:

{
  "address": "ik.service.token.sales.rest",
  "headers": {
    "action": "pay_order",
    "sid": "{{ _.sid }}",
    "token": "AVQ11071080687",
    "printer.dummy": ""
  },
  "data": {
    "order_id": "123",
    "payments": [
      {
        "payment_type": "cash",
        "value": "0.80"
      }
    ]
  },
  "type": "send"
}

get_orders_ids

Получение списка известных идентификаторов заказов.


Входные данные: null

Возвращаемые данные: массив идентификаторов заказов ([ *String ]).


Важно: для вызова данного метода требуется пройденная авторизация в СКО.

Важно: для вызова данного метода требуется открытая смена в СКО.

get_orders_ids

Получение заказа по идентификатору


Входные данные: String - идентификатор заказа

Возвращаемые данные:

  • null если заказ не найден
  • Order - описание заказа

Важно: для вызова данного метода требуется пройденная авторизация в СКО

Важно: для вызова данного метода требуется открытая смена в СКО

create_money_back

Операция возврата.


Входные данные: NewMoneyBackRequest

Возвращаемые данные: MoneyBack


Важно: Для совершения данной операции требуется Авторизация в СКО, иначе будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: Для совершения данной операции требуется открытая смена, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

Важно: Для совершения данной операции смена должна быть открыта менее 24 часов, иначе будет возвращена ошибка AVQFR_SHIFT_IS_PENDING

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


Примеры

Успех

Запрос:

{
  "address": "ik.service.token.moneyback",
  "headers": {
    "action": "create_money_back",
    "sid": "0855e0a7-93b9-4380-ad8d-a8d4b75deea9",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "money_back": {
      "header": {
        "cashier": "Test",
        "currency": "BYN"
      },
      "item": {
        "price": "1.00",
        "quantity": "1.000",
        "code": {
          "type": 0,
          "value": 0
        },
        "name": "Test name"
      },
      "payments": [
        {
          "payment_type": "cash",
          "value": "0.50"
        },
        {
          "payment_type": "cashless",
          "value": "0.50"
        }
      ]
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": {
    "extra": null,
    "header": {
      "cashier": "Test",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2021-09-25T14:27:27.769989+03:00",
      "device_id": 131010703,
      "number": 5921,
      "serial_number": "AVQ11031010703",
      "shift_number": 208,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "money_back",
      "uid": "D159F4DA89745B8407CF108F"
    },
    "item": {
      "item": {
        "code": {
          "type": 0,
          "value": 0
        },
        "comment": null,
        "discount": null,
        "id": null,
        "name": "Test name",
        "price": "1.00",
        "quantity": "1.000",
        "tax_rate": null
      },
      "values": {
        "discount": "0",
        "raw_sum": "1.00",
        "sum": "1.00",
        "tax": "0"
      }
    },
    "payments": [
      {
        "name": null,
        "payment_type": "cash",
        "ref": null,
        "value": "0.50"
      },
      {
        "name": null,
        "payment_type": "cashless",
        "ref": null,
        "value": "0.50"
      }
    ],
    "totals": {
      "cash": "0.50",
      "cashless": "0.50",
      "sum": "1.00"
    }
  },
  "headers": null
}

create_money_back_ex

Операция возврата.


Входные данные: ExNewMoneyBackRequest

Возвращаемые данные: MoneyBack


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

create_rollback

Операция аннулирования

Входные данные: NewRollbackRequest

Возвращаемые данные: Rollback


Важно: Для совершения данной операции требуется Авторизация в СКО, иначе будет возвращена ошибка AVQFR_SESSION_NOT_AUTHORIZED

Важно: Для совершения данной операции требуется открытая смена, иначе будет возвращена ошибка AVQFR_SHIFT_IS_CLOSED

Важно: Для совершения данной операции смена должна быть открыта менее 24 часов, иначе будет возвращена ошибка AVQFR_SHIFT_IS_PENDING

Важно: данная операция требует того, чтобы аннулируемый документ находился в текущей смене, а так же того, что чек не был аннулирован ранее. В случае, если документ не был найден, будет возвращена ошибка AVQFR_NO_DATA

Важно: Для данного запроса поле currency игнорируется и может быть не передано


Примеры

Успех

Запрос:

{
  "address": "ik.service.token.rollback",
  "headers": {
    "action": "create_rollback",
    "sid": "ed046722-8f66-4709-b087-3af224514802",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "rollback": {
      "header": {
        "cashier": "Кассир"
      },
      "target_num": 5979
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "send",
  "address": null,
  "reply_address": null,
  "data": {
    "extra": null,
    "header": {
      "cashier": "Кассир",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2021-09-27T18:26:40.693479+03:00",
      "device_id": 131010703,
      "number": 5980,
      "serial_number": "AVQ11031010703",
      "shift_number": 209,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "rollback",
      "uid": "BF9CCC355AD0A45307CF108F"
    },
    "target_num": 5979,
    "totals": {
      "cash": "2.01",
      "cashless": "0",
      "other": "0",
      "sum": "2.01"
    }
  },
  "headers": null
}

Ошибка (документ был аннулирован)

Запрос:

{
  "address": "ik.service.token.rollback",
  "headers": {
    "action": "create_rollback",
    "sid": "ed046722-8f66-4709-b087-3af224514802",
    "token": "AVQ11031010703",
    "printer.dummy": ""
  },
  "data": {
    "rollback": {
      "header": {
        "cashier": "Кассир"
      },
      "target_num": 5979
    }
  },
  "type": "send"
}

Ответ:

{
  "type": "error",
  "address": null,
  "reply_address": null,
  "data": {
    "description": "запрашиваемые данные отсутствуют (попытка получить внутренний или отсутствующий документ)",
    "name": "AVQFR_NO_DATA",
    "op_data": null
  },
  "headers": null
}

Тип Version

{
   "version": String
}

Поле version отдается в формате SemVer.

Тип Sum

Данный тип представляет собой значение, с плавающей точкой, представленное в строковом виде.

В случае, если данное значение фигурирует во входных данных, оно обязано содержать 2 знака после запятой (иметь формат X.XX), даже если последние равны 0 (например: 12345.00)

На данный тип наложен ряд ограничений:

  1. Максимальное значение: 549755813887.99
  2. Минимальное значение: -549755813887.99

Данные ограничения продиктованы ограничениями протокола СККО.

Пример валидного значения Sum:

"12345.67"

Тип UID

Данный тип представляет собой строковое значение в HEX формате Уникального Идентификатора (УИ) кассового документа

Пример значения:

"8914D11E9BA4471D0A327BFB"

Тип DateTime

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

Примеры:

С миллисекундами:

"2021-09-13T10:17:35.123+03:00"

Без миллисекунд:

"2021-09-13T10:17:35+03:00"

Тип Currency

Возможные значения:

enum имеющий следующие поддерживаемые значения:

  • BYN

С версии 1.7.1

  • USD
  • RUB
  • EUR

Пример:

"BYN"

Тип TokenInformation

{
   serial: String,
   device_id: u32,
   organization: String,
   tax_number: u32,
   pin_code_length: u32,
   puk_code_length: u32,
   operator_code: u32,
   "trade_point_name": String?
}
  • serial - серийный номер СКО
  • device_id - Регистрационный номер ПК в СККО
  • organization - наименование компании, на которую зарегистрировано СКО
  • tax_number - УНП СХ
  • pin_code_length - длина PIN-кода требуемого для авторизации
  • puk_code_length - длина PUK-кода требуемого для авторизации
  • operator_code - код Оператора Программной Кассы в соответствии с реестром
  • trade_point_name - наименование торговой точки (отсутствует, если не было установлено)

Пример:

{
  "device_id": 131010703,
  "operator_code": 5,
  "organization": "ИП Моров А.М.",
  "pin_code_length": 5,
  "puk_code_length": 8,
  "serial": "AVQ11031010703",
  "tax_number": 191832203,
  "trade_point_name": "Тестовая торговая точка"
}

Тип CashIn

{
  "currency": Currency,
  "cash": Sum
}

Используемые типы:

Пример:

{
  "cash": "25.46",
  "currency": "BYN"
}

Тип OldestDocument

{
  "uid": UID,
  "date" DateTime
}

Используемые типы:

Пример:

{
  "uid": "A50B7A727894C03707CF108F",
  "date": "2021-09-13T10:17:35+03:00"
}

Тип Pin

{
  "pin": String
}
  • pin - строковое представление PIN-кода

Пример:

{
  "pin": "16522"
}

Тип ChangePin

{
  "pin": String,
  "puk": String
}

Описание полей

  • pin - строковое представление нового PIN-кода
  • puk - строковое представление PUK-кода

Пример:

{
  "pin": "16522",
  "puk": "17307748"
}

Тип MinMaxReceipts

{
  min: u32,
  max: u32
}

Описание полей

  • min - номер первого документа в смене
  • max - номер последнего документа в смене

Пример

{
  "min": 5981,
  "max": 5981
}

Тип Receipt

{
  "type": "deposit" | "withdraw" | "money_back" | "rollback" | "sale",
  "content": Deposit | Withdraw | MoneyBack | Rollback | Sale
}

Описание полей

  • type - в зависимости от типа чека могут быть следующие значения:
    • deposit - Внесение
    • withdraw - Изъятие
    • money_back - Возврат
    • rollback - Аннулирование
    • sale - Продажа
  • content - содержимое чека. В зависимости от type могут быть следующие значения:

Пример:

{
  "content": {
    "extra": null,
    "header": {
      "cashier": "Test",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2021-10-05T15:27:36.803362+03:00",
      "device_id": 131010703,
      "number": 5981,
      "serial_number": "AVQ11031010703",
      "shift_number": 241,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "deposit",
      "uid": "7E047C2ABFC24FA207CF108F"
    },
    "sum": "1.00"
  },
  "type": "deposit"
}

Тип ReceiptRequest

{
  shift_number: u16?,
  number: u32
}

Описание полей

  • shift_number - опциональное поле номера смены, если не указано используется текущий номер смены
  • number - номер фискального документа в указанной/текущей смене

Пример

{
   "shift_number": null, 
   "number": 5981
}

Тип EscPosReq

{
  "b64_content": String,
  "reply_size": usize?
}

Описание полей

  • b64_content - EscPos команды в формате base64
  • reply_size - размер ожидаемого ответа. Если ответ не требуется, размер - 0, если значение данного поля null, то значением по умолчанию является 0

Тип Report

{
  uid: UID?,
  cashier: String?,
  device_id: u32,
  tax_number: u32,
  company_name: String,
  open_date: DateTime,
  close_date: DateTime?,
  number: u16,
  first_sale_number: u32,
  last_sale_number: u32,
  sales_count: u16,
  counters: [ *ReportCounter ],
  extra: String?
}
  • uid - УИ. В случае, если это Z-отчет - обязательное поле
  • cashier - Имя кассира в Z-отчете - опциональное поле, в X-отчете всегда null
  • device_id - Регистрационный номер ПК в СККО
  • tax_number - УНП
  • company_name - Наименование организации
  • open_date - Дата открытия смены
  • close_date - Дата закрытия смены, присутствует только в Z-отчете
  • number - Номер смены
  • first_sale_number - Номер первого документа продажи в смене
  • last_sale_number - Номер последнего документа продажи в смене
  • sales_count - Кол-во продаж в смене
  • counters - Массив сменных счетчиков, содержит информацию по каждой валюте, по которой совершались операции в смене
  • extra - доп. данные

Используемые типы:

Пример:

{
  "cashier": null,
  "close_date": "2021-09-13T21:40:53+03:00",
  "company_name": "ИП Моров А.М.",
  "counters": [
    {
      "cancels_count": 0,
      "cancels_sum": "0.00",
      "corrections_count": 0,
      "corrections_sum": "0.00",
      "currency": "BYN",
      "deposits_count": 0,
      "deposits_sum": "0.00",
      "extended_counters": null,
      "income": "4161.40",
      "money_backs_count": 0,
      "money_backs_sum": "0.00",
      "rollbacks_count": 0,
      "rollbacks_sum": "0.00",
      "sales_cash_sum": "0.00",
      "sales_cashless_sum": "0.00",
      "sales_count": 0,
      "sales_sum": "0.00",
      "withdraws_count": 0,
      "withdraws_sum": "0.00"
    }
  ],
  "device_id": 131010703,
  "first_sale_number": 0,
  "last_sale_number": 0,
  "number": 157,
  "open_date": "2021-09-13T21:38:40+03:00",
  "sales_count": 0,
  "tax_number": 191832203,
  "uid": "F8ED11C24E1D641D07CF108F"
}

Тип ReportCounter

{
  currency: Currency,
  income: Sum,
  
  sales_count: u16,
  sales_sum: Sum,
  sales_cashless_sum: Sum,
  sales_cash_sum: Sum,

  money_backs_count: u16,
  money_backs_sum: Sum,

  deposits_count: u16,
  deposits_sum: Sum,

  withdraws_count: u16,
  withdraws_sum: Sum,

  cancels_count: u16,
  cancels_sum: Sum,

  rollbacks_count: u16,
  rollbacks_sum: Sum,

  corrections_count: u16,
  corrections_sum: Sum,

  extended_counters: ExtendedCounters?
}
  • currency - валюта счетчиков
  • income - накопленный оборот
  • sales_count - кол-во продаж в валюте
  • sales_sum - сумма продаж в валюте
  • sales_cashless_sum - сумма продаж безналичными способами в валюте. Включает в себя оплаты "другими способами" в соответствии с требованиями к Программным Кассам.
  • sales_cash_sum - сумма продаж наличными в валюте
  • money_backs_count - кол-во аннулирований в валюте
  • money_backs_sum - сумма возвратов в валюте
  • deposits_count - кол-во внесений в валюте
  • deposits_sum - сумма внесений в валюте
  • withdraws_count - кол-во изъятий в валюте
  • withdraws_sum - сумма изъятий в валюте
  • cancels_count - кол-во отмен в валюте
  • cancels_sum - сумма отмен в валюте
  • rollbacks_count - кол-во аннулирований в валюте
  • rollbacks_sum - сумма аннулирований в валюте
  • corrections_count - кол-во коррекций в валюте
  • corrections_sum - сумма коррекций в валюте
  • extended_counters - опциональное поле, которое может содержать дополнительную информацию

Используемые типы:

Пример:

{
	"cancels_count": 0,
	"cancels_sum": "0.00",
	"corrections_count": 0,
	"corrections_sum": "0.00",
	"currency": "BYN",
	"deposits_count": 0,
	"deposits_sum": "0.00",
	"extended_counters": null,
	"income": "4161.40",
	"money_backs_count": 0,
	"money_backs_sum": "0.00",
	"rollbacks_count": 0,
	"rollbacks_sum": "0.00",
	"sales_cash_sum": "0.00",
	"sales_cashless_sum": "0.00",
	"sales_count": 0,
	"sales_sum": "0.00",
	"withdraws_count": 0,
	"withdraws_sum": "0.00"
}

Тип ExtendedCounters

{
  sales_other_sum: Sum,

  money_backs_cash_sum: Sum,
  money_backs_cashless_sum: Sum,

  rollbacks_cashless_sum: Sum,
  rollbacks_cash_sum: Sum,
  rollbacks_other_sum: Sum,

  tax_rates_sums: [ *TaxRateSum ],

  cheques_with_discounts: u16,
  discounts_sum: Sum,
}

Описание полей

  • sales_other_sum - сумма продаж другими способами оплаты
  • money_backs_cash_sum - сумма возвратов наличными
  • money_backs_cashless_sum - сумма возвратов безналичными
  • rollbacks_cashless_sum - сумма аннулирований чеков, оплаченных безналичными способами оплаты
  • rollbacks_cash_sum - сумма аннулирований чеков, оплаченных наличными
  • rollbacks_other_sum - сумма аннулирований чеков, оплаченных другими способами оплаты
  • tax_rates_sums - массив сумм выделенного налога по каждой налоговой ставке, если использовались
  • cheques_with_discounts - кол-во чеков со скидками
  • discounts_sum - сумма скидок

Используемые типы

Пример:

{
  "sales_other_sum": "0.00",
  "money_backs_cash_sum": "1.23",
  "money_backs_cashless_sum": "1000.32",
  "rollbacks_cashless_sum": "0.00",
  "rollbacks_cash_sum": "0.00",
  "rollbacks_other_sum": "0.00",
  "tax_rates_sums": [],
  "cheques_with_discounts": 1,
  "discounts_sum": "3.33"
}

Тип TaxRateSum

{
  tax_rate: TaxRate
  sum: Sum
}
  • tax_rate - ставка НДС
  • sum - сумма по ставке НДС

Используемые типы:

Пример:

{
  "tax_rate": "tax0",
  "sum": "0.00"
}

Тип TaxRate

enum имеющий следующие поддерживаемые значения:

  • tax0
  • tax10
  • tax20
  • tax25

Пример:

"tax0"

Тип CloseShiftRequest

{
  "data" CloseShiftData,
  "comments": ReportComments?
}

Описание полей

  • data - доп. информация для закрытия смены
  • comments - описание комментариев Z-отчёта

Пример:

{
  "data": {
    "cashier": "Администратор"
  }
}

Тип CloseShiftData

{
  "cashier" String?
}

Описание полей

  • cashier - имя кассира, закрывающего смену. Длина имени кассира не должны превышать 16 символов.

Пример:

{
  "cashier": "Администратор"
}

Тип HeaderComments

{
  "top": BlockComments?,
  "doc": BlockComments?,
  "info": BlockComments?
}

Описание полей

  • top - Верхняя часть заголовка чека:
# before header_top                            #
                Test tradepoint                 
               Test company name                
                 УНП: 123456789                 
# after header_top                             #
  • doc - Блок описания документа:
# before header_doc                            #
             Документ аннулирования             
                     № 123                      
# after header_doc                             #
  • info - Блок информации о чеке:
# before header_info                           #
Рег.№ Кассы: 119002614 Зав.№ СКО: AVQ11031010703
Валюта: BYN    Док-т закрыт: 2021-09-17 19:41:23
Кассир:.....................................Test
# after header_info                            #

Используемые типы

Пример

{
  "top": {
    "before": "before header_top",
    "after": "after header_top"
  },
  "doc": {
    "before": "before header_doc",
    "after": "after header_doc"
  },
  "info": {
    "before": "before header_info",
    "after": "after header_info"
  }
}

Тип BlockComments

{
  "before": String?,
  "after": String?
}

Описание полей

  • before - комментарий до блока
  • after - комментарий после блока

Пример:

{
  "before": "before header",
  "after": "after header"
}

Тип SaleComments

{
  "header": HeaderComments?,
  "items_block": ItemsBlockComments?,
  "sub_totals": BlockComments?,
  "totals": BlockComments?,
  "payments": PaymentsComments?
}

Описание полей

  • header - Описание комментариев в блоках заголовка чека
                Test tradepoint                 
               Test company name                
                 УНП: 123456789                 
------------------------------------------------
             Документ аннулирования             
                     № 123                      
Рег.№ Кассы: 119002614 Зав.№ СКО: AVQ11031010703
Валюта: BYN    Док-т закрыт: 2021-09-17 19:26:51
Кассир:.....................................Test           
  • items_block - Описание комментариев в блоках товарных позиций
Товар                            К-во  Цена Итог
Какое-то наименование товарной   1.000 0    0   
поз                                 Скидка: 0.33
  • sub_totals - Описание комментариев в блоке под-итогов чека
Итого:......................................0.00
  • totals - Описание комментариев в блоке итогов чека
Итоговая скидка: 0             ИТОГО К ОПЛАТЕ: 0
  • payments - Описание комментариев в блоке способов оплат
Внесено:
 Наличными:................................12.34
 Безналичными:.............................12.35
 Др.способами:.................................0
Сдача:.........................................0

Пример

{
  "header": {
    "top": {
      "before": "before header_top",
      "after": "after header_top"
    },
    "doc": {
      "before": "before header_doc",
      "after": "after header_doc"
    },
    "info": {
      "before": "before header_info",
      "after": "after header_info"
    }
  },
  "items_block": {
    "header": {
      "before": "before items header",
      "after": "after items header"
    },
    "items": {
      "before": "before items block",
      "after": "after items block"
    }
  },
  "sub_totals": {
    "before": "before sub_totals block",
    "after": "after sub_totals block"
  },
  "totals": {
    "before": "before totals block",
    "after": "after totals block"
  },
  "payments": {
    "payments": {
      "before": "before payments block",
      "after": "after payments block"
    },
    "change": {
      "before": "before change block",
      "after": "after change block"
    }
  }
}

Тип ItemsBlockComments

{
  "header": BlockComments?,
  "items": BlockComments?
}

Описание полей:

  • header - Описание заголовка блока товарных позиций
# header.before                                #
Товар                            К-во  Цена Итог
# header.after                                 #
  • items Описание блока товарных товарных позиций
Товар                            К-во  Цена Итог
# header.after                                 #
# items.before                                 # <-- items.before
Какое-то наименование товарной   1.000 0    0   
поз                                 Скидка: 0.33
...
# items.after                                  # <-- items.after

Пример:

{
  "header": {
    "before": "before items header",
    "after": "after items header"
  },
  "items": {
    "before": "before items block",
    "after": "after items block"
  }
}

Тип PaymentsComments

{
  "payments": BlockComments?,
  "change": BlockComments?
}

Описание полей

# payments.before                              #
Внесено:
 Наличными:................................12.34
 Безналичными:.............................12.35
 Др.способами:.................................0
# payments.after                               #
# change.before                                #
Сдача:.........................................0
# change.after                                 #

Пример:

{
  "payments": {
    "before": "before payments block",
    "after": "after payments block"
  },
  "change": {
    "before": "before change block",
    "after": "after change block"
  }
}

Тип DWComments

Расшифровывается как Deposit/Withdraw Comments

{
  "header": HeaderComments?,
  "sum": BlockComments?
}

Описание полей

  • header - Описание комментариев в блоках заголовка чека
  • sum - Описание комментариев в блоке суммы Внесения/Изъятия:
------------------------------------------------
# sum.before                                   # <-- sum.before
Изьято:..................................1234.23
# sum.after                                    # <-- sum.after
------------------------------------------------

Используемые типы

Тип RollbackComments

{
  "header": HeaderComments?,
  "body": BlockComments?,
  "body_header": BlockComments?,
  "number": BlockComments?,
  "totals": BlockComments?,
  "sum": BlockComments?,
  "cash": BlockComments?,
  "cashless": BlockComments?,
  "other": BlockComments?
}

Описание полей

  • header - Описание комментариев в блоках заголовка чека
  • body - Описание комментариев в блоке тела чека
# before body                                  # <-- body.before
        Аннулируемый платежный документ         
Номер документа: 123
Сумма аннул-ия:................................0
Наличными:.....................................0
Безналичными:..................................0
Др. способами:.................................0
# after body                                   # <-- body.after
  • body_header - Описание комментариев в блоке заголовка тела чека
#                                              # <-- body_header.before
        Аннулируемый платежный документ         
#                                              # <-- body_header.after
  • number - Описание комментариев в блоке номера аннулированного чека
# before number                                # <-- number.before
Номер документа: 123
# after number                                 # <-- number.after
  • totals - Описание комментариев в блоке итогов по аннулируемому чеку
# before totals                                # <-- totals.before
Сумма аннул-ия:................................0
Наличными:.....................................0
Безналичными:..................................0
Др. способами:.................................0
# after totals                                 # <-- totals.after
  • sum - Описание комментариев в блоке суммы аннулирования
# before sum                                   # <-- sum.before
Сумма аннул-ия:................................0
# after sum                                    # <-- sum.after
  • cash - Описание комментариев в блоке суммы наличными
# before cash                                  # <-- cash.before
Наличными:.....................................0
# after cash                                   # <-- cash.after
  • cashless - Описание комментариев в блоке суммы безналичными
# before cashless                              # <-- cashless.before
Безналичными:..................................0
# after cashless                               # <-- cashless.after
  • other - Описание комментариев в блоке суммы другими способами
# before other                                 # <-- other.before
Др. способами:.................................0
# after other                                  # <-- other.after

Тип MoneyBackComments

{
  "header": HeaderComments?,
  "items": ItemsBlockComments?,
  "totals": BlockComments?,
  "payments": BlockComments?,
  "cash": BlockComments?,
  "cashless": BlockComments?
}

Описание полей

  • header - Описание комментариев в блоках заголовка чека
  • items_block - Описание комментариев в блоках товарных позиций
Товар                            К-во  Цена Итог
Какое-то наименование товарной   1.000 0    0   
поз                                 Скидка: 0.33
# totals.before                                # <-- totals.before
ИТОГО К ВОЗВРАТУ:..............................0
# totals.after                                 # <-- totals.after
  • payments - Описание комментариев в блоке "Метод возврата"
# payments.before                              # <-- payments.before
Метод возврата:
Наличными:.....................................0
Безналичными:..................................0
# payments.after                               # <-- payments.before
  • cash - Описание комментариев в блоке "Наличными"
# cash.before                                  # <-- cash.before
Наличными:.....................................0
# cash.after                                   # <-- cash.after
  • cashless - Описание комментариев в блоке "Безналичными"
# cashless.before                              # <-- cashless.before
Безналичными:..................................0
# cashless.after                               # <-- cashless.after

Тип BillComments

{
   "header": HeaderComments?,
   "items_block": ItemsBlockComments?,
   "sub_totals": BlockComments?,
   "totals": BlockComments?
}

Описание полей

  • header - описание комментариев в заголовке счёта
  • items_block - описание комментариев в блоке товарных позиций
  • sub_totals - описание комментариев в блоке под-итогов
  • totals - описание комментариев в блоке итогов чека

Используемые типы

Тип ReportComments

{
  "header": HeaderComments?,
  "byn": CountersComments?,
  "usd": CountersComments?,
  "eur": CountersComments?,
  "rub": CountersComments?,
}

Описание полей

  • header - Описание комментариев в блоках заголовка чека
  • byn - Описание комментариев по счетчикам валюты BYN
  • usd - Описание комментариев по счетчикам валюты USD
  • eur - Описание комментариев по счетчикам валюты EUR
  • rub - Описание комментариев по счетчикам валюты RUB

Тип CountersComments

{
  "sales": BlockComments?,
  "money_backs": BlockComments?,
  "deposits": BlockComments?,
  "withdraws": BlockComments?,
  "rollbacks": BlockComments?,
  "cancels": BlockComments?,
  "corrections": BlockComments?
}

Описание полей

  • sales - Описание комментариев счетчиков продаж
  • money_backs - Описание комментариев счетчиков возвратов
  • deposits - Описание комментариев счетчиков внесений
  • withdraws - Описание комментариев счетчиков изьятий
  • rollbacks - Описание комментариев счетчиков аннулирований
  • cancels - Описание комментариев счетчиков отмен
  • corrections - Описание комментариев счетчиков коррекций

Тип ZReportCopyRequest

{
   "number": u16,
   "comments": ReportComments?
}

Описание полей

Используемые типы

Тип Order

{
   "header": TokenChequeHeader,
   "number": u32,
   "items": [ *Item ],
   "cheque_discount": Sum,
   "table": u16,
   "place": u16,
   "extra": String?
}

Описание полей

  • header - заголовок чека.
  • number - номер заказа
  • items - массив товарных позиций
  • cheque_discount - скидка по чеку
  • table - номер столика
  • place - номер места за столиком
  • extra - доп. информация переданная в запросе

Используемые типы

Пример

{
  "number": 111,
  "header": {
    "cashier": "Test",
    "currency": "BYN"
  },
  "items": [
    {
      "price": "1.00",
      "quantity": "1.000",
      "code": {
        "type": 0,
        "value": 9999999999
      },
      "name": "блюдо 1",
      "discount": "-1.02"
    }
  ],
  "cheque_discount": "1.22",
  "table": 1,
  "place": 1
}

Тип OrderRequest

{
   "order_id": String,
   "order": Order
}

Описание полей

  • order_id - идентификатор заказа
  • order - содержимое заказа

Используемые типы

Пример

{
  "order_id": "123",
  "order": {
    "number": 111,
    "header": {
      "cashier": "Test",
      "currency": "BYN"
    },
    "items": [
      {
        "price": "1.00",
        "quantity": "1.000",
        "code": {
          "type": 0,
          "value": 9999999999
        },
        "name": "блюдо",
        "discount": "-1.02"
      }
    ],
    "cheque_discount": "1.22",
    "table": 1,
    "place": 1
  }
}

Тип PayOrderRequest

{
   "order_id": String,
   "payments": [ *Payment ],
   "comments": SaleComments?
}

Описание полей

  • order_id - идентификатор заказа
  • payments - массив способов оплаты
  • comments - описание полей комментариев платежного документа

Используемые типы

Пример

{
  "order_id": "123",
  "payments": [
    {
      "payment_type": "cash",
      "value": "0.80"
    }
  ]
}

Тип PrintBillRequest

{
   "order_id": String,
   "comments": BillComments?
}

Описание полей

Используемые типы

Пример

{
   "order_id": "123"
}

Тип TokenChequeHeader

{
  "cashier": String,
  "currency": Currency?
}

Описание полей

  • cashier - имя кассира. Не может превышать 16 символов длинной, не может быть пустым. Пробелы в начале и конце строки удаляются и таким образом гарантируется, что не будет передано пустое имя кассира
  • currency - Валюта совершаемой операции, если не передано - byn

Используемые типы

Тип StorageItem

{
  "id": String,
  "price": Sum,
  "code": ItemCode,
  "name": String,
  "tax_rate": TaxRate?
}

Описание полей

  • id - идентификатор товара
  • price - цена за единицу тов. позиции
  • code - код тов. позиции
  • name - наименование тов. позиции
  • tax_rate - НДС тов. позиции

Используемые типы

Тип Item

{
  "id": String?,
  "price": Sum,
  "quantity": Quantity,
  "discount": Sum?,
  "code": ItemCode,
  "name": String,
  "tax_rate": TaxRate?,
  "comment": String?
}

Описание полей

  • id - клиентский идентификатор товарной позиции, на текущий момент не используется сервисом
  • price - Цена товарной позиции за 1 единицу
  • quantity - Кол-во товарной позиции
  • discount - Скидка товарной позиции. В случае, если скидка не должна быть применена, должно быть передано значение null
  • code - Описание Кода товарной позиции
  • name - Наименование товарной позиции. Не может быть пустым. Пробелы в начале и конце строки удаляются для избежания отсутствия наименования товарной позиции. Максимальная длина: 128 символов
  • tax_rate - НДС. Важно помнить, что НДС0 и отсутствие НДС - разные вещи.
  • comment - Комментарий к товарной позиции. Отображается после всех распечатывания всех данных по товарной позиции

Используемые типы

Тип ItemEx

{
  "id": String,
  "quantity": Quantity,
  "discount": Sum?,
  "comment": String?
}

Описание полей

  • id - идентификатор товара
  • quantity - кол-во товара
  • discount - скидка по позиции
  • comment - комментарий к тов. позиции

Используемые типы

Тип CalculatedItem

Товарная позиция с рассчитанными значениями

{
  "item": Item,
  "values": ItemCalculatedValues
}

Описание полей

Используемые типы

Тип ItemCode

{
  "type": u8,
  "value": u64
}

Описание полей

  • type - тип кода товарной позиции.
    • Ограничения:
      • Значения от 0-9
    • Поддерживаемые значения:
      • 0 - plain-код (не имеет классификации)
      • 1 - GTIN/EAN
      • 3 - Услуга
      • 4 - Аванс
  • value - непосредственно сам код товарной позиции
    • Ограничения:
      • Не может быть длиннее 13 знаков
      • Если был передан тип кода GTIN/EAN осуществляется проверка контрольного знака (check-digit) в соответствии со стандартом GTIN/EAN

Тип Payment

{
  "payment_type": PaymentType,
  "name": String?,
  "value": Sum,
  "ref": String?
}

Описание полей

  • payment_type - Тип платежа
  • name - Наименование платежа. Может отсутствовать
  • value - Сумма платежа
  • ref - Идентификатор платежного средства. Является опциональным полем и может быть использовано для идентификации RRN банковской транзакции, информации о банковском платеже, либо номере сертификата

Используемые типы

Тип PaymentType

enum имеющий следующие поддерживаемые значения:

  • cash
  • cashless
  • other

Пример:

"cashless"

Тип Quantity

Данный тип представляет собой значение, с плавающей точкой, представленное в строковом виде.

В случае, если данное значение фигурирует во входных данных, оно обязано содержать 3 знака после запятой (иметь формат X.XXX), даже если последние равны 0 (например: 12345.000)

На данный тип наложен ряд ограничений:

  1. Максимальное значение: 16777.215
  2. Минимальное значение: 0

Данные ограничения продиктованы ограничениями протокола СККО.

Пример валидного значения Quantity:

"12345.607"

Тип ChequeType

Возможные значения:

enum имеющий следующие поддерживаемые значения:

  • deposit
  • withdraw
  • rollback
  • money_back
  • sale
  • z_report

Пример:

"deposit"

Тип ChequeHeader

{
  "type_id": ChequeType,
  "uid": UID,
  "device_id": u32,
  "serial_number": String,
  "cashier": String,
  "number": u32,
  "date_time": DateTime,
  "currency": Currency,
  "company_name": String,
  "tax_number": u32,
  "trade_point_name": String?,
  "shift_number": u16
}

Описание полей

  • type_id - тип чека
  • uid - УИ чека
  • device_id - Рег. номер ПК в СККО, в которой зарегистрирована операция
  • serial_number - Серийный номер СКО в котором зарегистрирована операция
  • cashier - кассир, который провел операцию
  • number - номер чека
  • date_time - дата и время фискализации чека
  • currency - валюта операции
  • company_name - название компании, которая провела операцию
  • tax_number - УНП компании, которая провела операцию
  • trade_point_name - наименование торговой точки, на которой проведена операция
  • shift_number - номер смены, в которой проведена операция

Используемые типы

Тип ItemCalculatedValues

{
  "sum": Sum,
  "raw_sum: Sum,
  "tax": Sum,
  "discount": Sum
}

Описание полей

  • sum - рассчитанная сумма товарной позиции. Расчет происходит по формуле item.quantity * item.price - item.discount
  • raw_sum - рассчитанная сумма товарной позиции без учетка скидки
  • tax - сумма по налоговой ставке примененной к тов. позиции
  • discount - скидка по товарной позиции

Используемые типы

Тип State

{
  "last_uid": UID,
  "shift_state": ShiftState?
}

Описание полей

  • last_uid - УИ последнего документа
  • shift_state - информация о смене. Отсутствует в случае, если смена закрыта

Используемые типы

Тип Status

Возможные значения:

enum имеющий следующие поддерживаемые значения:

  • unknown
  • active
  • blocked

Пример:

"active"

Тип ShiftState

{
  "next_cheque_number": u32,
  "shift_number": u16,
  "shift_open_date": DateTime,
  "cash_in": Map<Currency, Sum>
}

Описание полей

  • next_cheque_number - номер следующего документа
  • shift_number - номер текущей смены
  • shift_open_date - Дата-время открытия смены
  • cash_in - Информация о наличных в смене. Представляет собой объект, где ключом является наименование валюты и значением значение наличных в кассе

Тип CancelRequest

Запрос на регистрацию отмены платежного док-та

{
   "currency": Currency,
   "sum": Sum,
   "corrections_sum": Sum,
   "corrections_count": u16
}

Описание полей

Используемые типы

Тип Deposit

{
  "header": ChequeHeader,
  "sum": Sum,
  "extra": Option<String>,
}

Описание полей

  • header - Заголовок чека
  • sum - сумма внесения
  • extra - доп. информация переданная в запросе

Используемые типы

Тип Withdraw

{
  "header": ChequeHeader,
  "sum": Sum,
  "extra": Option<String>,
}

Описание полей

  • header - Заголовок чека
  • sum - сумма изъятия
  • extra - доп. информация переданная в запросе

Используемые типы

Тип NewSumChequeRequest

{
  "sum_cheque_data": SumChequeData,
  "comments": DWComments?
}

Описание полей

Используемые типы

Тип SumChequeData

{
  "header": TokenChequeHeader,
  "sum": Sum,
  "extra": String?
}

Описание полей

  • header - описание заголовка чека
  • sum - сумма операции
  • extra - дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной

Используемые типы

Тип SaleRequest

{
  "sale": NewSale,
  "comments": SaleComments?
}

Описание полей

  • sale - описание продажи
  • comments - описание блоков комментариев чека продажи
  • DEPRECATED link - флаг, включающий добавление поля link в ответе на фискализацию. link содержит в себе URL адрес чека. По умолчанию - false

Используемые типы

Комментарии

Тип ExSaleRequest

{
  "sale": NewSaleEx,
  "comments": SaleComments?
}

Описание полей

  • sale - описание продажи (на основании товаров из внутренней БД товаров)
  • comments - описание блоков комментариев чека продажи

Используемые типы

Тип NewSale

{
  "header": TokenChequeHeader?,
  "items": [ *Item ],
  "payments": [ *Payment ],
  "cheque_discount": Sum,
  "extra": String?
}

Описание полей

  • header - описание заголовка чека
  • items - массив товарных позиций
  • payments - массив способов оплат
  • cheque_discount - скидка по чеку
  • extra - дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной

Используемые типы

Тип SaleRequestEx

{
  "header": TokenChequeHeader?,
  "items": [ *ItemEx ],
  "payments": [ *Payment ],
  "cheque_discount": Sum,
  "extra": String?
}

Описание полей

  • header - описание заголовка чека
  • items - массив товарных позиций из внутреннего хранилища
  • payments - массив способов оплат
  • cheque_discount - скидка по чеку
  • extra - дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной

Используемые типы

Тип Sale

Сформированный чек продажи

{
  "header": ChequeHeader,
  "items": [ *CalculatedItem ],
  "payments": [ *Payment ],
  "rolled_back_by": u32?,
  "change": Sum,
  "sub_totals": SaleSubTotals,
  "totals": SaleTotals,
  "extra": String?
}

Описание полей

Тип SaleSubTotals

{
  "sum": Sum,
  "cheque_discount": Sum,
  "taxes": [ *TaxRateSum ]
}

Описание полей

  • sum - сумма под-итога (сумма всех товарных позиций с учетом скидок по тов. позициям)
  • cheque_discount - скидка по чеку
  • taxes - массив сумм в разрезе используемых в чеке НДС

Используемые типы

Тип SaleTotals

{
  "sum": Sum,
  "discount": Sum
}

Описание полей

  • sum - сумма к оплате
  • discount - итоговая сумма скидки по чеку

Используемые типы

Тип NewMoneyBack

{
  "header": TokenChequeHeader,
  "item": Item,
  "payments": [ *Payment ],
  "extra": String?,
}

Описание полей

  • header - заголовок чека
  • item - товарная позиция к возврату
  • payments - Массив способов возврата. В случае возврата тип other игнорируется.
  • extra - дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной

Используемые типы

Тип NewMoneyBackEx

{
  "header": TokenChequeHeader,
  "item": ItemEx,
  "payments": [ *Payment ],
  "extra": String?,
}

Описание полей

Используемые типы

Тип NewMoneyBackRequest

{
  "money_back": NewMoneyBack,
  "comments": MoneyBackComments?
}

Описание полей

Используемые типы

Тип ExNewMoneyBackRequest

{
  "money_back": NewMoneyBackEx,
  "comments": MoneyBackComments?
}

Описание полей

  • money_back - информация для совершения операции возврата на основании товаров из хранилища товаров
  • comments - комментарии чека возврата

Используемые типы

Тип MoneyBackTotals

{
  "sum": Sum,
  "cash": Sum,
  "cashless": Sum
}

Описание полей

  • sum - сумма (cash + cashless) возврата
  • cash - сумма возврата наличными
  • cashless - сумма возврата безналичными

Используемые типы

Тип MoneyBack

{
  "header": ChequeHeader,
  "item": CalculatedItem,
  "payments": [ *Payment ],
  "totals": MoneyBackTotals,
  "extra": String?,
}

Описание полей

Используемые типы:

Тип NewRollback

{
  "header": TokenChequeHeader,
  "target_num": u32,
  "extra": String?
}

Описание полей

  • header - заголовок чека. Для данного запроса поле currency игнорируется.
  • target_num - номер аннулируемого чека продажи
  • extra - дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной

Используемые типы

Тип NewRollbackRequest

{
  "rollback": NewRollback,
  "comments": RollbackComments?
}

Описание полей

Используемые типы

Тип RollbackTotals

{
  "sum": Sum,
  "cash": Sum,
  "cashless": Sum,
  "other": Sum
}

Описание полей

  • sum - итоговая сумма (cash + cashless + other) аннулирования
  • cash - сумма аннулирования наличными
  • cashless - сумма аннулирования безналичными
  • other - сумма аннулирования др. способами оплаты

Используемые типы

Тип Rollback

{
  "header": ChequeHeader,
  "target_num": u32,
  "totals": RollbackTotals,
  "extra": String?
}

Описание полей

  • header - заголовок чека
  • target_num - номер аннулируемого чека
  • totals - итоги аннулирования
  • extra - доп. информация переданная в запросе

Используемые типы

Изменение от 2022-08-31

Пример ответа со всеми переданными заголовками repr.*:

{
  "type": "send",
  "data": {
    "header": {
      "cashier": "Test",
      "company_name": "ИП Моров А.М.",
      "currency": "BYN",
      "date_time": "2022-08-31T09:56:22.794436+03:00",
      "device_id": 131010705,
      "number": 10398,
      "serial_number": "AVQ11031010705",
      "shift_number": 878,
      "tax_number": 191832203,
      "trade_point_name": null,
      "type_id": "deposit",
      "uid": "1A5663901D4B4CE607CF1091"
    },
    "sum": "15.00",
    "repr": {
      "link": "https://receipts.test.imlab.by/?documentId=1A5663901D4B4CE607CF1091",
      "esc_pos": "G3QRICAgICAgICAgICAgICAgICCIjyCMruCuoiCALowuICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgk42POiAxOTE4MzIyMDMgICAgICAgICAgICAgICAgIAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KG0UBICAgICAgICCNhSCfgoufhZKRnyCPi4CShYaNm4wghI6Kk4yFjZKOjCAgICAgICAgG0UACi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIISuquOspa3iIOClo6jh4uCg5qioIK6vpeCg5qioIKKtpeGlrajvICAgICAKICAgICAgICAgICAgICAgICAgICD8IDEwMzk4ICAgICAgICAgICAgICAgICAgICAgChtFAZCloy78IIqg4eHrOiAbRQAxMzEwMTA3MDUgG0UBh6CiLvwgkYqOOiAbRQBBVlExMTAzMTAxMDcwNQobRQGCoKvu4qA6IBtFAEJZTiAgICAbRQGErqot4iCnoKrg6+I6IBtFADMxLjA4LjIwMjIgMDk6NTY6MjIKG0UBiqDh4ajgOhtFAC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi5UZXN0Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQobRQGCraXhpa2uOhtFAC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uMTUuMDAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICCTiDogMUE1NjYzOTAxRDRCNENFNjA3Q0YxMDkxICAgICAgICAgIAobYTEdKGsDADFDAx0oawMAMUUxHShrGwAxUDAxQTU2NjM5MDFENEI0Q0U2MDdDRjEwOTEdKGsDADFRMAoKCgoKCh1WAQ==",
      "html": "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ИП&nbsp;Моров&nbsp;А.М.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;УНП:&nbsp;191832203&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>------------------------------------------------<br/><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;НЕ&nbsp;ЯВЛЯЕТСЯ&nbsp;ПЛАТЕЖНЫМ&nbsp;ДОКУМЕНТОМ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b><br/>------------------------------------------------<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Документ&nbsp;регистрации&nbsp;операции&nbsp;внесения&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;№&nbsp;10398&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><b>Рег.№&nbsp;Кассы:&nbsp;</b>131010705&nbsp;<b>Зав.№&nbsp;СКО:&nbsp;</b>AVQ11031010705<br/><b>Валюта:&nbsp;</b>BYN&nbsp;&nbsp;&nbsp;&nbsp;<b>Док-т&nbsp;закрыт:&nbsp;</b>31.08.2022&nbsp;09:56:22<br/><b>Кассир:</b>.....................................Test<br/>------------------------------------------------<br/><b>Внесено:</b>...................................15.00<br/>------------------------------------------------<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;УИ:&nbsp;1A5663901D4B4CE607CF1091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>",
      "text": "                 ИП Моров А.М.                  \n                 УНП: 191832203                 \n------------------------------------------------\n        НЕ ЯВЛЯЕТСЯ ПЛАТЕЖНЫМ ДОКУМЕНТОМ        \n------------------------------------------------\n     Документ регистрации операции внесения     \n                    № 10398                     \nРег.№ Кассы: 131010705 Зав.№ СКО: AVQ11031010705\nВалюта: BYN    Док-т закрыт: 31.08.2022 09:56:22\nКассир:.....................................Test\n------------------------------------------------\nВнесено:...................................15.00\n------------------------------------------------\n          УИ: 1A5663901D4B4CE607CF1091          \n\n"
    }
  }
}

Изменения от 2022-04-18

  • Добавлено описание заголовка dreceipt.emails в разделе Заголовки
  • Добавлено описание заголовка printer.style в разделе Заголовки
  • Добавлено описание заголовка printer.prefix в разделе Заголовки
  • Добавлено поле cash_in в типе ShiftState
  • Исправлено описание поведения в методе получения наличных СКО
  • Добавлено описание поля link в SaleRequest
  • Добавление описание заголовка printer.escpos.required в разделе Заголовки

Изменения от 2022-02-09

Документация:

Изменения от 2022-02-02:

Документация: