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

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

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

CHECKBOX_BASE_URL=https://api.checkbox.ua POST /api/v1/fiscal/checkbox/shifts/{shift_id}/x-report

receipt.raw_response = response.raw_payload
Cash Register - auto_open_shift boolean Так }
return
Записати помилку, дозволити повтор.; Очікуваний результат

18.12. Dashboard

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

if status_response.is_fiscalized:
"unit": "послуга"
; Критерій

def open_checkbox_shift(

try:
AC-5 - payments array Сума повернення.; Retry не застосовується для: - Fiscal Queue - AC-15 Валідація налаштувань каси.; автоматичної фіскалізації чеків забезпечується через Головна ідея: розробити Python-сервіс, який інтегрує ERP / CRM / інтернет-магазин / POS-систему з ПРРО Checkbox; додатково реалізовано контролю касових змін, повернень, службових операцій, статусів, помилок та відправки електронних чеків покупцям.; |} платформа повинна дозволяти створити конфігурація підключення до Checkbox.; Створюється запис receipt зі статусом PENDING.;

щоб розуміти, чи можна фіскалізувати чеки.; |-

Checkbox Kasa Manager }

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

pass

</syntaxhighlight>

"items": [

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

AC-20 Керівник відкриває dashboard.; Тип

</syntaxhighlight>

cashier_id=receipt.cashier_id,

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

AC-13 - Невірний license key - Загальна БД чеків Усі чеки зберігаються в єдиній БД Python-сервісу.; Критерій ; характеристика

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

default_cash_register_id: str | None = None
)
"idempotency_key": command.idempotency_key,
=== 7.3.; Службове внесення / винесення ===

</pre>
 "receipt_type": "sale",
Як платформа продажів, 
</div>
|-
| Фіскалізація продажу
| Високий
| ключовий бізнес-процес.; |-
| Невірна податкова група
| Товар передано з неправильним податком.; | інтеграційні функціональні можливості зберігається в системі.; |-
| Payment
| Оплата в чеку: готівка, картка, онлайн-еквайринг тощо.; |-
| price
| integer
| Ціна в копійках.; характеристика

 receipt.fiscal_url = status_response.fiscal_url
{| class="wikitable"
GET /api/v1/fiscal/checkbox/dashboard?date_from=2026-05-01&date_to=2026-05-07
<div style="border-left: 6px solid #2e7d32; background: #e8f5e9; padding: 12px 16px; margin: 16px 0;">
=== 24.3.; Повернення ===
=== 20.2.; Retry-логіка ===

!; |-
| organization_id
| string
| Так
| Внутрішній ID організації.; характеристика
 |
 | 1.; |-
| error_message
| text
| Остання помилка.; | Заборонити операції по касі.; 
!; Логічний endpoint Python-сервісу:

 payload={"checkbox_shift_id": response.id},
!; "email": "customer@example.com",

{| class="wikitable"
 },
== 15.; Дедублікація ==
 db=db,
from pydantic_settings import BaseSettings
|-
| Чернетка
| DRAFT
| Чек створено у Python-сервісі, але ще не відправлено.; |}

!;<pre>

* помилок валідації;
* неправильного токена;
* неправильного license key;
* дублювання чека;
* некоректних сум;
* неправильних податкових груп;
* повернення понад доступну суму;
* офлайн-операцій без дозволеного режиму.; характеристика
!; |-
| is_active
| boolean
| Активність.; 

 retry_count: int = 3
== 8.; Функціональні вимоги ==
== 19.; Приклад Python-логіки ==

!; |-
| base_url
| varchar
| URL API.; Статус

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

 pass
Checkbox
CHECKBOX_RETRY_COUNT=3
=== 7.1.; Фіскалізація продажу ===
|-
| ValidationError
| Некоректні інформаційні дані чека.; Поле
<pre>
 |
 | 3.; |-
| LicenseKeyError
| Невірний або відсутній license key.; # Чи потрібно зберігати HTML/PNG/TXT чека локально?; |-
| raw_request
| jsonb
| Запит.; |-
| error_message
| text
| Остання помилка.; # Чи потрібно відправляти чек покупцю через email/SMS?; |-
| Z Report
| Звіт із закриттям зміни.; | Виконати retry.; |}

 audit_logger.log(

# Який сценарій інтеграції застосовується: WebAPI, Checkbox Kasa Manager або гібрид?; !; |-
| Офлайн-режим
| є собою обмеження й додаткові правила для офлайн-операцій.; |-
| license_key
| secret
| Так
| License key каси.; Тип
=== 21.3.; Список проблемних операцій ===
 "currency": command.currency,

!; | платформа відкриває зміну, якщо auto_open_shift = true.; # Які платіжні провайдери використовуються?; |-
| AC-11
| Сума повернення більша за суму продажу.; |-
| integration_id
| uuid
| ID інтеграції.; Очікуваний результат
|-
| Чеків за день
| 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;" | Потрібна дія
|}

== 12.; технічна архітектура рішення для бізнесу ==

<pre>
=== 18.11.; X-звіт ===
{| class="wikitable"
 default_cashier_id: str | None = None
 )
GET /api/v1/fiscal/checkbox/receipts/{receipt_id}
!; Сценарій

 receipt.fiscal_number = status_response.fiscal_number
Python-сервіс напряму викликає Checkbox API.; # Чи потрібна супровід декількох торгових точок?; |-
| license_key_encrypted
| text
| Зашифрований license key.; |-
| x_client_name
| string
| Так
| Назва інтеграції для заголовка X-Client-Name.; |-
| raw_request
| jsonb
| Запит до API.; Коментар
 pass
|-
| external_order_id
| ключовий ключ від зовнішньої системи.; Колір
</pre>
|-
| Підходить для
| Фізичних магазинів, POS-систем, торгових точок.; Код
!; !; # Який SLA по фіскалізації?; Поле
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
Ключі дедублікації:
 "sku": "SKU-001",
<syntaxhighlight lang="python">
Для підвищення надійності фіскалізація повинна виконуватись через чергу.; |-
| unit
| varchar
| Одиниця виміру.; |}

=== 24.1.; інтеграційні функціональні можливості ===

