Skip to main content

Справочник API POSfix

Обзор​

API-сервер POSfix работает локально на POS-устройстве и предоставляет REST API на порту 4567 (HTTP). Он позволяет внешней ERP-системе выполнять фискальные операции — продажи, внесение/выдача наличных, отчёты Z/X, периодические отчёты и запросы — напрямую на POS-терминале через локальную сеть.

Базовый URL: http://<ip-устройства>:4567

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

  1. Убедитесь, что POS-устройство и ERP находятся в одной локальной сети.
  2. Получите IP-адрес устройства из Настройки > Оборудование в приложении POS или из endpoint-а health.
  3. Получите API-ключ в панели управления POSfix cloud.
  4. Проверьте подключение:
    GET http://<ip-устройства>:4567/api/health
  5. Начните выполнять фискальные операции, используя заголовок X-API-Key.

Аутентификация​

Все endpoint-ы (кроме /api/health) требуют заголовок X-API-Key.

X-API-Key: ваш-api-ключ

API-ключ предоставляется через облачную платформу POSfix и уникален для каждого терминала.

Ключ отсутствует → 401 MISSING_API_KEY Недействительный ключ → 401 INVALID_API_KEY


Формат ответа​

Каждый ответ соответствует следующему формату:

{
"success": true,
"data": { ... },
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}

В случае ошибки:

{
"success": false,
"error": {
"code": "КОД_ОШИБКИ",
"message": "Описание ошибки",
"details": [ ... ]
},
"timestamp": "2026-02-16T12:00:00.000Z"
}
ПолеТипОписание
successbooleantrue если операция выполнена успешно
dataobject | nullДанные ответа (null при ошибке)
errorobject | nullИнформация об ошибке (null при успехе)
error.codestringМашиночитаемый код ошибки
error.messagestringЧитаемое описание ошибки
error.detailsarray | nullДетали ошибок валидации (на уровне полей)
timestampstringВременная метка ISO 8601 UTC

Endpoint-ы​

1. Состояние и здоровье​

GET /api/health​

Проверка состояния сервера. Аутентификация не требуется.

Возвращает версию приложения, фискальный статус, ID терминала, IP устройства и время работы.

Поля ответа:

ПолеТипОписание
statusstringСостояние сервера: "ready"
versionstringВерсия приложения (напр. "1.0.1+5")
fiscalStatusstringФискальный статус: "online", "offline", "not_fiscal"
terminalIdstringИдентификатор терминала
serverPortintПорт прослушивания (4567)
uptimeintВремя работы сервера в секундах
serverStartedAtstringВременная метка ISO 8601 запуска сервера
deviceIpstringIP-адрес устройства в локальной сети

Пример ответа:

{
"success": true,
"data": {
"status": "ready",
"version": "1.0.1+5",
"fiscalStatus": "online",
"terminalId": "T-12345",
"serverPort": 4567,
"uptime": 3600,
"serverStartedAt": "2026-02-16T10:00:00.000Z",
"deviceIp": "192.168.1.50"
},
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}

2. Продажи​

POST /api/sales​

Создание новой продажи. Выполняет фискальную регистрацию в MEV (налоговый орган), печатает чек и опционально доставляет чек по SMS/email.

Тело запроса:

ПолеТипОбязательноПо умолч.Описание
itemsarrayДа—Массив позиций продажи (минимум 1)
items[].idstringНетnullВнешний ID товара из ERP. Если опущен, payload синхронизации будет содержать null
items[].namestringДа—Название товара (1-100 символов)
items[].unitPricenumberДа—Цена за единицу (должна быть > 0)
items[].quantitynumberДа—Количество (должно быть > 0). Десятичные допускаются при allowDecimals: true
items[].vatCodestringДа—Код НДС: A, B, C, D, E или _
items[].discountPercentnumberНет0Процент скидки на позицию (0-100)
items[].allowDecimalsbooleanНетfalseРазрешить дробное количество (напр. 0.750 кг)
cartDiscountobjectНетnullСкидка на уровне корзины
cartDiscount.percentnumberДа—Процент скидки на корзину (0-100)
paymentsarrayДа—Массив платежей (минимум 1)
payments[].typestringДа—Код типа оплаты ACPS (см. Типы оплаты)
payments[].amountnumberДа—Сумма платежа
payments[].rrnstringНетnullRRN карточного платежа, уже проведённого в другом приложении или на другом терминале, не более 12 символов. С ним касса не запускает банковский терминал и только выдаёт чек; без него касса сама проводит оплату картой. Отмену и возврат платежа, отправленного с RRN, делают в приложении, которое провело оплату.
amountReceivednumberДа—Общая сумма, полученная от клиента
changenumberДа—Сдача, возвращённая клиенту
deliveryobjectНетnullОпции доставки чека (SMS/email)
delivery.customerPhonestringНетnullНомер телефона для доставки по SMS (формат: +XXXXXXXXXXX)
delivery.customerEmailstringНетnullEmail для доставки чека
delivery.customerNamestringНетnullИмя клиента (макс. 60 символов)
delivery.languagestringНет"ro"Язык чека: "ro", "en", "ru"
printReceiptbooleanНетtrueПечатать чек на принтере POS

