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

Технічне завдання: інтеграція ПРРО Checkbox для Python

Матеріал з K2 ERP Wiki

pass

audit_logger.log(


Приклад hash: До MVP входить:

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

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

1. # Чи потрібна технічна підтримка декількох торгових точок? |- | entity_type | varchar | receipt, shift, integration. |- | Завантаження візуалізації чека | Низький | Не блокує фіскалізацію. |- | discount_amount | integer | Знижка в копійках. Якщо зміна не відкрита і auto_open_shift = true, worker відкриває зміну. |- | Checkbox Kasa Manager | Фронт-агент для retail/POS-сценаріїв. SEO-опис

v
receipt.error_message = str(exc)
x_client_version: str
entity_type="shift",

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

4. | Помилки фіскалізації, незакрита зміна. |}

class CheckboxSettings(BaseSettings):

}
def get_receipt_qrcode(self, receipt_id: str) -> bytes:
- Конфлікт фронт-агентів По одній касі одночасно працюють різні інтеграції. Колір

8. | style="background:#f3e5f5;" | Спеціальні операції

Службові операції - Dashboard API - cash_register_id uuid Каса. Помилка
shift.raw_response = response.raw_payload

POST /api/v1/fiscal/checkbox/shifts/{shift_id}/close ДПС

id uuid - receipt_uuid платформа блокує операцію. |- AC-18 користувач системи створює службове винесення. Критерій
def check_connection(self) -> "ConnectionStatus":
Створення чека external_order_id, сума, каса, касир. SEO-опис
entity_id=receipt.id,
cash_register_id=cash_register.id,
pass

7. |-

tax_group varchar Не відправляти чек, повернути список помилок. |- AC-20 Керівник відкриває dashboard. Для реалізації задачі необхідно отримати:
"name": "Іван Петренко",

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

Критично критично: якщо зміна відкривається через API, потрібно уникати паралельних дій через інші фронт-агенти по тій самій касі, щоб не отримати неконсистентні стани, помилкові звіти або конфлікти в роботі каси. Параметр

}
  1. Який сценарій інтеграції застосовується для: WebAPI, Checkbox Kasa Manager або гібрид? |-
Фізичні магазини style="background:#c8e6c9;" | Зелений
Помилка фіскалізації FISCALIZATION_ERROR - name varchar Назва каси. ! Поле

29. Джерела

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

платформа повинна підтримувати відкриття касової зміни. Подія

style="background:#eeeeee;" | Сірий
Створюється 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-звіту.