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

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

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

Канали:

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

!; |- | Помилка фіскалізації | код помилки, повідомлення, raw-відповідь.; |}

receipt.status = "FISCALIZATION_ERROR"

Див.; 30.; додатково

!; Критерій !; |- | items | array | Позиції чека.; характеристика !; |- | payment_type | varchar | cash, card, online, mixed.; |- | style="background:#ffcc80;" | Помаранчевий | #ffcc80 | Потрібна дія або повтор.; !; Статус !; |- | CashRegisterError | Каса не знайдена або неактивна.; Тип

"amount": 570.00,

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

</syntaxhighlight> |- | Підходить для | Хмарних ERP, CRM, інтернет-магазинів, SaaS-систем.; HTML це Python-клас або пакет, який інкапсулює роботу з API «Вчасно виступає ключовою рисою Vchasno Kasa Client.Каса» або Device Manager.; Стан

existing = receipt_repository.get_by_idempotency_key(
from datetime import datetime, timezone Як керівник,

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

finally: "quantity": 2, def close_shift(self, shift_id: str) -> "ZReportResponse": Мінімальні інформаційні дані: "name": "Іван Петренко",
  • наявність external_order_id;
  • відсутність уже фіскалізованого чека по цьому external_order_id;
  • наявність каси;
  • наявність касира;
  • наявність відкритої зміни або можливість її відкрити;
  • наявність хоча б однієї позиції;
  • коректність кількості;
  • коректність ціни;
  • коректність суми рядка;
  • відповідність total_amount сумі товарів і оплат;
  • коректність типу оплати;
  • коректність податкових груп;
  • коректність email або телефону покупця, якщо чек потрібно відправити.; Окремо варто відзначити який інтегрує ERP / CRM / інтернет-магазин / POS-систему з «Вчасно.Каса» для автоматичної фіскалізації чеків, контролю касових змін, повернень, статусів, помилок і друку або відправки електронних чеків покупцям.; |-
shift_id uuid Зміна.; Поле
; !; Коментар

Критично істотно: чек повернення повинен бути пов'язаний із первинним чеком.; |-

Status Sync Worker - auto_open_shift boolean Так - original_fiscal_number string Фіскальний номер первинного чека.; Колір

VCHASNO_KASA_RETRY_COUNT=3

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

}
- Device Manager Локальний або інтеграційний застосунок для роботи з ПРРО, POS-пристроями та фіскалізацією.; * інтернет-магазинів;
  • POS-систем;
  • CRM;
  • ERP;
  • служб доставки;
  • маркетплейсів;
  • сервісів підписок;
  • систем обліку продажів;
  • компаній, які хочуть автоматизувати фіскалізацію оплат.; # Чи потрібна супровід декількох юридичних осіб?; | Довідник tax_group і валідація.; !; Код

17.4. fiscal_receipts

style="background:#bbdefb;" | Блакитний
Закрита CLOSED_WITH_Z_REPORT Зміна закрита із Z-звітом.; характеристика

</syntaxhighlight>

- total_amount decimal - old_status varchar - Fiscal Status - Фізичні магазини Через Device Manager.; актуалізація ERP / CRM / POS ; я хочу бачити dashboard по касах і чеках,

5.; №

  • реалізувати створення чеків;
  • реалізувати валідацію;
  • реалізувати дедублікацію;
  • реалізувати чергу;
  • реалізувати worker фіскалізації.; Фіскальний результат
},
"price": 250.00,
- payments array style="background:#bbdefb;" | Блакитний
Фіскалізовано FISCALIZED Чек успішно фіскалізовано.; Пріоритет

POST /api/v1/fiscal/refund-receipts

"fiscal_operation_type": "sale",
def create_x_report(self, shift_id: str) -> "XReportResponse":
pass
db.commit()
],
original_receipt_id uuid як ілюстрація K2 ERP або інша платформа.; retry_count: int = 3
"price": 70.00,

Головна ідея: розробити Python-сервіс.;== 16.; Черга фіскалізації ==

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

6.; |-

Успішна фіскалізація }
style="background:#ef9a9a;" | Червоний
Потребує повтору NEEDS_RETRY - Z Report - send_receipt_to_customer boolean Ні - sku varchar Артикул.; платформа повинна забезпечити:
def get_shift_status(self, shift_id: str) -> "ShiftStatusResponse":
- Повторна обробка - currency varchar Він бачить кількість чеків, помилок, повернень і незакритих змін.;