Поля ответа:

ПолеТипОписание
saleIdstringЛокальный UUID продажи
purchaseIdstringID покупки на сервере
serverSaleIdstringID продажи на сервере
fiscalOperationIdstringUUID фискальной операции
receiptNumberintПорядковый номер чека в текущем отчёте Z
reportNumberintНомер текущего отчёта Z
fiscalCodestringФискальный код от MEV
mevIdstring | nullID транзакции MEV (null при offline)
isOfflinebooleantrue если MEV был недоступен (офлайн фискальный чек)
offlineFiscalCodestring | nullОфлайн фискальный код (при работе в офлайне)
totalnumberИтоговая сумма продажи (после скидок)
subtotalnumberПодитог до скидки на корзину
amountReceivednumberСумма, полученная от клиента
changenumberВозвращённая сдача
vatBreakdownobjectРазбивка по кодам НДС (см. Разбивка НДС)
paymentBreakdownarrayМассив объектов { type, amount }
qrCodeDatastringURL QR-кода для проверки чека
mevResponseXmlstringSOAP XML ответ от MEV
receiptDeliveryobject | null{ smsSent, emailSent } — указывает, что доставка запрошена, но не подтверждена
createdAtstringВременная метка ISO 8601

Пример — Простая продажа (1 позиция, наличные):

// Запрос
POST /api/sales
{
"items": [
{
"name": "Cafea espresso",
"unitPrice": 45.00,
"quantity": 1,
"vatCode": "B"
}
],
"payments": [
{ "type": "1", "amount": 45.00 }
],
"amountReceived": 45.00,
"change": 0,
"printReceipt": true
}
// Ответ 200
{
"success": true,
"data": {
"saleId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"purchaseId": "server-purchase-001",
"serverSaleId": "server-sale-001",
"fiscalOperationId": "fiscal-op-001",
"receiptNumber": 1,
"reportNumber": 1,
"fiscalCode": "MEV-TXN-001",
"mevId": "MEV-TXN-001",
"isOffline": false,
"offlineFiscalCode": null,
"total": 45.00,
"subtotal": 45.00,
"amountReceived": 45.00,
"change": 0.00,
"vatBreakdown": {
"B": {
"code": "B",
"percent": 20.0,
"vatAmount": 7.50,
"taxableBase": 37.50,
"totalWithVat": 45.00
}
},
"paymentBreakdown": [
{ "type": "1", "amount": 45.00 }
],
"qrCodeData": "https://sift-mev.sfs.md/verify?id=MEV-TXN-001",
"mevResponseXml": "<?xml version=\"1.0\"?><soap:Envelope>...</soap:Envelope>",
"receiptDelivery": null,
"createdAt": "2026-02-16T12:00:00.000Z"
},
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}

Пример — Сложная продажа (несколько позиций, смешанная оплата, скидки, доставка):

// Запрос
POST /api/sales
{
"items": [
{
"id": "prod-001",
"name": "Cafea espresso",
"unitPrice": 45.00,
"quantity": 2,
"vatCode": "B"
},
{
"name": "Tort Napoleon (kg)",
"unitPrice": 180.00,
"quantity": 0.750,
"vatCode": "B",
"discountPercent": 10.0,
"allowDecimals": true
},
{
"name": "Apa minerala 0.5L",
"unitPrice": 15.00,
"quantity": 3,
"vatCode": "B"
}
],
"cartDiscount": {
"percent": 5.0
},
"payments": [
{ "type": "1", "amount": 200.00 },
{ "type": "2", "amount": 50.00, "rrn": "123456789012" }
],
"amountReceived": 250.00,
"change": 0,
"delivery": {
"customerPhone": "+37369123456",
"customerEmail": "client@email.com",
"customerName": "Vasile Munteanu",
"language": "ro"
},
"printReceipt": true
}