CHECKBOX_RETRY_BACKOFF_SECONDS=5

3.; |-
| style="background:#f3e5f5;" | Фіолетовий
| #f3e5f5
| Повернення або спеціальна операційна дія.; Тип
6.; !; характеристика
{| class="wikitable"
{| class="wikitable"
{{DISPLAYTITLE:Технічне завдання: Інтеграція ПРРО Checkbox для Python}}
платформа повинна не допускати дублювання чеків.; | style="background:#fff9c4;" | Увага
|-
| Помилки
| Чеки з помилкою.; |}

!; |}

CHECKBOX_X_CLIENT_NAME=K2-ERP-Integration
 def get_receipt_png(self, receipt_id: str) -> bytes:
 cash_register = cash_register_repository.get_by_id(db, cash_register_id)

[[Категорія:Python]]

POST /api/v1/fiscal/checkbox/shifts/open
!; '''Управлінський результат:''' керівник повинен бачити, скільки чеків створено, скільки фіскалізовано, скільки чеків очікують, скільки помилок, які каси відкриті, які зміни не закриті, скільки повернень і які операції потребують уваги.; |}

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

{| class="wikitable"
!; | Не відправляти чек, повернути список помилок.; |-
| AC-8
| Повторний запит має той самий idempotency_key.; |-
| AC-22
| є собою незакриті зміни.; |-
| AC-14
| користувач системи закриває зміну.; |-
| AC-2
| Адміністратор перевіряє підключення.; |-
| receipt_uuid
| UUID чека, який передається в Checkbox.; # Чи потрібно автономно закривати зміну?; |-
| DuplicateReceiptError
| Чек уже створено.; "cash_register_id": "cash-register-001",
=== 8.8.; X-звіт ===
платформа повинна підтримувати отримання візуалізації чека.; |-
| ShiftError
| Помилка відкриття або закриття зміни.; |}

!; # Які податкові групи товарів використовуються?; |-
| cashier_id
| string
| Касир.; |-
| external_order_id
| varchar
| ID замовлення.; характеристика
 "customer": {

Checkbox

event_type="SHIFT_OPEN_REQUESTED",

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

; Стан ; KPI

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

"name": "Товар 1",

функціональні можливості застосовується для:

id uuid - created_at timestamp Python-сервіс синхронізує локальний статус.; |- Відкриття зміни Вони підсвічуються червоним.; | Довідник tax_group і валідація.; Очікуваний результат
<div style="border-left: 6px solid #1565c0; background: #e3f2fd; padding: 12px 16px; margin: 16px 0;">
=== 8.4.; Чек повернення ===
<pre>
=== 19.1.; Створення чека ===
!;== 17.; Модель даних ==

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

class CheckboxClient:

"unit": "шт"

1.; Очікуваний результат

allow_offline_mode: bool = False except Exception as exc:
{| class="wikitable"
!;== 26.; Етапи реалізації ==

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

 "external_order_id": command.external_order_id,

<pre>
!; | style="background:#f3e5f5;" | Спеціальні операції
|-
| Службові операції
| Кількість внесень і винесень готівки.; |-
| shift_id
| uuid
| Зміна.; | style="background:#bbdefb;" | Блакитний
|-
| Відкрита
| OPENED
| Можна фіскалізувати чеки.; # Чи потрібна супровід змішаних оплат?; |-
| items
| array
| Позиції, які повертаються.; # Чи потрібна супровід службового внесення / винесення готівки?; Worker перевіряє зміну.; |-
| cash_register_id
| uuid
| Каса.; | style="background:#ef9a9a;" | Критично
|-
| Повернення
| Кількість чеків повернення.; У межах цього ТЗ ключовий сценарій.; Колір
=== 8.7.; Закриття зміни ===
|-
| id
| uuid
| Внутрішній ID чека.;<pre>

* реалізувати замовник 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;
* реалізувати отримання візуалізації;
* реалізувати обробку помилок.; # Чи потрібна інтеграційні функціональні можливості з POS-терміналами?; Тип
=== Етап 5.; Повернення ===
== 24. Acceptance Criteria ==

9.; |}

!; |-
| api_token
| secret
| Так
| Токен авторизації.; shift.raw_response = response.raw_payload

Перед фіскалізацією платформа повинна перевірити:
=== 17.2. cash_registers ===
</div>
Сценарії:

=== 18.9.; Відкриття зміни ===
 {

 pass
 validation_service.validate_receipt(command)

</pre>
== 22.; Безпека ==

=== Етап 3.; Checkbox Client ===
 "quantity": 2000,

платформа повинна підтримувати створення чека повернення.; |-
| AC-21
| є собою помилки фіскалізації.; |-
| RefundLimitError
| Сума повернення перевищує доступний залишок.; |-
| FiscalApiError
| API повернув помилку.; Параметр

</pre>
=== 24.4.; Зміни ===
</div>

 v

Логічний endpoint:
 db.commit()
!; |-
| created_at
| timestamp
| Дата створення.; Колір

<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">

<syntaxhighlight lang="python">
!; |-
| Shift Service
| Відкриття, контроль і закриття змін.; |-
| Офлайн-відкриття
| Дозволяється тільки за окремим налаштуванням і правилами Checkbox.; |-
| Checkbox API
| REST API для інтеграції з eCommerce / ERP / CRM / POS.; | style="background:#ef9a9a;" | Червоний
|-
| Потребує повтору
| NEEDS_RETRY
| Можна повторити відправку.; |-
| customer
| object
| інформаційні дані покупця.; |}

!; характеристика
<pre>
Retry застосовується для:
=== 24.2.; Чеки ===
!;=== 12.1.; Загальна схема ===

* додати rate limiting;
* додати alerting;
* додати retry policy;
* додати dead letter queue;
* додати моніторинг;
* додати резервне копіювання.; |-
| Відправка в API
| endpoint, час, request_id.; | Check-connection і сповіщення адміністратора.; Дія
|-
| AC-10
| користувач системи створює повернення.; | платформа блокує операцію.; Сума
 if current_shift:
 receipt.qr_code = status_response.qr_code

<pre>
!; | платформа формує Z-звіт.; ERP / CRM / сайт отримує статус.; |}

 }

 pass