* реалізувати створення інтеграції;
* реалізувати зберігання токена;
* реалізувати check-connection;
* реалізувати права доступу.; №
POST /api/v1/fiscal/integrations
!; # Чи потрібна супровід локального друку чеків?; |-
| FiscalApiError
| API повернув помилку.; |-
| closed_at
| timestamp
| Дата закриття.; Час

!; Cloud API або Device Manager
<pre>
== 15.; Дедублікація ==
 |
 | 4.; |-
| ERP / CRM / сайт / POS
| Джерело продажів, повернень, оплат і даних покупця.; |}

<pre>

VCHASNO_KASA_INTEGRATION_MODE=cloud_api
!; |-
| is_active
| boolean
| Чи застосовується.; Поле

=== Етап 6.; Зміни та звіти ===
<syntaxhighlight lang="python">
GET /api/v1/fiscal/receipts/{receipt_id}
платформа повинна підтримувати закриття касової зміни та формування Z-звіту.; # Які податкові групи товарів використовуються?; | Чек отримує статус FISCALIZED.; |-
| created_at
| timestamp
| Дата події.; |-
| Payment
| Оплата в чеку: готівка, картка, онлайн-еквайринг тощо.; |}

{| class="wikitable"

from uuid import UUID

* timeout;
* тимчасової недоступності API;
* HTTP 429;
* HTTP 500;
* HTTP 502;
* HTTP 503;
* HTTP 504;
* мережевих помилок;
* тимчасової помилки Device Manager.; |
 | 2.; | style="background:#eeeeee;" | Сірий
|-
| Відкривається
| OPENING
| Виконується відкриття зміни.; Колір

 payload={
!; |-
| name
| varchar
| Назва каси.; !; organization_id: str | None = None

* Python API для прийому продажів;
* замовник інтеграції з «Вчасно.Каса»;
* супровід фіскалізації чеків;
* супровід повернень;
* відкриття та закриття змін;
* збереження чеків;
* збереження статусів;
* журнал помилок;
* retry-механізм;
* dashboard / API для контролю;
* інтеграційні функціональні можливості з внутрішньою системою.;</div>
|-
| external_order_id
| ключовий ключ від зовнішньої системи.; POST /api/v1/fiscal/receipts
 audit_logger.log(
<pre>
|-
| Дублювання чеків
| Повторний запит має змогу створити другий чек.; !; Тип
 receipt.error_message = str(exc)
{| class="wikitable"
!;<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">

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

 {

 default_cashier_id: str | None = None
!; Тип
 pass
Логічний endpoint:

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

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

7.; |-

Зміна налаштувань } ;=== 24.1.; інтеграційні функціональні можливості ===
"sku": "SKU-001",
; Тип
!; платформа не повинна дозволяти створювати повернення на суму більшу, ніж залишок доступний до повернення.; # Які типи оплат підтримуються?; |-
| customer
| object
| інформаційні дані покупця.; №

{| class="wikitable"
 audit_logger.log(
pass
AC-4 ERP передає продаж.; №
retry_backoff_seconds: int = 5
)
10:42 Каса 1 ORDER-123 570.00 Помилка Timeout API Повторити
11:05 Каса 2 ORDER-124 1200.00 Потребує повтору Тимчасова помилка Повторити
12:10 Каса 3 SHIFT-55 - Зміна відкрита Не закрито Z-звіт Закрити зміну

ДПС

- AC-16 є собою помилки фіскалізації.; Замовлення

24.2.; Чеки

Етап 4.; Чеки

; Показник ; Компонент
integration_name string Так - api_token secret Так }

POST /api/v1/fiscal/shifts/open

17.1. fiscal_integrations

Чек переходить у NEEDS_RETRY.; |- integration_mode varchar Dashboard, нагадування, авто-закриття за правилом.; |- ДПС - Фіолетовий #f3e5f5 - fiscal_operation_type string }
"fiscal_url": response.fiscal_url,

VCHASNO_KASA_ORGANIZATION_ID=org-001

) ) ERP / CRM / Website / POS
Підходить для інтеграцій з локальними системами, POS, принтерами.; | Черга чеків, pending-операції.; |- Receipt Service платформа створює чек повернення.; | style="background:#ffcc80;" | Потрібна дія
def open_shift(self, cash_register_id: str, cashier_id: str) -> "ShiftResponse":
- Refund Service Створення чеків повернення.; №

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

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

},
idempotency_key=command.idempotency_key,

POST /api/v1/fiscal/refund-receipts

Python-сервіс повинен приймати інформаційні дані продажу та створювати фіскальний чек.; Worker викликає API «Вчасно.Каса».; VCHASNO_KASA_BASE_URL=https://api.example.vchasno-kasa

- external_order_id varchar style="background:#f3e5f5;" | Фіолетовий

18.11. Dashboard

- Receipt Item - Dashboard API - переважні аспекти - entity_type varchar - Незакрита зміна Касир або платформа не закрили зміну.; Тип

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

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

id uuid ID зміни.; Тип
Cash Register - Відправка в API style="background:#f3e5f5;" | Спеціальні операції
Незакриті зміни - updated_at timestamp - Загальна БД чеків Усі чеки зберігаються в єдиній БД Python-сервісу.; Поле

3.; |}

