Технічне завдання: передача документів для звітності в податкову через Приват24 для Python
</syntaxhighlight>
7.1. Передача документа в Приват24
4. | Додати healthcheck інтеграції та повідомлення адміністратору. |- | report_id | uuid | ID документа. Статус Приват24
- реалізувати endpoint send-to-privat24;
- зберігати privat24_document_id;
- оновлювати статуси;
- логувати API-взаємодію. №
Приклад змінних середовища:
"metadata": {
! # Де виконується КЕП: у Python-сервісі, у Приват24 або користувачем у веб-інтерфейсі? Поле
15. Модель даних
def download_signed_document(self, document_id: str) -> bytes:
tax_report_service.py
"message": "Document sent to Privat24"
<pre>
! |}
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
POST /api/v1/tax-reports/{report_id}/sync-status
* REST API для створення документа;
* збереження документа;
* базова валідація;
* Privat24 Integration Client;
* передача документа у Приват24;
* збереження зовнішнього ID;
* ручний запуск синхронізації статусу;
* журнал подій;
* базова обробка помилок. |-
| Containers
| Docker. Тип помилки
new_status=new_status,
|
| 3. |-
| file_format
| varchar
| XML, PDF, ZIP тощо. | платформа не створює дубль без окремого підтвердження. report_id=report.id,
- створення Python API для прийому документів;
- створення клієнта інтеграції з Приват24 / ПриватБанком;
- формування XML або прийом готового XML;
- збереження документа;
- перевірка обов'язкових реквізитів;
- передача документа в Приват24;
- отримання статусів;
- отримання квитанцій;
- журнал подій;
- retry-механізм;
- захист API-ключів;
- інтеграційні функції ERP з ERP. Критерій
metadata={
)
=== 6.1. Загальна схема ===
Мінімальний набір вхідних даних:
unit/
щоб мати підтвердження результату подання звітності. |-
| WaitingForTaxReceipt
| Очікується квитанція або результат обробки. Перевірити, що документ має статус ReadyToSend. "source_system": "K2 ERP",
функції ERP застосовують, коли потрібно для автоматизації передачі документів податкової звітності з ERP або облікової системи до Приват24 для бізнесу з подальшим поданням до податкової. |}
платформа повинна забезпечити:
{| class="wikitable"
)
'''Заборонено:''' зберігати API key, client secret, токени або паролі КЕП у коді, Git-репозиторії чи відкритих логах. я хочу бачити статус документа в ERP,
* реалізувати створення документа;
* реалізувати збереження файлу;
* реалізувати валідацію;
* реалізувати статуси;
* реалізувати журнал подій. Отримати файл зі сховища. SEO-опис
},
! |-
| ДПС
| Державна податкова служба України. # Який SLA по оновленню статусів? Поле
try:
=== 8.3. Передача документа в Приват24 ===
retry_backoff_seconds: int = 5
core/
=== 15.1. tax_reports ===
from pydantic_settings import BaseSettings
class Privat24Client:
=== 15.3. tax_report_files ===
file_name=report.file_name,
Очікувана відповідь:
def cancel_document(self, document_id: str, reason: str) -> "Privat24DocumentResponse":
! |-
| XSD
| Схема перевірки XML-документа. * зберігання API key тільки у змінних середовища або secret storage;
* заборону логування API key;
* заборону зберігання паролів КЕП у відкритому вигляді;
* маскування персональних даних у технічних логах;
* контроль доступу до документів;
* контроль доступу до квитанцій;
* журналювання всіх операцій;
* HTTPS для всіх API-запитів;
* перевірку SSL-сертифіката;
* обмеження доступу до адміністративних endpoint-ів;
* резервне копіювання документів і квитанцій. |-
| Privat24AuthError
| Помилка авторизації у Приват24. | Виконати retry. Внутрішній статус
Retry не застосовується для:
{
number=report.document_number,
GET /api/v1/tax-reports/{report_id}
! |- | metadata | object | Ні | Додаткові реквізити для Приват24. Очікуваний результат
details={
details={
class Privat24Settings(BaseSettings): |- | Python | 3.11 або вище. |- | ПриватБанк | Банк, через сервіси якого виконується передача документів. |- | Privat24TimeoutError | Перевищено час очікування. |- | Privat24ApiError | API повернув помилку. Критерій
)
платформа повинна мати background worker, який періодично оновлює статуси документів.
бізнесу та інтеграційних сервісів для бухгалтерських програм забезпечується через '''критично:''' публічна інформаційні матеріали підтверджує наявність електронної звітності в Приват24; так само реалізовано але фінальні API endpoint-и для автоматичної передачі звітності потрібно отримати від ПриватБанку. №
! |-
| Скасування документа
| Причина, користувач системи, дата. # Чи потрібно робити UI, чи тільки backend API? Тип
== 22. Етапи реалізації ==
Очікувана відповідь:
{| class="wikitable"
=== 11.1. Створення документа ===
== 21. MVP ==
"raw_status": response.status,
{{SEO
|title=Технічне завдання: Передача документів для звітності в податкову через Приват24 для Python
|description=Технічне завдання на реалізацію Python-сервісу для передачі документів податкової звітності через Приват24 для бізнесу.
|keywords=Python, Приват24, Приват24 для бізнесу, ПриватБанк, податкова звітність, API, XML, КЕП, ДПС, електронна звітність, технічне завдання
}}
</pre>
APP_ENV=production
це Python-клас або пакет, який інкапсулює роботу з API / інтеграційним каналом Приват24 для бізнесу виступає ключовою рисою Privat24 Integration Client. |-
| created_at
| timestamp
| Дата створення. | Він бачить всі пов'язані файли та статуси. |-
| Document Builder
| Формує XML або приймає готовий файл. |-
| Generated
| Файл документа сформовано. privat24_status = privat24_client.get_document_status(
* додати Dockerfile;
* додати docker-compose;
* додати structured logging;
* додати metrics;
* додати alerting;
* додати rate limiting;
* додати security review. |-
| updated_at
| timestamp
| Дата оновлення версій. |-
| old_status
| varchar
| Попередній статус. | Отримати офіційну технічну документацію від ПриватБанку. | платформа зберігає помилку та не втрачає документ. Критерій
<pre>
"taxpayer_id": "1234567890",
платформа повинна завантажувати та зберігати:
Метою задачі виступає як створення Python-сервісу для передачі документів податкової звітності через Приват24 для бізнесу. # Оновити статус документа. Що зберігати
timeout_seconds: int = 30
! | Зберігати raw-статус та мати UnknownStatus. | платформа дає можливість передачу у Приват24. | Реалізується в межах цього ТЗ. |-
| size_bytes
| integer
| Розмір файлу. |-
| Failed
| Технічна помилка. # Які endpoint-и використовуються для отримання статусів? Рекомендація
1. |-
| file_format
| string
| Так
| XML, PDF, ZIP або інший підтримуваний формат. |-
| Невідомі статуси
| Приват24 здатна повертати статуси, яких немає в системі. |-
| report_type
| string
| Так
| Тип звіту або документа. Ризик
! }
if report.status != TaxReportStatus.READY_TO_SEND:
integrations/
download_receipts.py
sync_statuses.py
Для реалізації задачі необхідно отримати від ПриватБанку або адміністратора Приват24:
! PRIVAT24_RETRY_BACKOFF_SECONDS=5
* https://privatbank.ua/business/tax-help
* https://privatbank.ua/business/elektronnyje-otchety
* https://privatbank.ua/business/intehratsiya
* https://privatbank.ua/business/paperless
* https://privatbank.ua/business/vse-servisy-ucheta-i-otchetnosti
=== Етап 2. Робота з документами ===
* [[Python]]
* [[FastAPI]]
* [[K2 ERP]]
* [[Податкова звітність]]
* [[Приват24]]
* [[Приват24 для бізнесу]]
* [[ПриватБанк]]
* [[ДПС]]
* [[КЕП]]
* [[API інтеграція]]
README.md
Python Tax Reporting Service
main.py
! |- | AC-5 | API / інтеграційний канал Приват24 повертає успішну відповідь. |- | taxpayer_name | string | Так | Назва компанії або ПІБ ФОП. Отримати ID документа в Приват24. # Чи підтримуються webhook-и? SEO-опис
- реалізувати background worker;
- реалізувати періодичне оновлення версій статусів;
- реалізувати мапінг статусів;
- реалізувати обробку невідомих статусів. Тип
POST /api/v1/tax-reports/{report_id}/send-to-privat24 Як бухгалтер,
7.3. Отримання квитанцій
[[Категорія:Python]]
STATUS_SYNC_ENABLED=true
requires_signature: true
</pre>
def sync_pending_reports() -> None:
=== Етап 3. Privat24 Integration Client ===
logging.py
tax_report_repository.update_status(
allowed_formats:
unified_report:
<pre>
"privat24_document_id": response.id,
schemas.py
=== 11.2. Перевірка документа ===
== 16. Обробка помилок ==
v
f"Report {report_id} cannot be sent from status {report.status}"
</pre>
|-
| Створення документа
| ID, користувач системи, дата, тип документа. |-
| HTTP client
| httpx. # Чи виступає як тестове середовище? |-
| Python-сервіс
| Інтеграційний шар між ERP та Приват24. | У системі створюється запис tax_reports. |-
| AC-3
| Передано некоректні інформаційні дані. |-
| accepted
| Accepted
| Документ прийнято. |-
| waiting_receipt
| WaitingForTaxReceipt
| Очікується квитанція. Тип
! |-
| Tests
| pytest. workers/
* повна заміна інтерфейсу Приват24 для бізнесу;
* власна реалізація КЕП, якщо підписання виконується на стороні Приват24;
* інтеграційні функції ERP напряму з API ДПС;
* автоматичне оновлення версій всіх XSD-схем;
* повноцінний UI для бухгалтера;
* автоматична бухгалтерська перевірка сум;
* технічна підтримка всіх типів податкової та статистичної звітності. |-
| last_sync_at
| timestamp
| Дата останньої синхронізації. |-
| file_type
| varchar
| original, signed, pdf, receipt, error_protocol. # Записати подію в журнал. # Підготувати метадані. # Який механізм авторизації застосовується для: API key, OAuth, client certificate або інший варіант? |-
| created_by
| varchar
| користувач системи або system. - xml
Сервіс повинен забезпечити:
11.8. Повторна відправка
20.1. Створення документа
Перед передачею платформа повинна перевірити:
- Отримати документ із локальної БД. |-
| ERP / облікова платформа | Джерело даних для звітності. verify_ssl: bool = True
PRIVAT24_RETRY_COUNT=3
23. Ризики
"file_format": "xml",
! інформаційні дані для звітності або готовий XML
requires_receipt: true
}
| | 2. Очікуваний результат "privat24_status": privat24_status.raw_status,
"privat24_document_id": "external-document-id",
tax_reporting_privat24_service/
20.3. Статуси
2. |}
}
"file_content_base64": "BASE64_XML_CONTENT",
- timeout;
- тимчасової недоступності API;
- HTTP 429;
- HTTP 500;
- HTTP 502;
- HTTP 503;
- HTTP 504. |-
| DB | PostgreSQL. SEO-опис Python-сервіс повинен приймати документ від ERP. №
! |- | Privat24 Client | Python-клієнт для роботи з API / інтеграційним каналом ПриватБанку. POST /api/v1/tax-reports
- наявність обов'язкових полів;
- коректність РНОКПП або ЄДРПОУ;
- коректність звітного періоду;
- наявність файлу;
- допустимий формат файлу;
- розмір файлу;
- коректність імені файлу;
- відповідність XML-структурі;
- відповідність XSD, якщо схема доступна;
- відсутність дубля документа;
- наявність налаштувань інтеграції з Приват24. Викликати Privat24Client.upload_tax_report(). |-
| WaitingForSignature | Документ очікує підписання. |- | StatusMappingError | Невідомий статус від Приват24. Очікуваний результат
- прийом даних звітності з ERP / облікової системи;
- формування або прийом готового XML-документа;
- перевірку документа перед передачею;
- передачу документа через інтеграційний канал Приват24 / ПриватБанку;
- отримання зовнішнього ID документа;
- синхронізацію статусів;
- отримання квитанцій або результатів обробки;
- збереження історії передачі;
- обробку помилок;
- повторну відправку;
- журналювання всіх технічних і бізнес-подій. |}
PRIVAT24_BASE_URL=https://api.privatbank.ua/...
платформа повинна логувати:
! |- | document_date | date | Дата документа. Обов'язковість
)
</syntaxhighlight>
},
<pre>
new_status = status_mapper.map_privat24_status(privat24_status)
POST /api/v1/tax-reports/{report_id}/resend
pass
[[Категорія:K2 ERP]]
file_bytes = file_storage.read(report.file_path)
__TOC__
|-
| id
| uuid
| Внутрішній ID документа. # Чи Python-сервіс має сам формувати XML, чи отримує готовий XML з ERP? |
| 1. | Інкапсулювати API в окремому Privat24Client. |-
| Storage Layer
| Зберігає документи, квитанції, статуси та логи. # Перевірити статус документа. # Хто має доступ до API key? |-
| Logging
| structlog або стандартний logging у JSON-форматі. pass
title=report.title,
=== 8.4. Отримання статусів ===
=== 7.2. Отримання статусу ===
== 17. Безпека ==
- xml
Логічний endpoint Python-сервісу:
{| class="wikitable"
! |-
| waiting_signature
| WaitingForSignature
| Очікується підпис. |-
| Signed
| Документ підписано. |-
| AC-7
| Документ вже був переданий. |-
| DeliveryError
| Помилка доставки. |-
| privat24_document_id
| varchar
| ID документа у Приват24. SEO-опис
! Зберегти ID у локальній БД. ! Внутрішній статус
[[Категорія:Податкова звітність]]
requires_signature: true
=== 8.5. Отримання квитанцій ===
"taxpayer_name": report.taxpayer_name,
client.py
=== 6.2. Основні компоненти Python-сервісу ===
! Дія системи
exceptions.py
"status": "ReadyToSend",
|-
| AC-4
| Документ має статус ReadyToSend. |-
| Недоступність сервісу
| Приват24 або мережа можуть бути тимчасово недоступні. # Який формат документа підтримується: XML, PDF, ZIP, JSON? |-
| Validation
| Pydantic. |-
| DuplicateDocumentError
| Документ вже був переданий. SEO-опис
'''Головна ідея:''' розробити Python-сервіс, який формує, перевіряє, передає та контролює документи податкової звітності через інтеграцію з Приват24 для бізнесу / сервісами ПриватБанку. |-
| privat24_raw_status
| varchar
| Останній raw-статус Приват24. Оновити статус на SentToPrivat24. )
event_repository.py
=== Етап 6. Квитанції та результати обробки ===
pass
}
- xml
from datetime import datetime, timezone
def upload_tax_report(self, document: "DocumentPayload") -> "Privat24DocumentResponse": event_type="STATUS_CHANGED",single_tax_declaration: v
| - | content_type | varchar | MIME-тип. Інтервал перевірки
PRIVAT24_RETRY_BACKOFF_SECONDS=5 file_storage.py report.privat24_document_id = response.id |
entity_id=report.id,
12. Privat24 Integration Client
requires_signature: true }, config.py Приват24 для бізнесу db.commit() "taxpayer_id": report.taxpayer_id, report.sent_at = datetime.now(timezone.utc) 8. Функціональні вимоги16.1. Типи помилок"source_system": report.source_system, 9. Статуси документащоб не створювати документ заново. ! ! |- |
title | varchar | - | rejected_at | timestamp | }
PRIVAT24_CLIENT_ID=******** "report_type": report.report_type, if new_status != report.status: Як бухгалтер, | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AC-8 | }
FILE_STORAGE_PATH=/data/tax-reports 12.3. Конфігурація клієнта
|
Sending | - | SentToTax | платформа завантажує квитанцію або результат обробки. # Отримати зовнішній ID документа. |- | SentToPrivat24 | - | КЕП | }
7.5. Технічний аудитaudit_logger.log( я хочу повторно відправити документ після технічної помилки, === 12.1. Призначення === |- | id | uuid | ID файлу.<syntaxhighlight lang="yaml"> </syntaxhighlight> from uuid import UUID == Див. 29. так само == file_format=report.file_format, == 13. Передача документа в Приват24 == <pre> == 7. User Story == ERP / Accounting System ! # Отримати файл зі сховища. щоб оперативно знаходити причину помилок інтеграції. Отримати документ з БД. |- | period | string | Так | Звітний період. |- | FileStorageError | Неможливо прочитати або записати файл. |- | error | Failed | Помилка обробки. |- | error_message | text | Остання помилка. |- | оновлення версій статусу | Старий статус, новий статус, raw-статус Приват24. |} === 11.4. оновлення версій статусу === == 28. Джерела == * Python-сервіс розгортається через Docker; * API створення документа функціонує; * документ зберігається у БД та файловому сховищі; * документ проходить валідацію; * документ передається у Приват24; * зовнішній ID документа зберігається; * статус документа оновлюється; * помилки API обробляються; * retry-механізм функціонує; * журнал подій заповнюється; * написані unit-тести для ключових сервісів; * написані інтеграційні тести для Privat24Client з mock API; * документація для запуску додана в README; * фінальні endpoint-и ПриватБанку винесені в конфігурацію. |- | Rejected | Документ відхилено. |- | Помилки авторизації | API key здатна бути неправильним або простроченим. |- | AC-12 | Документ відхилено. Компонент status_mapper.py == 11. API Python-сервісу == == 20. Acceptance Criteria == <syntaxhighlight lang="python">
v До першої версії не входить: POST /api/v1/tax-reports/{report_id}/validate client_id: str | None = None tax_reports.py POST /api/v1/tax-reports/{report_id}/send-to-privat24 Етап 5. Синхронізація статусівold_status = report.status 25. Приклад структури Python-проєктуdef get_document(self, document_id: str) -> "Privat24DocumentResponse": entity_id=report.id, Рекомендована періодичність: {
v
POST /api/v1/tax-reports/{report_id}/download-receipts
<syntaxhighlight lang="json">
== 27. Definition of Done ==
allowed_formats:
{
requires_receipt: true
entity_id=report.id,
Приклад тіла запиту:
5. | Перевіряти privat24_document_id перед відправкою. Призначення
<pre>
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
|-
| AC-1
| ERP передає інформаційні дані документа у Python-сервіс. | Статуси документів оновлюються автоматизовано. # Зберегти зовнішній ID у БД. |-
| report_id
| uuid
| ID документа. |-
| payload
| jsonb
| Технічні інформаційні дані події. Очікувана відповідь:
* webhook-інтеграція;
* інтеграційні функції ERP напряму з ДПС;
* власний компонент КЕП;
* складний UI;
* автоматичне оновлення версій XSD;
* технічна підтримка всіх типів звітності;
* автоматичне створення декларації з банківських виписок. |-
| AC-9
| Приват24 повертає новий статус. def download_receipts(self, document_id: str) -> list [bytes]:
== 6. технічна архітектура рішення для бізнесу ==
"status": "Generated",
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
)
PRIVAT24_BASE_URL=https://api.privatbank.ua/...
=== 18.1. Змінні середовища ===
"created_by": "user@example.com"
! | Зупинити відправку, повідомити адміністратора. |-
| Polling
| Періодичне опитування зовнішнього API. !=== 8.2. Валідація документа ===
payload = DocumentPayload(
Python-сервіс повинен мати метод для передачі документа в Приват24. |-
| AC-6
| Приват24 повертає помилку. |-
| Завантаження квитанції
| Тип файлу, назва, дата. |-
| Status Sync Worker
| Фоновий бізнес-процес для оновлення версій статусів. |-
| AC-13
| користувач системи відкриває картку документа. | Обов'язково для MVP.<div style="border-left: 6px solid #1565c0; background: #e3f2fd; padding: 12px 16px; margin: 16px 0;">
|
| 4. |-
| AC-10
| Приват24 повертає невідомий статус. |-
| taxpayer_id
| varchar
| РНОКПП або ЄДРПОУ. |-
| sent_to_tax
| SentToTax
| Документ передано до ДПС. |-
| document_number
| string
| Так
| Номер документа. |-
| rejected
| Rejected
| Документ відхилено. "taxpayer_name": "ФОП Іваненко Іван Іванович",
- zip
tax_report_repository.py
=== 8.1. Створення документа ===
PRIVAT24_RETRY_COUNT=3
[[Категорія:Технічні завдання]]
app/
=== 20.4. Квитанції та файли ===
session.py
integration/
{| class="wikitable"
<syntaxhighlight lang="python">
"privat24_status": "waiting_signature"
! |-
| event_type
| varchar
| Тип події. |-
| Audit Logger
| Фіксує всі дії користувачів і системи. Компонент
document_types:
=== 11.3. Передача в Приват24 ===
security.py
|-
| Draft
| Документ створено, але ще не готовий до передачі. |-
| file_content_base64
| string
| Так
| Вміст документа у Base64. |-
| AC-2
| Передано файл документа. |-
| ValidationError
| Документ не пройшов перевірку. |-
| created_at
| timestamp
| Дата створення. Як зменшити
title: "Об'єднана формування звітів"
base_url: str
def download_original(self, document_id: str) -> bytes:
"old_status": old_status,
Попередній логічний мапінг:
details={"error": str(exc)},
! |-
| file_path
| varchar
| Шлях до файлу у сховищі. Термін
я хочу бачити журнал API-запитів і відповідей,
audit_logger.log(
</div>
== 5. Терміни та скорочення ==
=== 13.2. Приклад Python-логіки ===
ДПС
== 24. Відкриті питання ==
! |-
| document_number
| varchar
| Номер документа. Компонент
! | Внутрішній статус документа змінюється. # Де зберігати файли: локально, S3, MinIO, DMS? Retry застосовується для:
<pre>
! |-
| Квитанція
| Підтвердження прийняття, відхилення або обробки звіту. | Зафіксувати помилку, повідомити адміністратора.<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
</syntaxhighlight>
=== Етап 4. Передача документів ===
=== 18.2. Конфігурація типів документів ===
! |-
| Дублювання документів
| Повторна відправка здатна створити дубль. # Чи потрібна технічна підтримка ФОП, юридичних осіб або обох варіантів? SEO-опис
Як користувач системи ERP,
report.privat24_document_id
! |-
| Повторна відправка
| Причина, користувач системи, дата. pass
щоб скоротити час підготовки та подання звітності. "period": "2026-Q1",
Як адміністратор,
* ValidationError;
* Failed;
* Rejected;
* DeliveryError;
* NeedResend. |}
{| class="wikitable"
{| class="wikitable"
Приват24 для бізнесу
! |-
| Webhook
| Механізм отримання подій від зовнішньої системи. | Використовувати retry та чергу задач. |-
| report_type
| varchar
| Тип звіту. |-
| Валідація
| Результат, список помилок. # Викликати Privat24 Integration Adapter. | Не відправляти документ, показати список помилок. ! |-
| Migrations
| Alembic. raise InvalidStatusError(
{| class="wikitable"
file_repository.py
{| class="wikitable"
== 1. Мета ==
services/
| |||||||||||||||||||||||||||||||||||||||