== 25. MVP ==
=== 18.2.; Перевірка підключення ===
 def check_connection(self) -> "ConnectionStatus":
|-
| id
| uuid
| ID події.; Статус
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
POST /api/v1/fiscal/checkbox/shifts/{shift_id}/close
=== 18.7.; Синхронізація статусу чека ===
До першої версії не входить:

!; Коментар

* акаунт у Checkbox;
* зареєстрованого торговця;
* торгову точку;
* зареєстровану касу / ПРРО;
* касира;
* спосіб підпису чеків;
* доступ до API;
* токен авторизації;
* license key каси;
* назву інтеграції для заголовка X-Client-Name;
* версію інтеграції для заголовка X-Client-Version;
* тестове середовище або тестову касу, якщо доступно;
* перелік кас, які будуть використовуватись;
* перелік касирів;
* правила відкриття і закриття зміни;
* правила формування чеків;
* правила повернень;
* формат оплати;
* формат товарних позицій;
* формат податкових ставок;
* вимоги до відправки електронного чека покупцю.; | style="background:#fff9c4;" | Жовтий
|-
| Відкривається
| OPENING
| Виконується відкриття зміни.; |-
| Refund Receipt
| Чек повернення.;=== Етап 2.; конфігурація інтеграції ===
|-
| Ручне відкриття
| користувач системи або адміністратор відкриває зміну.; |}

 shift = shift_repository.create(

'''Критично істотно:''' чек повернення повинен бути пов'язаний із первинним чеком.; Статус / номер / посилання / візуалізація
CHECKBOX_TIMEOUT_SECONDS=30
!; # Чи потрібна супровід декількох юридичних осіб?; # Чи потрібно автономно відкривати зміну?; |-
| payload
| jsonb
| Технічні інформаційні дані.; |-
| Невірні суми
| Сума товарів не відповідає оплатам.; |-
| name
| varchar
| Назва товару або послуги.; Показник
 def open_shift(self, payload: "OpenShiftPayload") -> "ShiftResponse":
 def get_receipt_qrcode(self, receipt_id: str) -> bytes:
 def get_receipt_status(self, receipt_id: str) -> "ReceiptStatusResponse":
!; },

from datetime import datetime, timezone

 v
 },
POST /api/v1/fiscal/checkbox/integrations
=== 17.4. fiscal_receipts ===
=== Етап 9.; Production hardening ===
|-
| integration_name
| string
| Так
| Назва інтеграції.; Каса
 "external_payment_id": command.external_payment_id,
=== Етап 6.; Службові операції ===

До MVP не входить:
 "cash_register_id": cash_register.id,
__TOC__
 "payment_id": "PAY-123456"
 entity_type="receipt",
