Данный документ является описанием взаимодействия ККМ с фискальной системой КИВИ Казахстан.
Содержание
Список сокращений
СФД |
Система фискальных данных QIWI |
ОФД |
Оператор фискальных данных ОФД (Казактелеком, Транстелеком) |
ККМ |
Контрольно кассовая машина |
АРМ |
Автоматизированное рабочее место (веб портал) |
Описание работы
Прежде чем начать работу ККМ должен быть зарегистрироан в СФД.
После регистрации необходимо сгенерировать ключевую пару и зарегистрировать публичный ключ в СФД отправив команду SET_KKM_PUBLIC_KEY
. После успешной регистрации ключа ККМ может переходить в рабочий режим и выполнять фискальные операции.
ККМ должен с некоторой периодичностью (примерно раз в 5 минут) запрашивать информацию о терминале GET_KKM_INFO
для актуализации информации о ККМ.
Общее описание протокола
- URL адрес:
api.osfd.kz
- Коммуникация осуществляется по протоколу HTTP.
- Тело запроса и ответа должны быть в кодировке UTF-8.
- В качестве формата обмена данными используется JSON. В случае, если какие-либо поля не обязательны, они опускаются. Также допускается, чтобы значением этих полей был
null
.
Формат запроса
- Все операции осуществляются методом
POST
. На все другие методы сервер будет возвращать ошибку 405 Method Not Allowed
- В заголовке должен быть указан идентификатор ККМ
QF-KKM-ID
.
- Все запросы должны быть подписаны приватным ключем терминала. Подписываться должно тело запроса. Сама подпись должна быть в формате
hex
и передаваться в заголовоке QF-Request-Sign
.
Поддерживаемые алгоритмы подписи:
SHA256withRSA
SHA1withRSA
Пример полного запроса с заголовками и подписью
POST / HTTP/1.1
Host: api.osfd.kz
Content-Length: 125
QF-KKM-ID: K24829
QF-Request-Sign-Alg: SHA256withRSA
QF-Request-Sign: babbb9da99411bf2440cd852ec7b4ba65d9ecb19590a51a90f183c88793ea52edf4b374d73fe0a277bb00fb6e1e2b9f811a76aea290f9cdccfcf63fd0f00f887431086f096e99694f33d62f47e66cfe5be684e3235df3e342267d03f2a0900ffa59bcc24f1bc571181a8d57d38b0c26389a786c8a9dd34ebce0a54882121d8f28efdd062931b36545a1268088bbde3c35fa530cbfd0172c768a4709dd1022201016629ce2c405e9390d4c17ca00ff07cb12cc0b29eb6727d4500fb6e47ae9f8ab7351931d1144ca5c5e4c46ae7e82b6072baba62bfe51819340ef4da14cfd63cd728c7bc4a544c9348e720dae20875bd6ffc1e030b2230b698aa4a6c570767d2
{"api_version":"1.0","client_soft":"KKM Emulator v1.0","kkm_id":"K24829","command":{"type":"GET_KKM_INFO"}}
Общая структура запроса
{
"api_version": "1.0",
"kkm_id": "1234567",
"client_request_id": "fa2cf7dd-fca3-42a8-b0bc-ebba0b945888",
"client_soft": "Cashier 3000",
"command": {
"type" : "DO_COMMAND",
"arg1" : "val1",
"arg2" : "val2"
}
}
REQUEST
api_version |
string |
Да |
Версия протокола |
kkm_id |
string |
Да |
Идентификатор терминала |
client_request_id |
string |
Нет |
Идентификатор запроса |
client_soft |
string |
Нет |
Информация о ПО на клиенте |
command |
object |
Да |
Команда |
api_version
- Версия состоит из двух частей. major.minor
major
- Старшая версия протокола. Если эта версия меняется, то протокол не имеет обратной совместимости.
minor
- Младшая версия протокола. Если эта версия меняется, то протокол имеет обратную совместимость. В этом случае поля только добавляются либо переходят в статус необязательных.
client_request_id
- служит для сверки логов запроса и ответа от сервера. Клиент генерирует его самостоятельно и обеспечивает его уникальность.
Формат ответа
{
"api_version": "1.0",
"client_request_id": "fa2cf7dd-fca3-42a8-b0bc-ebba0b945888",
"error_code": 0,
"error_token": "OK",
"error_message": "Операция выполнена успешно",
"result": {
"some_property": "some_value"
}
}
RESPONSE
api_version |
string |
Да |
Версия протокола |
client_request_id |
string |
Нет |
Идентификтор запроса |
error_code |
i32 |
Да |
Цифровой код ответа |
error_token |
string |
Да |
Символьный код ошибки |
error_message |
string |
Да |
Описание кода ошибки |
session_id |
guid |
Да |
Идентификатор сессии |
result |
object |
Нет |
Результат выполения команды |
client_request_id
- идентификатор который был передан в запросе.
error_token
- токен ошибки. Это своеобразный литеральный идентификатор. Служит для обозначения возможных кодов ошибки в более понятном виде как для человека так и для устройства. Утройство может распозновать ответ как по коду ошибки так и по токену ошибки.
result
- Возвращаемое значение комманды. Если команда не подразумевает результат, то свойство опускается.
Описание примитивных типов данных
i16 |
Целочисленный со знаком |
-32768 : 32767 |
i32 |
Целочисленный со знаком |
–2147483648 : 2147483647 |
i64 |
Целочисленный со знаком |
-9223372036854775808 : 9223372036854775807 |
money |
Число с фикс. точностью 19 и масштабом 2 |
-92233720368547758.08 : 92233720368547758.07 |
num_10_3 |
Число с фикс. точностью 10 и масштабом 3 |
–2147483.648 : 2147483.647 |
string |
Строковый |
|
bool |
Булевый |
true, false |
datetime |
Дата и время |
"YYYY-MM-DDThh:mm:ss" |
guid |
Универсальный уникальный идентификатор |
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
interval |
Временной интервал |
"hh:mm" |
hex |
Массив байт |
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
datetime
- Дата и время должны быть в формате YYYY-MM-DDThh:mm:ss
. Данный формат совместим с ISO 8601. Например дата 24.06.2018 18:30:02 по времени Астаны должна быть 2018-06-24T18:30:02
.
hex
- Массив байт должен передаваться в шеснадцетиричном формате, нижнего регистра без разделителей байт.
Например: "bd637b59816232bf99f183fb7b8a6a06"
money
- Значение может передаваться в виде текстового значения.
Например: "12.05"
num_10_3
- Значение может передваться в виде текстового значения.
Например: "12.345"
Описание общих типов данных
Информация об операторе-кассире CASHIER_INFO
code |
int |
Да |
Код оператора-кассира |
name |
string |
Да |
Имя оператора-кассира |
Описание команд
Регистрация публичного ключа терминала SET_KKM_PUBLIC_KEY
Формат аргументов запроса
{
"type": "SET_KKM_PUBLIC_KEY",
"kkm_pub_key": {
"type": "RSA_PUBLIC_KEY",
"modulus": "00aa18aba43b50deef38598faf87d2ab634e4571c130a9bca7b878267414faab8b471bd8965f5c9fc",
"public_exponent": "010001"
}
}
kkm_pub_key |
object |
Да |
Публичный ключ ккм |
- Список поддерживаемых типов
kkm_pub_key
:
Публичный ключ RSA RSA_PUBLIC_KEY
modulus |
hex |
Да |
Модуль |
public_exponent |
hex |
Да |
Открытая экспонента |
Формат результата ответа
Команда не подразумевает результат.
Получение информации о терминале GET_KKM_INFO
Формат аргументов запроса
{
"type": "GET_KKM_INFO"
}
Формат результата ответа
{
"kkm": {
"kkm_id": "123456",
"kkm_serial_number": "345234",
"kkm_kgd_id": "123456789012",
"timezone": "06:00",
"is_ready": true,
},
"organization": {
"title": "ТОО Касса 24/7",
"address": "Жубанова 42",
"iinbin": "123456789012",
},
"position": {
"title": "Торговая точка 1",
"address": "Муканова 23",
},
"taxation": {
"taxation_type": "USN",
"taxes":[
{
"tax_type": "NDS",
"tax_rate_percent": "18.000"
}
]
},
"cash_amount": "1240.00",
"last_shift": {
"shift_number": 123,
"open_date": "2019-03-13T23:44:00",
"is_closed": true,
"expiry_date": "2019-03-14T23:44:00",
"close_date": "2019-03-13T22:44:00"
}
}
kkm |
KKM_INFO |
Да |
Информация о ккм |
organisation |
ORGANISATION_INFO |
Да |
Информация об организации |
position |
POSITION_INFO |
Да |
Информация о позиции продажи |
cash_amount |
money |
Да |
Количество наличных в кассе |
taxation |
TAXATION_INFO |
Нет |
Информация о привязанном налогоблажении |
last_shift |
LAST_SHIFT_INFO |
Нет |
Информация о последней смене |
Информация о последней смене LAST_SHIFT_INFO
shift_number |
i32 |
Да |
Номер смены |
open_date |
datetime |
Да |
Дата открытия смены |
is_closed |
bool |
Да |
Закрыта ли смена |
expiry_date |
datetime |
Да |
Дата истечения смены, если смена закрыта |
close_date |
datetime |
Нет |
Дата закрытия смены, если смена закрыта |
Информация о ккм KKM_INFO
kkm_id |
string |
Да |
Идентификатор ККМ в СФД |
kkm_serial_number |
i32 |
Да |
Заводской номер ККМ |
kkm_kgd_id |
string |
Да |
Код ККМ КГД |
timezone |
interval |
Да |
Часовой пояс к которому привязан ККМ |
is_ready |
bool |
Да |
Готов ли терминал к работе |
Информация об организации ORGANIZATION_INFO
iinbin |
string |
Да |
ИИН / БИН |
title |
string |
Нет |
Название организации |
address |
string |
Нет |
Адрес организации |
Информация о точке продажи POSITION_INFO
title |
string |
Нет |
Название торговой точки |
address |
string |
Нет |
Адрес торговой точки |
Информация о налогоблажении TAXATION_INFO
taxation_type |
TAXATION_TYPE_ENUM |
Да |
Тип налогоблажения |
taxes |
TAX_INFO[] |
Нет |
Информация о налогах |
Информация о налоге TAX_INFO
tax_type |
TAX_TYPE_ENUM |
Да |
Тип налога |
tax_rate_percent |
num_10_3 |
Да |
Процент налога |
Регистрация чековой транзакции REGISTER_TICKET
Формат аргументов запроса
{
"type": "REGISTER_TICKET",
"client_txn_id": "d108a81b-1a0e-4b7b-824e-a25bd64b21a4",
"client_txn_date": "2018-05-03T16:27:30",
"is_offline": false,
"operation_type" : "SELL",
"total": "180.00",
"items": [
{
"type": "COMMODITY",
"section_code": "Секция 1",
"name": "Пицца с грибами",
"quantity": "2.000",
"price": "200.00",
"total": "400.00"
},
{
"type": "STORNO_COMMODITY",
"section_code": "Секция 1",
"name": "Пицца с грибами - отмена",
"quantity": "2.000",
"price": "200.00",
"total": "400.00"
},
{
"type": "COMMODITY",
"section_code": "Секция 1",
"name": "Пицца с сыром",
"quantity": "1.000",
"price": "200.00",
"total": "200.00"
},
{
"type": "MARKUP",
"name": "Наценка",
"total": "20.00"
},
],
"total_modifier": {
"type": "DISCOUNT",
"name": "Общая скидка",
"total": "40.00"
},
"taxes" : [
{
"tax_type": "NDS",
"taxation_type": "USN",
"tax_rate_percent": "18.000",
"total": "27.46",
"is_included_in_total": true
},
{
"tax_type": "NDS",
"taxation_type": "USN",
"tax_rate_percent": "10.000",
"total": "13.86",
"is_included_in_total": true
},
],
"payments": {
"cash": {
"amount": "180.00",
"taken": "1000.00",
"change": "820.00"
}
},
"cashier": {
"code": 12,
"name": "Иванов"
}
}
client_txn_id |
guid |
Да |
Идентификатор транзакции присваиваемый клиентом |
client_txn_date |
datetime |
Да |
Дата транзакции на момент операции |
is_offline |
bool |
Да |
Режим офлайн или онлайн (был распечатан чек или нет) |
operation_type |
TICKET_OPERATION_TYPE_ENUM |
Да |
Тип операций |
total |
money |
Да |
Итоговая сумма чековой транзакции |
items |
object[] |
Да |
Список товаров / услуг |
total_modifier |
object |
Нет |
Общая скидка или наценка |
taxes |
TAX[] |
Нет |
Налог на чек (отсутствует если налоги укзаны в элементах) |
payment |
PAYMENT_INFO |
Да |
Информация о платеже |
cashier |
CASHIER_INFO |
Нет |
Информация об операторе-кассире |
- Список поддерживаемых типов
items
:
COMMODITY
STORNO_COMMODITY
DISCOUNT
STORNO_DISCOUNT
MARKUP
STORNO_MARKUP
- Список поддерживаемых типов
total_modifier
:
taxes
- налог с определенным процентом должен встречаться не более одного раза.
Также если указано поле taxes
в чеке, то в отдельных элементах items/taxes
оно должно отсутствовать.
Информация о товаре услуге COMMODITY
section_code |
string |
Да |
Код секции или отдела |
name |
string |
Да |
Наименование |
quantity |
num_10_3 |
Да |
Количество |
price |
money |
Да |
Цена |
total |
money |
Да |
Итоговая сумма |
taxes |
TAX[] |
Нет |
Список налогов (отсутствует если есть в чеке) |
excise_stamp |
string |
Нет |
Номер акцизной марки |
Информация о сторно товара / услуги STORNO_COMMODITY
section_code |
string |
Да |
Код секции или отдела |
name |
string |
Да |
Наименование |
quantity |
num_10_3 |
Да |
Количество |
price |
money |
Да |
Цена |
total |
money |
Да |
Итоговая сумма |
taxes |
TAX[] |
Нет |
Список налогов (отсутствует если есть в чеке) |
excise_stamp |
string |
Нет |
Номер акцизной марки |
Информация о скидке DISCOUNT
name |
string |
Да |
Наименование |
total |
money |
Да |
Итоговая сумма |
taxes |
TAX[] |
Нет |
Список налогов (отсутствует если есть в чеке) |
Информация о сторно скидки STORNO_DISCOUNT
name |
string |
Да |
Наименование |
total |
money |
Да |
Итоговая сумма |
taxes |
TAX[] |
Нет |
Список налогов (отсутствует если есть в чеке) |
Информация о наценке MARKUP
name |
string |
Да |
Наименование |
total |
money |
Да |
Итоговая сумма |
taxes |
TAX[] |
Нет |
Список налогов (отсутствует если есть в чеке) |
Информация о сторно наценки STORNO_MARKUP
name |
string |
Да |
Наименование |
total |
money |
Да |
Итоговая сумма |
taxes |
TAX[] |
Нет |
Список налогов (отсутствует если есть в чеке) |
Информация о налоге TAX
tax_type |
TAX_TYPE_ENUM |
Да |
Тип налога |
taxation_type |
TAXATION_TYPE_ENUM |
Да |
Тип налогоблажения |
tax_rate_percent |
num_10_3 |
Да |
Значение налога в процентах |
total |
money |
Да |
Значение налога в деньгах |
is_included_in_total |
bool |
Да |
Заложен ли налог в сумму |
Информация о платеже PAYMENT
cash |
CASH_PAYMENT |
Нет |
Инфо об оплате наличными |
card |
CARD_PAYMENT |
Нет |
Инфо об оплате картой |
credit |
CREDIT_PAYMENT |
Нет |
Инфо об оплате в кредит |
tare |
TARE_PAYMENT |
Нет |
Инфо об оплате тарой |
Информация о наличном платеже CASH_PAYMENT
amount |
money |
Да |
Сумма для оплаты наличными |
taken |
money |
Да |
Принято наличными |
change |
money |
Да |
Сдача |
Информация о платеже картой CARD_PAYMENT
amount |
money |
Да |
Сумма для оплаты наличными |
Информация о платеже кредитом CREDIT_PAYMENT
amount |
money |
Да |
Сумма для оплаты наличными |
Информация о платеже тарой TARE_PAYMENT
amount |
money |
Да |
Сумма для оплаты наличными |
Типы операций (TICKET_OPERATION_TYPE_ENUM
)
BUY |
Покупка |
BUY_RETURN |
Возврат покупки |
SELL |
Продажа |
SELL_RETURN |
Возврат продажи |
Типы налогооблажения (TAXATION_TYPE_ENUM
)
USN |
УСН |
OSN |
ОСН |
PEASANT_AND_FARM |
Налоговый режим для крестьянских и фермерских хозяйств |
SMALL_BUSINESS_PATENT |
Налоговый режим для малых предприятий на основе патента |
Типы налогов (TAX_TYPE_ENUM
)
Формат аргументов ответа
{
"is_offline": false,
"ofd_ticket_number": "AS2304342",
"ofd_ticket_qr_code": "687474703a2f2f636f6e73756d65722e746573742d6f6f66642e6b7a3f693d3131393635373238373126663d36373839383031323334353626733d302e3026743d323032303035313854313831383137",
"offline_ticket_number": 123453,
"shift_number": 22,
"shift_document_number": 11
}
ofd_ticket_number |
string |
Нет |
Номер чека полученый от ОФД |
ofd_ticket_qr_code |
hex |
Нет |
QR код, полученный от ОФД |
offline_ticket_number |
i32 |
Да |
Автономный номер чека |
is_offline |
bool |
Да |
Чек был онлайн или офлайн |
shift_number |
i32 |
Да |
Номер смены |
shift_document_number |
i32 |
Да |
Номер документа в смене |
Если платеж был офлайн, то is_offline: true
, а ofd_ticket_number
и ofd_ticket_qr_code
будут отсутствовать.
Изъятие наличных WITHDRAW_MONEY
Формат аргументов запроса
{
"type": "WITHDRAW_MONEY",
"client_txn_id": "5d8b06e4-0560-4dcd-8162-8bb23f5ee258",
"client_txn_date": "2018-05-03T16:27:30",
"amount": "2345.00"
}
client_txn_id |
guid |
Да |
Идентификатор транзакции клиента |
client_txn_date |
timestamp |
Да |
Дата транзакции |
amount |
money |
Да |
Количество денег |
Формат аргументов ответа
{
"shift_number": 22,
"shift_document_number": 11
}
shift_number |
i32 |
Да |
Номер смены |
shift_document_number |
i32 |
Да |
Номер документа в смене |
Взнос наличных DEPOSIT_MONEY
Формат аргументов запроса
{
"type": "DEPOSIT_MONEY",
"client_txn_id": "603dc6a3-ab05-49d0-9059-ed3599b2fae7",
"client_txn_date": "2018-05-03T16:27:30",
"amount": "2345.00"
}
client_txn_id |
guid |
Да |
Идентификатор транзакции клиента |
client_txn_date |
timestamp |
Да |
Дата транзакции |
amount |
money |
Да |
Количество денег |
Формат аргументов ответа
{
"shift_number": 22,
"shift_document_number": 11
}
shift_number |
i32 |
Да |
Номер смены |
shift_document_number |
i32 |
Да |
Номер документа в смене |
Закрытие смены CLOSE_SHIFT
Формат аргументов запроса
{
"type": "CLOSE_SHIFT",
"shift_number": 5,
"cashier": {
"code": 12,
"name": "Иванов"
}
}
shift_number |
i32 |
Да |
Номер смены |
cashier |
CASHIER_INFO |
Нет |
Информация об операторе-кассире |
shift_number
- должен быть последней открытой сменой
Команда не подразумевает результат.
Коды ошибок
Успешное завершение операции 0
0 |
OK |
Операция выполнена успешно. |
Ошибки формата запроса 1xx
100 |
FMT_ERR |
Неверный формат запроса. |
Ошибки предметной области 2xx
200 |
DMN_ERR |
В данный момент невозможно выполнить данную операцию в текущем состоянии терминала либо с текущими параметрами. |
201 |
DMN_ERR_AUTH_FAILED |
Неверный идентификатор терминала или подпись. |
202 |
DMN_ERR_KKM_NOT_FOUND |
Не найден ККМ. |
203 |
DMN_ERR_NOT_ENOUGH_CASH |
Недостаточно наличных для выполнения операции. |
204 |
DMN_ERR_KKM_BLOCKED |
Терминал заблокирован. Любые операции запрещены |
205 |
DMN_ERR_KKM_BLOCKED_BY_OFD |
Терминал заблокирован на стороне ОФД. Фискальные операции запрещены. |
206 |
DMN_ERR_KKM_BLOCKED_BY_OFD_ERROR |
Терминал заблокирован т.к. имеентся ошибка при передаче данных в ОФД. Требуется ручное вмешательство. |
207 |
DMN_ERR_SHIFT_NOT_FOUND |
Не найдена смена. |
208 |
DMN_ERR_INVALID_TICKET |
Чек неправильно сформирован. |
Ошибки сервера 3xx
300 |
SRV_ERR |
Ошибка на стороне сервера. В данном случае необходимо отправить запрос позже. |