class VchasnoKasaClient:

24.5. Dashboard

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

- external_payment_id - id uuid Внутрішній ID каси.; характеристика

Критично істотно: інтеграційні функціональні можливості з ПРРО не повинна втрачати чеки.;=== 12.2.; Основні компоненти Python-сервісу ===

Чернетка DRAFT Чек створено у Python-сервісі, але ще не відправлено.; Статус
VCHASNO_KASA_TIMEOUT_SECONDS=30
!; Призначення

* [[Python]]
* [[FastAPI]]
* [[K2 ERP]]
* [[Вчасно.Каса]]
* [[ПРРО]]
* [[Фіскалізація]]
* [[Фіскальний чек]]
* [[Касова зміна]]
* [[Z-звіт]]
* [[X-звіт]]
* [[Device Manager]]
* [[API інтеграція]]
* [[POS]]
* [[Інтернет-магазин]]

 "cashier_id": "cashier-001",
 "raw_request": command.model_dump(),
!; # Чи потрібна інтеграційні функціональні можливості з POS-терміналами?; |-
| cash_register_id
| uuid
| Каса.; |-
| created_at
| timestamp
| Дата створення.; |-
| auto_close_shift
| boolean
| Ні
| автономно закривати зміну за розкладом.; Очікуваний результат

!; | style="background:#c8e6c9;" | Норма
|-
| Очікують
| Чеки в черзі.;== 10.; Статуси зміни ==
 },