<pre>

 payload={"external_order_id": command.external_order_id},
 payload={
платформа повинна підтримувати отримання проміжного X-звіту без закриття зміни.; |-
| fiscalized_at
| timestamp
| Дата фіскалізації.; Очікуваний результат

=== 19.3.; Відкриття зміни ===
 "quantity": 1000,

!; Checkbox API
{| class="wikitable"
!; | style="background:#fff9c4;" | Жовтий
|-
| Відправляється
| SENDING
| Виконується API-запит.; | style="background:#eeeeee;" | Сірий
|-
| Очікує фіскалізації
| PENDING
| Чек у черзі на відправку.; Тип
=== 13.1.; Призначення ===
== 14.; Валідація чека ==

Метою задачі є собою створення Python-сервісу для інтеграції з ПРРО Checkbox з метою автоматизації фіскалізації продажів, повернень, службових операцій і касових змін.; |-
| auto_close_shift
| boolean
| Ні
| автономно закривати зміну за розкладом.; |-
| Фізичні магазини
| Через Checkbox Kasa Manager або інший фронт-агент.; Тип

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

 entity_id=receipt.id,

POST /api/v1/fiscal/checkbox/shifts/open
=== 18.10.; Закриття зміни ===
!; Помилка

{| class="wikitable"
 ],
 "name": "Доставка",

</div>
=== 17.7. fiscal_events ===
{| class="wikitable"

</pre>

 x_client_name: str

Мінімальні інформаційні дані:

платформа повинна підтримувати службові касові операції:

* прийом замовлень, продажів або оплат із зовнішньої системи;
* створення фіскального чека продажу;
* створення чека повернення;
* створення службового внесення готівки;
* створення службового винесення готівки;
* контроль відкриття касової зміни;
* контроль закриття касової зміни;
* формування X-звіту;
* формування Z-звіту;
* отримання статусів чеків;
* отримання статусів змін;
* збереження фіскальних номерів;
* збереження посилання або візуалізації чека;
* отримання HTML / PNG / TXT / QR-візуалізації чека, якщо потрібно;
* відправку електронного чека покупцю, якщо підтримується налаштуваннями;
* журналювання всіх API-запитів;
* повторну обробку помилкових операцій;
* захист від дублювання чеків;
* передачу статусів назад в ERP / CRM / сайт / POS.; |-
| Refund Service
| Створення чеків повернення.; |-
| z_report_number
| varchar
| Номер Z-звіту.; актуалізація ERP / CRM / POS
!; Дія системи
 response = checkbox_client.open_shift(payload)
</div>

!; |-
| x_client_version
| string
| Так
| реліз інтеграції для заголовка X-Client-Version.; |-
| status
| varchar
| Активна, неактивна, помилка.; Що зберігати
|-
| Підходить для
| Хмарних ERP, CRM, інтернет-магазинів, SaaS-систем.; Призначення
{| class="wikitable"
CHECKBOX_DEFAULT_CASH_REGISTER_ID=cash-register-001
 pass
|-
| id
| uuid
| ID оплати.; |-
| Service Receipt Service
| Службове внесення та винесення готівки.; |}

POST /api/v1/fiscal/checkbox/receipts
== 3.; Джерела інтеграції ==
 "amount": 57000,

</div>

 retry_backoff_seconds: int = 5

* службове внесення готівки;
* службове винесення готівки.; v
 v
|-
| Створення чека
| external_order_id, сума, каса, касир.; |-
| receipt_id
| uuid
| ID чека.;== 23.; Логування та аудит ==

</pre>
POST /api/v1/fiscal/checkbox/service-receipts

 if receipt.status == "FISCALIZED":
</pre>

'''Технічний стек:''' Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker.; | Він бачить кількість чеків, помилок, повернень, службових операцій і незакритих змін.; |-
| allow_offline_mode
| boolean
| Ні
| Чи дозволена офлайн-робота.; |-
| Помилка фіскалізації
| код помилки, повідомлення, raw-відповідь.; | Заборонити повернення.; |}

=== 17.6. fiscal_payments ===

!; Поле

 },
CHECKBOX_ALLOW_OFFLINE_MODE=false
<div style="border-left: 6px solid #6a1b9a; background: #f3e5f5; padding: 12px 16px; margin: 16px 0;">

 "total_amount": 57000,

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

* наявність external_order_id;
* наявність idempotency_key;
* відсутність уже фіскалізованого чека по цьому external_order_id;
* наявність каси;
* наявність license key;
* наявність касира;
* наявність відкритої зміни або можливість її відкрити;
* наявність хоча б однієї позиції;
* коректність кількості;
* коректність ціни;
* коректність суми рядка;
* відповідність total_amount сумі товарів і оплат;
* коректність типу оплати;
* коректність податкових груп;
* коректність email або телефону покупця, якщо чек потрібно відправити;
* коректність формату UUID для операцій, які вимагають UUID.; |-
| currency
| varchar
| Валюта.; |-
| Service Receipt
| Службове внесення або винесення готівки.; |-
| ДПС
| Кінцевий отримувач фіскальних даних через ПРРО.; |-
| Status Sync Worker
| актуалізація статусів чеків і змін.; |-
| X Report
| Проміжний звіт без закриття зміни.; | Черга, статуси API.; 2.; Поле

<pre>

!; характеристика
 return current_shift

платформа повинна підтримувати відкриття касової зміни.; | Зупинити інтеграцію, повідомити адміністратора.; # Чи потрібен QR-code у внутрішній системі?; Подія

* реалізувати відкриття зміни;
* реалізувати закриття зміни;
* реалізувати X-звіт;
* реалізувати контроль незакритих змін.; |-
| cash_register_id
| string
| Каса.; | style="background:#e3f2fd;" | Інформаційний
|-
| Фіскалізовано
| Кількість успішних чеків.; |-
| ERP / CRM / сайт / POS
| Джерело продажів, повернень, оплат і даних покупця.;</div>
 {

 "name": "Іван Петренко",

* перевірити відкриту зміну;
* перевірити незавершені чеки;
* сформувати Z-звіт;
* зберегти результат;
* змінити статус зміни на Closed;
* записати подію в журнал.; |-
| discount_amount
| integer
| Знижка в копійках.; 
 "amount": 50000,

{| class="wikitable"

</pre>

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

!; |-
| original_fiscal_number
| string
| Фіскальний номер первинного чека.; |-
| Повторна обробка
| хто запустив, коли, результат.; | style="background:#c8e6c9;" | Зелений
|-
| Помилка фіскалізації
| FISCALIZATION_ERROR
| Виникла помилка при фіскалізації.;</div>

!; | Dashboard, список чеків, касові зміни.; |-
| Помилки токена
| Токен змінено або відкликано.; |-
| payments
| array
| Оплати.; | style="background:#c8e6c9;" | Зелений
|-
| Закривається
| CLOSING
| Виконується закриття зміни.; |-
| style="background:#bbdefb;" | Блакитний
| #bbdefb
| операційна дія виконується або в роботі.; Валідація, дедублікація, черга
!; |-
| API Layer
| REST API для прийому продажів, повернень, службових операцій, команд зміни.; |-
| z_report_id
| varchar
| ID Z-звіту.; Обов'язковість

<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">

{| class="wikitable"
!; | style="background:#eeeeee;" | Сірий
|-
| Створюється
| CREATED
| Створено запит на відкриття зміни.;</pre>
 }
 pass
!;<pre>

* реалізувати dashboard API;
* реалізувати журнал подій;
* реалізувати фільтри;
* реалізувати експорт, якщо потрібно.; default_license_key: str | None = None

</pre>
!; |-
| amount
| integer
| Сума в копійках.; |-
| idempotency_key
| string
| Ключ дедублікації.; Ключ
}
платформа повинна підтримувати синхронізацію статусу чека з Checkbox.; Поле


 "raw_request": command.model_dump(),
 receipt.error_message = str(exc)
!; |-
| Shift
| Касова зміна.; | style="background:#bbdefb;" | Блакитний
|-
| Фіскалізовано
| FISCALIZED
| Чек успішно фіскалізовано.; '''Критично істотно:''' інтеграційні функціональні можливості з ПРРО не повинна втрачати чеки.; |-
| cashier_id
| string
| Ні
| ID касира за замовчуванням.; |}

class CheckboxSettings(BaseSettings):

21.1.; Основні KPI

receipt.status = "FISCALIZED"

{

AC-17 - external_payment_id varchar - Незакрита зміна Касир або платформа не закрили зміну.; payload = receipt_mapper.to_checkbox_sell_payload(receipt, shift)

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

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

; {

CHECKBOX_DEFAULT_CASHIER_ID=cashier-001

щоб контролювати фіскалізацію, помилки, повернення і незакриті зміни.; Тип

  • timeout;
  • тимчасової недоступності API;
  • HTTP 429;
  • HTTP 500;
  • HTTP 502;
  • HTTP 503;
  • HTTP 504;
  • мережевих помилок;
  • тимчасових помилок статусу.; | Draft, Cancelled, Closed.; |}
- Завантаження візуалізації чека Низький Не блокує фіскалізацію.; Де застосовується
"cashier_id": cashier_id,
if existing:

ERP / CRM / Website / POS POST /api/v1/fiscal/checkbox/receipts/{receipt_id}/sync-status

щоб не втратити продаж.; характеристика cashier_id: str, Логічний endpoint:

17.1. fiscal_integrations

; Час
)

8.1.; конфігурація інтеграції

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

платформа повинна логувати:

- Fiscal Status Статус фіскалізації.; HTML

POST /api/v1/fiscal/checkbox/service-receipts

db: "Session",

До MVP входить:

entity_type="shift",
- Єдиний dashboard Керівник бачить усі чеки, каси, статуси й помилки в одному місці.; характеристика
],

