Перейти до вмісту

Технічне завдання: інтеграція Вчасно каса для Python

Матеріал з K2 ERP Wiki Ukraine — База знань з автоматизації та санкцій в Україні
Версія від 13:59, 7 травня 2026, створена R (обговорення | внесок) (Створена сторінка: {{DISPLAYTITLE:Технічне завдання: Інтеграція Вчасно.Каса для Python}} {{SEO |title=Технічне завдання: Інтеграція Вчасно.Каса для Python |description=Технічне завдання на реалізацію Python-сервісу для інтеграції з Вчасно.Каса: фіскалізація чеків, відкриття і закриття змін, повер...)
(різн.) ← Попередня версія | Поточна версія (різн.) | Новіша версія → (різн.)


SEO title: Технічне завдання: Інтеграція Вчасно.Каса для Python SEO description: Технічне завдання на реалізацію Python-сервісу для інтеграції з Вчасно.Каса: фіскалізація чеків, відкриття і закриття змін, повернення, X/Z-звіти, статуси, помилки, API-клієнт, черги та журналювання. SEO keywords: Python, Вчасно.Каса, ПРРО, API, фіскалізація чеків, каса, програмний РРО, FastAPI, інтеграція, технічне завдання, K2 ERP Alternative to:


Головна ідея: розробити Python-сервіс, який інтегрує ERP / CRM / інтернет-магазин / POS-систему з «Вчасно.Каса» для автоматичної фіскалізації чеків, контролю касових змін, повернень, статусів, помилок та друку або відправки електронних чеків покупцям.

Критично важливо: інтеграція з ПРРО не повинна втрачати чеки. Кожна операція продажу, повернення, відкриття зміни, закриття зміни та помилка фіскалізації повинні мати внутрішній ID, статус, журнал подій і можливість повторної обробки без створення дубля.

Важливо: у «Вчасно.Каса» можуть використовуватись різні сценарії інтеграції: хмарне API, Device Manager, інтеграція з обліковою системою, сайтом або POS. Конкретний сценарій потрібно зафіксувати в налаштуваннях інтеграції.

Технічний стек: Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker.

Управлінський результат: керівник повинен бачити, скільки чеків сформовано, скільки фіскалізовано, скільки помилок, які каси відкриті, які зміни не закриті, скільки повернень і які операції потребують уваги.

1. Мета

Метою задачі є створення Python-сервісу для інтеграції з «Вчасно.Каса» з метою автоматизації фіскалізації продажів, повернень і касових операцій.

Сервіс повинен забезпечити:

  • прийом замовлень, продажів або оплат із зовнішньої системи;
  • створення фіскального чека;
  • створення чека повернення;
  • контроль відкриття касової зміни;
  • контроль закриття касової зміни;
  • формування X-звіту;
  • формування Z-звіту;
  • отримання статусів чеків;
  • збереження фіскальних номерів;
  • збереження посилання на чек або PDF/HTML-візуалізацію, якщо доступна;
  • відправку електронного чека покупцю, якщо підтримується API або налаштуваннями сервісу;
  • журналювання всіх API-запитів;
  • повторну обробку помилкових операцій;
  • захист від дублювання чеків;
  • передачу статусів назад в ERP / CRM / сайт / POS.

2. Область застосування

Функціонал використовується для:

  • інтернет-магазинів;
  • POS-систем;
  • CRM;
  • ERP;
  • служб доставки;
  • маркетплейсів;
  • сервісів підписок;
  • систем обліку продажів;
  • компаній, які хочуть автоматизувати фіскалізацію оплат.

До області задачі входить:

  • Python API для прийому продажів;
  • клієнт інтеграції з «Вчасно.Каса»;
  • підтримка фіскалізації чеків;
  • підтримка повернень;
  • відкриття та закриття змін;
  • збереження чеків;
  • збереження статусів;
  • журнал помилок;
  • retry-механізм;
  • dashboard / API для контролю;
  • інтеграція з внутрішньою системою.

До першої версії не входить:

  • повноцінний POS-інтерфейс касира;
  • власна реалізація ПРРО без «Вчасно.Каса»;
  • самостійна реєстрація ПРРО в ДПС через Python-сервіс;
  • власний модуль КЕП;
  • інтеграція з усіма еквайрингами;
  • складний UI для касира;
  • заміна кабінету «Вчасно.Каса».

3. Джерела інтеграції

Компонент Призначення Коментар
«Вчасно.Каса» ПРРО-сервіс для фіскалізації чеків. Основний зовнішній сервіс інтеграції.
Хмарне API «Вчасно.Каса» Пряма інтеграція з кабінетом та фіскалізацією чеків. Підходить для хмарних систем.
Device Manager Локальний або інтеграційний застосунок для роботи з ПРРО, POS-пристроями та фіскалізацією. Підходить для інтеграцій з локальними системами, POS, принтерами.
Python-сервіс Інтеграційний шар між ERP / сайтом / CRM / POS та «Вчасно.Каса». Реалізується в межах цього ТЗ.
ERP / CRM / сайт / POS Джерело продажів, повернень, оплат і даних покупця. Наприклад K2 ERP або інша система.
ДПС Кінцевий отримувач фіскальних даних через ПРРО. Python-сервіс напряму з ДПС у MVP не працює.

4. Передумови

Для реалізації задачі необхідно отримати:

  • акаунт у «Вчасно.Каса»;
  • зареєстрований суб'єкт господарювання;
  • зареєстровану торгову точку;
  • зареєстрований ПРРО;
  • зареєстрованого касира;
  • активний доступ до API або Device Manager;
  • токен інтеграції;
  • тестову касу або тестовий режим, якщо доступний;
  • перелік кас, які будуть використовуватись;
  • перелік касирів;
  • правила відкриття і закриття зміни;
  • правила формування чеків;
  • правила повернень;
  • формат оплати;
  • формат товарних позицій;
  • формат податків і ставок;
  • вимоги до відправки електронного чека покупцю.

Критично важливо: до початку розробки потрібно визначити сценарій інтеграції: хмарне API або Device Manager. Від цього залежить архітектура, мережеві налаштування, обробка офлайн-ситуацій і друк чеків.

5. Варіанти інтеграції

5.1. Варіант 1. Хмарне API

Python-сервіс напряму викликає хмарне API «Вчасно.Каса».

Параметр Опис
Підходить для Хмарних ERP, CRM, інтернет-магазинів, SaaS-систем.
Переваги Немає локального застосунку, простіша інфраструктура.
Обмеження Потрібен стабільний інтернет і доступ до зовнішнього API.
Основні операції Створення чеків, повернень, отримання статусів, робота з касами.

5.2. Варіант 2. Device Manager

Python-сервіс взаємодіє з Device Manager, який виконує інтеграційні функції локально або в середовищі клієнта.

Параметр Опис
Підходить для POS-систем, локальних облікових систем, магазинів із чековими принтерами.
Переваги Можливість роботи з POS-пристроями, принтерами, локальною інфраструктурою.
Обмеження Потрібна інсталяція та підтримка Device Manager.
Основні операції Фіскалізація чеків, друк, робота з POS-пристроями, X/Z-звіти.

5.3. Варіант 3. Гібридна схема

Python-сервіс підтримує обидва способи інтеграції.

Сценарій Опис
Хмарні продажі Через хмарне API.
Фізичні магазини Через Device Manager.
Загальна БД чеків Усі чеки зберігаються в єдиній БД Python-сервісу.
Єдиний dashboard Керівник бачить усі чеки, каси, статуси й помилки в одному місці.

6. Основні сутності

Сутність Опис
Cash Register Каса / ПРРО, через яку фіскалізуються чеки.
Cashier Касир, від імені якого виконується операція.
Shift Касова зміна.
Receipt Фіскальний чек продажу.
Refund Receipt Чек повернення.
Receipt Item Товарна або послугова позиція в чеку.
Payment Оплата в чеку: готівка, картка, онлайн-еквайринг тощо.
Fiscal Status Статус фіскалізації.
X Report Проміжний звіт без закриття зміни.
Z Report Звіт із закриттям зміни.
API Event Технічна подія інтеграції.

7. User Story

7.1. Фіскалізація продажу

Як система продажів, я хочу передати інформацію про оплату в Python-сервіс, щоб він автоматично створив фіскальний чек у «Вчасно.Каса».

7.2. Повернення

Як оператор або ERP, я хочу створити чек повернення, щоб коректно відобразити повернення коштів покупцю.

7.3. Контроль зміни

Як касир або адміністратор, я хочу бачити, чи відкрита касова зміна, щоб розуміти, чи можна фіскалізувати чеки.

7.4. Повторна обробка

Як адміністратор, я хочу повторити фіскалізацію після технічної помилки, щоб не втратити продаж.

7.5. Контроль керівника

Як керівник, я хочу бачити dashboard по касах і чеках, щоб контролювати фіскалізацію, помилки, повернення і незакриті зміни.

8. Функціональні вимоги

8.1. Налаштування інтеграції

Система повинна дозволяти створити налаштування підключення до «Вчасно.Каса».

Поле Тип Обов'язковість Опис
integration_name string Так Назва інтеграції.
integration_mode enum Так cloud_api, device_manager, hybrid.
base_url string Так Базова адреса API або Device Manager.
api_token secret Так Токен інтеграції.
organization_id string Так Внутрішній ID організації.
cash_register_id string Так ID каси / ПРРО.
cashier_id string Ні ID касира за замовчуванням.
default_tax_group string Ні Податкова група за замовчуванням.
auto_open_shift boolean Так Автоматично відкривати зміну перед першим чеком.
auto_close_shift boolean Ні Автоматично закривати зміну за розкладом.
send_receipt_to_customer boolean Ні Відправляти чек покупцю.
is_active boolean Так Ознака активності інтеграції.

8.2. Створення чека продажу

Python-сервіс повинен приймати дані продажу та створювати фіскальний чек.

Логічний endpoint Python-сервісу:

POST /api/v1/fiscal/receipts

Мінімальні дані:

Поле Тип Опис
external_order_id string ID замовлення у зовнішній системі.
fiscal_operation_type string sale.
cash_register_id string Каса / ПРРО.
cashier_id string Касир.
customer object Дані покупця.
items array Позиції чека.
payments array Оплати.
total_amount decimal Загальна сума чека.
currency string Валюта.

8.3. Приклад запиту на чек

{
  "external_order_id": "ORDER-2026-000123",
  "fiscal_operation_type": "sale",
  "cash_register_id": "cash-register-001",
  "cashier_id": "cashier-001",
  "customer": {
    "name": "Іван Петренко",
    "email": "customer@example.com",
    "phone": "+380501112233"
  },
  "items": [
    {
      "name": "Товар 1",
      "sku": "SKU-001",
      "quantity": 2,
      "price": 250.00,
      "amount": 500.00,
      "tax_group": "VAT_20",
      "unit": "шт"
    },
    {
      "name": "Доставка",
      "sku": "DELIVERY",
      "quantity": 1,
      "price": 70.00,
      "amount": 70.00,
      "tax_group": "NO_VAT",
      "unit": "послуга"
    }
  ],
  "payments": [
    {
      "type": "card",
      "amount": 570.00,
      "provider": "liqpay",
      "payment_id": "PAY-123456"
    }
  ],
  "total_amount": 570.00,
  "currency": "UAH"
}

8.4. Чек повернення

Система повинна підтримувати створення чека повернення.

Логічний endpoint:

POST /api/v1/fiscal/refund-receipts

Мінімальні дані:

Поле Тип Опис
original_receipt_id uuid Внутрішній ID первинного чека.
original_fiscal_number string Фіскальний номер первинного чека.
external_refund_id string ID повернення у зовнішній системі.
items array Позиції, які повертаються.
payments array Сума повернення.
reason string Причина повернення.

Критично важливо: чек повернення повинен бути пов'язаний із первинним чеком. Система не повинна дозволяти створювати повернення на суму більшу, ніж залишок доступний до повернення.

8.5. Відкриття зміни

Система повинна підтримувати відкриття касової зміни.

Логічний endpoint:

POST /api/v1/fiscal/shifts/open

Сценарії:

Сценарій Опис
Ручне відкриття Користувач або адміністратор відкриває зміну.
Автоматичне відкриття Система відкриває зміну перед першим чеком.
Перевірка перед чеком Якщо зміна вже відкрита, повторно не відкривати.

8.6. Закриття зміни

Система повинна підтримувати закриття касової зміни та формування Z-звіту.

Логічний endpoint:

POST /api/v1/fiscal/shifts/{shift_id}/close

Система повинна:

  • перевірити відкриту зміну;
  • перевірити незавершені чеки;
  • сформувати Z-звіт;
  • зберегти результат;
  • змінити статус зміни на Closed;
  • записати подію в журнал.

8.7. X-звіт

Система повинна підтримувати отримання проміжного X-звіту без закриття зміни.

POST /api/v1/fiscal/shifts/{shift_id}/x-report

8.8. Отримання статусу чека

Система повинна підтримувати синхронізацію статусу чека з «Вчасно.Каса».

POST /api/v1/fiscal/receipts/{receipt_id}/sync-status

8.9. Відправка чека покупцю

Якщо API або налаштування «Вчасно.Каса» підтримують електронну відправку чека, Python-сервіс повинен передавати email або телефон покупця.

Канали:

  • email;
  • SMS;
  • Viber;
  • інший канал, якщо підтримується сервісом.

9. Статуси чеків

Статус Код Опис Колір
Чернетка DRAFT Чек створено у Python-сервісі, але ще не відправлено. Сірий
Очікує фіскалізації PENDING Чек у черзі на відправку. Жовтий
Відправляється SENDING Виконується API-запит. Блакитний
Фіскалізовано FISCALIZED Чек успішно фіскалізовано. Зелений
Помилка фіскалізації FISCALIZATION_ERROR Виникла помилка при фіскалізації. Червоний
Потребує повтору NEEDS_RETRY Можна повторити відправку. Помаранчевий
Скасовано CANCELLED Операцію скасовано. Сірий
Повернення створено REFUNDED По чеку є повне або часткове повернення. Фіолетовий

10. Статуси зміни

Статус Код Опис Колір
Не відкрита CLOSED Зміна закрита або ще не відкривалась. Сірий
Відкривається OPENING Виконується відкриття зміни. Блакитний
Відкрита OPEN Можна фіскалізувати чеки. Зелений
Закривається CLOSING Виконується закриття зміни. Блакитний
Закрита CLOSED_WITH_Z_REPORT Зміна закрита із Z-звітом. Зелений
Помилка ERROR Помилка відкриття або закриття зміни. Червоний

11. Єдина логіка кольорів

Колір HTML Значення Де використовується
Зелений #c8e6c9 Успішно: чек фіскалізовано, зміна відкрита або закрита коректно. Dashboard, список чеків, касові зміни.
Блакитний #bbdefb Операція виконується або в роботі. Черга, статуси API.
Жовтий #fff9c4 Очікування або попередження. Черга чеків, pending-операції.
Помаранчевий #ffcc80 Потрібна дія або повтор. Retry, незавершені операції.
Червоний #ef9a9a Помилка або критична ситуація. Помилки фіскалізації, незакрита зміна.
Фіолетовий #f3e5f5 Повернення або спеціальна операція. Refund, сторно, коригування.
Сірий #eeeeee Неактивно або скасовано. Draft, Cancelled, Closed.

12. Архітектура рішення

12.1. Загальна схема

ERP / CRM / Website / POS
        |
        | 1. Продаж / оплата / повернення
        v
Python Fiscal Service
        |
        | 2. Валідація, дедублікація, черга
        v
Vchasno Kasa Adapter
        |
        | 3. Cloud API або Device Manager
        v
Вчасно.Каса
        |
        | 4. Фіскалізація через ПРРО
        v
ДПС
        |
        | 5. Фіскальний результат
        v
Вчасно.Каса
        |
        | 6. Статус / номер / посилання на чек
        v
Python Fiscal Service
        |
        | 7. Оновлення ERP / CRM / POS
        v
ERP / CRM / Website / POS

12.2. Основні компоненти Python-сервісу

Компонент Опис
API Layer REST API для прийому продажів, повернень, команд зміни.
Validation Layer Перевіряє товари, суми, оплати, податки, касу, касира.
Deduplication Service Захищає від повторної фіскалізації одного продажу.
Fiscal Queue Черга задач на фіскалізацію.
Vchasno Kasa Client Python-клієнт для API «Вчасно.Каса» або Device Manager.
Shift Service Відкриття, контроль і закриття змін.
Receipt Service Створення чеків продажу.
Refund Service Створення чеків повернення.
Status Sync Worker Оновлення статусів чеків.
Audit Logger Журнал API-запитів, відповідей, помилок і змін статусів.
Dashboard API Дані для керівника: чеки, зміни, помилки, обороти.

13. Vchasno Kasa Client

13.1. Призначення

Vchasno Kasa Client — це Python-клас або пакет, який інкапсулює роботу з API «Вчасно.Каса» або Device Manager.

13.2. Основні методи

class VchasnoKasaClient:
    def check_connection(self) -> "ConnectionStatus":
        pass

    def open_shift(self, cash_register_id: str, cashier_id: str) -> "ShiftResponse":
        pass

    def close_shift(self, shift_id: str) -> "ZReportResponse":
        pass

    def create_x_report(self, shift_id: str) -> "XReportResponse":
        pass

    def create_receipt(self, payload: "ReceiptPayload") -> "ReceiptResponse":
        pass

    def create_refund_receipt(self, payload: "RefundReceiptPayload") -> "ReceiptResponse":
        pass

    def get_receipt_status(self, receipt_id: str) -> "ReceiptStatusResponse":
        pass

    def get_shift_status(self, shift_id: str) -> "ShiftStatusResponse":
        pass

    def get_receipt_pdf(self, receipt_id: str) -> bytes:
        pass

13.3. Конфігурація клієнта

from pydantic_settings import BaseSettings


class VchasnoKasaSettings(BaseSettings):
    integration_mode: str = "cloud_api"
    base_url: str
    api_token: str
    organization_id: str | None = None
    default_cash_register_id: str | None = None
    default_cashier_id: str | None = None
    timeout_seconds: int = 30
    retry_count: int = 3
    retry_backoff_seconds: int = 5
    verify_ssl: bool = True

Приклад змінних середовища:

VCHASNO_KASA_INTEGRATION_MODE=cloud_api
VCHASNO_KASA_BASE_URL=https://api.example.vchasno-kasa
VCHASNO_KASA_API_TOKEN=********
VCHASNO_KASA_ORGANIZATION_ID=org-001
VCHASNO_KASA_DEFAULT_CASH_REGISTER_ID=cash-register-001
VCHASNO_KASA_DEFAULT_CASHIER_ID=cashier-001
VCHASNO_KASA_TIMEOUT_SECONDS=30
VCHASNO_KASA_RETRY_COUNT=3
VCHASNO_KASA_RETRY_BACKOFF_SECONDS=5

Заборонено: зберігати API token, ключі, паролі касирів або інші секрети у коді, Git-репозиторії, відкритих логах або frontend-змінних.

14. Валідація чека

Перед фіскалізацією система повинна перевірити:

  • наявність external_order_id;
  • відсутність уже фіскалізованого чека по цьому external_order_id;
  • наявність каси;
  • наявність касира;
  • наявність відкритої зміни або можливість її відкрити;
  • наявність хоча б однієї позиції;
  • коректність кількості;
  • коректність ціни;
  • коректність суми рядка;
  • відповідність total_amount сумі товарів і оплат;
  • коректність типу оплати;
  • коректність податкових груп;
  • коректність email або телефону покупця, якщо чек потрібно відправити.

15. Дедублікація

Система повинна не допускати дублювання чеків.

Ключі дедублікації:

Ключ Призначення
external_order_id Основний ключ від зовнішньої системи.
external_payment_id Додатковий ключ від платіжної системи.
idempotency_key Унікальний ключ запиту.
receipt_hash Hash товарів, сум, оплат і замовлення.

Приклад hash:

sha256(external_order_id + total_amount + payment_id + cash_register_id)

Критично важливо: повторний запит із тим самим idempotency_key не повинен створити другий фіскальний чек. Він повинен повернути результат уже створеної операції.

16. Черга фіскалізації

Для підвищення надійності фіскалізація повинна виконуватись через чергу.

16.1. Логіка черги

1. API приймає запит на створення чека.
2. Дані проходять валідацію.
3. Створюється запис receipt зі статусом PENDING.
4. Задача додається в чергу.
5. Worker викликає API «Вчасно.Каса».
6. Результат зберігається в БД.
7. ERP / CRM / сайт отримує статус.

16.2. Пріоритети задач

Тип задачі Пріоритет Коментар
Фіскалізація продажу Високий Основний бізнес-процес.
Повернення Високий Важлива фінансова операція.
Закриття зміни Критичний Не можна залишати зміну незакритою.
Синхронізація статусів Середній Може виконуватись фоново.
Завантаження PDF Низький Не блокує фіскалізацію.

17. Модель даних

17.1. fiscal_integrations

Поле Тип Опис
id uuid ID інтеграції.
provider varchar vchasno_kasa.
integration_mode varchar cloud_api, device_manager, hybrid.
name varchar Назва інтеграції.
base_url varchar URL API.
api_token_encrypted text Зашифрований токен.
organization_id varchar Організація.
is_active boolean Активність.
created_at timestamp Дата створення.
updated_at timestamp Дата оновлення.

17.2. cash_registers

Поле Тип Опис
id uuid Внутрішній ID каси.
integration_id uuid ID інтеграції.
external_cash_register_id varchar ID каси у «Вчасно.Каса».
name varchar Назва каси.
fiscal_number varchar Фіскальний номер ПРРО, якщо доступний.
status varchar Активна, неактивна, помилка.
current_shift_id uuid Поточна зміна.
is_active boolean Чи використовується.

17.3. fiscal_shifts

Поле Тип Опис
id uuid ID зміни.
cash_register_id uuid Каса.
cashier_id varchar Касир.
external_shift_id varchar ID зміни у «Вчасно.Каса».
status varchar OPEN, CLOSED, ERROR тощо.
opened_at timestamp Дата відкриття.
closed_at timestamp Дата закриття.
z_report_number varchar Номер Z-звіту.
error_message text Остання помилка.

17.4. fiscal_receipts

Поле Тип Опис
id uuid Внутрішній ID чека.
integration_id uuid ID інтеграції.
cash_register_id uuid Каса.
shift_id uuid Зміна.
external_order_id varchar ID замовлення.
external_payment_id varchar ID оплати.
idempotency_key varchar Ключ дедублікації.
receipt_type varchar sale або refund.
status varchar Статус чека.
total_amount numeric Загальна сума.
currency varchar Валюта.
fiscal_number varchar Фіскальний номер.
fiscal_url varchar Посилання на чек, якщо доступне.
qr_code text QR або дані QR, якщо доступні.
raw_request jsonb Запит до API.
raw_response jsonb Відповідь API.
error_message text Остання помилка.
created_at timestamp Дата створення.
fiscalized_at timestamp Дата фіскалізації.

17.5. fiscal_receipt_items

Поле Тип Опис
id uuid ID позиції.
receipt_id uuid ID чека.
name varchar Назва товару або послуги.
sku varchar Артикул.
quantity numeric Кількість.
unit varchar Одиниця виміру.
price numeric Ціна.
amount numeric Сума.
tax_group varchar Податкова група.
discount_amount numeric Знижка.

17.6. fiscal_payments

Поле Тип Опис
id uuid ID оплати.
receipt_id uuid ID чека.
payment_type varchar cash, card, online, mixed.
provider varchar LiqPay, WayForPay, Mono, terminal тощо.
amount numeric Сума оплати.
external_payment_id varchar ID оплати в платіжній системі.

17.7. fiscal_events

Поле Тип Опис
id uuid ID події.
entity_type varchar receipt, shift, integration.
entity_id uuid ID сутності.
event_type varchar Тип події.
old_status varchar Попередній статус.
new_status varchar Новий статус.
payload jsonb Технічні дані.
created_at timestamp Дата події.

18. API Python-сервісу

18.1. Створення інтеграції

POST /api/v1/fiscal/integrations

18.2. Перевірка підключення

POST /api/v1/fiscal/integrations/{integration_id}/check-connection

18.3. Створення чека продажу

POST /api/v1/fiscal/receipts

18.4. Створення чека повернення

POST /api/v1/fiscal/refund-receipts

18.5. Отримання чека

GET /api/v1/fiscal/receipts/{receipt_id}

18.6. Синхронізація статусу чека

POST /api/v1/fiscal/receipts/{receipt_id}/sync-status

18.7. Повторна фіскалізація

POST /api/v1/fiscal/receipts/{receipt_id}/retry

18.8. Відкриття зміни

POST /api/v1/fiscal/shifts/open

18.9. Закриття зміни

POST /api/v1/fiscal/shifts/{shift_id}/close

18.10. X-звіт

POST /api/v1/fiscal/shifts/{shift_id}/x-report

18.11. Dashboard

GET /api/v1/fiscal/dashboard?date_from=2026-05-01&date_to=2026-05-07

19. Приклад Python-логіки

19.1. Створення чека

from uuid import UUID
from datetime import datetime, timezone


def create_fiscal_receipt(command: "CreateReceiptCommand", db: "Session") -> "FiscalReceipt":
    existing = receipt_repository.get_by_idempotency_key(
        db=db,
        idempotency_key=command.idempotency_key,
    )

    if existing:
        return existing

    validation_service.validate_receipt(command)

    receipt = receipt_repository.create(
        db=db,
        data={
            "external_order_id": command.external_order_id,
            "external_payment_id": command.external_payment_id,
            "idempotency_key": command.idempotency_key,
            "receipt_type": "sale",
            "status": "PENDING",
            "total_amount": command.total_amount,
            "currency": command.currency,
            "raw_request": command.model_dump(),
        },
    )

    fiscal_queue.enqueue(
        task_name="fiscalize_receipt",
        payload={"receipt_id": str(receipt.id)},
    )

    audit_logger.log(
        entity_type="receipt",
        entity_id=receipt.id,
        event_type="RECEIPT_QUEUED",
        payload={"external_order_id": command.external_order_id},
    )

    db.commit()
    return receipt

19.2. Worker фіскалізації

def fiscalize_receipt(receipt_id: UUID, db: "Session") -> None:
    receipt = receipt_repository.get_by_id(db, receipt_id)

    if receipt.status == "FISCALIZED":
        return

    try:
        receipt.status = "SENDING"
        db.commit()

        shift = shift_service.ensure_open_shift(
            cash_register_id=receipt.cash_register_id,
            cashier_id=receipt.cashier_id,
            db=db,
        )

        payload = receipt_mapper.to_vchasno_payload(receipt, shift)

        response = vchasno_kasa_client.create_receipt(payload)

        receipt.status = "FISCALIZED"
        receipt.fiscal_number = response.fiscal_number
        receipt.fiscal_url = response.fiscal_url
        receipt.qr_code = response.qr_code
        receipt.raw_response = response.raw_payload
        receipt.fiscalized_at = datetime.now(timezone.utc)

        audit_logger.log(
            entity_type="receipt",
            entity_id=receipt.id,
            event_type="RECEIPT_FISCALIZED",
            payload={
                "fiscal_number": response.fiscal_number,
                "fiscal_url": response.fiscal_url,
            },
        )

    except TemporaryFiscalError as exc:
        receipt.status = "NEEDS_RETRY"
        receipt.error_message = str(exc)

    except Exception as exc:
        receipt.status = "FISCALIZATION_ERROR"
        receipt.error_message = str(exc)

    finally:
        db.commit()

20. Обробка помилок

20.1. Типи помилок

Тип помилки Опис Дія системи
ValidationError Некоректні дані чека. Не відправляти чек, повернути список помилок.
AuthError Невірний API token або відсутній доступ. Зупинити інтеграцію, повідомити адміністратора.
CashRegisterError Каса не знайдена або неактивна. Заборонити фіскалізацію.
ShiftError Помилка відкриття або закриття зміни. Записати помилку, дозволити повтор.
FiscalApiError API повернув помилку. Зберегти raw-відповідь, перевести в NEEDS_RETRY або ERROR.
TimeoutError Перевищено час очікування. Виконати retry.
DuplicateReceiptError Чек уже створено. Повернути існуючий чек.
RefundLimitError Сума повернення перевищує доступний залишок. Заборонити повернення.

20.2. Retry-логіка

Retry застосовується для:

  • timeout;
  • тимчасової недоступності API;
  • HTTP 429;
  • HTTP 500;
  • HTTP 502;
  • HTTP 503;
  • HTTP 504;
  • мережевих помилок;
  • тимчасової помилки Device Manager.

Retry не застосовується для:

  • помилок валідації;
  • неправильного токена;
  • дублювання чека;
  • некоректних сум;
  • неправильних податкових груп;
  • повернення понад доступну суму.

21. Dashboard керівника

21.1. Основні KPI

KPI Опис Колір
Чеків створено Загальна кількість чеків за період. Інформаційний
Фіскалізовано Кількість успішних чеків. Норма
Очікують Чеки в черзі. Увага
Помилки Чеки з помилкою. Критично
Повернення Кількість чеків повернення. Спеціальні операції
Незакриті зміни Каси з відкритими змінами. Потрібна дія

21.2. Приклад dashboard

Показник Значення Стан
Чеків за день 1240 Інформація
Фіскалізовано 1218 Норма
Очікують у черзі 12 Увага
Помилки фіскалізації 7 Критично
Повернення 14 Контроль
Незакриті зміни 2 Потрібна дія

21.3. Список проблемних операцій

Час Каса Замовлення Сума Статус Помилка Дія
10:42 Каса 1 ORDER-123 570.00 Помилка Timeout API Повторити
11:05 Каса 2 ORDER-124 1200.00 Потребує повтору Тимчасова помилка Повторити
12:10 Каса 3 SHIFT-55 - Зміна відкрита Не закрито Z-звіт Закрити зміну

22. Безпека

Система повинна забезпечити:

  • зберігання токенів тільки у secret storage або в зашифрованому вигляді;
  • заборону логування токенів;
  • маскування персональних даних покупців;
  • обмеження доступу до чеків;
  • контроль доступу до повернень;
  • окремі права на закриття зміни;
  • журнал усіх дій;
  • HTTPS для API-запитів;
  • перевірку SSL;
  • обмеження повторних запитів;
  • захист від дублювання чеків.

23. Логування та аудит

Система повинна логувати:

Подія Що зберігати
Створення чека external_order_id, сума, каса, касир.
Відправка в API endpoint, час, request_id.
Успішна фіскалізація fiscal_number, fiscal_url, дата.
Помилка фіскалізації код помилки, повідомлення, raw-відповідь.
Повторна обробка хто запустив, коли, результат.
Повернення первинний чек, сума, причина.
Відкриття зміни каса, касир, час.
Закриття зміни Z-звіт, час, результат.
Зміна налаштувань користувач, старі та нові параметри.

24. Acceptance Criteria

24.1. Інтеграція

Критерій Очікуваний результат
AC-1 Адміністратор створює інтеграцію. Інтеграція зберігається в системі.
AC-2 Адміністратор перевіряє підключення. Система повертає успішний або помилковий статус.
AC-3 Токен неправильний. Система показує AuthError і не виконує фіскалізацію.

24.2. Чеки

Критерій Очікуваний результат
AC-4 ERP передає продаж. Python-сервіс створює чек зі статусом PENDING.
AC-5 API «Вчасно.Каса» повертає успіх. Чек отримує статус FISCALIZED.
AC-6 Чек фіскалізовано. У БД зберігається fiscal_number.
AC-7 Повторний запит має той самий idempotency_key. Другий чек не створюється.
AC-8 API повертає тимчасову помилку. Чек переходить у NEEDS_RETRY.

24.3. Повернення

Критерій Очікуваний результат
AC-9 Користувач створює повернення. Система створює чек повернення.
AC-10 Сума повернення більша за суму продажу. Система блокує операцію.
AC-11 Повернення успішне. Первинний чек отримує ознаку повного або часткового повернення.

24.4. Зміни

Критерій Очікуваний результат
AC-12 Перед першим чеком зміна закрита. Система відкриває зміну, якщо auto_open_shift = true.
AC-13 Користувач закриває зміну. Система формує Z-звіт.
AC-14 Є незавершені чеки. Система попереджає перед закриттям зміни.

24.5. Dashboard

Критерій Очікуваний результат
AC-15 Керівник відкриває dashboard. Він бачить кількість чеків, помилок, повернень і незакритих змін.
AC-16 Є помилки фіскалізації. Вони підсвічуються червоним.
AC-17 Є незакриті зміни. Вони підсвічуються помаранчевим.

25. MVP

До MVP входить:

  • створення інтеграції;
  • перевірка підключення;
  • створення чека продажу;
  • створення чека повернення;
  • валідація чеків;
  • дедублікація;
  • черга фіскалізації;
  • відкриття зміни;
  • закриття зміни;
  • отримання статусу чека;
  • збереження fiscal_number;
  • журнал подій;
  • retry-механізм;
  • dashboard API;
  • базові unit-тести;
  • mock API для інтеграційних тестів.

До MVP не входить:

  • повноцінний POS UI;
  • власний ПРРО;
  • інтеграція з усіма еквайрингами;
  • складна аналітика;
  • автоматична реєстрація ПРРО в ДПС;
  • підтримка всіх нестандартних податкових сценаріїв;
  • повна офлайн-робота без Device Manager.

26. Етапи реалізації

Етап 1. Базова структура сервісу

  • створити FastAPI-проєкт;
  • налаштувати PostgreSQL;
  • створити моделі інтеграції, кас, змін, чеків;
  • налаштувати Alembic;
  • реалізувати healthcheck.

Етап 2. Налаштування інтеграції

  • реалізувати створення інтеграції;
  • реалізувати зберігання токена;
  • реалізувати check-connection;
  • реалізувати права доступу.

Етап 3. Vchasno Kasa Client

  • реалізувати клієнт API;
  • реалізувати авторизацію;
  • реалізувати open_shift;
  • реалізувати close_shift;
  • реалізувати create_receipt;
  • реалізувати create_refund_receipt;
  • реалізувати get_status;
  • реалізувати обробку помилок.

Етап 4. Чеки

  • реалізувати створення чеків;
  • реалізувати валідацію;
  • реалізувати дедублікацію;
  • реалізувати чергу;
  • реалізувати worker фіскалізації.

Етап 5. Повернення

  • реалізувати чек повернення;
  • перевірити доступний залишок повернення;
  • зв'язати повернення з первинним чеком.

Етап 6. Зміни та звіти

  • реалізувати відкриття зміни;
  • реалізувати закриття зміни;
  • реалізувати X-звіт;
  • реалізувати контроль незакритих змін.

Етап 7. Dashboard та аудит

  • реалізувати dashboard API;
  • реалізувати журнал подій;
  • реалізувати фільтри;
  • реалізувати експорт, якщо потрібно.

Етап 8. Production hardening

  • додати rate limiting;
  • додати alerting;
  • додати retry policy;
  • додати dead letter queue;
  • додати моніторинг;
  • додати резервне копіювання.

27. Ризики

Ризик Опис Як зменшити
Дублювання чеків Повторний запит може створити другий чек. Idempotency key і дедублікація.
Втрата чека API недоступне під час продажу. Черга, retry, статус NEEDS_RETRY.
Незакрита зміна Касир або система не закрили зміну. Dashboard, нагадування, авто-закриття за правилом.
Невірні суми Сума товарів не відповідає оплатам. Валідація перед фіскалізацією.
Помилки токена Токен змінено або відкликано. Check-connection і сповіщення адміністратора.
Невірна податкова група Товар передано з неправильним податком. Довідник tax_group і валідація.
Device Manager недоступний Локальний застосунок не відповідає. Healthcheck і fallback-сценарій.

28. Відкриті питання

  1. Який сценарій інтеграції використовується: хмарне API, Device Manager або гібрид?
  2. Чи потрібна підтримка локального друку чеків?
  3. Чи потрібно відправляти чек покупцю через email/SMS/Viber?
  4. Які типи оплат підтримуються?
  5. Які платіжні провайдери використовуються?
  6. Чи потрібна інтеграція з POS-терміналами?
  7. Чи потрібно автоматично відкривати зміну?
  8. Чи потрібно автоматично закривати зміну?
  9. Чи потрібна підтримка часткових повернень?
  10. Чи потрібна підтримка змішаних оплат?
  11. Чи потрібно зберігати PDF чека локально?
  12. Який SLA по фіскалізації?
  13. Чи потрібен dashboard у UI, чи тільки API?
  14. Чи потрібна інтеграція з K2 ERP?
  15. Які податкові групи товарів використовуються?
  16. Чи потрібна підтримка декількох юридичних осіб?
  17. Чи потрібна підтримка декількох торгових точок?

29. Джерела

30. Див. також