Ошибки валидации возвращают HTTP 400 с деталями на уровне полей:

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "items[0].name",
"code": "ITEM_NAME_INVALID",
"message": "Item name must be 1-100 characters"
},
{
"field": "items[0].unitPrice",
"code": "ITEM_PRICE_INVALID",
"message": "Unit price must be greater than 0"
}
]
},
"timestamp": "2026-02-16T12:00:00.000Z"
}

GET /api/sales​

Список продаж с фильтрацией по диапазону дат и пагинацией.

Параметры запроса:

ПараметрТипОбязательноПо умолч.Описание
dateFromstringНет—Дата начала (ISO: YYYY-MM-DD)
dateTostringНет—Дата окончания (ISO: YYYY-MM-DD)
limitintНет50Макс. количество результатов на страницу
offsetintНет0Смещение пагинации

Поля ответа:

ПолеТипОписание
salesarrayМассив сводок продаж
sales[].idstringUUID продажи
sales[].purchaseIdstringID покупки на сервере
sales[].serverSaleIdstringID продажи на сервере
sales[].fiscalOperationIdstringUUID фискальной операции
sales[].cashierIdstringID кассира
sales[].cashierNamestringИмя кассира
sales[].subtotalnumberСумма подитога
sales[].totalnumberИтоговая сумма
sales[].paymentTypestringМетка основного типа оплаты
sales[].paymentAmountnumberОплаченная сумма
sales[].changeAmountnumberВозвращённая сдача
sales[].statusstringСтатус синхронизации
sales[].createdAtstringВременная метка ISO 8601
totalintОбщее количество найденных продаж
limitintПрименённый лимит
offsetintПрименённое смещение

Пример:

GET /api/sales?dateFrom=2026-02-01&dateTo=2026-02-16&limit=50&offset=0

GET /api/sales/{saleId}​

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

Параметры пути:

ПараметрТипОписание
saleIdstringUUID продажи

Ответ включает:

РазделОписание
items[]Детали товара: productId, productName, quantity, unitPrice, originalPrice, discountAmount, markupAmount, netAmount, vatCode, vatPercent, vatAmount
payments[]Детали оплаты: paymentType, amount, notes
fiscalOperationФискальные данные: mevId, receiptNumber, reportNumber, status, isOffline, mevResponseXml, qrCodeData

Ошибка: 404 SALE_NOT_FOUND если ID продажи не существует.


3. Операции с наличными​

POST /api/cash/in​

Внесение наличных в кассу. Создаёт фискальный сервисный чек, отправляемый в MEV.

Тело запроса:

ПолеТипОбязательноПо умолч.Описание
amountnumberДа—Сумма для внесения (должна быть > 0)
reasonstringНетnullПричина внесения
printReceiptbooleanНетtrueПечатать сервисный чек

Поля ответа:

ПолеТипОписание
operationIdstringUUID операции
fiscalOperationIdstringUUID фискальной операции
receiptNumberintНомер сервисного чека
reportNumberintНомер текущего отчёта Z
mevIdstring | nullID транзакции MEV
isOfflinebooleanБыла ли операция офлайн
amountnumberВнесённая сумма
newBalancenumberНовый баланс наличных
operationTypestring"cashIn"
mevResponseXmlstringSOAP XML ответ
createdAtstringВременная метка ISO 8601

Пример:

// Запрос
POST /api/cash/in
{
"amount": 500.00,
"reason": "Depunere inceput zi",
"printReceipt": true
}
// Ответ 200
{
"success": true,
"data": {
"operationId": "op-uuid-001",
"fiscalOperationId": "fiscal-op-003",
"receiptNumber": 1,
"reportNumber": 1,
"mevId": "MEV-SVC-001",
"isOffline": false,
"amount": 500.00,
"newBalance": 500.00,
"operationType": "cashIn",
"mevResponseXml": "...",
"createdAt": "2026-02-16T08:00:00.000Z"
}
}