Checkbox Client — це Python-клас або пакет, який інкапсулює роботу з Checkbox API.; |-

Особистий кабінет Checkbox Керування торговими точками, касами, касирами.; ) ;

) -> "FiscalShift": я хочу передати інформацію про оплату в Python-сервіс,

5.; |-
Обмеження Idempotency key, receipt_uuid і дедублікація.; Компонент
10:42 Каса 1 ORDER-123 570.00 Помилка Timeout API Повторити
11:05 Каса 2 ORDER-124 1200.00 Потребує повтору Тимчасова помилка Повторити
12:10 Каса 3 SHIFT-55 - Зміна відкрита Не закрито Z-звіт Закрити зміну
db=db,
- amount integer - Перевірка перед чеком Якщо зміна вже відкрита, повторно не відкривати.;
finally:
entity_id=receipt.id,

7.5.; Повторна обробка

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

Checkbox - event_type varchar - idempotency_key varchar - reason string - Червоний #ef9a9a Помилка або критична ситуація.; характеристика
"provider": "liqpay",

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

pass
; Пріоритет shift.external_shift_id = response.id
Не відкрита CLOSED - CashRegisterError - entity_type varchar receipt, shift, integration.; Замовлення
  • зберігання токенів тільки у secret storage або в зашифрованому вигляді;
  • зберігання license key тільки у secret storage або в зашифрованому вигляді;
  • заборону логування токенів;
  • маскування персональних даних покупців;
  • обмеження доступу до чеків;
  • контроль доступу до повернень;
  • окремі права на закриття зміни;
  • окремі права на службове винесення готівки;
  • журнал усіх дій;
  • HTTPS для API-запитів;
  • перевірку SSL;
  • обмеження повторних запитів;
  • захист від дублювання чеків.; |-
external_shift_id varchar - fiscal_operation_type string sale.; характеристика
"status": "CREATED",
; інформаційні дані проходять валідацію.; Параметр

POST /api/v1/fiscal/checkbox/integrations/{integration_id}/check-connection GET /api/v1/fiscal/checkbox/receipts/{receipt_id}/html

GET /api/v1/fiscal/checkbox/receipts/{receipt_id}/qrcode
id uuid ID позиції.; Якщо зміна не відкрита і auto_open_shift = true, worker відкриває зміну.;=== 18.6.; Отримання чека ===
return existing
payload={"receipt_id": str(receipt.id)},

платформа повинна підтримувати закриття касової зміни та формування Z-звіту.; | Черга чеків, pending-операції.; істотно: для інтеграції з Checkbox комфортно зберігати суми в копійках, щоб уникати помилок округлення у фінансових операціях.; |-

name varchar Заблокувати офлайн-операцію та повідомити адміністратора.; |- Checkbox Client style="background:#bbdefb;" | Блакитний
Створено в Checkbox CREATED_IN_CHECKBOX Retry, незавершені операції.; |}
verify_ssl: bool = True
;

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

return receipt
status_response = checkbox_client.get_receipt_status(response.id)

Варіант 1.; 5.1.; WebAPI для eCommerce

CHECKBOX_API_TOKEN=********

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

"tax_group": "NO_VAT",
- Основні операції Фіскалізація чеків, робота касира, контроль зміни.; Сценарій
x_client_version: str
pass
def create_x_report(self, shift_id: str) -> "XReportResponse": Мінімальні інформаційні дані:

18.5.; Службове внесення / винесення

- total_amount integer Загальна сума в копійках.; Поле ; !; Тип
payload = {
я хочу фіксувати службове внесення або винесення готівки, 
 )

!; |-
| currency
| string
| Валюта.; | Refund, сторно, коригування.; |-
| Receipt
| Фіскальний чек продажу.; |-
| provider
| varchar
| LiqPay, WayForPay, Mono, terminal тощо.; |-
| closed_at
| timestamp
| Дата закриття.; |-
| updated_at
| timestamp
| Дата актуалізація.; |-
| Обмеження
| Потрібна інсталяція й супровід агентів.; |-
| Конфлікт фронт-агентів
| По одній касі одночасно працюють різні інтеграції.; | Чек переходить у NEEDS_RETRY.; |-
| entity_id
| uuid
| ID сутності.; Поле

* реалізувати чек повернення;
* перевірити доступний залишок повернення;
* зв'язати повернення з первинним чеком.; Поле
POST /api/v1/fiscal/checkbox/shifts/{shift_id}/x-report
ДПС
 pass
!; |-
| AC-3
| Токен неправильний.; receipt = receipt_repository.get_by_id(db, receipt_id)

* реалізувати створення інтеграції;
* реалізувати зберігання токена;
* реалізувати зберігання license key;
* реалізувати check-connection;
* реалізувати права доступу.; Worker викликає Checkbox API.; "cashier_id": "cashier-001",

* повноцінний POS-інтерфейс касира;
* власна реалізація ПРРО без Checkbox;
* самостійна реєстрація ПРРО в ДПС через Python-сервіс;
* власний компонент КЕП;
* інтеграційні функціональні можливості з усіма еквайрингами;
* складний UI для касира;
* заміна кабінету Checkbox;
* повна офлайн-робота без окремого погодженого сценарію.; |-
| allow_offline_mode
| boolean
| Чи дозволений офлайн.;== 18.; API Python-сервісу ==

* реалізувати службове внесення;
* реалізувати службове винесення;
* реалізувати права доступу до службових операцій;
* реалізувати аудит.; |-
| Успішна фіскалізація
| fiscal_number, fiscal_url, дата.; |-
| Службова операційна дія
| тип, сума, каса, касир.; Поле

 "total_amount": command.total_amount,

=== Етап 4.; Чеки ===
 def create_service_receipt(self, payload: "ServiceReceiptPayload") -> "ReceiptResponse":
def create_fiscal_receipt(command: "CreateReceiptCommand", db: "Session") -> "FiscalReceipt":


!; |-
| total_amount
| integer
| Загальна сума чека в копійках.; |-
| cash_register_id
| uuid
| Каса.;<pre>

