| Створюється
|
CREATED
|
-
|
ERP / CRM / сайт / POS
|
Реалізується в межах цього ТЗ. ! | Валідація перед фіскалізацією. |
|
-
|
allow_offline_mode
|
boolean
|
Ні
|
Чи дозволена офлайн-робота. Поле
</syntaxhighlight>
Сервіс повинен забезпечити:
"receipt_type": "sale",
Checkbox
Як адміністратор,
|
-
|
created_at
|
timestamp
|
Дата створення. "sku": "SKU-001",
"unit": "шт"
def create_x_report(self, shift_id: str) -> "XReportResponse":
|-
| Онлайн-продажі
| Через WebAPI. |-
| FiscalApiError
| API повернув помилку. finally:
</div>
=== 8.11. Відправка чека покупцю ===
платформа повинна підтримувати створення чека повернення. |-
| allow_offline_mode
| boolean
| Чи дозволений офлайн. |-
| raw_response
| jsonb
| Відповідь API. |-
| payment_type
| varchar
| CASH, CARD, ONLINE, MIXED. |-
| shift_id
| uuid
| Зміна. # Які податкові групи товарів використовуються? Задача додається в чергу. |-
| AC-12
| Повернення успішне. |-
| fiscal_url
| varchar
| Посилання на чек, якщо доступне. |-
| TimeoutError
| Перевищено час очікування. |-
| receipt_id
| uuid
| ID чека. | style="background:#bbdefb;" | Контроль
|-
| Незакриті зміни
| Каси з відкритими змінами. | Заборонити фіскалізацію. | Черга, retry, статус NEEDS_RETRY. | базовий канал для Python-сервісу. Призначення
! Поле
* службове внесення готівки;
* службове винесення готівки. # Чи потрібно зберігати HTML/PNG/TXT чека локально? |-
| AC-16
| Статус зміни змінився у Checkbox. |-
| cash_register_id
| string
| Каса / ПРРО. Worker перевіряє зміну. | Вони підсвічуються помаранчевим. |-
| unit
| varchar
| Одиниця виміру. Поле
! # Чи потрібно автоматизовано закривати зміну? |-
| customer
| object
| інформаційні дані покупця. |-
| base_url
| string
| Так
| Базова адреса API Checkbox. Очікуваний результат
def open_shift(self, payload: "OpenShiftPayload") -> "ShiftResponse":
=== 19.1. Створення чека ===
{| class="wikitable"
Метою задачі виступає як створення Python-сервісу для інтеграції з ПРРО Checkbox з метою автоматизації фіскалізації продажів, повернень, службових операцій і касових змін. '''Управлінський результат:''' керівник повинен бачити, скільки чеків створено, скільки фіскалізовано, скільки чеків очікують, скільки помилок, які каси відкриті, які зміни не закриті, скільки повернень і які операції потребують уваги. # Чи потрібна технічна підтримка локального друку чеків? Кожна операційна дія продажу, повернення, відкриття зміни, закриття зміни, службове внесення / винесення готівки та помилка фіскалізації повинні мати внутрішній ID, статус, журнал подій і можливість безпечного повтору без створення дубля. |-
| is_active
| boolean
| Активність. |-
| Особистий кабінет Checkbox
| Керування торговими точками, касами, касирами. |-
| raw_response
| jsonb
| Відповідь. Поле
|-
| id
| uuid
| ID інтеграції. | платформа створює service receipt. |-
| idempotency_key
| string
| Ключ захисту від дублювання. Призначення
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
платформа повинна:
=== 13.3. Конфігурація клієнта ===
|-
| Чернетка
| DRAFT
| Чек створено у Python-сервісі, але ще не відправлено. Поле
=== 18.11. X-звіт ===
платформа повинна підтримувати синхронізацію статусу чека з Checkbox. # Чи потрібна технічна підтримка декількох юридичних осіб? |-
| Receipt Service
| Створення чеків продажу. |-
| raw_request
| jsonb
| Запит до API. | style="background:#ef9a9a;" | Червоний
|-
| Потребує повтору
| NEEDS_RETRY
| Можна повторити відправку. |-
| style="background:#ffcc80;" | Помаранчевий
| #ffcc80
| Потрібна дія або повтор. |-
| Офлайн-відкриття
| Дозволяється тільки за окремим налаштуванням і правилами Checkbox. Тип
! |-
| x_client_name
| varchar
| Назва інтеграції. платформа не повинна дозволяти створювати повернення на суму більшу, ніж залишок доступний до повернення. |-
| Audit Logger
| Журнал API-запитів, відповідей, помилок і змін статусів. default_cash_register_id: str | None = None
Для підвищення надійності фіскалізація повинна виконуватись через чергу. |-
| created_at
| timestamp
| Дата події. * HTML;
* PNG;
* TXT;
* QR-code. | Idempotency key, receipt_uuid і дедублікація. |-
| style="background:#ef9a9a;" | Червоний
| #ef9a9a
| Помилка або критична ситуація. |-
| Deduplication Service
| Захищає від повторної фіскалізації одного продажу. |-
| provider
| varchar
| LiqPay, WayForPay, Mono, terminal тощо. |-
| License Key
| Ключ ліцензії каси, який застосовується для в запитах до API. Обов'язковість
Як керівник,
{| class="wikitable"
"email": "customer@example.com",
! |-
| style="background:#eeeeee;" | Сірий
| #eeeeee
| Неактивно або скасовано. Валідація, дедублікація, черга
== 16. Черга фіскалізації ==
fiscal_queue.enqueue(
|
| 3. SEO-опис
! Значення
я хочу бачити, чи відкрита касова зміна,
<pre>
db.commit()
CHECKBOX_TIMEOUT_SECONDS=30
CHECKBOX_ALLOW_OFFLINE_MODE=false
=== 19.2. Worker фіскалізації ===
"raw_request": command.model_dump(),
cash_register_id=receipt.cash_register_id,
sha256(external_order_id + total_amount + payment_id + cash_register_id)
! |-
| Обмеження
| Потрібна інсталяція й технічна підтримка агентів. |-
| organization_id
| string
| Так
| Внутрішній ID організації. |-
| RefundLimitError
| Сума повернення перевищує доступний залишок. |-
| external_payment_id
| Додатковий ключ від платіжної системи. |-
| idempotency_key
| Унікальний ключ запиту. |-
| payload
| jsonb
| Технічні інформаційні дані. |-
| Основні операції
| Створення чеків, повернень, службових операцій, отримання статусів, робота зі змінами. |-
| closed_at
| timestamp
| Дата закриття. # Чи потрібен dashboard у UI, чи тільки API? |-
| fiscal_number
| varchar
| Фіскальний номер. Критерій
|-
| id
| uuid
| ID позиції. Колір
{
{| class="wikitable"
|-
| Фіскалізація продажу
| Високий
| базовий бізнес-процес. |-
| AC-22
| виступає як незакриті зміни. ! SEO-опис
13. Checkbox Client
| -
|
Службове внесення / винесення
|
Середній
|
-
|
DuplicateReceiptError
|
Заблокувати офлайн-операцію та повідомити адміністратора. Дія системи
- повноцінний POS UI;
- власний ПРРО;
- інтеграційні функції ERP з усіма еквайрингами;
- складна аналітичні інструменти;
- автоматична реєстрація ПРРО в ДПС;
- повна технічна підтримка офлайн-режиму;
- повна технічна підтримка всіх нестандартних податкових сценаріїв. | Заборонити повернення. |-
|
auto_close_shift
|
boolean
|
Ні
|
автоматизовано закривати зміну за розкладом. Коментар
Приклад змінних середовища:
if receipt.status == "FISCALIZED":
Етап 5. Повернення
pass
12. технічна архітектура рішення для бізнесу
status_response = checkbox_client.get_receipt_status(response.id)
|
Зупинити інтеграцію, повідомити адміністратора. Параметр
GET /api/v1/fiscal/checkbox/receipts/{receipt_id}/text
receipt = receipt_repository.get_by_id(db, receipt_id)
data={
</syntaxhighlight>
db=db,
"total_amount": command.total_amount,
21.3. Список проблемних операцій
|
-
|
Повернення
|
Високий
|
-
|
organization_id
|
varchar
|
-
|
Refund Receipt
|
}
api_token: str
|
-
|
reason
|
string
|
-
|
cashier_id
|
string
|
Ні
|
ID касира за замовчуванням. Тип
</syntaxhighlight>
GET /api/v1/fiscal/checkbox/receipts/{receipt_id}
8. Функціональні вимоги
class CheckboxClient:
Python Fiscal Service
18.4. Створення чека повернення
21.1. Основні KPI
[[Категорія:Фіскалізація]]
! |-
| AC-7
| Чек фіскалізовано. {| class="wikitable"
* реалізувати службове внесення;
* реалізувати службове винесення;
* реалізувати права доступу до службових операцій;
* реалізувати аудит. я хочу створити чек повернення,
* реалізувати клієнт ERP API;
* реалізувати авторизацію;
* реалізувати заголовки X-Client-Name, X-Client-Version, X-License-Key;
* реалізувати open_shift;
* реалізувати close_shift;
* реалізувати create_sell_receipt;
* реалізувати create_refund_receipt;
* реалізувати create_service_receipt;
* реалізувати get_status;
* реалізувати отримання візуалізації;
* реалізувати обробку помилок. |-
| api_token_encrypted
| text
| Зашифрований токен. |-
| base_url
| varchar
| URL API. | Заборонити змішування сценаріїв для однієї каси. |}
entity_id=receipt.id,
! SEO-опис
{{DISPLAYTITLE:Технічне завдання: Інтеграція ПРРО Checkbox для Python}}
щоб він автоматизовано створив фіскальний чек у Checkbox. | Первинний чек отримує ознаку повного або часткового повернення. |-
| cashier_id
| varchar
| Касир. |-
| Невірний license key
| Каса не здатна виконувати операції. |-
| z_report_id
| varchar
| ID Z-звіту. Очікуваний результат
|-
| Чеків за день
| 1240
| style="background:#e3f2fd;" | інформаційні матеріали
|-
| Фіскалізовано
| 1218
| style="background:#c8e6c9;" | Норма
|-
| Очікують у черзі
| 12
| style="background:#fff9c4;" | Увага
|-
| Помилки фіскалізації
| 7
| style="background:#ef9a9a;" | Критично
|-
| Повернення
| 14
| style="background:#f3e5f5;" | Контроль
|-
| Службові внесення / винесення
| 6
| style="background:#bbdefb;" | Контроль
|-
| Незакриті зміни
| 2
| style="background:#ffcc80;" | Потрібна дія
|}
"provider": "liqpay",
=== 8.5. Службове внесення та винесення готівки ===
Як адміністратор каси,
from uuid import UUID, uuid4
}
{| class="wikitable"
|-
| 10:42
| Каса 1
| ORDER-123
| 570.00
| style="background:#ef9a9a;" | Помилка
| Timeout API
| Повторити
|-
| 11:05
| Каса 2
| ORDER-124
| 1200.00
| style="background:#ffcc80;" | Потребує повтору
| Тимчасова помилка
| Повторити
|-
| 12:10
| Каса 3
| SHIFT-55
| -
| style="background:#ffcc80;" | Зміна відкрита
| Не закрито Z-звіт
| Закрити зміну
|}
'''Критично критично:''' чек повернення повинен бути пов'язаний із первинним чеком.=== 24.5. Службові операції ===
|-
| id
| uuid
| Внутрішній ID чека. |-
| status
| varchar
| Статус чека. | Виконати retry. |-
| external_payment_id
| varchar
| ID оплати. |-
| receipt_type
| varchar
| sale, refund, service. |-
| Fiscal Queue
| Черга задач на фіскалізацію. Очікуваний результат
)
{| class="wikitable"
* перевірити відкриту зміну;
* перевірити незавершені чеки;
* сформувати Z-звіт;
* зберегти результат;
* змінити статус зміни на Closed;
* записати подію в журнал. |-
| Повернення
| первинний чек, сума, причина. |-
| cash_register_id
| string
| Так
| ID каси / ПРРО у локальній системі.=== Етап 2. конфігурація інтеграції ===
* реалізувати відкриття зміни;
* реалізувати закриття зміни;
* реалізувати X-звіт;
* реалізувати контроль незакритих змін. Тип
! |}
"tax_group": "NO_VAT",
"tax_group": "VAT_20",
<pre>
entity_type="receipt",
| AC-5
|
Записати помилку, дозволити повтор. |-
|
license_key_encrypted
|
text
|
Зберегти raw-відповідь, перевести в NEEDS_RETRY або ERROR. Ризик
def create_service_receipt(self, payload: "ServiceReceiptPayload") -> "ReceiptResponse":
|
-
|
Checkbox Client
|
-
|
auto_open_shift
|
boolean
|
Так
|
автоматизовано відкривати зміну перед першим чеком. SEO-опис
receipt.status = "FISCALIZATION_ERROR"
"external_order_id": command.external_order_id,
|
-
|
idempotency_key
|
string
|
}
18.3. Створення чека продажу
"payments": [
"id": str(shift.id)
|
-
|
Помилки токена
|
Токен змінено або відкликано. POST /api/v1/fiscal/checkbox/receipts
|
| AC-13
|
-
|
opened_at
|
timestamp
|
-
|
OfflineModeError
|
-
|
receipt_uuid
|
uuid
|
-
|
value
|
integer
|
Сума в копійках. Тип
|
-
|
amount
|
integer
|
class="wikitable"
POST /api/v1/fiscal/checkbox/refund-receipts
Ключі дедублікації:
Канали:
|
| operation_type
|
enum
|
Refund, сторно, коригування. | Retry, незавершені операції. |-
|
Закриття зміни
|
Критичний
|
платформа створює чек повернення. |-
|
is_active
|
boolean
|
Так
|
Ознака активності інтеграції. CHECKBOX_DEFAULT_LICENSE_KEY=********
v
|
застосовується для для конфігурація. Каса
shift = shift_service.ensure_open_shift(
shift = shift_repository.create(
|
Де застосовується для
18.2. Перевірка підключення
|
| id
|
uuid
|
ID події. Ключ
"payment_id": "PAY-123456"
|
SEO-опис
|
-
|
LicenseKeyError
|
class="wikitable"
- реалізувати створення чеків;
- реалізувати валідацію;
- реалізувати дедублікацію;
- реалізувати чергу;
- реалізувати worker фіскалізації. | інтеграційні функції ERP зберігається в системі. | У БД зберігається fiscal_number. Критерій
|
-
|
payments
|
array
|
-
|
old_status
|
varchar
|
Попередній статус.== 18. API Python-сервісу ==
"sku": "DELIVERY",
13.2. Основні методи
"type": "CARD",
|
-
|
Закриття зміни
|
Z-звіт, час, результат. Очікуваний результат
20. Обробка помилок
"status": receipt.status,
pass
=== 7.6. Контроль керівника ===
== 23. Логування та аудит ==
! Статус
=== 24.2. Чеки ===
=== Етап 7. Зміни та звіти ===
<pre>
|-
| Чеків створено
| Загальна кількість чеків за період. |-
| конкурентні переваги
| Зручніше для касового вузла, retail-логіки, локальної роботи. {| class="wikitable"
* реалізувати dashboard API;
* реалізувати журнал подій;
* реалізувати фільтри;
* реалізувати експорт, якщо потрібно. Фіскальний результат
=== 8.10. Отримання візуалізації чека ===
POST /api/v1/fiscal/checkbox/receipts
|
| 6. |-
| AC-9
| API повертає тимчасову помилку. |-
| cashier_id
| string
| Касир. Очікуваний результат
default_license_key: str | None = None
"status": "CREATED",
GET /api/v1/fiscal/checkbox/receipts/{receipt_id}/qrcode
cash_register = cash_register_repository.get_by_id(db, cash_register_id)
щоб контролювати фіскалізацію, помилки, повернення і незакриті зміни. |}
{| class="wikitable"
receipt.status = "SENDING"
=== 16.2. Пріоритети задач ===
ERP / CRM / Website / POS
cash_register_id: UUID,
|-
| AC-17
| користувач системи створює службове внесення. |-
| Єдиний dashboard
| Керівник бачить усі чеки, каси, статуси й помилки в одному місці. Замовлення
event_type="RECEIPT_QUEUED",
<pre>
],
"name": "Доставка",
POST /api/v1/fiscal/checkbox/receipts/{receipt_id}/sync-status
я хочу передати інформацію про оплату в Python-сервіс,
CHECKBOX_DEFAULT_CASHIER_ID=cashier-001
"cashier_id": cashier_id,
<syntaxhighlight lang="python">
! |-
| raw_request
| jsonb
| Запит. GET /api/v1/fiscal/checkbox/dashboard?date_from=2026-05-01&date_to=2026-05-07
{| class="wikitable"
== 25. MVP ==
"status": "PENDING",
=== 20.1. Типи помилок ===
"customer": {
|-
| external_order_id
| базовий ключ від зовнішньої системи. | style="background:#eeeeee;" | Сірий
|-
| Очікує фіскалізації
| PENDING
| Чек у черзі на відправку. |-
| Service Receipt
| Службове внесення або винесення готівки. SEO-опис
|-
| Checkbox
| ПРРО-сервіс для фіскалізації чеків. | style="background:#ef9a9a;" | Червоний
|}
Окремо варто відзначити який інтегрує ERP / CRM / інтернет-магазин / POS-систему з ПРРО Checkbox; так само реалізовано контролю касових змін, повернень, службових операцій, статусів, помилок і відправки електронних чеків покупцям. |-
| total_amount
| integer
| Загальна сума чека в копійках. |-
| Receipt Item
| Товарна або послугова позиція в чеку. | Валідація налаштувань каси. SEO-опис
== 17. Модель даних ==
'''Критично критично:''' інтеграційні функції ERP з ПРРО не повинна втрачати чеки. |-
| default_tax_group
| string
| Ні
| Податкова група за замовчуванням. |}
== 28. Відкриті питання ==
=== 20.2. Retry-логіка ===
* створення інтеграції Checkbox;
* перевірка підключення;
* збереження token і license key;
* створення чека продажу;
* створення чека повернення;
* службове внесення / винесення готівки;
* валідація чеків;
* дедублікація;
* черга фіскалізації;
* відкриття зміни;
* закриття зміни;
* отримання статусу чека;
* отримання статусу зміни;
* збереження fiscal_number;
* журнал подій;
* retry-механізм;
* dashboard API;
* базові unit-тести;
* mock API для інтеграційних тестів. |-
| style="background:#fff9c4;" | Жовтий
| #fff9c4
| Очікування або попередження. |}
Як платформа продажів,
Логічний endpoint Python-сервісу:
{
POST /api/v1/fiscal/checkbox/receipts/{receipt_id}/sync-status
|
здатна використовуватись у локальних інтеграціях. |-
|
Невірні суми
|
-
|
Перевірка перед чеком
|
Якщо зміна вже відкрита, повторно не відкривати. Критерій
|
| Дублювання чеків
|
-
|
is_active
|
boolean
|
Dashboard, список чеків, касові зміни. {| class="wikitable"
- помилок валідації;
- неправильного токена;
- неправильного license key;
- дублювання чека;
- некоректних сум;
- неправильних податкових груп;
- повернення понад доступну суму;
- офлайн-операцій без дозволеного режиму. | style="background:#fff9c4;" | Жовтий
|
| Відкривається
|
OPENING
|
style="background:#c8e6c9;" | Зелений
|
| Закривається
|
CLOSING
|
-
|
Успішна фіскалізація
|
}
! |-
| AC-21
| виступає як помилки фіскалізації. |-
| Незакрита зміна
| Касир або платформа не закрили зміну. |-
| license_key
| secret
| Так
| License key каси. |-
| Службова операційна дія
| тип, сума, каса, касир. Поле
<syntaxhighlight lang="python">
|-
| style="background:#c8e6c9;" | Зелений
| #c8e6c9
| Успішно: чек фіскалізовано, зміна відкрита або закрита коректно. |-
| reason
| string
| Коментар або причина. |}
cashier_id: str,
v
! |-
| name
| varchar
| Назва товару або послуги. |-
| AuthError
| Невірний API token або відсутній доступ. audit_logger.log(
data={
=== 18.12. Dashboard ===
pass
"items": [
payload={
== 24. Acceptance Criteria ==
"price": 25000,
=== 17.1. fiscal_integrations ===
! SEO-опис
"fiscal_operation_type": "sale",
|-
| Підходить для
| Хмарних ERP, CRM, інтернет-магазинів, SaaS-систем. |-
| Автоматичне відкриття
| платформа відкриває зміну перед першим чеком. |-
| items
| array
| Позиції чека. | Черга, статуси API. |-
| cashier_id
| string
| Касир. Тип
def get_shift_status(self, shift_id: str) -> "ShiftStatusResponse":
* наявність external_order_id;
* наявність idempotency_key;
* відсутність уже фіскалізованого чека по цьому external_order_id;
* наявність каси;
* наявність license key;
* наявність касира;
* наявність відкритої зміни або можливість її відкрити;
* наявність хоча б однієї позиції;
* коректність кількості;
* коректність ціни;
* коректність суми рядка;
* відповідність total_amount сумі товарів і оплат;
* коректність типу оплати;
* коректність податкових груп;
* коректність email або телефону покупця, якщо чек потрібно відправити;
* коректність формату UUID для операцій, які вимагають UUID. Колір
я хочу фіксувати службове внесення або винесення готівки,
<pre>
{| class="wikitable"
! Фіскалізація через ПРРО
17.4. fiscal_receipts
|
|
5. SEO-опис
"cash_register_id": "cash-register-001",
POST /api/v1/fiscal/checkbox/integrations
Формати:
<pre>
! |-
| Відправка в API
| endpoint, час, request_id. | style="background:#eeeeee;" | Сірий
|-
| Повернення створено
| REFUNDED
| По чеку виступає як повне або часткове повернення. "phone": "+380501112233"
POST /api/v1/fiscal/checkbox/shifts/{shift_id}/close
* створити FastAPI-проєкт;
* налаштувати PostgreSQL;
* створити моделі інтеграції, кас, змін, чеків;
* налаштувати Alembic;
* реалізувати healthcheck. |-
| z_report_number
| varchar
| Номер Z-звіту. |-
| entity_id
| uuid
| ID сутності. |-
| currency
| string
| Валюта. |-
| currency
| varchar
| Валюта. SEO-опис
ERP / CRM / Website / POS
=== Етап 1. Базова структура сервісу ===
! Код
! Критерій
=== 12.1. Загальна схема ===
{| class="wikitable"
},
},
def create_fiscal_receipt(command: "CreateReceiptCommand", db: "Session") -> "FiscalReceipt":
=== Етап 6. Службові операції ===
== 27. Ризики ==
if current_shift:
|-
| original_receipt_id
| uuid
| Внутрішній ID первинного чека. Поле
! |}
POST /api/v1/fiscal/checkbox/refund-receipts
"idempotency_key": command.idempotency_key,
* timeout;
* тимчасової недоступності API;
* HTTP 429;
* HTTP 500;
* HTTP 502;
* HTTP 503;
* HTTP 504;
* мережевих помилок;
* тимчасових помилок статусу. Тип
from pydantic_settings import BaseSettings
current_shift = shift_repository.get_current_open_shift(
|-
| id
| uuid
| ID оплати. |-
| api_token
| secret
| Так
| Токен авторизації. |-
| Втрата чека
| API недоступне під час продажу. |-
| AC-4
| License key неправильний. |-
| total_amount
| integer
| Загальна сума в копійках. "external_order_id": "ORDER-2026-000123",
== Див. 30. так само ==
receipt.error_message = str(exc)
retry_backoff_seconds: int = 5
== 6. Основні сутності ==
=== Етап 3. Checkbox Client ===
! Пріоритет
=== Етап 8. Dashboard та аудит ===
! |-
| Validation Layer
| Перевіряє товари, суми, оплати, податки, касу, касира. |-
| receipt_id
| uuid
| ID чека. Тип
|
-
|
x_client_version
|
varchar
|
реліз системи інтеграції. SEO-опис
) -> "FiscalShift":
До MVP не входить:
Сценарії:
</syntaxhighlight>
|
| integration_name
|
string
|
Так
|
-
|
Блакитний
|
#bbdefb
|
-
|
Status Sync Worker
|
оновлення версій статусів чеків і змін. Статус / номер / посилання / візуалізація
event_type="RECEIPT_SENT_TO_CHECKBOX",
щоб касові операції були відображені в системі. |-
|
Основні операції
|
}
|
-
|
x_client_version
|
string
|
Так
|
-
|
fiscal_number
|
varchar
|
}
Якщо конфігурація Checkbox або інтеграції підтримують електронну відправку чека, Python-сервіс повинен передавати email або телефон покупця. db.commit()
payload={"receipt_id": str(receipt.id)},
|
-
|
AC-15
|
-
|
Помилка фіскалізації
|
код помилки, повідомлення, raw-відповідь. Як зменшити
18.6. Отримання чека
"amount": 57000,
- email;
- SMS;
- месенджер, якщо підтримується налаштуваннями;
- посилання на чек через зовнішню систему. | Python-сервіс напряму з ДПС у MVP не функціонує. |-
|
receipt_hash
|
-
|
fiscalized_at
|
timestamp
|
-
|
Офлайн-режим
|
виступає як обмеження й додаткові правила для офлайн-операцій. SEO-опис
|
Python-сервіс синхронізує локальний статус. Сценарій
11. Єдина логіка кольорів
pass
receipt.fiscal_url = status_response.fiscal_url
19.3. Відкриття зміни
Retry не застосовується для:
|
-
|
qr_code
|
text
|
-
|
AC-14
|
користувач системи закриває зміну. Час
Python-сервіс повинен приймати інформаційні дані продажу та створювати фіскальний чек. | платформа формує Z-звіт.</syntaxhighlight>
|
Статус
|
платформа показує AuthError і не виконує фіскалізацію. |-
|
Fiscal Status
|
Статус фіскалізації. ! def open_checkbox_shift(
response = checkbox_client.open_shift(payload)
3. Статус
v
! Логічний endpoint:
! |-
| Shift Service
| Відкриття, контроль і закриття змін. | style="background:#c8e6c9;" | Норма
|-
| Очікують
| Чеки в черзі. | style="background:#bbdefb;" | Блакитний
|-
| Відкрита
| OPENED
| Можна фіскалізувати чеки.</div>
! | Чек отримує статус FISCALIZED. {| class="wikitable"
* прийом замовлень, продажів або оплат із зовнішньої системи;
* створення фіскального чека продажу;
* створення чека повернення;
* створення службового внесення готівки;
* створення службового винесення готівки;
* контроль відкриття касової зміни;
* контроль закриття касової зміни;
* формування X-звіту;
* формування Z-звіту;
* отримання статусів чеків;
* отримання статусів змін;
* збереження фіскальних номерів;
* збереження посилання або візуалізації чека;
* отримання HTML / PNG / TXT / QR-візуалізації чека, якщо потрібно;
* відправку електронного чека покупцю, якщо підтримується налаштуваннями;
* журналювання всіх API-запитів;
* повторну обробку помилкових операцій;
* захист від дублювання чеків;
* передачу статусів назад в ERP / CRM / сайт / POS. | style="background:#c8e6c9;" | Зелений
|-
| Помилка
| ERROR
| Помилка відкриття або закриття зміни.== 1. Мета ==
return current_shift
! |-
| send_receipt_to_customer
| boolean
| Ні
| Відправляти чек покупцю. | Повернути існуючий чек. Логічний endpoint:
db=db,
! інформаційні дані проходять валідацію. |}
=== 18.9. Відкриття зміни ===
'''Критично критично:''' повторний запит із тим самим idempotency_key або receipt_uuid не повинен створити другий фіскальний чек.=== 24.6. Dashboard ===
}
receipt.raw_response = response.raw_payload
! | платформа попереджає перед закриттям зміни. |-
| external_order_id
| varchar
| ID замовлення. db.commit()
* додати rate limiting;
* додати alerting;
* додати retry policy;
* додати dead letter queue;
* додати моніторинг;
* додати резервне копіювання. | style="background:#fff9c4;" | Увага
|-
| Помилки
| Чеки з помилкою. |-
| integration_id
| uuid
| ID інтеграції. 2. Тип помилки
'''Технічний стек:''' Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker. |-
| status
| varchar
| Активна, неактивна, помилка. SEO-опис
],
=== 18.5. Службове внесення / винесення ===
CHECKBOX_X_CLIENT_VERSION=1.0.0
cashier_id=receipt.cashier_id,
=== 7.4. Контроль зміни ===
! |}
! |-
| fiscal_operation_type
| string
| sale. |-
| error_message
| text
| Остання помилка. |}
def get_receipt_status(self, receipt_id: str) -> "ReceiptStatusResponse":
<div style="border-left: 6px solid #2e7d32; background: #e8f5e9; padding: 12px 16px; margin: 16px 0;">
{| class="wikitable"
|
| Підходить для
|
}
16.1. Логіка черги
Мінімальні інформаційні дані:
def create_refund_receipt(self, payload: "RefundReceiptPayload") -> "ReceiptResponse":
)
db=db,
8.8. X-звіт)
)
| external_order_id
|
string
|
ID замовлення у зовнішній системі. Сума
CHECKBOX_DEFAULT_CASH_REGISTER_ID=cash-register-001
|
платформа повинна підтримувати службові касові операції:
payload = receipt_mapper.to_checkbox_sell_payload(receipt, shift)
"checkbox_receipt_id": response.id,
)
|
}
До першої версії не входить:
|
Критерій
try:
|
== 21. Dashboard керівника ==
|
Очікуваний результат
|
style="background:#e3f2fd;" | Інформаційний
|
| Фіскалізовано
|
-
|
API Event
|
-
|
X Report
|
Проміжний звіт без закриття зміни. SEO-опис
|
-
|
Cashier
|
-
|
updated_at
|
timestamp
|
style="background:#bbdefb;" | Блакитний
|
| Закрита
|
CLOSED_WITH_Z_REPORT
|
-
|
cash_register_id
|
string
|
-
|
Обмеження
|
як приклад K2 ERP або інша платформа. ! SEO-опис
8.7. Закриття зміни
платформа повинна забезпечити:
|
-
|
integration_id
|
uuid
|
ID інтеграції.=== 8.2. Створення чека продажу ===
Етап 9. Production hardening
18.10. Закриття зміни
|
}
Варіант 1. 5.1. WebAPI для eCommerce
if existing:
Python-сервіс напряму викликає Checkbox API. №
4. Передумови
|
№
|
Check-connection і сповіщення адміністратора. |}
shift.status = response.status
pass
Python Fiscal Service
15. Дедублікація
платформа повинна логувати:
|
| AC-10
|
користувач системи створює повернення. автоматичної фіскалізації чеків забезпечується через Головна ідея: розробити Python-сервіс. HTML
|
| ValidationError
|
-
|
idempotency_key
|
string
|
Ключ дедублікації. У межах цього ТЗ базовий сценарій. Checkbox API
|
style="background:#f3e5f5;" | Фіолетовий
|
"quantity": 1000,
GET /api/v1/fiscal/checkbox/receipts/{receipt_id}/html
idempotency_key=command.idempotency_key,
existing = receipt_repository.get_by_idempotency_key(
Checkbox Adapter
| Не відкрита
|
CLOSED
|
Зміна закрита або ще не відкривалась. event_type="SHIFT_OPEN_REQUESTED",
Логічні endpoint-и Python-сервісу:
|
-
|
sku
|
varchar
|
class="wikitable"
|
except TemporaryFiscalError as exc:
Python-сервіс, який функціонує з API Checkbox виступає ключовою рисою критично: Checkbox має декілька сценаріїв роботи: WebAPI для eCommerce, Checkbox Kasa Manager для retail/POS-сценаріїв, мобільний застосунок та кабінет. Поле
def get_receipt_text(self, receipt_id: str) -> str:
return
def get_receipt_html(self, receipt_id: str) -> str:
<pre>
я хочу повторити фіскалізацію після технічної помилки,
"price": 7000,
POST /api/v1/fiscal/checkbox/shifts/{shift_id}/x-report
"unit": "послуга"
</div>
Мінімальні інформаційні дані:
GET /api/v1/fiscal/checkbox/receipts/{receipt_id}/png
if status_response.is_fiscalized:
<pre>
"receipt_uuid": uuid4(),
receipt.status = "FISCALIZED"
! | Він бачить кількість чеків, помилок, повернень, службових операцій і незакритих змін. Продаж / оплата / повернення
|
|
-
|
Відкриття зміни
|
каса, касир, час. №
pass
| -
|
amount
|
integer
|
Вмикати тільки після окремого погодження. Сценарій
19. Приклад Python-логіки
{
POST /api/v1/fiscal/checkbox/shifts/open
response = checkbox_client.create_sell_receipt(payload)
POST /api/v1/fiscal/checkbox/receipts/{receipt_id}/retry
Python-сервіс підтримує централізований обліковий облік чеків, але різні торгові точки можуть використовувати різні канали. |-
| idempotency_key
|
varchar
|
-
|
конкурентні переваги
|
Пряме API, зручна автоматизація процесів, можливість працювати з чергою. # Чи потрібна технічна підтримка службового внесення / винесення готівки? Компонент
12.2. Основні компоненти Python-сервісу
|
SEO-опис
"external_payment_id": command.external_payment_id,
</div>
! |-
| AC-6
| Checkbox повертає успіх. | Draft, Cancelled, Closed. API приймає запит на створення чека. |-
| AC-2
| Адміністратор перевіряє підключення. | Довідник tax_group і валідація. # Чи потрібно відправляти чек покупцю через email/SMS? |-
| external_cash_register_id
| varchar
| ID каси у Checkbox або локальній системі. | платформа блокує операцію. |-
| price
| integer
| Ціна в копійках. |-
| Загальна БД чеків
| Усі чеки зберігаються в єдиній БД Python-сервісу. |-
| cash_register_id
| uuid
| Каса. Компонент
! |-
| Checkbox API
| REST API для інтеграції з eCommerce / ERP / CRM / POS. | Dashboard, нагадування, авто-закриття за правилом. |}
=== Етап 4. Чеки ===
<pre>
== 26. Етапи реалізації ==
{| class="wikitable"
POST /api/v1/fiscal/checkbox/integrations/{integration_id}/check-connection
|-
| id
| uuid
| Внутрішній ID каси. | style="background:#ffcc80;" | Потрібна дія
|}
db: "Session",
</div>
=== 18.1. Створення інтеграції ===
CHECKBOX_RETRY_BACKOFF_SECONDS=5
! Тип
=== 21.2. Приклад dashboard ===
payload = {
платформа повинна підтримувати отримання візуалізації чека. |-
|
current_shift_id
|
uuid
|
}
Логічний endpoint Python-сервісу:
POST /api/v1/fiscal/checkbox/shifts/open
{
CHECKBOX_BASE_URL=https://api.checkbox.ua
{| class="wikitable"
|-
| AC-1
| Адміністратор створює інтеграцію Checkbox. |-
| original_fiscal_number
| string
| Фіскальний номер первинного чека. | Чек переходить у NEEDS_RETRY. |}
entity_id=shift.id,
! | Другий чек не створюється. |
| 7. |-
| CashRegisterError
| Каса не знайдена або неактивна. | style="background:#bbdefb;" | Блакитний
|-
| Фіскалізовано
| FISCALIZED
| Чек успішно фіскалізовано. |-
| Service Receipt Service
| Службове внесення та винесення готівки.== 9. Статуси чеків ==
* реалізувати створення інтеграції;
* реалізувати зберігання токена;
* реалізувати зберігання license key;
* реалізувати check-connection;
* реалізувати права доступу. Колір
v
"quantity": 2000,
== 5. Варіанти інтеграції ==
Логічний endpoint:
=== 17.2. cash_registers ===
audit_logger.log(
task_name="fiscalize_checkbox_receipt",
receipt.status = "NEEDS_RETRY"
)
{| class="wikitable"
платформа повинна підтримувати отримання проміжного X-звіту без закриття зміни. |-
| x_client_name
| string
| Так
| Назва інтеграції для заголовка X-Client-Name. payload={"external_order_id": command.external_order_id},
* повноцінний POS-інтерфейс касира;
* власна реалізація ПРРО без Checkbox;
* самостійна реєстрація ПРРО в ДПС через Python-сервіс;
* власний компонент КЕП;
* інтеграційні функції ERP з усіма еквайрингами;
* складний UI для касира;
* заміна кабінету Checkbox;
* повна офлайн-робота без окремого погодженого сценарію. Стан
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
! |-
| Payment
| Оплата в чеку: готівка, картка, онлайн-еквайринг тощо. | платформа створює service receipt з відповідним напрямком суми. |-
| Ручне відкриття
| користувач системи або адміністратор відкриває зміну. |-
| provider
| varchar
| checkbox. №
=== 17.5. fiscal_receipt_items ===
* інтернет-магазинів;
* POS-систем;
* CRM;
* ERP;
* служб доставки;
* маркетплейсів;
* сервісів підписок;
* систем обліку продажів;
* компаній, які хочуть цифровізувати фіскалізацію оплат. SEO-опис
CHECKBOX_RETRY_COUNT=3
! |}
return receipt
Як оператор або ERP,
=== 7.2. Повернення ===
<pre>
! # Які типи оплат підтримуються? Поле
db.commit()
SEO title: Технічне завдання: Інтеграція ПРРО Checkbox для Python
SEO keywords: Python, Checkbox, ПРРО, API Checkbox, фіскалізація чеків, каса, програмний РРО, FastAPI, інтеграція, технічне завдання, K2 ERP
</noinclude>
{{SEO
Шаблон для службового SEO-опису сторінки. }}
7.5. Повторна обробкаreturn existing
8.1. конфігурація інтеграціїкритично: для інтеграції з Checkbox інтуїтивно зберігати суми в копійках, щоб уникати помилок округлення у фінансових операціях. |-
| ShiftError
|
Помилка відкриття або закриття зміни. KPI
"currency": "UAH"
<syntaxhighlight lang="python">
|
style="background:#fff9c4;" | Жовтий
|
| Відправляється
|
SENDING
|
Виконується API-запит. Тип
щоб розуміти, чи можна фіскалізувати чеки.=== Варіант 2. 5.2. Checkbox Kasa Manager === застосовують, коли потрібно для retail/POS-сценаріїв, коли касовий вузол має локальний агент. # Чи потрібна інтеграційні функції ERP з POS-терміналами? |-
|
Z Report
|
-
|
payments
|
array
|
Оплати.
|
Код
"amount": 50000,
def close_shift(self, shift_id: str) -> "ZReportResponse":
платформа повинна дозволяти створити конфігурація підключення до Checkbox. Worker викликає Checkbox API. |-
|
error_message
|
text
|
-
|
Python-сервіс
|
Інтеграційний шар між ERP / сайтом / CRM / POS та Checkbox. Поле
6. |-
|
name
|
varchar
|
Назва інтеграції. # Чи дозволяється офлайн-режим? timeout_seconds: int = 30
- зберігання токенів тільки у secret storage або в зашифрованому вигляді;
- зберігання license key тільки у secret storage або в зашифрованому вигляді;
- заборону логування токенів;
- маскування персональних даних покупців;
- обмеження доступу до чеків;
- контроль доступу до повернень;
- окремі права на закриття зміни;
- окремі права на службове винесення готівки;
- журнал усіх дій;
- HTTPS для API-запитів;
- перевірку SSL;
- обмеження повторних запитів;
- захист від дублювання чеків. №
|
pass
22. Безпека
|
}
)
|
-
|
Receipt
|
Фіскальний чек продажу. оновлення версій ERP / CRM / POS
retry_count: int = 3
7.3. Службове внесення / винесення
pass
)
функції ERP застосовується для для:
3. Джерела інтеграції
10. Статуси зміни
|
| API Layer
|
-
|
Повторна обробка
|
-
|
new_status
|
varchar
|
-
|
external_payment_id
|
varchar
|
ID оплати в платіжній системі. Показник
7. User Story
},
|
Сутність
13.1. Призначення
from datetime import datetime, timezone
18.8. Повторна фіскалізаціяdef fiscalize_checkbox_receipt(receipt_id: UUID, db: "Session") -> None:
8.4. Чек поверненняv
5. |-
| external_refund_id
|
string
|
-
|
ДПС
|
-
|
AC-19
|
Сума службової операції некоректна.== 2. Область сценарії використання ==
POST /api/v1/fiscal/checkbox/service-receipts
POST /api/v1/fiscal/checkbox/shifts/{shift_id}/x-report
pass
receipt = receipt_repository.create(
"currency": command.currency,
allow_offline_mode: bool = False
def create_sell_receipt(self, payload: "SellReceiptPayload") -> "ReceiptResponse":
pass
POST /api/v1/fiscal/checkbox/service-receipts
db=db,
Як касир або адміністратор,
v
validation_service.validate_receipt(command)
receipt.fiscalized_at = datetime.now(timezone.utc)
x_client_name: str
)
платформа повинна не допускати дублювання чеків. ERP / CRM / сайт отримує статус. Що зберігати
receipt.qr_code = status_response.qr_code
receipt.fiscal_number = status_response.fiscal_number
24.3. Повернення
Retry застосовується для:
17.3. fiscal_shifts
17.7. fiscal_events
"cash_register_id": cash_register.id,
base_url: str
|
}
pass
8.3. Приклад запиту на чек продажу
18.7. Синхронізація статусу чека
24.1. інтеграційні функції ERP
|
| Cash Register
|
платформа повертає успішний або помилковий статус. |-
|
status
|
varchar
|
-
|
Невірна податкова група
|
базовий зовнішній сервіс інтеграції. | Python-сервіс створює чек зі статусом PENDING. |-
|
Shift
|
Касова зміна. №
8.9. Отримання статусу чека
default_cashier_id: str | None = None
Checkbox
|
style="background:#ef9a9a;" | Критично
|
| Повернення
|
-
|
Синхронізація статусів
|
Середній
|
-
|
AC-11
|
-
|
created_at
|
timestamp
|
}
|
CHECKBOX_X_CLIENT_NAME=K2-ERP-Integration
},
},
|
Дія
До області задачі входить:
"cashier_id": "cashier-001",
|
Значення
- акаунт у Checkbox;
- зареєстрованого торговця;
- торгову точку;
- зареєстровану касу / ПРРО;
- касира;
- спосіб підпису чеків;
- доступ до API;
- токен авторизації;
- license key каси;
- назву інтеграції для заголовка X-Client-Name;
- версію інтеграції для заголовка X-Client-Version;
- тестове середовище або тестову касу, якщо доступно;
- перелік кас, які будуть використовуватись;
- перелік касирів;
- правила відкриття і закриття зміни;
- правила формування чеків;
- правила повернень;
- формат оплати;
- формат товарних позицій;
- формат податкових ставок;
- вимоги до відправки електронного чека покупцю. |-
| AC-3
|
-
|
items
|
array
|
-
|
event_type
|
varchar
|
Тип події. verify_ssl: bool = True
- реалізувати чек повернення;
- перевірити доступний залишок повернення;
- зв'язати повернення з первинним чеком. Тип
def get_receipt_png(self, receipt_id: str) -> bytes:
}
17.6. fiscal_payments
shift.external_shift_id = response.id
db=db,
|
}
|
-
|
external_shift_id
|
varchar
|
платформа відкриває зміну, якщо auto_open_shift = true. entity_type="receipt",
9. |-
| AC-8
|
Вони підсвічуються червоним. Коментар
|
-
|
Зміна налаштувань
|
Черга чеків, pending-операції. Тип задачі
"idempotency_key": "ORDER-2026-000123-PAY-123456",
5.3. Варіант 3. Гібридна схема24.4. Зміни
<syntaxhighlight lang="json">
except Exception as exc:
"amount": 7000,
<syntaxhighlight lang="python">
| }
я хочу бачити dashboard по касах і чеках,
щоб не втратити продаж. SEO-опис
|
SEO-опис
Checkbox Client — це Python-клас або пакет, який інкапсулює роботу з Checkbox API. # Чи потрібен QR-code у внутрішній системі? | style="background:#bbdefb;" | Блакитний
|
| Створено в Checkbox
|
CREATED_IN_CHECKBOX
|
Чек створено в Checkbox, очікується фінальний статус.
* Python API для прийому продажів;
* клієнт ERP інтеграції з Checkbox API;
* технічна підтримка фіскалізації чеків продажу;
* технічна підтримка повернень;
* технічна підтримка службового внесення та винесення готівки;
* відкриття та закриття змін;
* збереження чеків;
* збереження статусів;
* журнал помилок;
* retry-механізм;
* dashboard / API для контролю;
* інтеграційні функції ERP з внутрішньою системою. | style="background:#ffcc80;" | Помаранчевий
|
| Скасовано
|
CANCELLED
|
платформа блокує операції по касі. Тип
"total_amount": 57000,
receipt.status = "CREATED_IN_CHECKBOX"
"name": "Товар 1",
|
SEO-опис
return shift
|
-
|
Фіолетовий
|
#f3e5f5
|
Заборонити операції по касі. |-
|
Refund Service
|
-
|
quantity
|
integer
|
Кількість у мінімальних одиницях, якщо застосовується для масштабування. payload={"checkbox_shift_id": response.id},
CHECKBOX_API_TOKEN=********
платформа повинна підтримувати закриття касової зміни та формування Z-звіту.
|
| |
|
|
|
| |
|
|
|
|
|