|-
| Фіскалізація продажу
| Високий
| ключовий бізнес-процес.; |-
| external_cash_register_id
| varchar
| ID каси у «Вчасно.Каса».; Колір
== 26.; Етапи реалізації ==

 receipt = receipt_repository.create(
== 28.; Відкриті питання ==
POST /api/v1/fiscal/receipts/{receipt_id}/retry
<pre>
<pre>
 "external_order_id": command.external_order_id,
{| class="wikitable"
{| class="wikitable"
 event_type="RECEIPT_QUEUED",

До області задачі входить:
=== 8.3.; Приклад запиту на чек ===
 "tax_group": "VAT_20",

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

До першої версії не входить:
 pass
 verify_ssl: bool = True

!; |}

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

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

* акаунт у «Вчасно.Каса»;
* зареєстрований суб'єкт господарювання;
* зареєстровану торгову точку;
* зареєстрований ПРРО;
* зареєстрованого касира;
* активний доступ до API або Device Manager;
* токен інтеграції;
* тестову касу або тестовий режим, якщо доступний;
* перелік кас, які будуть використовуватись;
* перелік касирів;
* правила відкриття і закриття зміни;
* правила формування чеків;
* правила повернень;
* формат оплати;
* формат товарних позицій;
* формат податків і ставок;
* вимоги до відправки електронного чека покупцю.; |-
| Закриття зміни
| Z-звіт, час, результат.; |-
| qr_code
| text
| QR або інформаційні дані QR, якщо доступні.; | платформа повертає успішний або помилковий статус.; |-
| status
| varchar
| Статус чека.; VCHASNO_KASA_DEFAULT_CASHIER_ID=cashier-001

щоб контролювати фіскалізацію, помилки, повернення і незакриті зміни.; |-
| Втрата чека
| API недоступне під час продажу.; Що зберігати
<pre>

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

 v
VCHASNO_KASA_RETRY_BACKOFF_SECONDS=5
 "unit": "шт"
|-
| API Layer
| REST API для прийому продажів, повернень, команд зміни.;== 25. MVP ==

* https://service.vchasno.ua/tech-doc-kasa
* https://wiki-kasa.vchasno.ua/uk/DeviceManager/Functionality/API
* https://kasa.vchasno.com.ua/check-list
* https://kasa.vchasno.com.ua/integraciya
* https://kasa.vchasno.com.ua/devise-manager
* https://wiki-kasa.vchasno.ua/uk/DeviceManager/Start/Create_prro
* https://wiki-kasa.vchasno.ua/uk/DeviceManager/Functionality/Emulator

!; Результат зберігається в БД.; |-
| status
| varchar
| OPEN, CLOSED, ERROR тощо.; VCHASNO_KASA_DEFAULT_CASH_REGISTER_ID=cash-register-001
Python-сервіс напряму викликає хмарне API «Вчасно.Каса».; |-
| fiscalized_at
| timestamp
| Дата фіскалізації.; характеристика
=== 21.1.; Основні KPI ===
!; |-
| opened_at
| timestamp
| Дата відкриття.; | Валідація перед фіскалізацією.; |-
| AC-7
| Повторний запит має той самий idempotency_key.; |-
| Refund Receipt
| Чек повернення.; API приймає запит на створення чека.; |-
| amount
| numeric
| Сума оплати.; # Чи потрібно автономно закривати зміну?; |-
| tax_group
| varchar
| Податкова група.; Критерій
"currency": "UAH"
entity_id=receipt.id,
- Fiscal Queue Вони підсвічуються помаранчевим.; |- base_url varchar інтеграційні функціональні можливості зберігається в системі.; | Dashboard, список чеків, касові зміни.; "provider": "liqpay",

ERP / CRM / Website / POS
!; |-
| status
| varchar
| Активна, неактивна, помилка.; |-
| Vchasno Kasa Client
| Python-клієнт для API «Вчасно.Каса» або Device Manager.; Задача додається в чергу.; |}

платформа повинна не допускати дублювання чеків.; Фіскалізація через ПРРО
Логічний endpoint:
!; POST /api/v1/fiscal/receipts/{receipt_id}/sync-status

Як оператор або ERP, 
 "type": "card",
=== 18.2.; Перевірка підключення ===

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

- Основні операції style="background:#eeeeee;" | Сірий
Повернення створено REFUNDED По чеку є собою повне або часткове повернення.; { validation_service.validate_receipt(command)

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

pass
ValidationError Некоректні інформаційні дані чека.; # Який SLA по фіскалізації?; характеристика
|-
| external_order_id
| string
| ID замовлення у зовнішній системі.; Значення
 db.commit()

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

платформа повинна підтримувати синхронізацію статусу чека з «Вчасно.Каса».; Конкретний сценарій потрібно зафіксувати в налаштуваннях інтеграції.; | У БД зберігається fiscal_number.; |-
| AC-8
| API повертає тимчасову помилку.; |-
| Перевірка перед чеком
| Якщо зміна вже відкрита, повторно не відкривати.; Сценарій

sha256(external_order_id + total_amount + payment_id + cash_register_id)
 "status": "PENDING",
}


def create_fiscal_receipt(command: "CreateReceiptCommand", db: "Session") -> "FiscalReceipt":
 if receipt.status == "FISCALIZED":
=== 7.2.; Повернення ===
 db.commit()
Як касир або адміністратор, 

Вчасно.Каса
<pre>

!; receipt.raw_response = response.raw_payload

 "receipt_type": "sale",

</div>
=== 8.1.; конфігурація інтеграції ===
 "amount": 500.00,

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

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

'''Технічний стек:''' Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker.; | Виконати retry.; інформаційні дані проходять валідацію.; |}

receipt.status = "NEEDS_RETRY"
- idempotency_key Унікальний ключ запиту.; Помилка

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

- name varchar - receipt_id uuid - ShiftError - idempotency_key varchar - quantity numeric - items array - cash_register_id uuid Healthcheck і fallback-сценарій.; |- is_active boolean Активність.; def fiscalize_receipt(receipt_id: UUID, db: "Session") -> None:
  • додати rate limiting;
  • додати alerting;
  • додати retry policy;
  • додати dead letter queue;
  • додати моніторинг;
  • додати резервне копіювання.; Критерій
  • створити FastAPI-проєкт;
  • налаштувати PostgreSQL;
  • створити моделі інтеграції, кас, змін, чеків;
  • налаштувати Alembic;
  • реалізувати healthcheck.; Тип
платформа формує Z-звіт.; |}
}

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

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

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

id uuid ID позиції.; Очікуваний результат
receipt.status = "SENDING"

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

entity_type="receipt",
Черга, статуси API.; Поле
task_name="fiscalize_receipt",

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

Як адміністратор,

"cash_register_id": "cash-register-001",

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

POST /api/v1/fiscal/shifts/open

платформа попереджає перед закриттям зміни.; Тип помилки
  • реалізувати чек повернення;
  • перевірити доступний залишок повернення;
  • зв'язати повернення з первинним чеком.; |-