я хочу бачити, чи відкрита касова зміна, 

'''Заборонено:''' зберігати API token, license key, ключі, паролі касирів або інші секрети у коді, Git-репозиторії, відкритих логах або frontend-змінних.; платформа не повинна дозволяти створювати повернення на суму більшу, ніж залишок доступний до повернення.; |}

from uuid import UUID, uuid4

!; | Черга, retry, статус NEEDS_RETRY.; |-
| reason
| string
| Коментар або причина.; POST /api/v1/fiscal/checkbox/receipts/{receipt_id}/retry
=== 8.6.; Відкриття зміни ===
=== 16.1.; Логіка черги ===

Приклад hash:

 data={
Python-сервіс, який функціонує з API Checkbox виступає ключовою рисою '''істотно:''' Checkbox має декілька сценаріїв роботи: WebAPI для eCommerce, Checkbox Kasa Manager для retail/POS-сценаріїв, мобільний застосунок та кабінет.; Статус

 cash_register_id=receipt.cash_register_id,
Як адміністратор каси, 
=== 7.6.; Контроль керівника ===
 receipt.fiscalized_at = datetime.now(timezone.utc)
!; |-
| Deduplication Service
| Захищає від повторної фіскалізації одного продажу.; |-
| name
| varchar
| Назва каси.; | Чек отримує статус FISCALIZED.; | платформа створює service receipt.; | style="background:#bbdefb;" | Блакитний
|-
| Закрита
| CLOSED_WITH_Z_REPORT
| Зміна закрита із Z-звітом.; характеристика
 def create_sell_receipt(self, payload: "SellReceiptPayload") -> "ReceiptResponse":
 "status": "PENDING",
!; | Вони підсвічуються помаранчевим.; |-
| x_client_version
| varchar
| реліз інтеграції.; |-
| external_payment_id
| varchar
| ID оплати в платіжній системі.; |-
| cashier_id
| string
| Касир.; |-
| is_active
| boolean
| Так
| Ознака активності інтеграції.; характеристика
!; |-
| old_status
| varchar
| Попередній статус.; | style="background:#c8e6c9;" | Норма
|-
| Очікують
| Чеки в черзі.; receipt.status = "FISCALIZATION_ERROR"

 "external_order_id": "ORDER-2026-000123",

щоб касові операції були відображені в системі.; щоб він автономно створив фіскальний чек у Checkbox.; характеристика

 "phone": "+380501112233"
!; характеристика
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
!; |-
| OfflineModeError
| Помилка офлайн-режиму або перевищення лімітів.; |-
| fiscal_number
| varchar
| Фіскальний номер ПРРО, якщо доступний.; | має змогу використовуватись у локальних інтеграціях.; |-
| AC-9
| API повертає тимчасову помилку.; |-
| переважні аспекти
| Пряме API, зручна автоматизація процесів, можливість працювати з чергою.; |-
| idempotency_key
| Унікальний ключ запиту.; |-
| Службове внесення / винесення
| Середній
| Касова технічна операційна дія.; | style="background:#ffcc80;" | Потрібна дія
|}

!; |-
| Receipt Service
| Створення чеків продажу.; # Чи дозволяється офлайн-режим?; Як зменшити
[[Категорія:Checkbox]]
!; |-
| AC-6
| Checkbox повертає успіх.; |-
| API Event
| Технічна подія інтеграції.; |-
| Python-сервіс
| Інтеграційний шар між ERP / сайтом / CRM / POS та Checkbox.; Критерій
 "price": 25000,

=== 8.10.; Отримання візуалізації чека ===

 )
<syntaxhighlight lang="python">
== 1.; Мета ==

'''Критично істотно:''' якщо зміна відкривається через API, потрібно уникати паралельних дій через інші фронт-агенти по тій самій касі, щоб не отримати неконсистентні стани, помилкові звіти або конфлікти в роботі каси.; !; |-
| created_at
| timestamp
| Дата створення.; |-
| raw_response
| jsonb
| Відповідь.; | Python-сервіс напряму з ДПС у MVP не функціонує.; |-
| Втрата чека
| API недоступне під час продажу.; |-
| Повернення
| первинний чек, сума, причина.; |-
| idempotency_key
| string
| Ключ захисту від дублювання.; |-
| Cashier
| Касир, від імені якого виконується операційна дія.; |-
| receipt_type
| varchar
| sale, refund, service.; |-
| style="background:#ffcc80;" | Помаранчевий
| #ffcc80
| Потрібна дія або повтор.; Ризик
<pre>
[[Категорія:Інтеграції]]
|-
| Дублювання чеків
| Повторний запит має змогу створити другий чек.; |-
| License Key
| Ключ ліцензії каси, який застосовується в запитах до API.; | У БД зберігається fiscal_number.; №
 |
 | 7.; характеристика
!; | застосовується для конфігурація.; |-
| receipt_id
| uuid
| ID чека.; |-
| organization_id
| varchar
| Організація.; |}

 event_type="RECEIPT_SENT_TO_CHECKBOX",

 cash_register_id=cash_register.id,

