Автентифікація
API використовує JWT Bearer Token. Отримайте токен через /api/v1/auth/token/ і передавайте його у заголовку кожного запиту:
Заголовок авторизації
Authorization: Bearer <access_token>
Отримати JWT-токен
POST
/api/v1/auth/token/
Логін — отримати access + refresh токен
Тіло запиту
{
"username": "your_username",
"password": "your_password"
}
Відповідь 200
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
access токен діє 1 годину. refresh токен діє 7 днів. Після закінчення access-токена використайте refresh для його оновлення.
Оновити access-токен
POST
/api/v1/auth/token/refresh/
Отримати новий access-токен
Тіло запиту
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Відповідь 200
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Перевірити токен
POST
/api/v1/auth/token/verify/
Перевірити чинність токена
Тіло запиту
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Відповідь 200
{}
Термінали
Перегляд доступний усім учасникам команди. Оновлення та видалення — лише при наявності дозволу
can_manage_terminals.
GET/api/v1/terminals/Список терміналів
GET/api/v1/terminals/{id}/Деталі терміналу
PATCH/api/v1/terminals/{id}/Оновити термінал
DELETE/api/v1/terminals/{id}/Видалити термінал
POST/api/v1/terminals/{id}/sync_registers/Синхронізувати QR-каси
POST/api/v1/terminals/{id}/sync_invoices/Синхронізувати виписку (30 днів)
Тіло запиту (PATCH)
{
"name": "Основна каса",
"is_active": true,
"show_payments": true
}
Приклад відповіді
{
"id": 3,
"name": "Основна каса",
"merchant_id": "Mexxxxxxxxxx",
"merchant_name": "ФОП Іваненко І.І.",
"edrpou": "12345678",
"is_active": true,
"show_payments": true,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-05T12:30:00Z"
}
Поля
merchant_id, merchant_name, edrpou заповнюються автоматично при синхронізації. Токен Monobank не повертається і не приймається через API.
Параметри пошуку (GET /terminals/)
| Параметр | Тип | Опис |
|---|---|---|
search | string | Пошук по назві, мерчанту, ЄДРПОУ |
ordering | string | name, -name, created_at, -created_at |
page | integer | Номер сторінки |
page_size | integer | Розмір сторінки (макс. 200) |
Відповідь sync_registers
{
"synced": 4,
"merchant_name": "ФОП Іваненко І.І.",
"merchant_id": "Mexxxxxxxxxx"
}
QR-каси
Каси створюються автоматично через синхронізацію терміналів. Через API доступний лише перегляд.
GET/api/v1/cash-registers/Список кас
GET/api/v1/cash-registers/{id}/Деталі каси
Приклад відповіді
{
"id": 12,
"terminal": 3,
"terminal_name":"Основна каса",
"qr_id": "QRxxxxxxxxxx",
"short_qr_id": "QRxx",
"name": "Стійка №1",
"is_active": true,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-05T12:30:00Z"
}
Фільтри (GET /cash-registers/)
| Параметр | Тип | Опис |
|---|---|---|
terminal | integer | ID терміналу |
is_active | boolean | true / false |
ordering | string | name, created_at |
Інвойси
Перегляд —
can_view_invoices. Створення — can_create_invoices. Скасування — can_cancel_invoices.
GET/api/v1/invoices/Список інвойсів (з фільтрацією)
POST/api/v1/invoices/Створити інвойс
GET/api/v1/invoices/{id}/Деталі інвойсу
POST/api/v1/invoices/{id}/cancel/Скасувати інвойс
POST/api/v1/invoices/{id}/refresh/Оновити статус з Monobank
Створення інвойсу — тіло запиту
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
terminal | integer | так | ID терміналу |
amount | integer | — | Сума в копійках (наприклад 15000 = 150.00 ₴). Обов'язкове, якщо не передані items |
cash_register | integer | — | ID QR-каси (якщо прив'язати до каси) |
destination | string | — | Призначення платежу (відображається платнику) |
reference | string | — | Номер замовлення |
comment | string | — | Внутрішній коментар |
validity | integer | — | Час дії інвойсу в секундах (за замовч. 86400 = 24 год) |
items | array | — | Позиції (см. нижче) |
Структура позиції (items[])
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
name | string | так | Назва товару / послуги |
price | integer | так | Ціна за одиницю в копійках |
quantity | decimal | — | Кількість (за замовч. 1) |
unit | string | — | Одиниця виміру (наприклад шт, кг) |
product | integer | — | ID товару з каталогу |
discount_pct | decimal | — | Знижка у відсотках |
Приклад — інвойс з товарами
{
"terminal": 3,
"destination":"Оплата замовлення №123",
"reference": "ORDER-123",
"validity": 86400,
"items": [
{ "name": "Кава Латте", "price": 8500, "quantity": 2, "unit": "шт" },
{ "name": "Тістечко", "price": 4500, "quantity": 1, "unit": "шт", "discount_pct": 10 }
]
}
Приклад — інвойс без позицій (фіксована сума)
{
"terminal": 3,
"amount": 25000,
"destination": "Оплата послуг"
}
Відповідь — об'єкт інвойсу
{
"id": 42,
"number": 17,
"number_display": "00017",
"invoice_id": "2304xxxxxxxx",
"status": "created",
"status_display": "Створено",
"terminal": 3,
"terminal_name": "Основна каса",
"cash_register": null,
"amount": 25000,
"ccy": 980,
"final_amount": null,
"reference": "ORDER-123",
"destination": "Оплата послуг",
"comment": "",
"page_url": "https://pay.mbnk.biz/230400xxxx",
"failure_reason": "",
"masked_pan": "",
"approval_code": "",
"rrn": "",
"payment_system": "",
"fee": 0,
"created_locally":true,
"webhook_received":false,
"created_date": "2026-03-05T10:00:00Z",
"modified_date": null,
"paid_date": null,
"is_cancellable": true,
"items": []
}
Статуси інвойсу
| Значення | Опис |
|---|---|
created | Створено — очікує оплати |
processing | В обробці |
success | Оплачено |
failure | Помилка оплати |
reversed | Повернуто |
expired | Скасований / прострочений |
Фільтри та пошук (GET /invoices/)
| Параметр | Тип | Опис |
|---|---|---|
status | string | Фільтр по статусу |
terminal | integer | ID терміналу |
cash_register | integer | ID каси |
created_locally | boolean | Створено через MMPay |
created_from | datetime | Дата створення від |
created_to | datetime | Дата створення до |
paid_from | datetime | Дата оплати від |
paid_to | datetime | Дата оплати до |
amount_min | integer | Сума від (копійки) |
amount_max | integer | Сума до (копійки) |
search | string | Пошук по ID, референсу, призначенню, масці картки, RRN |
ordering | string | number, -created_date, amount, -paid_date тощо |
page | integer | Номер сторінки |
page_size | integer | Розмір сторінки (макс. 200) |
Відповідь списку включає поле
totals із загальними сумами по всіх відфільтрованих записах (до пагінації): total_amount, success_amount (в копійках).
Категорії товарів
GET/api/v1/catalog/categories/Список категорій
POST/api/v1/catalog/categories/Створити категорію
GET/api/v1/catalog/categories/{id}/Деталі
PATCH/api/v1/catalog/categories/{id}/Оновити
DELETE/api/v1/catalog/categories/{id}/Видалити
Тіло запиту (POST/PATCH)
{
"name": "Напої"
}
Відповідь
{
"id": 5,
"name": "Напої",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-05T12:30:00Z"
}
Одиниці виміру
GET/api/v1/catalog/units/Список одиниць
POST/api/v1/catalog/units/Створити
GET/api/v1/catalog/units/{id}/Деталі
PATCH/api/v1/catalog/units/{id}/Оновити
DELETE/api/v1/catalog/units/{id}/Видалити
Тіло запиту (POST/PATCH)
{
"name": "Кілограм",
"short_name": "кг"
}
Відповідь
{
"id": 3,
"name": "Кілограм",
"short_name": "кг",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-05T12:30:00Z"
}
Товари
GET/api/v1/catalog/products/Список товарів
POST/api/v1/catalog/products/Додати товар
GET/api/v1/catalog/products/{id}/Деталі товару
PATCH/api/v1/catalog/products/{id}/Оновити
DELETE/api/v1/catalog/products/{id}/Видалити
Поля (POST/PATCH)
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
name | string | так | Назва товару |
price | integer | так | Ціна в копійках |
name_for_docs | string | — | Назва для передачі в Monobank (якщо потрібна інша) |
article | string | — | Артикул |
external_code | string | — | Зовнішній код |
category | integer | — | ID категорії |
unit | integer | — | ID одиниці виміру |
is_archived | boolean | — | Архівувати товар |
Приклад відповіді
{
"id": 17,
"name": "Кава Латте",
"name_for_docs":"",
"code": 1,
"article": "LATTE-200",
"external_code":"",
"category": 5,
"category_name":"Напої",
"unit": 3,
"unit_name": "Кілограм",
"price": 8500,
"is_archived": false,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-05T12:30:00Z"
}
Фільтри (GET /catalog/products/)
| Параметр | Тип | Опис |
|---|---|---|
category | integer | ID категорії |
unit | integer | ID одиниці виміру |
is_archived | boolean | true / false |
search | string | Пошук по назві, артикулу, зовнішньому коду |
ordering | string | name, -price, code, -created_at |
Співробітники
Доступно лише для власника акаунту. Лише перегляд — керування співробітниками через веб-інтерфейс.
GET/api/v1/employees/Список співробітників
GET/api/v1/employees/{id}/Деталі співробітника
Приклад відповіді
{
"id": 8,
"username": "kasir_ivan",
"email": "ivan@example.com",
"full_name": "Іван Петренко",
"position": "Касир",
"can_view_invoices": true,
"can_create_invoices": true,
"can_cancel_invoices": false,
"can_manage_terminals": false,
"can_manage_employees": false,
"is_active": true,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-05T12:30:00Z"
}
Статистика
GET/api/v1/stats/Зведена статистика по інвойсах
Параметри (необов'язкові)
| Параметр | Тип | Опис |
|---|---|---|
created_from | datetime | Фільтр — дата створення від |
created_to | datetime | Фільтр — дата створення до |
Приклад відповіді
{
"total_count": 158,
"success_count": 94,
"created_count": 12,
"expired_count": 38,
"failure_count": 14,
"total_amount": 285000,
"success_amount": 195000,
"unpaid_amount": 90000
}
Пагінація та коди відповідей
Структура пагінованої відповіді
{
"count": 158,
"next": "https://mmpay.com.ua/api/v1/invoices/?page=2",
"previous": null,
"results": [ ... ]
}
За замовчуванням
page_size = 25. Максимум — 200. Для каталогу: за замовчуванням 100, макс. 500.
HTTP-коди відповідей
| Код | Значення |
|---|---|
200 | OK — запит успішний |
201 | Created — об'єкт створено |
400 | Bad Request — помилка валідації даних |
401 | Unauthorized — не передано або невалідний токен |
403 | Forbidden — недостатньо дозволів |
404 | Not Found — об'єкт не знайдено |
429 | Too Many Requests — ліміт запитів (60/хв анонім, 600/хв авторизовані) |
502 | Bad Gateway — помилка Monobank API |
Структура помилки (400 / 403 / 404 / 429 / 502)
>Усі помилки повертаються у єдиному форматі з полем detail. Помилки валідації (400) додатково містять errors з деталями по полях.
Помилка валідації (400) — з помилками по полях
{
"detail": "Помилка валідації.",
"errors": {
"terminal": ["Це поле обов'язкове."],
"items": [
{ "price": ["Ensure this value is greater than or equal to 0."] }
]
}
}
Загальна помилка (400 / 403 / 404 / 429)
{
"detail": "Не знайдено."
}
Помилка Monobank API (502)
{
"detail": "Невірний токен",
"err_code": "INVALID_TOKEN"
}
Обмеження запитів (Rate Limiting)
Для захисту від зловживань API використовує обмеження кількості запитів на хвилину.
Ліміти
| Тип клієнта | Ліміт | Вікно |
|---|---|---|
| Анонімний (без токена) | 60 запитів | 1 хвилина |
| Авторизований (Bearer Token) | 600 запитів | 1 хвилина |
Заголовки відповіді
Кожна відповідь містить заголовки з інформацією про ліміти:
| Заголовок | Опис |
|---|---|
X-RateLimit-Limit | Максимальна кількість запитів за вікно |
X-RateLimit-Remaining | Залишок доступних запитів |
Retry-After | Секунди до скидання ліміту (тільки при 429) |
Відповідь при перевищенні ліміту
429
Too Many Requests
{
"detail": "Request was throttled. Expected available in 23 seconds."
}
Зачекайте кількість секунд, вказаних у
Retry-After, перш ніж повторювати запит.