cashier_id string Ні }

21.2.; Приклад dashboard

</syntaxhighlight>

- integration_id uuid - integration_mode enum Так cloud_api, device_manager, hybrid.; характеристика
  • зберігання токенів тільки у secret storage або в зашифрованому вигляді;
  • заборону логування токенів;
  • маскування персональних даних покупців;
  • обмеження доступу до чеків;
  • контроль доступу до повернень;
  • окремі права на закриття зміни;
  • журнал усіх дій;
  • HTTPS для API-запитів;
  • перевірку SSL;
  • обмеження повторних запитів;
  • захист від дублювання чеків.; |-
base_url string Так Базова адреса API або Device Manager.; характеристика
cashier_id=receipt.cashier_id,
- new_status varchar Новий статус.; Очікуваний результат
v
"currency": command.currency,
 db=db,

Мінімальні інформаційні дані:
== 21.; Dashboard керівника ==
!; Параметр

!; receipt = receipt_repository.get_by_id(db, receipt_id)

 "external_order_id": "ORDER-2026-000123",
 return existing
[[Категорія:Інтеграції]]
from pydantic_settings import BaseSettings
|-
| «Вчасно.Каса»
| ПРРО-сервіс для фіскалізації чеків.; "unit": "послуга"

!; Компонент

!; Критерій

 return receipt
=== 13.1.; Призначення ===

{| class="wikitable"
!; |-
| raw_request
| jsonb
| Запит до API.; # Чи потрібно автономно відкривати зміну?; Тип задачі
Python-сервіс підтримує роботу обидва способи інтеграції.; |-
| API Event
| Технічна подія інтеграції.; |}

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

{| class="wikitable"

</pre>

=== 19.1.; Створення чека ===
!; |-
| fiscal_number
| varchar
| Фіскальний номер ПРРО, якщо доступний.; |-
| Shift Service
| Відкриття, контроль і закриття змін.; |}

!; {| class="wikitable"
== 7. User Story ==
 data={
 event_type="RECEIPT_FISCALIZED",
Якщо API або конфігурація «Вчасно.Каса» підтримують електронну відправку чека, Python-сервіс повинен передавати email або телефон покупця.; | Idempotency key і дедублікація.; | Первинний чек отримує ознаку повного або часткового повернення.; |-
| Єдиний dashboard
| Керівник бачить усі чеки, каси, статуси й помилки в одному місці.; |-
| organization_id
| string
| Так
| Внутрішній ID організації.; |-
| AC-6
| Чек фіскалізовано.; |-
| AC-2
| Адміністратор перевіряє підключення.; |-
| current_shift_id
| uuid
| Поточна зміна.; Дія системи
|-
| AC-1
| Адміністратор створює інтеграцію.; | Підходить для хмарних систем.; характеристика

!; |-
| Автоматичне відкриття
| платформа відкриває зміну перед першим чеком.; | style="background:#bbdefb;" | Блакитний
|-
| Відкрита
| OPEN
| Можна фіскалізувати чеки.; |-
| AC-3
| Токен неправильний.; db=db,

{{DISPLAYTITLE:Технічне завдання: Інтеграція Вчасно.Каса для Python}}

 "sku": "DELIVERY",

!; |}

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

# Який сценарій інтеграції застосовується: хмарне API, Device Manager або гібрид?; | Вони підсвічуються червоним.; Створюється запис receipt зі статусом PENDING.; !; | style="background:#ffcc80;" | Помаранчевий
|-
| Скасовано
| CANCELLED
| Операцію скасовано.; |-
| z_report_number
| varchar
| Номер Z-звіту.; | Черга, retry, статус NEEDS_RETRY.; |-
| receipt_type
| varchar
| sale або refund.; ERP / CRM / сайт отримує статус.; |}

!; |-
| RefundLimitError
| Сума повернення перевищує доступний залишок.; Дія

До MVP входить:
</pre>
'''Критично істотно:''' повторний запит із тим самим idempotency_key не повинен створити другий фіскальний чек.; | Помилки фіскалізації, незакрита зміна.; | Draft, Cancelled, Closed.; |-
| discount_amount
| numeric
| Знижка.; |-
| external_payment_id
| varchar
| ID оплати в платіжній системі.; |}

!; |-
| AC-10
| Сума повернення більша за суму продажу.; | Другий чек не створюється.; |}

 except TemporaryFiscalError as exc:

 )

Python Fiscal Service

 pass

 response = vchasno_kasa_client.create_receipt(payload)
<pre>
</div>
 "external_payment_id": command.external_payment_id,