=== Варіант 2.; 5.2.; Checkbox Kasa Manager === застосовують, коли потрібно для retail/POS-сценаріїв, коли касовий вузол має локальний агент.; !; |-
| current_shift_id
| uuid
| Поточна зміна.; Критерій
shift = shift_service.ensure_open_shift(
db=db,
receipt.status = "CREATED_IN_CHECKBOX"

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

sha256(external_order_id + total_amount + payment_id + cash_register_id) POST /api/v1/fiscal/checkbox/refund-receipts

data={
; Поле
receipt.error_message = str(exc)
}
fiscal_queue.enqueue(
- cash_register_id string Каса / ПРРО.; Тип задачі

я хочу бачити dashboard по касах і чеках, Як оператор або ERP,

db.commit()

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

shift.status = response.status

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

"idempotency_key": "ORDER-2026-000123-PAY-123456",
"status": receipt.status,
платформа повертає успішний або помилковий статус.; | ключовий канал для Python-сервісу.; response = checkbox_client.create_sell_receipt(payload)
 "price": 7000,
До області задачі входить:
!; | style="background:#c8e6c9;" | Зелений
|-
| Помилка
| ERROR
| Помилка відкриття або закриття зміни.; v
!; |-
| payment_type
| varchar
| CASH, CARD, ONLINE, MIXED.; pass
Логічний endpoint:

!; | платформа блокує операцію.; |-
| send_receipt_to_customer
| boolean
| Ні
| Відправляти чек покупцю.; |-
| Закриття зміни
| Критичний
| Не можна залишати зміну незакритою.; * реалізувати створення чеків;
* реалізувати валідацію;
* реалізувати дедублікацію;
* реалізувати чергу;
* реалізувати worker фіскалізації.; |-
| style="background:#fff9c4;" | Жовтий
| #fff9c4
| Очікування або попередження.; |-
| cash_register_id
| string
| Так
| ID каси / ПРРО у локальній системі.; Checkbox Adapter
 current_shift = shift_repository.get_current_open_shift(
 }
|-
| original_receipt_id
| uuid
| Внутрішній ID первинного чека.; | платформа створює чек повернення.; | як ілюстрація K2 ERP або інша платформа.; |-
| style="background:#eeeeee;" | Сірий
| #eeeeee
| Неактивно або скасовано.; |}

 "amount": 7000,

== 30.; Див.; додатково ==
 )
 api_token: str
POST /api/v1/fiscal/checkbox/receipts
|-
| id
| uuid
| ID зміни.; # Які типи оплат підтримуються?; | платформа показує AuthError і не виконує фіскалізацію.;[[Категорія:K2 ERP]]

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

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

Мінімальні інформаційні дані:

=== Етап 7.; Зміни та звіти ===

Як касир або адміністратор, 
 },
=== 17.5. fiscal_receipt_items ===

<pre>

 )
'''Критично істотно:''' повторний запит із тим самим idempotency_key або receipt_uuid не повинен створити другий фіскальний чек.; def close_shift(self, shift_id: str) -> "ZReportResponse":

Якщо конфігурація Checkbox або інтеграції підтримують електронну відправку чека, Python-сервіс повинен передавати email або телефон покупця.; |-
| integration_id
| uuid
| ID інтеграції.; |-
| opened_at
| timestamp
| Дата відкриття.; |-
| receipt_hash
| Hash товарів, сум, оплат і замовлення.; |-
| api_token_encrypted
| text
| Зашифрований токен.; |-
| status
| varchar
| Статус чека.; |}

!; |}

== 27.; Ризики ==

 "currency": "UAH"

 audit_logger.log(
 task_name="fiscalize_checkbox_receipt",
</syntaxhighlight>
 def create_refund_receipt(self, payload: "RefundReceiptPayload") -> "ReceiptResponse":
|-
| AC-1
| Адміністратор створює інтеграцію Checkbox.; |}

=== Етап 8.; Dashboard та аудит ===

{| class="wikitable"
!; |-
| Закриття зміни
| Z-звіт, час, результат.; |-
| status
| varchar
| CREATED, OPENED, CLOSED, ERROR тощо.; |-
| Receipt Item
| Товарна або послугова позиція в чеку.; {| class="wikitable"

!; | style="background:#bbdefb;" | Контроль
|-
| Незакриті зміни
| Каси з відкритими змінами.; def get_receipt_text(self, receipt_id: str) -> str:
Python Fiscal Service
|-
| Чеків створено
| Загальна кількість чеків за період.; |-
| external_refund_id
| string
| ID повернення у зовнішній системі.; Фіскальний результат
{| class="wikitable"
- AC-16 class="wikitable"

2.; Область сфера застосування

Python-сервіс підтримує роботу централізований обліковий облік чеків, але різні торгові точки можуть використовувати різні канали.; |-

Dashboard API }
"tax_group": "VAT_20",

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

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

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

receipt.status = "SENDING"
cash_register_id: UUID,

Канали:

- is_active boolean - fiscal_number varchar Фіскальний номер.; Він повинен повернути результат уже створеної операції.; Значення
db.commit()

29.; Джерела

db.commit()

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

  • HTML;
  • PNG;
  • TXT;
  • QR-code.; Критерій

!; |-
| provider
| varchar
| checkbox.; |}

Кожна операційна дія продажу, повернення, відкриття зміни, закриття зміни, службове внесення / винесення готівки та помилка фіскалізації повинні мати внутрішній ID, статус, журнал подій і можливість безпечного повтору без створення дубля.; |-
| AC-19
| Сума службової операції некоректна.;=== 21.2.; Приклад dashboard ===

!; характеристика

[[Категорія:ПРРО]]

 db=db,
=== 18.1.; Створення інтеграції ===
== 13. Checkbox Client ==
!; Тип
Python Fiscal Service
|-
| external_order_id
| string
| ID замовлення у зовнішній системі.; | Dashboard, нагадування, авто-закриття за правилом.; Задача додається в чергу.; | style="background:#f3e5f5;" | Фіолетовий
|}

