Введение
Данный документ является Руководством Программиста, а так же Руководством Пользователя по использованию Программной Кассы.
В данной документации описан протокол, типы и ошибки, которые могут возникать при использовании протокола 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. Указание кол-ва символов в ширину на бумаге, на которой будет происходить печать. По умолчанию:48printer.code.policy- правило печати кодов товарных позиций. По умолчанию:only_gtinno_plain- все, кроме типа кода без GTIN/EAN (тип кода - 0)only_gtin- только GTIN/EAN (тип кода - 1)all- печатать коды товарных позиций всех типов
printer.cp866- указание номера таблицы символов в принтере соответствующий кодировкеCP866. По умолчанию -17printer.feed- указание кол-во строк прокрутки бумаги после печати. По умолчанию:5printer.cut- принудительное отрезание бумаги после завершения печати. По умолчанию:trueprinter.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.* заголовков в следующей приоритетности:
USBDummy
Если заголовки первого принтера не были найдены - будет попытка найти следующий принтер.
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окружение iKassa910000001-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:1828TSRV_REST_MODE- переменная окружения для переключения режима работы Программной Кассы в режимобслуживания за столиками. Должно иметь значениеtrueилиfalse. Значение по умолчаниюfalseOPERATOR_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, это поддерживается
Общее описание принципов взаимодействия
Пример взаимодействия с СКО
- Инициализация сессии
- Если сессия была проинициализирована ранее данный этап можно пропустить, используя ранее полученный (и, вероятно, сохраненный) идентификатор сессии
- Получение СКО с передачей заголовка
tokens.refreshсо значениемtrue, как описано в разделе Работа с СКО - Авторизация
- Получение состояния СКО с целью проверки, открыта ли смена
- Если смена закрыта - Открытие смены
- Внесение
- Продажа
- Аннулирование
- Возврат
- Изъятие
- Закрытие смены
- Завершение сессии
Обработка ошибок
Ошибки разделяются на подтипы, на основании используемых префиксов:
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_PARTvalueявляется положительным числом, иначе ошибкаTIN_NEGATIVE_SUMvalueне превышает максимального значения
Проверка скидки тов. позиции
Список проверок
discountимеет не более2знаков после запятой, иначе ошибкаTSRV_INVALID_SUM_DEC_PARTdiscountнаходится в интервале от-549755813887.99до549755813887.99включительно
Проверка наименования тов. позиции
Важно: перед началом проверки удаляются пробелы в начале и конце строки.
Осуществляемые проверки
- Длина
nameне равна 0, иначе ошибкаTIN_EMPTY_NAME - Длина
nameне превышает 128 символов, иначе ошибкаTIN_NAME_LEN
Проверка способов оплат и сдачи
Осуществляемые проверки
cash + cashless + otherбольше, либо равно суммеК оплатепо чеку, иначе ошибкаTIN_NOT_ENOUGH_MONEYcashless + otherменьше, либо равно суммеК оплатепо чеку, иначе ошибкаTIN_CASHLESS_OVERFLOWcashless + 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
- Пример 1. было:
Все поля, требующие округления, описаны в соответствующих запросах, либо описании полей.
Сервисы
Сервисы представляют собой наборы функций, агрегированные по назначению.
Название каждого сервиса (например - 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
Важно: должны быть соблюдены следующие условия:
- В СКО должна быть произведения авторизация по 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 - номер следующего чека
Важно: должны быть соблюдены следующие условия:
- В СКО должна быть произведения авторизация по PIN-коду, иначе будет
отдана ошибка
AVQFR_SESSION_NOT_AUTHORIZED - Смена в СКО должна быть открыта, иначе будет отдана
ошибка
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 - количество неотправленных документов на сервер.
Важно: должно быть соблюдено следующее условие:
- В СКО должна быть произведения авторизация по 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
Важно: должны быть соблюдены следующие условия:
- В СКО должна быть произведения авторизация по 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-кода неверна
Данный метод совершает следующие операции:
- Попытка совершить
logout - Авторизация по PUK-коду
- Смена PIN-кода
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 часов.
Важно: в случае, если имеются неотправленные документы на сервер требуется:
- Проверить соединение с интернетом.
- Сессия в СКО должна быть авторизована для отправки документов.
- Проверить, что сервера Оператора Программной Кассы доступны из текущей сети.
- В случае, если предыдущие пункты выполнены, обратиться к представителям Оператора Программной Кассы, предоставив серийный номер СКО, а так же лог-файл.
Примеры
Успех
Запрос:
{
"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 сохраняется, для дальнейшего возможного совершения операции аннулирования.
Осуществляемые действия перед операцией продажи
- Проверка заголовка чека
- Проверка кол-ва товарных позиций в поле
items- Кол-во тов. позиций не равно
0, иначе ошибкаTIN_NO_ITEMS - Кол-во тов. позиций не превышает
140, иначе ошибкаTIN_MAX_ITEMS
- Кол-во тов. позиций не равно
- Проверка скидки по чеку - Проверка суммы
- Проверка товарных позиций
- Проверка наименования тов. позиции
- Проверка цены (
item.price) - Проверка суммы - Расчёт значений по полям товарной позиции
(формирование ItemCalculatedValues)
raw_sum = (item.price * item.quantity), значение округляетсяdiscount = item.discount ?: 0(скидка/надбавка, если указана, иначе0)sum = raw_sum - discounttax = (sum * tax_rate_sum.sum) / (100 + tax_rate_sum.sum), значение округляется- Проверка значений
sumиraw_sum- Проверка суммы - Проверка значения
discount- Проверка скидки тов. позиции
- Проверка суммы всех тов. позиций с учетом скидок по тов. позициям и скидки по чеку
- Проверка суммы всех наличных способов оплаты
- Проверка суммы всех безналичных способов оплаты
- Проверка суммы всех др. способов оплаты
- Вычисление сдачи:
change = cash + cashless + other - cheque_sum, гдеcheque_sum- сумма скидок всех товарных позиций с учетом скидок и с учетом скидки по чеку. - Проверка способов оплат и сдачи
Важно: если скидка на товарную позицию имеет отрицательное значение, скидка считается надбавкой
Примеры
Успех
Запрос:
{
"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 - замененный заказ (тот, что имел тот же идентификатор и был заменен заказом в запросе).
Важно: для вызова данного метода требуется пройденная авторизация в СКО.
Важно: для вызова данного метода требуется открытая смена в СКО.
Осуществляемые действия перед сохранением заказа
- Проверка заголовка чека
- Проверка кол-ва товарных позиций в поле
items- Кол-во тов. позиций не равно
0, иначе ошибкаTIN_NO_ITEMS - Кол-во тов. позиций не превышает
140, иначе ошибкаTIN_MAX_ITEMS
- Кол-во тов. позиций не равно
- Проверка скидки по чеку - Проверка суммы
- Проверка товарных позиций
- Проверка наименования тов. позиции
- Проверка цены (
item.price) - Проверка суммы - Расчёт значений по полям товарной позиции
(формирование ItemCalculatedValues)
raw_sum = (item.price * item.quantity), значение округляетсяdiscount = item.discount ?: 0(скидка/надбавка, если указана, иначе0)sum = raw_sum - discount- Проверка значений
sumиraw_sum- Проверка суммы - Проверка значения
discount- Проверка скидки тов. позиции
- Проверка суммы всех тов. позиций с учетом скидок по тов. позициям и скидки по чеку
Примеры
Запрос:
{
"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)
На данный тип наложен ряд ограничений:
- Максимальное значение:
549755813887.99 - Минимальное значение:
-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
USDRUBEUR
Пример:
"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команды в формате base64reply_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-отчете всегдаnulldevice_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 имеющий следующие поддерживаемые значения:
tax0tax10tax20tax25
Пример:
"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- Описание комментариев блока оплат:
# payments.before #
Внесено:
Наличными:................................12.34
Безналичными:.............................12.35
Др.способами:.................................0
# payments.after #
change- Описание комментариев блока сдачи:
# 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Описание комментариев блокаИтого
# 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- Описание комментариев по счетчикам валюты BYNusd- Описание комментариев по счетчикам валюты USDeur- Описание комментариев по счетчикам валюты EURrub- Описание комментариев по счетчикам валюты 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?
}
Описание полей
number- номер сменыcomments- комментарии Z-отчёта
Используемые типы
Тип 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- идентификатор заказаcomments- описание комментариев счета
Используемые типы
Пример
{
"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- Скидка товарной позиции. В случае, если скидка не должна быть применена, должно быть передано значение nullcode- Описание Кода товарной позицииname- Наименование товарной позиции. Не может быть пустым. Пробелы в начале и конце строки удаляются для избежания отсутствия наименования товарной позиции. Максимальная длина: 128 символовtax_rate- НДС. Важно помнить, что НДС0 и отсутствие НДС - разные вещи.comment- Комментарий к товарной позиции. Отображается после всех распечатывания всех данных по товарной позиции
Используемые типы
Тип ItemEx
{
"id": String,
"quantity": Quantity,
"discount": Sum?,
"comment": String?
}
Описание полей
id- идентификатор товараquantity- кол-во товараdiscount- скидка по позицииcomment- комментарий к тов. позиции
Используемые типы
Тип CalculatedItem
Товарная позиция с рассчитанными значениями
{
"item": Item,
"values": ItemCalculatedValues
}
Описание полей
item- товарная позицияvalues- рассчитанные значения товарной позиции
Используемые типы
Тип ItemCode
{
"type": u8,
"value": u64
}
Описание полей
type- тип кода товарной позиции.- Ограничения:
- Значения от
0-9
- Значения от
- Поддерживаемые значения:
- 0 -
plain-код(не имеет классификации) - 1 -
GTIN/EAN - 3 -
Услуга - 4 -
Аванс
- 0 -
- Ограничения:
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 имеющий следующие поддерживаемые значения:
cashcashlessother
Пример:
"cashless"
Тип Quantity
Данный тип представляет собой значение, с плавающей точкой, представленное в строковом виде.
В случае, если данное значение фигурирует во входных данных, оно обязано
содержать 3 знака после запятой (иметь формат X.XXX), даже если последние
равны 0 (например: 12345.000)
На данный тип наложен ряд ограничений:
- Максимальное значение:
16777.215 - Минимальное значение:
0
Данные ограничения продиктованы ограничениями протокола СККО.
Пример валидного значения Quantity:
"12345.607"
Тип ChequeType
Возможные значения:
enum имеющий следующие поддерживаемые значения:
depositwithdrawrollbackmoney_backsalez_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.discountraw_sum- рассчитанная сумма товарной позиции без учетка скидкиtax- сумма по налоговой ставке примененной к тов. позицииdiscount- скидка по товарной позиции
Используемые типы
Тип State
{
"last_uid": UID,
"shift_state": ShiftState?
}
Описание полей
last_uid- УИ последнего документаshift_state- информация о смене. Отсутствует в случае, если смена закрыта
Используемые типы
Тип Status
Возможные значения:
enum имеющий следующие поддерживаемые значения:
unknownactiveblocked
Пример:
"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
}
Описание полей
currency- валютаsum- сумма отменыcorrections_sum- сумма коррекций отмененного платежного док-таcorrections_count- кол-во коррекций в отмененном платежном док-те
Используемые типы
Тип 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?
}
Описание полей
sum_cheque_data- Информация по чекуcomments- Комментарии чека
Используемые типы
Тип SumChequeData
{
"header": TokenChequeHeader,
"sum": Sum,
"extra": String?
}
Описание полей
header- описание заголовка чекаsum- сумма операцииextra- дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной
Используемые типы
Тип SaleRequest
{
"sale": NewSale,
"comments": SaleComments?
}
Описание полей
sale- описание продажиcomments- описание блоков комментариев чека продажи- DEPRECATED
link- флаг, включающий добавление поляlinkв ответе на фискализацию.linkсодержит в себе URL адрес чека. По умолчанию - false
Используемые типы
Комментарии
- Поле
linkустарело. См. раздел Заголовки
Тип 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?
}
Описание полей
header- Заголовок чекаitems- массив рассчитанных товарных позиций чекаpayments- массив оплат чекаrolled_back_by- номер чека аннулирования, если данный документ был аннулированchange- рассчитанная сдача по чекуsub_totals- Под-итогtotals- Итогextra- доп. информация переданная в запросе на создание продажи
Тип SaleSubTotals
{
"sum": Sum,
"cheque_discount": Sum,
"taxes": [ *TaxRateSum ]
}
Описание полей
sum- сумма под-итога (сумма всех товарных позиций с учетом скидок по тов. позициям)cheque_discount- скидка по чекуtaxes- массив сумм в разрезе используемых в чеке НДС
Используемые типы
Тип SaleTotals
{
"sum": Sum,
"discount": Sum
}
Описание полей
Используемые типы
Тип NewMoneyBack
{
"header": TokenChequeHeader,
"item": Item,
"payments": [ *Payment ],
"extra": String?,
}
Описание полей
header- заголовок чекаitem- товарная позиция к возвратуpayments- Массив способов возврата. В случае возврата типotherигнорируется.extra- дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной
Используемые типы
Тип NewMoneyBackEx
{
"header": TokenChequeHeader,
"item": ItemEx,
"payments": [ *Payment ],
"extra": String?,
}
Описание полей
header- заголовок чекаitem- товарная позиция из хранилища товаров к возвратуpayments- Массив способов возврата. В случае возврата типotherигнорируется.extra- дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной
Используемые типы
Тип NewMoneyBackRequest
{
"money_back": NewMoneyBack,
"comments": MoneyBackComments?
}
Описание полей
money_back- информация для совершения операции возвратаcomments- комментарии чека возврата
Используемые типы
Тип 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?,
}
Описание полей
header- заголовок чекаitem- тов. позиция с рассчитанными значениямиpayments- массив сумм возвратаtotals- рассчитанные итоги возвратаextra- доп. информация переданная в запросе
Используемые типы:
Тип NewRollback
{
"header": TokenChequeHeader,
"target_num": u32,
"extra": String?
}
Описание полей
header- заголовок чека. Для данного запроса полеcurrencyигнорируется.target_num- номер аннулируемого чека продажиextra- дополнительная информация. Игнорируется при обработке данных, однако сохраняется и может быть запрошена клиентской стороной
Используемые типы
Тип NewRollbackRequest
{
"rollback": NewRollback,
"comments": RollbackComments?
}
Описание полей
rollback- информация для совершения операции аннулированияcomments- комментарии чека аннулирования
Используемые типы
Тип 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
- Обновлен раздел Заголовки
-
- Устарел заголовок
printer.escpos.required
- Устарел заголовок
-
- Добавлены заголовки
repr.*
- Добавлены заголовки
- Добавлен раздел Настройки
- Добавлен раздел Служба (windows)
- Обновлен тип SaleRequest
-
- Устарело поле
link
- Устарело поле
Пример ответа со всеми переданными заголовками 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": " ИП Моров А.М. <br/> УНП: 191832203 <br/>------------------------------------------------<br/><b> НЕ ЯВЛЯЕТСЯ ПЛАТЕЖНЫМ ДОКУМЕНТОМ </b><br/>------------------------------------------------<br/> Документ регистрации операции внесения <br/> № 10398 <br/><b>Рег.№ Кассы: </b>131010705 <b>Зав.№ СКО: </b>AVQ11031010705<br/><b>Валюта: </b>BYN <b>Док-т закрыт: </b>31.08.2022 09:56:22<br/><b>Кассир:</b>.....................................Test<br/>------------------------------------------------<br/><b>Внесено:</b>...................................15.00<br/>------------------------------------------------<br/> УИ: 1A5663901D4B4CE607CF1091 <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
Документация:
- Исправлено описание входных данных при закрытии смены
- Добавлен тип CloseShiftData
- Исправлено описание в разделе Закрытие смены
- Добавлен пример с комментариями в разделе Закрытие смены
Изменения от 2022-02-02:
Документация:
- Добавлен ReportComments
- Добавлен CountersComments
- Добавлено поле
commentsв CloseShiftRequest - Добавлен раздел "Очередь печати" в Работа с принтером
- Добавлена возможность печати копии Z-отчёта
- Добавлен тип ZReportCopyRequest
- Добавлена информация о конфигурации менеджера СКО
- Добавлены пути лог-конфигов в раздел Логирование