POST /api/cash/out​

Выдача наличных из кассы. Проверяет достаточность баланса перед выполнением.

Тело запроса:

ПолеТипОбязательноПо умолч.Описание
amountnumberДа—Сумма для выдачи (должна быть > 0)
reasonstringНетnullПричина выдачи
printReceiptbooleanНетtrueПечатать сервисный чек

Поля ответа: Аналогичны внесению, с operationType: "cashOut".

Ошибка: 409 INSUFFICIENT_CASH_BALANCE если текущий баланс меньше запрашиваемой суммы.

{
"success": false,
"error": {
"code": "INSUFFICIENT_CASH_BALANCE",
"message": "Cash balance (300.00) is insufficient for withdrawal of 500.00"
}
}

4. Отчёты​

POST /api/reports/z​

Генерация Z-отчёта — закрытие фискального дня.

warning

Это необратимая операция. Она сбрасывает счётчики чеков и увеличивает номер отчёта.

Тело запроса:

ПолеТипОбязательноПо умолч.Описание
printReportbooleanНетtrueПечатать отчёт

Требуется: Терминал должен быть фискализирован и иметь действительные учётные данные MEV.

Поля ответа:

ПолеТипОписание
reportNumberintНомер Z-отчёта
operationIdstringUUID фискальной операции
mevIdstring | nullID транзакции MEV
isOfflinebooleanБыла ли операция офлайн
reportDataobjectПолные данные отчёта (см. Объект Report Data ниже)
mevResponseXmlstringSOAP XML ответ от MEV
generatedAtstringВременная метка ISO 8601

Объект Report Data:

ПолеТипОписание
reportNumberintНомер Z-отчёта
dailyTotalnumberОбщая сумма продаж за день
dailyTaxnumberОбщая сумма НДС за день
dailyUntaxednumberНеоблагаемая сумма
vatBreakdownobjectРазбивка по кодам НДС
receiptsIssuedintКоличество выданных чеков
lastReceiptNumberintПоследний номер чека
receiptsSentToMevintЧеки, успешно отправленные в MEV
paymentTotalsobjectСумма по коду типа оплаты ACPS (напр. { "1": 3000.00, "2": 2000.00 })
paymentCountsobjectКоличество по коду типа оплаты ACPS (напр. { "1": 25, "2": 17 })
cashInnumberОбщая сумма внесений наличных
cashOutnumberОбщая сумма выдач наличных
cashBalancenumberТекущий баланс наличных
yearTotalnumber | nullНакопительный годовой итог (только Z)
yearTaxnumber | nullНакопительный годовой НДС (только Z)
totalSalesnumberОбщая сумма продаж (брутто)
totalReturnsnumberОбщая сумма возвратов
returnsCountintКоличество операций возврата
cashInCountintКоличество операций внесения
cashOutCountintКоличество операций выдачи
generatedAtstringВременная метка ISO 8601

POST /api/reports/x​

Генерация X-отчёта — промежуточный снимок фискального дня.

НЕ сбрасывает счётчики. Структура запроса/ответа аналогична Z-отчёту.


POST /api/reports/periodic​

Генерация Периодического отчёта — агрегированные данные по нескольким Z-отчётам.

Это только локальный отчёт (не отправляется в MEV). Поддерживает два взаимоисключающих режима фильтрации.

Тело запроса:

ПолеТипОбязательноПо умолч.Описание
dateFromstringУсловно—Дата начала (ISO: YYYY-MM-DD). Обязательно для режима диапазона дат
dateTostringУсловно—Дата окончания (ISO: YYYY-MM-DD). Обязательно для режима диапазона дат
reportFromintУсловно—Начальный номер Z-отчёта. Для режима диапазона отчётов
reportTointУсловно—Конечный номер Z-отчёта. Для режима диапазона отчётов
detailedbooleanНетfalseВключить разбивку по отдельным Z-отчётам
printReportbooleanНетtrueПечатать отчёт на принтере POS