{| class="wikitable"

 audit_logger.log(
4.; | платформа створює service receipt з відповідним напрямком суми.; |-
| external_payment_id
| Додатковий ключ від платіжної системи.; |-
| Зміна налаштувань
| користувач системи, старі та нові параметри.; Результат зберігається в БД.; |-
| base_url
| string
| Так
| Базова адреса API Checkbox.; |-
| Автоматичне відкриття
| платформа відкриває зміну перед першим чеком.; характеристика

{| class="wikitable"
 pass
 return shift
!; CHECKBOX_X_CLIENT_VERSION=1.0.0

<pre>
!;=== 18.8.; Повторна фіскалізація ===

* Python API для прийому продажів;
* замовник інтеграції з Checkbox API;
* супровід фіскалізації чеків продажу;
* супровід повернень;
* супровід службового внесення та винесення готівки;
* відкриття та закриття змін;
* збереження чеків;
* збереження статусів;
* журнал помилок;
* retry-механізм;
* dashboard / API для контролю;
* інтеграційні функціональні можливості з внутрішньою системою.; | Python-сервіс створює чек зі статусом PENDING.; !; характеристика

{| class="wikitable"

 "payments": [
Як адміністратор, 
!; |-
| items
| array
| Позиції чека.; |}

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

CHECKBOX_DEFAULT_LICENSE_KEY=********

* створення інтеграції Checkbox;
* перевірка підключення;
* збереження token і license key;
* створення чека продажу;
* створення чека повернення;
* службове внесення / винесення готівки;
* валідація чеків;
* дедублікація;
* черга фіскалізації;
* відкриття зміни;
* закриття зміни;
* отримання статусу чека;
* отримання статусу зміни;
* збереження fiscal_number;
* журнал подій;
* retry-механізм;
* dashboard API;
* базові unit-тести;
* mock API для інтеграційних тестів.; |-
| idempotency_key
| string
| Ключ захисту від дублювання повернення.; !; Фіскалізація через ПРРО
 entity_type="receipt",
 v
 |
 | 5.; |-
| qr_code
| text
| QR або інформаційні дані QR, якщо доступні.; |-
| Основні операції
| Створення чеків, повернень, службових операцій, отримання статусів, робота зі змінами.; |-
| переважні аспекти
| Зручніше для касового вузла, retail-логіки, локальної роботи.; |-
| AuthError
| Невірний API token або відсутній доступ.; | Зберегти raw-відповідь, перевести в NEEDS_RETRY або ERROR.; # Чи потрібна супровід часткових повернень?; характеристика

щоб коректно відобразити повернення коштів покупцю.; # Чи потрібен dashboard у UI, чи тільки API?; | Помилки фіскалізації, незакрита зміна.; | ключовий зовнішній сервіс інтеграції.; Поле

POST /api/v1/fiscal/checkbox/refund-receipts

я хочу створити чек повернення, 
{| class="wikitable"
 entity_id=shift.id,

!; | Первинний чек отримує ознаку повного або часткового повернення.; | платформа блокує операції по касі.; |-
| Validation Layer
| Перевіряє товари, суми, оплати, податки, касу, касира.; |-
| sku
| varchar
| Артикул.; |-
| receipt_uuid
| uuid
| UUID чека, який передається в Checkbox.; Тип
!; |-
| TimeoutError
| Перевищено час очікування.; |-
| AC-4
| License key неправильний.; # Чи потрібна інтеграційні функціональні можливості з K2 ERP?; | Другий чек не створюється.; |-
| x_client_name
| varchar
| Назва інтеграції.;<pre>

!; # Чи потрібна супровід локального друку чеків?; Код
 |
 | 4.; |-
| AC-12
| Повернення успішне.; |-
| quantity
| integer
| Кількість у мінімальних одиницях, якщо застосовується масштабування.; | Вмикати тільки після окремого погодження.; характеристика

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

 "id": str(shift.id)

* email;
* SMS;
* месенджер, якщо підтримується налаштуваннями;
* посилання на чек через зовнішню систему.; | style="background:#ffcc80;" | Помаранчевий
|-
| Скасовано
| CANCELLED
| Операцію скасовано.; |-
| cashier_id
| varchar
| Касир.; Колір

 "receipt_uuid": uuid4(),
Формати:
 existing = receipt_repository.get_by_idempotency_key(
Як керівник, 
|-
| operation_type
| enum
| cash_in або cash_out.; | платформа попереджає перед закриттям зміни.; |-
| raw_response
| jsonb
| Відповідь API.; |-
| value
| integer
| Сума в копійках.; | Повернути існуючий чек.; Тип помилки
|-
| id
| uuid
| ID інтеграції.; |-
| Audit Logger
| Журнал API-запитів, відповідей, помилок і змін статусів.; Критерій
 "checkbox_receipt_id": response.id,
{{SEO
|title=Технічне завдання: Інтеграція ПРРО Checkbox для Python
|description=Технічне завдання на реалізацію Python-сервісу для інтеграції з ПРРО Checkbox: фіскалізація чеків, відкриття і закриття змін, повернення, службові операції, X/Z-звіти, статуси, помилки, API-клієнт, черги та журналювання.
|keywords=Python, Checkbox, ПРРО, API Checkbox, фіскалізація чеків, каса, програмний РРО, FastAPI, інтеграція, технічне завдання, K2 ERP
}}

 timeout_seconds: int = 30
<pre>
 receipt = receipt_repository.create(
!; |-
| AC-18
| користувач системи створює службове винесення.; | Заборонити змішування сценаріїв для однієї каси.; API приймає запит на створення чека.; |-
| external_cash_register_id
| varchar
| ID каси у Checkbox або локальній системі.; Продаж / оплата / повернення
платформа повинна забезпечити:
=== 13.2.; Основні методи ===
 |
 | 2.; Тип

!; |-
| Синхронізація статусів
| Середній
| має змогу виконуватись фоново.; | style="background:#ef9a9a;" | Червоний
|}

=== 17.3. fiscal_shifts ===

 "fiscal_operation_type": "sale",
=== 24.6. Dashboard ===
 base_url: str
платформа повинна:
=== 8.5.; Службове внесення та винесення готівки ===
|-
| style="background:#c8e6c9;" | Зелений
| #c8e6c9
| Успішно: чек фіскалізовано, зміна відкрита або закрита коректно.; | Валідація перед фіскалізацією.; |-
| fiscal_url
| varchar
| Посилання на чек, якщо доступне.; )
 pass
 "type": "CARD",
=== 8.3.; Приклад запиту на чек продажу ===
def fiscalize_checkbox_receipt(receipt_id: UUID, db: "Session") -> None:
v
- tax_group varchar style="background:#eeeeee;" | Сірий
Повернення створено REFUNDED - default_tax_group string Ні Податкова група за замовчуванням.; №

24.5.; Службові операції

ERP / CRM / Website / POS

7.; db=db,

7. User Story

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

Онлайн-продажі - Повернення Високий - new_status varchar Заборонити фіскалізацію.; №

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

except TemporaryFiscalError as exc: 8.; |-
AC-7 Реалізується в межах цього ТЗ.; Сутність ; "sku": "DELIVERY",
idempotency_key=command.idempotency_key,
def get_receipt_html(self, receipt_id: str) -> str:
event_type="RECEIPT_QUEUED",

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

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

receipt.status = "NEEDS_RETRY"

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

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

; Призначення