<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
[[Категорія:Фіскалізація]]

Як платформа продажів, 
=== 18.10.; X-звіт ===

[[Категорія:Python]]
</pre>

 receipt.qr_code = response.qr_code
я хочу бачити, чи відкрита касова зміна, 

{| class="wikitable"
 "total_amount": command.total_amount,

<pre>
 "quantity": 1,

Vchasno Kasa Adapter
=== 8.4.; Чек повернення ===

!; Сума
{| class="wikitable"
|-
| Хмарні продажі та реалізація
| Через хмарне API.; |-
| AC-14
| є собою незавершені чеки.; | style="background:#e3f2fd;" | Інформаційний
|-
| Фіскалізовано
| Кількість успішних чеків.; характеристика

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

 v
я хочу передати інформацію про оплату в Python-сервіс, 
== 5.; Варіанти інтеграції ==

[[Категорія:Вчасно.Каса]]

=== Варіант 3.; 5.3.; Гібридна схема ===
!;=== 17.3. fiscal_shifts ===
=== 7.1.; Фіскалізація продажу ===
!; Поле
!; | Python-сервіс напряму з ДПС у MVP не функціонує.; !; Значення
|-
| AC-9
| користувач системи створює повернення.; |-
| style="background:#eeeeee;" | Сірий
| #eeeeee
| Неактивно або скасовано.; Поле

Приклад hash:
 pass
 shift = shift_service.ensure_open_shift(

 if existing:

{| class="wikitable"

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

{| class="wikitable"
<div style="border-left: 6px solid #6a1b9a; background: #f3e5f5; padding: 12px 16px; margin: 16px 0;">
<pre>
!; # Чи потрібно відправляти чек покупцю через email/SMS/Viber?; характеристика
'''Критично істотно:''' до початку розробки потрібно визначити сценарій інтеграції: хмарне API або Device Manager.; |}

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

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

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

!; |-
| Обмеження
| Потрібна інсталяція та супровід Device Manager.; |-
| cash_register_id
| string
| Так
| ID каси / ПРРО.; Від цього залежить технічна архітектура, мережеві конфігурація, обробка офлайн-ситуацій і друк чеків.; |-
| payments
| array
| Сума повернення.; |-
| style="background:#fff9c4;" | Жовтий
| #fff9c4
| Очікування або попередження.; | Заборонити фіскалізацію.; |-
| cashier_id
| string
| Касир.; | Зберегти raw-відповідь, перевести в NEEDS_RETRY або ERROR.; |-
| created_at
| timestamp
| Дата створення.; |-
| Завантаження PDF
| Низький
| Не блокує фіскалізацію.; Поле

 "payment_id": "PAY-123456"
 v
</pre>

Метою задачі є собою створення Python-сервісу для інтеграції з «Вчасно.Каса» з метою автоматизації фіскалізації продажів, повернень і касових операцій.; |-
| error_message
| text
| Остання помилка.; |-
| Audit Logger
| Журнал API-запитів, відповідей, помилок і змін статусів.; |-
| переважні аспекти
| Можливість роботи з POS-пристроями, принтерами, локальною інфраструктурою.; Очікуваний результат

== 9.; Статуси чеків ==
 ],
VCHASNO_KASA_API_TOKEN=********
db=db,
Реалізується в межах цього ТЗ.; |- raw_response jsonb - Повернення Високий Важлива фінансова операційна дія.; Критерій - AC-5 - DuplicateReceiptError Чек уже створено.;
  • реалізувати dashboard API;
  • реалізувати журнал подій;
  • реалізувати фільтри;
  • реалізувати експорт, якщо потрібно.; |-
Закриття зміни Критичний - Червоний #ef9a9a Помилка або критична ситуація.; Призначення

{{SEO


entity_id=receipt.id,

Логічний endpoint:

"customer": {

1.; Мета

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

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

except Exception as exc:
Ручне відкриття - receipt_id uuid ID чека.; характеристика
try:

17.7. fiscal_events

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

{ я хочу створити чек повернення,

Чеків створено style="background:#eeeeee;" | Сірий
Очікує фіскалізації PENDING Чек у черзі на відправку.; характеристика
"email": "customer@example.com",

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

- Python-сервіс Інтеграційний шар між ERP / сайтом / CRM / POS та «Вчасно.Каса».;=== 20.2.; Retry-логіка ===
  • реалізувати замовник API;
  • реалізувати авторизацію;
  • реалізувати open_shift;
  • реалізувати close_shift;
  • реалізувати create_receipt;
  • реалізувати create_refund_receipt;
  • реалізувати get_status;
  • реалізувати обробку помилок.; |}
base_url: str

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

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

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

- AuthError - payload jsonb Технічні інформаційні дані.; характеристика
"items": [
{
style="background:#c8e6c9;" | Зелений
Помилка ERROR style="background:#c8e6c9;" | Зелений
Закривається CLOSING Виконується закриття зміни.; Як зменшити - AC-11 - Shift Касова зміна.; Сутність
def create_refund_receipt(self, payload: "RefundReceiptPayload") -> "ReceiptResponse":
def get_receipt_pdf(self, receipt_id: str) -> bytes:
v

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

v
pass
)

2.; |}

payload={"external_order_id": command.external_order_id},

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

return

17.6. fiscal_payments

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

timeout_seconds: int = 30
id uuid ID інтеграції.; Обов'язковість
pass
- price numeric Ціна.; receipt.fiscal_url = response.fiscal_url

24.4.; Зміни

22.; Безпека

|-
| style="background:#c8e6c9;" | Зелений
| #c8e6c9
| Успішно: чек фіскалізовано, зміна відкрита або закрита коректно.; Колір
|-
| id
| uuid
| ID події.; !; |-
| organization_id
| varchar
| Організація.; |-
| entity_id
| uuid
| ID сутності.; |-
| external_shift_id
| varchar
| ID зміни у «Вчасно.Каса».; |-
| X Report
| Проміжний звіт без закриття зміни.; | style="background:#ef9a9a;" | Червоний
|}

 v

4.; | style="background:#ef9a9a;" | Критично
|-
| Повернення
| Кількість чеків повернення.; | платформа блокує операцію.; | платформа показує AuthError і не виконує фіскалізацію.; | Не відправляти чек, повернути список помилок.; |-
| Cashier
| Касир, від імені якого виконується операційна дія.; !; |-
| Receipt
| Фіскальний чек продажу.; |-
| external_refund_id
| string
| ID повернення у зовнішній системі.; |-
| provider
| varchar
| LiqPay, WayForPay, Mono, terminal тощо.; Статус / номер / посилання на чек
!; |-
| Validation Layer
| Перевіряє товари, суми, оплати, податки, касу, касира.; |-
| Підходить для
| POS-систем, локальних облікових систем, магазинів із чековими принтерами.; |-
| api_token_encrypted
| text
| Зашифрований токен.; характеристика
|-
| Не відкрита
| CLOSED
| Зміна закрита або ще не відкривалась.; |-
| provider
| varchar
| vchasno_kasa.;=== 13.3.; Конфігурація клієнта ===

"amount": 70.00, платформа повинна підтримувати отримання проміжного X-звіту без закриття зміни.; характеристика

24. Acceptance Criteria

} - amount numeric Сума.; Поле

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

receipt.error_message = str(exc)

Вчасно.Каса

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

Створення чека external_order_id, сума, каса, касир.;=== 8.5.; Відкриття зміни === ; Де застосовується
receipt.fiscal_number = response.fiscal_number

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

receipt.fiscalized_at = datetime.now(timezone.utc)

29.; Джерела

- AC-13 Повернути існуючий чек.;

</syntaxhighlight>

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

Етап 8.; Production hardening

; характеристика Заборонено: зберігати API token, ключі, паролі касирів або інші секрети у коді, Git-репозиторії, відкритих логах або frontend-змінних.; |-
integration_id uuid - Хмарне API «Вчасно.Каса» Пряма інтеграційні функціональні можливості з кабінетом та фіскалізацією чеків.; # Які платіжні провайдери використовуються?; Код Refund, сторно, коригування.; |- Невірні суми - Блакитний #bbdefb Python-сервіс створює чек зі статусом PENDING.; | style="background:#fff9c4;" | Увага
Помилки Retry, незавершені операції.; |- receipt_hash }

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

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

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

default_cash_register_id: str | None = None

class VchasnoKasaSettings(BaseSettings):

27.; Ризики

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

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

<syntaxhighlight lang="python">
|-
| id
| uuid
| ID оплати.; Очікуваний результат
 api_token: str
Сценарії:
 "payments": [
|-
| Чеків за день
| 1240
| style="background:#e3f2fd;" | відомості
|-
| Фіскалізовано
| 1218
| style="background:#c8e6c9;" | Норма
|-
| Очікують у черзі
| 12
| style="background:#fff9c4;" | Увага
|-
| Помилки фіскалізації
| 7
| style="background:#ef9a9a;" | Критично
|-
| Повернення
| 14
| style="background:#f3e5f5;" | Контроль
|-
| Незакриті зміни
| 2
| style="background:#ffcc80;" | Потрібна дія
|}

{| class="wikitable"

щоб не втратити продаж.; |-
| error_message
| text
| Остання помилка.; характеристика
Retry не застосовується для:
 integration_mode: str = "cloud_api"
!; |-
| external_payment_id
| varchar
| ID оплати.;== 13. Vchasno Kasa Client ==
POST /api/v1/fiscal/receipts
 payload = receipt_mapper.to_vchasno_payload(receipt, shift)
=== 8.2.; Створення чека продажу ===
 cash_register_id=receipt.cash_register_id,
 "total_amount": 570.00,
"phone": "+380501112233"

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

"idempotency_key": command.idempotency_key,
"tax_group": "NO_VAT",
- Основні операції - Невірна податкова група Товар передано з неправильним податком.; Коментар платформа повинна дозволяти створити конфігурація підключення до «Вчасно.Каса».; | style="background:#fff9c4;" | Жовтий
Відправляється SENDING - name varchar - default_tax_group string Ні Заборонити повернення.; # Чи потрібна супровід часткових повернень?; |- Повернення первинний чек, сума, причина.; # Чи потрібна супровід змішаних оплат?; payload={"receipt_id": str(receipt.id)},
  • реалізувати відкриття зміни;
  • реалізувати закриття зміни;
  • реалізувати X-звіт;
  • реалізувати контроль незакритих змін.; KPI
fiscal_queue.enqueue(
AC-15 Check-connection і сповіщення адміністратора.; |- TimeoutError - fiscal_number varchar - currency string - cashier_id varchar Зупинити інтеграцію, повідомити адміністратора.; |- reason string - Deduplication Service Захищає від повторної фіскалізації одного продажу.; характеристика

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

ключовий зовнішній сервіс інтеграції.; | style="background:#c8e6c9;" | Зелений
Помилка фіскалізації FISCALIZATION_ERROR Виникла помилка при фіскалізації.; Тип

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

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

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

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

1.; |-
event_type varchar Тип події.; Подія

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

<syntaxhighlight lang="json">
; Кожна операційна дія продажу, повернення, відкриття зміни, закриття зміни та помилка фіскалізації повинні мати внутрішній ID, статус, журнал подій і можливість повторної обробки без створення дубля.; * повноцінний POS UI; * власний ПРРО; * інтеграційні функціональні можливості з усіма еквайрингами; * складна аналітичні інструменти; * автоматична реєстрація ПРРО в ДПС; * супровід всіх нестандартних податкових сценаріїв; * повна офлайн-робота без Device Manager.; | Записати помилку, дозволити повтор.; |- is_active boolean Так class="wikitable" * помилок валідації; * неправильного токена; * дублювання чека; * некоректних сум; * неправильних податкових груп; * повернення понад доступну суму.; * email; * SMS; * Viber; * інший канал, якщо підтримується сервісом.; характеристика def get_receipt_status(self, receipt_id: str) -> "ReceiptStatusResponse":
щоб розуміти, чи можна фіскалізувати чеки.; характеристика

 entity_type="receipt",

8.7.; X-звіт

AC-12 платформа відкриває зміну, якщо auto_open_shift = true.; Продаж / оплата / повернення
Python-сервіс взаємодіє з Device Manager, який виконує інтеграційні функції локально або в середовищі клієнта.; характеристика
я хочу повторити фіскалізацію після технічної помилки, 

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

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

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

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

- Синхронізація статусів Середній - Обмеження - fiscal_url varchar - total_amount numeric Загальна сума.; Тип платформа повинна логувати:
id uuid - Device Manager недоступний - AC-17 є собою незакриті зміни.; }, receipt.status = "FISCALIZED" ; Статус Управлінський результат: керівник повинен бачити, скільки чеків сформовано, скільки фіскалізовано, скільки помилок, які каси відкриті, які зміни не закриті, скільки повернень і які операції потребують уваги.; |- unit varchar }

17.5. fiscal_receipt_items

; !; Параметр def check_connection(self) -> "ConnectionStatus": ; Каса щоб він автономно створив фіскальний чек у «Вчасно.Каса».; |- cash_register_id string Каса / ПРРО.; Ризик щоб коректно відобразити повернення коштів покупцю.;
"fiscal_number": response.fiscal_number,

17.2. cash_registers

- Відкриття зміни - Помилки токена Токен змінено або відкликано.; Тип

Етап 3.; Vchasno Kasa Client

"name": "Доставка", <syntaxhighlight lang="python">