Режимы фильтрации (взаимоисключающие — укажите один набор):

  1. Диапазон дат: dateFrom + dateTo
  2. Диапазон номеров отчётов: reportFrom и/или reportTo (оба необязательны — опустите reportFrom для начала с Z#1, опустите reportTo для последнего)

Поля ответа:

ПолеТипОписание
filterModestring"dateRange" или "reportRange"
dateFromstringДата начала (YYYY-MM-DD)
dateTostringДата окончания (YYYY-MM-DD)
reportFromint(только диапазон отчётов) Начальный номер Z-отчёта
reportToint(только диапазон отчётов) Конечный номер Z-отчёта
totalSalesnumberАгрегированная сумма продаж
totalTaxnumberАгрегированная сумма НДС
totalUntaxednumberАгрегированная необлагаемая сумма
vatBreakdownobjectАгрегированная разбивка по кодам НДС
receiptsCountintОбщее количество чеков по всем Z-отчётам
paymentTotalsobjectАгрегированные итоги платежей по типам
cashInnumberОбщая сумма внесений наличных
cashOutnumberОбщая сумма выдач наличных
cashInCountintКоличество операций внесения
cashOutCountintКоличество операций выдачи
zReportsCountintКоличество Z-отчётов в диапазоне
xReportsCountintКоличество X-отчётов в диапазоне
firstZReportNumberintПервый номер Z-отчёта в диапазоне
lastZReportNumberintПоследний номер Z-отчёта в диапазоне
firstZReportTimestampstringВременная метка закрытия первого Z-отчёта
lastZReportTimestampstringВременная метка закрытия последнего Z-отчёта
totalReturnsnumberАгрегированные возвраты
returnsCountintКоличество операций возврата
individualZReportsarray | nullРазбивка по каждому Z (при detailed: true)
generatedAtstringВременная метка ISO 8601

Поля индивидуального Z-отчёта (при detailed: true):

ПолеТипОписание
reportNumberintНомер Z-отчёта
closedAtstringВременная метка ISO 8601 закрытия Z
firstReceiptNumberintПервый номер чека в этом Z
lastReceiptNumberintПоследний номер чека в этом Z
receiptsCountintКоличество чеков
totalSalesnumberОбщая сумма продаж за этот Z
totalTaxnumberОбщая сумма НДС за этот Z
vatBreakdownobjectРазбивка НДС за этот Z
paymentTotalsobjectИтоги платежей по типам
cashInnumberВнесения наличных в этом Z
cashOutnumberВыдачи наличных в этом Z

Пример — Сводка по диапазону дат:

// Запрос
POST /api/reports/periodic
{
"dateFrom": "2026-02-01",
"dateTo": "2026-02-16",
"detailed": false,
"printReport": true
}

Пример — Сводка по диапазону номеров Z-отчётов:

// Запрос
POST /api/reports/periodic
{
"reportFrom": 5,
"reportTo": 10,
"detailed": false,
"printReport": true
}

Пример — Детализированный по диапазону дат:

// Запрос
POST /api/reports/periodic
{
"dateFrom": "2026-02-01",
"dateTo": "2026-02-16",
"detailed": true,
"printReport": false
}

Ошибки валидации:

КодУсловие
FILTER_REQUIREDНе указан ни диапазон дат, ни диапазон отчётов
DATE_RANGE_INVALIDdateFrom позже dateTo
DATE_TO_FUTUREdateTo в будущем
REPORT_NUMBER_INVALIDreportFrom или reportTo < 1
REPORT_RANGE_INVALIDreportFrom > reportTo

5. Фискальные запросы​

GET /api/fiscal/operations​

Запрос фискальных операций из аудиторской базы данных с фильтрацией.

Параметры запроса:

ПараметрТипОбязательноОписание
dateFromstringНетДата начала (ISO: YYYY-MM-DD)
dateTostringНетДата окончания (ISO: YYYY-MM-DD)
typestringНетФильтр по типу операции (см. Справочные таблицы)
statusstringНетФильтр по статусу операции (см. Справочные таблицы)
limitintНетМакс. количество результатов (по умолч. 50)
offsetintНетСмещение пагинации (по умолч. 0)

Поля ответа:

ПолеТипОписание
operationsarrayМассив фискальных операций
operations[].idstringUUID операции
operations[].operationTypestringТип фискальной операции
operations[].receiptNumberintНомер чека
operations[].reportNumberintНомер Z-отчёта
operations[].mevIdstring | nullID транзакции MEV
operations[].statusstringСтатус операции
operations[].isOfflinebooleanРаботал ли в офлайне
operations[].totalAmountnumberСумма операции
operations[].vatBreakdownobjectУпрощённая разбивка НДС
operations[].vatDetailsobjectДетализированный НДС с процентом, ставкой, себестоимостью, брутто
operations[].paymentsBreakdownobjectПлатежи по типам
operations[].mevResponseXmlstringSOAP XML ответ
operations[].errorMessagestring | nullСообщение об ошибке при неудачной операции
operations[].createdAtstringВременная метка ISO 8601 создания
operations[].completedAtstringВременная метка ISO 8601 завершения
totalintОбщее количество найденных операций
limitintПрименённый лимит
offsetintПрименённое смещение

GET /api/fiscal/daily-summary​

Получение сводки текущего фискального дня. Возвращает те же данные, что и X-отчёт, но без отправки в MEV. Только чтение, фискальная блокировка не требуется.

Требуется: Терминал должен быть фискализирован.

Ответ: Аналогичен объекту Report Data (см. раздел Z-отчёт).


6. Печать​

POST /api/print​

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

Тело запроса:

ПолеТипОбязательноПо умолч.Описание
linesarrayДа—Массив массивов строк
feedLinesintНет3Количество пустых строк после содержимого
cutbooleanНетtrueОбрезать бумагу после печати

Формат строки — каждая строка представляет собой массив из 1-3 строковых значений:

КолонкиРаскладка
["текст"]Полная ширина, выравнивание по левому краю
["лево", "право"]Выравнивание по левому + правому краю
["лево", "центр", "право"]Трёхколоночная раскладка
[""]Пустая строка (разделитель)
info

Это нефискальная операция — без взаимодействия с MEV, без фискального чека.

Поля ответа:

ПолеТипОписание
linesCountintКоличество напечатанных строк
printedAtstringВременная метка ISO 8601

Пример — Отчёт по инвентаризации (3 колонки):

POST /api/print
{
"lines": [
["RAPORT INVENTAR"],
["Data:", "16.02.2026"],
[""],
["Cod", "Denumire", "Cantitate"],
["────────────────────────────────"],
["001", "Cafea espresso", "150 buc"],
["002", "Tort Napoleon", "12.5 kg"],
["003", "Apa minerala 0.5L", "340 buc"],
[""],
["Total pozitii:", "4"],
["────────────────────────────────"],
["Responsabil:", "", "Ion Popescu"]
],
"feedLines": 3,
"cut": true
}

Ошибка: 503 PRINTER_UNAVAILABLE если принтер отключён или недоступен.


Справочные таблицы​

Коды ошибок​

КодHTTP-статусОписание
MISSING_API_KEY401Заголовок X-API-Key не предоставлен
INVALID_API_KEY401Предоставленный API-ключ недействителен
VALIDATION_ERROR400Валидация тела запроса не пройдена (см. details[])
INVALID_JSON400Тело запроса не является валидным JSON
TERMINAL_NOT_FISCAL409Терминал не фискализирован (нет сертификата MEV)
MEV_CREDENTIALS_MISSING409Терминал фискализирован, но учётные данные MEV отсутствуют
FISCAL_DAY_EXPIRED409Прошло 24ч с первого чека фискального дня — необходим Z-отчёт для продолжения
INSUFFICIENT_CASH_BALANCE409Баланс наличных недостаточен для запрашиваемой выдачи
MEV_ERROR502Связь с MEV (SFS) не удалась (таймаут, ошибка SOAP, истёкший сертификат)
BUSY429Другая фискальная операция в процессе (превышен таймаут 30с)
SALE_NOT_FOUND404Продажа с указанным ID не найдена
PRINTER_UNAVAILABLE503Принтер недоступен или отключён

Коды НДС​

КодОписание
AСтавка НДС A (согласно настройкам терминала)
BСтавка НДС B (обычно 20%)
CСтавка НДС C
DСтавка НДС D
EСтавка НДС E
_Освобождён (без НДС)

Типы оплаты (ACPS WSDL)​

ТипОписание
"1"NUMERAR (Наличные)
"2"CARD (Карта)
"3.1"VAUCHER (Ваучер)
"3.2"CEC / Certificat valoric (Чек / Ценный сертификат)
"3.3"TICHET — оплата документом установленной стоимости (MDL)
"5"TME — электронный талон на питание
"6"ABONAMENT (Абонемент)
"7"ALT IP (другой платёжный инструмент)
"8.1"Credit (Кредит)
"8.2"Leasing (Лизинг)
"8.3"Avans (Аванс)
"8.4"Arvuna (Задаток)
"8.5"Gaj (Залог)
"8.8"Compensare (Взаимозачёт)
"8.9"Alt mod (Другой способ)

Типы фискальных операций​

ТипОписание
receiptФискальный чек (продажа)
cash_inВнесение наличных
cash_outВыдача наличных
refundВозврат
x_reportX-отчёт
z_reportZ-отчёт

Статусы фискальных операций​

СтатусОписание
pendingСоздана, ещё не отправлена в MEV
sentОтправлена в MEV, ожидание ответа
successУспешно обработана MEV
failedMEV вернул ошибку
offlineСохранена локально (MEV недоступен)

Объект разбивки НДС​

{
"B": {
"code": "B",
"percent": 20.0,
"vatAmount": 7.50,
"taxableBase": 37.50,
"gross": 45.00
}
}
ПолеТипОписание
codestringКод ставки НДС
percentnumberПроцент НДС
vatAmountnumberСумма НДС
taxableBasenumberСумма нетто (без НДС)
grossnumberСумма брутто (с НДС)

Примечания​

  • Все денежные суммы указаны в MDL (Молдавский лей) как number с точностью до 2 десятичных знаков.
  • Все временные метки в формате ISO 8601 UTC.
  • Сервер использует блокировку фискальных операций — только одна фискальная операция (продажа, внесение/выдача, отчёт Z/X) может выполняться одновременно. Параллельные запросы будут ожидать до 30 секунд перед возвратом 429 BUSY.
  • Офлайн режим: Когда MEV (сервер налогового органа) недоступен, фискальные операции сохраняются локально и синхронизируются позже. Ответ будет содержать isOffline: true и mevId: null.
  • Печать чеков выполняется по принципу fire-and-forget — ответ API не ожидает завершения печати.

Коллекции Postman​

Две коллекции — для двух разных API. Импортируются через Import → File.

КоллекцияЧто внутриСкачать
API терминалаСправочник API кассы — 28 запросов: продажи, касса, X/Z и периодические отчёты, печать, каталог, отмена и возврат оплаты картой, лоты доставки. У каждого запроса описаны поля запроса и ответа, ошибки с HTTP-статусом и примеры. Один и тот же API на Android и на PC-ECC (Windows); где они различаются, это указано в описании запроса.posfix-terminal-api.postman_collection.json
Публичный API интеграции24 запроса, которыми внешняя система (интернет-магазин, ERP) читает и пишет данные торговца: каталог, остатки, цены, клиенты, заказы, Z-отчёты, вебхуки.posfix-integration-api.postman_collection.json

API терминала​

Заполните переменные коллекции:

  • baseUrl → http://<ip-терминала>:4567 в локальной сети или https://api.posfix.md/api/relay/<publicId> через relay — адрес показан на кассе, в окне режима Provider
  • apiKey → ключ с терминала (Настройки → Developer → Показать API-ключ)

Нажмите на название коллекции в Postman, чтобы открыть её описание: полную карту ошибок, правила повтора с Idempotency-Key и справочные таблицы. Вся коллекция, включая описания, — на румынском.

Z-отчёт закрывает день

POST /api/reports/z нельзя отменить, он обнуляет счётчики дня. Не запускайте его как тест на рабочем терминале.

Смена открывается сама

Открывать смену не нужно: терминал открывает её при первой продаже, внесении или изъятии наличных. День закрывается Z-отчётом.

Публичный API интеграции​

Ключ создаётся в панели управления → Ключи API интеграции и показывается открытым текстом один раз, при создании. Впишите его в переменную apiKey; он уходит с каждым запросом в заголовке X-Posfix-Api-Key.

У каждого ключа только те права (scopes), которые выбраны при создании — в описании каждого запроса указано, какое нужно. Без него ответ 403.

Модуль подписки

API требует активного модуля «API Integrare» у торговца. Без него ответ 403 даже с действующим ключом и нужным scope.

Торговец не передаётся параметром: организация берётся из ключа, поэтому чужие данные прочитать нельзя. Начните с GET /api/public/v1/ping — он подтверждает ключ, торговца и scopes.