Технічне завдання: передача документів для звітності в податкову через Птах для Python
Головна ідея: розробити Python-сервіс, який формує, перевіряє, передає та контролює документи звітності через інтеграцію з платформою ПТАХ / API.ПТАХ.
Важливо: API.ПТАХ публічно описується як API для електронного документообігу: створення, підписання, відправка та отримання документів. Можливість саме подання податкової звітності до ДПС через ПТАХ потрібно підтвердити в офіційній API-документації або договорі з постачальником.
Технічний стек: Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Docker.
1. Мета
Метою задачі є створення Python-сервісу для передачі документів звітності через платформу ПТАХ.
Сервіс повинен забезпечити:
- прийом даних звітності з ERP / облікової системи;
- формування або прийом готового XML-документа;
- перевірку документа перед передачею;
- передачу документа в ПТАХ;
- запуск підписання документа, якщо це підтримується API;
- запуск відправки документа, якщо це підтримується API;
- отримання зовнішнього ID документа;
- синхронізацію статусів;
- отримання квитанцій або результатів обробки;
- збереження історії передачі;
- обробку помилок;
- повторну відправку;
- журналювання всіх технічних і бізнес-подій.
2. Область застосування
Функціонал використовується для автоматизації передачі документів звітності з ERP або облікової системи до ПТАХ.
До області задачі входить:
- створення Python API для прийому документів;
- створення клієнта інтеграції з API.ПТАХ;
- формування XML або прийом готового XML;
- збереження документа;
- перевірка обов'язкових реквізитів;
- передача документа в ПТАХ;
- запуск підписання / відправки через ПТАХ, якщо підтримується API;
- отримання статусів;
- отримання квитанцій або результатів обробки;
- журнал подій;
- retry-механізм;
- захист API-ключів і службових доступів;
- інтеграція з ERP.
До першої версії не входить:
- повна заміна інтерфейсу ПТАХ;
- власна реалізація подання напряму до API ДПС;
- власна реалізація КЕП, якщо підписання виконується на стороні ПТАХ;
- автоматичне оновлення всіх XSD-схем;
- повноцінний UI для бухгалтера;
- автоматична бухгалтерська перевірка сум;
- підтримка всіх типів податкової, статистичної та фінансової звітності.
3. Джерела інтеграції
| Компонент | Призначення | Коментар |
|---|---|---|
| ПТАХ | Платформа електронного документообігу та обміну юридично значущими документами. | Основна система для передачі документів. |
| API.ПТАХ | Інтеграційний API для роботи з документами. | Потрібна офіційна API-документація та доступ. |
| Python-сервіс | Інтеграційний шар між ERP та ПТАХ. | Реалізується в межах цього ТЗ. |
| ERP / облікова система | Джерело даних для звітності. | Наприклад K2 ERP або інша система. |
| ДПС | Кінцевий отримувач податкової звітності. | Сценарій передачі через ПТАХ потрібно підтвердити окремо. |
4. Передумови
Для реалізації задачі необхідно отримати:
- доступ до платформи ПТАХ;
- активований доступ до API.ПТАХ;
- базовий URL API;
- спосіб авторизації;
- API key / token / client credentials;
- технічну документацію endpoint-ів;
- перелік доступних типів документів;
- підтвердження можливості передачі звітності до ДПС через ПТАХ;
- формат передачі файлів;
- формат метаданих документа;
- правила створення документа в ПТАХ;
- правила підписання документа;
- правила відправки документа;
- правила отримання статусів;
- правила отримання квитанцій;
- тестове середовище, якщо доступне;
- технічний контакт з боку постачальника ПТАХ.
5. Терміни та скорочення
| Термін | Опис |
|---|---|
| Python-сервіс | Окремий backend-сервіс або модуль, який виконує інтеграцію з ПТАХ. |
| ПТАХ | Платформа електронного документообігу. |
| API.ПТАХ | API для інтеграції облікових систем із платформою ПТАХ. |
| ДПС | Державна податкова служба України. |
| XML | Формат електронного документа звітності. |
| XSD | Схема перевірки XML-документа. |
| КЕП | Кваліфікований електронний підпис. |
| API | Програмний інтерфейс інтеграції. |
| Webhook | Механізм отримання подій від зовнішньої системи. |
| Polling | Періодичне опитування зовнішнього API. |
| Квитанція | Підтвердження прийняття, відхилення або обробки звіту. |
6. Архітектура рішення
6.1. Загальна схема
ERP / Accounting System
|
| 1. Дані для звітності або готовий XML
v
Python Tax Reporting Service
|
| 2. Валідація та збереження документа
v
Ptah Integration Adapter
|
| 3. Передача документа через API.ПТАХ
v
ПТАХ
|
| 4. Підписання / відправка / обробка
v
ДПС або інший отримувач
|
| 5. Квитанції / статуси
v
ПТАХ
|
| 6. Синхронізація статусів
v
Python Tax Reporting Service
|
| 7. Оновлення статусу в ERP
v
ERP / Accounting System
6.2. Основні компоненти Python-сервісу
| Компонент | Опис |
|---|---|
| API Layer | REST API для прийому документів від ERP. |
| Document Builder | Формує XML або приймає готовий файл. |
| Validation Layer | Перевіряє реквізити, структуру та статус документа. |
| Ptah Client | Python-клієнт для роботи з API.ПТАХ. |
| Status Sync Worker | Фоновий процес для оновлення статусів. |
| Receipt Loader | Завантажує квитанції та результати обробки. |
| Storage Layer | Зберігає документи, квитанції, статуси та логи. |
| Audit Logger | Фіксує всі дії користувачів і системи. |
7. User Story
7.1. Передача документа в ПТАХ
Як користувач ERP, я хочу передати документ звітності в ПТАХ без ручного імпорту, щоб скоротити час підготовки та подання документів.
7.2. Підписання та відправка
Як бухгалтер, я хочу ініціювати підписання та відправку документа через ПТАХ, щоб не виконувати ці дії вручну, якщо це підтримується API.
7.3. Отримання статусу
Як бухгалтер, я хочу бачити статус документа в ERP, щоб розуміти, чи документ створено, передано, підписано, відправлено, прийнято або відхилено.
7.4. Отримання квитанцій
Як бухгалтер, я хочу отримати квитанції або результати обробки в ERP, щоб мати підтвердження результату передачі документа.
7.5. Повторна відправка
Як користувач, я хочу повторно відправити документ після технічної помилки, щоб не створювати документ заново.
7.6. Технічний аудит
Як адміністратор, я хочу бачити журнал API-запитів і відповідей, щоб швидко знаходити причину помилок інтеграції.
8. Функціональні вимоги
8.1. Створення документа
Python-сервіс повинен приймати документ від ERP.
Мінімальний набір вхідних даних:
| Поле | Тип | Обов'язковість | Опис |
|---|---|---|---|
| taxpayer_id | string | Так | РНОКПП або ЄДРПОУ платника. |
| taxpayer_name | string | Так | Назва компанії або ПІБ ФОП. |
| report_type | string | Так | Тип звіту або документа. |
| period | string | Так | Звітний період. |
| document_number | string | Так | Номер документа. |
| document_date | date | Так | Дата документа. |
| file_format | string | Так | XML, PDF, ZIP або інший підтримуваний формат. |
| file_content_base64 | string | Так | Вміст документа у Base64. |
| metadata | object | Ні | Додаткові реквізити для ПТАХ. |
8.2. Валідація документа
Перед передачею система повинна перевірити:
- наявність обов'язкових полів;
- коректність РНОКПП або ЄДРПОУ;
- коректність звітного періоду;
- наявність файлу;
- допустимий формат файлу;
- розмір файлу;
- коректність імені файлу;
- відповідність XML-структурі;
- відповідність XSD, якщо схема доступна;
- відсутність дубля документа;
- наявність налаштувань інтеграції з ПТАХ.
8.3. Передача документа в ПТАХ
Python-сервіс повинен мати метод для передачі документа в ПТАХ.
Логічний endpoint Python-сервісу:
POST /api/v1/tax-reports/{report_id}/send-to-ptah
Очікувана дія:
- Отримати документ із локальної БД.
- Перевірити статус документа.
- Отримати файл зі сховища.
- Підготувати метадані.
- Викликати Ptah Integration Adapter.
- Отримати зовнішній ID документа в ПТАХ.
- Зберегти зовнішній ID у БД.
- Оновити статус документа.
- Записати подію в журнал.
8.4. Підписання документа
Система повинна підтримувати один із режимів:
| Режим | Опис | Пріоритет |
|---|---|---|
| Підписання в ПТАХ | Документ передається в ПТАХ, а підписання виконується засобами платформи. | Основний режим, якщо підтримується API. |
| Підписання в Python-сервісі | Python-сервіс підписує документ до передачі в ПТАХ. | Опційно. |
| Ручне підписання | Користувач підписує документ у веб-інтерфейсі або клієнті ПТАХ. | Резервний режим. |
8.5. Відправка документа
Якщо API.ПТАХ підтримує відповідний метод, Python-сервіс повинен ініціювати відправку документа отримувачу.
Логічний endpoint Python-сервісу:
POST /api/v1/tax-reports/{report_id}/send
Очікувана дія:
- Перевірити, що документ створено в ПТАХ.
- Перевірити, що документ підписано або готовий до підписання.
- Викликати метод ПТАХ для відправки.
- Оновити статус на Sent.
- Записати подію в журнал.
8.6. Отримання статусів
Система повинна підтримувати два способи оновлення статусів:
| Спосіб | Опис | Пріоритет |
|---|---|---|
| Polling | Періодичне опитування API.ПТАХ. | Обов'язково для MVP. |
| Webhook | Отримання подій від ПТАХ, якщо підтримується. | Опційно. |
8.7. Отримання квитанцій
Система повинна завантажувати та зберігати:
- квитанцію про отримання;
- квитанцію про прийняття;
- квитанцію про відхилення;
- підписаний документ;
- PDF-візуалізацію, якщо доступна;
- технічний протокол обробки, якщо доступний;
- raw-відповідь ПТАХ.
8.8. Повторна відправка
Повторна відправка дозволена тільки для документів у статусах:
- ValidationError;
- Failed;
- Rejected;
- DeliveryError;
- NeedResend.
Повторна відправка не дозволена для статусів:
- Accepted;
- Sent;
- WaitingForReceipt;
- SentToPtah;
- WaitingForSignature.
9. Статуси документа
| Внутрішній статус | Опис |
|---|---|
| Draft | Документ створено, але ще не готовий до передачі. |
| Generated | Файл документа сформовано. |
| ValidationError | Документ не пройшов перевірку. |
| ReadyToSend | Документ готовий до передачі. |
| Sending | Документ передається в ПТАХ. |
| SentToPtah | Документ успішно передано в ПТАХ. |
| CreatedInPtah | Документ створено в ПТАХ. |
| WaitingForSignature | Документ очікує підписання. |
| Signed | Документ підписано. |
| Sent | Документ відправлено отримувачу. |
| SentToTax | Документ передано до ДПС, якщо такий сценарій підтримується. |
| WaitingForReceipt | Очікується квитанція або результат обробки. |
| ReceiptReceived | Отримано квитанцію або результат обробки. |
| Accepted | Документ прийнято. |
| Rejected | Документ відхилено. |
| DeliveryError | Помилка доставки. |
| Failed | Технічна помилка. |
| Cancelled | Документ скасовано. |
10. Мапінг статусів ПТАХ
Фінальний мапінг статусів потрібно побудувати після отримання офіційного довідника статусів API.ПТАХ.
Попередній логічний мапінг:
| Статус ПТАХ | Внутрішній статус | Опис |
|---|---|---|
| created | CreatedInPtah | Документ створено в ПТАХ. |
| uploaded | SentToPtah | Документ завантажено в ПТАХ. |
| waiting_signature | WaitingForSignature | Очікується підпис. |
| signed | Signed | Документ підписано. |
| sent | Sent | Документ відправлено. |
| sent_to_tax | SentToTax | Документ передано до ДПС, якщо підтримується. |
| waiting_receipt | WaitingForReceipt | Очікується квитанція або результат обробки. |
| receipt_received | ReceiptReceived | Отримано квитанцію або результат обробки. |
| accepted | Accepted | Документ прийнято. |
| rejected | Rejected | Документ відхилено. |
| error | Failed | Помилка обробки. |
Уточнення: значення статусів є попередніми. Реальні коди статусів потрібно взяти з API-документації ПТАХ.
11. API Python-сервісу
11.1. Створення документа
POST /api/v1/tax-reports
Приклад тіла запиту:
{
"taxpayer_id": "1234567890",
"taxpayer_name": "ФОП Іваненко Іван Іванович",
"report_type": "single_tax_declaration",
"period": "2026-Q1",
"document_number": "DECL-2026-0001",
"document_date": "2026-04-15",
"file_format": "xml",
"file_content_base64": "BASE64_XML_CONTENT",
"metadata": {
"source_system": "K2 ERP",
"created_by": "user@example.com"
}
}
Очікувана відповідь:
{
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
"status": "Generated",
"message": "Document created"
}
11.2. Перевірка документа
POST /api/v1/tax-reports/{report_id}/validate
Очікувана відповідь:
{
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
"status": "ReadyToSend",
"errors": []
}
11.3. Передача в ПТАХ
POST /api/v1/tax-reports/{report_id}/send-to-ptah
Очікувана відповідь:
{
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
"status": "SentToPtah",
"ptah_document_id": "external-document-id",
"message": "Document sent to Ptah"
}
11.4. Підписання документа
POST /api/v1/tax-reports/{report_id}/sign
Очікувана відповідь:
{
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
"status": "Signed",
"message": "Document signed via Ptah"
}
11.5. Відправка документа
POST /api/v1/tax-reports/{report_id}/send
Очікувана відповідь:
{
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
"status": "Sent",
"message": "Document sent via Ptah"
}
11.6. Оновлення статусу
POST /api/v1/tax-reports/{report_id}/sync-status
Очікувана відповідь:
{
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
"old_status": "SentToPtah",
"new_status": "WaitingForSignature",
"ptah_status": "waiting_signature"
}
11.7. Отримання документа
GET /api/v1/tax-reports/{report_id}
11.8. Отримання журналу
GET /api/v1/tax-reports/{report_id}/events
11.9. Завантаження квитанцій
POST /api/v1/tax-reports/{report_id}/download-receipts
11.10. Повторна відправка
POST /api/v1/tax-reports/{report_id}/resend
12. Ptah Integration Client
12.1. Призначення
Ptah Integration Client — це Python-клас або пакет, який інкапсулює роботу з API.ПТАХ.
12.2. Основні методи
class PtahClient:
def create_document(self, document: "DocumentPayload") -> "PtahDocumentResponse":
pass
def upload_tax_report(self, document: "DocumentPayload") -> "PtahDocumentResponse":
pass
def get_document(self, document_id: str) -> "PtahDocumentResponse":
pass
def get_document_status(self, document_id: str) -> "PtahStatusResponse":
pass
def sign_document(self, document_id: str) -> "PtahDocumentResponse":
pass
def send_document(self, document_id: str) -> "PtahDocumentResponse":
pass
def download_original(self, document_id: str) -> bytes:
pass
def download_signed_document(self, document_id: str) -> bytes:
pass
def download_receipts(self, document_id: str) -> list[bytes]:
pass
def cancel_document(self, document_id: str, reason: str) -> "PtahDocumentResponse":
pass
12.3. Конфігурація клієнта
from pydantic_settings import BaseSettings
class PtahSettings(BaseSettings):
base_url: str
api_key: str | None = None
client_id: str | None = None
client_secret: str | None = None
company_code: str | None = None
timeout_seconds: int = 30
retry_count: int = 3
retry_backoff_seconds: int = 5
verify_ssl: bool = True
Приклад змінних середовища:
PTAH_BASE_URL=https://api.ptah.example PTAH_API_KEY=******** PTAH_CLIENT_ID=******** PTAH_CLIENT_SECRET=******** PTAH_COMPANY_CODE=12345678 PTAH_TIMEOUT_SECONDS=30 PTAH_RETRY_COUNT=3 PTAH_RETRY_BACKOFF_SECONDS=5
Заборонено: зберігати API key, client secret, токени або паролі КЕП у коді, Git-репозиторії чи відкритих логах.
13. Передача документа в ПТАХ
13.1. Логічний процес
1. Отримати документ з БД. 2. Перевірити, що документ має статус ReadyToSend. 3. Отримати файл зі сховища. 4. Підготувати метадані. 5. Викликати PtahClient.upload_tax_report(). 6. Отримати ID документа в ПТАХ. 7. Зберегти ID у локальній БД. 8. Оновити статус на SentToPtah. 9. Записати подію в журнал.
13.2. Приклад Python-логіки
from uuid import UUID
from datetime import datetime, timezone
def send_report_to_ptah(report_id: UUID, db: "Session") -> "TaxReport":
report = tax_report_repository.get_by_id(db, report_id)
if report.status != TaxReportStatus.READY_TO_SEND:
raise InvalidStatusError(
f"Report {report_id} cannot be sent from status {report.status}"
)
file_bytes = file_storage.read(report.file_path)
payload = DocumentPayload(
title=report.title,
number=report.document_number,
date=report.document_date,
file_name=report.file_name,
file_content=file_bytes,
file_format=report.file_format,
metadata={
"taxpayer_id": report.taxpayer_id,
"taxpayer_name": report.taxpayer_name,
"report_type": report.report_type,
"period": report.period,
"source_system": report.source_system,
},
)
response = ptah_client.upload_tax_report(payload)
report.ptah_document_id = response.id
report.status = TaxReportStatus.SENT_TO_PTAH
report.sent_at = datetime.now(timezone.utc)
audit_logger.log(
entity_id=report.id,
event_type="SENT_TO_PTAH",
details={
"ptah_document_id": response.id,
"raw_status": response.status,
},
)
db.commit()
return report
14. Підписання та відправка через ПТАХ
14.1. Логічний процес підписання
1. Перевірити, що документ створено в ПТАХ. 2. Перевірити, що документ не був відправлений раніше. 3. Викликати метод підписання ПТАХ, якщо він доступний. 4. Отримати результат підписання. 5. Оновити статус на Signed або Failed. 6. Записати подію в журнал.
14.2. Логічний процес відправки
1. Перевірити, що документ підписано. 2. Викликати метод відправки ПТАХ. 3. Отримати результат відправки. 4. Оновити статус на Sent або Failed. 5. Запустити очікування квитанцій. 6. Записати подію в журнал.
14.3. Приклад Python-логіки
def sign_and_send_report(report_id: UUID, db: "Session") -> "TaxReport":
report = tax_report_repository.get_by_id(db, report_id)
if not report.ptah_document_id:
raise InvalidStatusError("Report is not created in Ptah")
if report.status not in {
TaxReportStatus.SENT_TO_PTAH,
TaxReportStatus.CREATED_IN_PTAH,
TaxReportStatus.WAITING_FOR_SIGNATURE,
}:
raise InvalidStatusError(
f"Report {report_id} cannot be signed from status {report.status}"
)
sign_response = ptah_client.sign_document(report.ptah_document_id)
report.status = TaxReportStatus.SIGNED
audit_logger.log(
entity_id=report.id,
event_type="SIGNED_IN_PTAH",
details={"raw_status": sign_response.status},
)
send_response = ptah_client.send_document(report.ptah_document_id)
report.status = TaxReportStatus.SENT
report.sent_to_receiver_at = datetime.now(timezone.utc)
audit_logger.log(
entity_id=report.id,
event_type="SENT_VIA_PTAH",
details={"raw_status": send_response.status},
)
db.commit()
return report
15. Робота зі статусами
15.1. Фонове оновлення
Система повинна мати background worker, який періодично оновлює статуси документів.
Рекомендована періодичність:
| Статус документа | Інтервал перевірки |
|---|---|
| SentToPtah | кожні 5 хвилин |
| CreatedInPtah | кожні 5 хвилин |
| WaitingForSignature | кожні 15 хвилин |
| Sent | кожні 10 хвилин |
| SentToTax | кожні 10 хвилин |
| WaitingForReceipt | кожні 10 хвилин |
| ReceiptReceived | кожні 30 хвилин або не перевіряти |
| Accepted / Rejected | не перевіряти |
15.2. Приклад worker-а
def sync_pending_reports() -> None:
reports = tax_report_repository.get_reports_for_sync()
for report in reports:
try:
ptah_status = ptah_client.get_document_status(
report.ptah_document_id
)
new_status = status_mapper.map_ptah_status(ptah_status)
if new_status != report.status:
old_status = report.status
tax_report_repository.update_status(
report_id=report.id,
new_status=new_status,
raw_status=ptah_status.raw_status,
)
audit_logger.log(
entity_id=report.id,
event_type="STATUS_CHANGED",
details={
"old_status": old_status,
"new_status": new_status,
"ptah_status": ptah_status.raw_status,
},
)
except Exception as exc:
audit_logger.log(
entity_id=report.id,
event_type="STATUS_SYNC_FAILED",
details={"error": str(exc)},
)
16. Модель даних
16.1. tax_reports
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | Внутрішній ID документа. |
| taxpayer_id | varchar | РНОКПП або ЄДРПОУ. |
| taxpayer_name | varchar | Назва платника. |
| report_type | varchar | Тип звіту. |
| period | varchar | Звітний період. |
| document_number | varchar | Номер документа. |
| document_date | date | Дата документа. |
| title | varchar | Назва документа. |
| file_name | varchar | Назва файлу. |
| file_path | varchar | Шлях до файлу у сховищі. |
| file_format | varchar | XML, PDF, ZIP тощо. |
| status | varchar | Внутрішній статус. |
| ptah_document_id | varchar | ID документа у ПТАХ. |
| ptah_raw_status | varchar | Останній raw-статус ПТАХ. |
| last_sync_at | timestamp | Дата останньої синхронізації. |
| sent_at | timestamp | Дата передачі в ПТАХ. |
| sent_to_receiver_at | timestamp | Дата відправки отримувачу. |
| sent_to_tax_at | timestamp | Дата відправки до ДПС, якщо підтримується. |
| accepted_at | timestamp | Дата прийняття. |
| rejected_at | timestamp | Дата відхилення. |
| error_message | text | Остання помилка. |
| source_system | varchar | ERP або інша система-джерело. |
| created_at | timestamp | Дата створення. |
| updated_at | timestamp | Дата оновлення. |
16.2. tax_report_events
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID події. |
| report_id | uuid | ID документа. |
| event_type | varchar | Тип події. |
| old_status | varchar | Попередній статус. |
| new_status | varchar | Новий статус. |
| payload | jsonb | Технічні дані події. |
| created_by | varchar | Користувач або system. |
| created_at | timestamp | Дата події. |
16.3. tax_report_files
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID файлу. |
| report_id | uuid | ID документа. |
| file_type | varchar | original, signed, pdf, receipt_1, receipt_2, error_protocol. |
| file_name | varchar | Назва файлу. |
| file_path | varchar | Шлях до файлу. |
| content_type | varchar | MIME-тип. |
| size_bytes | integer | Розмір файлу. |
| created_at | timestamp | Дата створення. |
17. Обробка помилок
17.1. Типи помилок
| Тип помилки | Опис | Дія системи |
|---|---|---|
| ValidationError | Некоректні дані документа. | Не відправляти документ, показати список помилок. |
| PtahAuthError | Помилка авторизації в API.ПТАХ. | Зупинити відправку, повідомити адміністратора. |
| PtahApiError | API повернув помилку. | Записати відповідь API, дозволити повтор. |
| PtahTimeoutError | Перевищено час очікування. | Виконати retry. |
| PtahUnavailableError | Платформа ПТАХ недоступна. | Повторити пізніше, повідомити адміністратора. |
| DuplicateDocumentError | Документ вже був переданий. | Заборонити повтор без підтвердження. |
| FileStorageError | Неможливо прочитати або записати файл. | Зафіксувати помилку, повідомити адміністратора. |
| StatusMappingError | Невідомий статус від ПТАХ. | Зберегти raw-статус, створити подію UnknownStatus. |
| SignatureError | Помилка підписання документа. | Зберегти помилку, дозволити повторне підписання. |
17.2. Retry-логіка
Retry застосовується для:
- timeout;
- тимчасової недоступності API.ПТАХ;
- HTTP 429;
- HTTP 500;
- HTTP 502;
- HTTP 503;
- HTTP 504;
- тимчасових мережевих помилок.
Retry не застосовується для:
- помилок валідації;
- неправильного API key;
- відсутності прав доступу;
- відхилення документа отримувачем;
- дублювання документа;
- некоректного формату файлу;
- помилки КЕП через неправильний пароль.
18. Безпека
Система повинна забезпечити:
- зберігання API key тільки у змінних середовища або secret storage;
- заборону логування API key;
- заборону зберігання паролів КЕП у відкритому вигляді;
- маскування персональних даних у технічних логах;
- контроль доступу до документів;
- контроль доступу до квитанцій;
- журналювання всіх операцій;
- HTTPS для API-запитів;
- перевірку SSL-сертифіката;
- обмеження доступу до адміністративних endpoint-ів;
- резервне копіювання документів і квитанцій.
19. Налаштування
19.1. Змінні середовища
APP_ENV=production DATABASE_URL=postgresql+psycopg://user:password@db:5432/reports FILE_STORAGE_PATH=/data/tax-reports PTAH_BASE_URL=https://api.ptah.example PTAH_API_KEY=******** PTAH_CLIENT_ID=******** PTAH_CLIENT_SECRET=******** PTAH_COMPANY_CODE=12345678 PTAH_TIMEOUT_SECONDS=30 PTAH_RETRY_COUNT=3 PTAH_RETRY_BACKOFF_SECONDS=5 STATUS_SYNC_ENABLED=true STATUS_SYNC_INTERVAL_SECONDS=300 RECEIPT_DOWNLOAD_ENABLED=true
19.2. Конфігурація типів документів
document_types:
single_tax_declaration:
title: "Декларація платника єдиного податку"
allowed_formats:
- xml
- pdf
requires_signature: true
requires_receipt: true
tax_request:
title: "Запит до податкової"
allowed_formats:
- xml
- pdf
requires_signature: true
requires_receipt: true
unified_report:
title: "Об'єднана звітність"
allowed_formats:
- xml
- zip
requires_signature: true
requires_receipt: true
vat_declaration:
title: "Декларація з ПДВ"
allowed_formats:
- xml
- zip
requires_signature: true
requires_receipt: true
20. Логування та аудит
Система повинна логувати:
| Подія | Що зберігати |
|---|---|
| Створення документа | ID, користувач, дата, тип документа. |
| Валідація | Результат, список помилок. |
| Передача в ПТАХ | Endpoint, час, статус відповіді, зовнішній ID. |
| Підписання | Результат, дата, raw-відповідь ПТАХ. |
| Відправка | Результат, дата, raw-відповідь ПТАХ. |
| Помилка API | HTTP-код, тіло відповіді, correlation ID. |
| Оновлення статусу | Старий статус, новий статус, raw-статус ПТАХ. |
| Завантаження квитанції | Тип файлу, назва, дата. |
| Повторна відправка | Причина, користувач, дата. |
| Скасування документа | Причина, користувач, дата. |
21. Acceptance Criteria
21.1. Створення документа
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-1 | ERP передає дані документа у Python-сервіс. | У системі створюється запис tax_reports. |
| AC-2 | Передано файл документа. | Файл зберігається у файловому сховищі. |
| AC-3 | Передано некоректні дані. | Система повертає список помилок валідації. |
21.2. Передача в ПТАХ
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-4 | Документ має статус ReadyToSend. | Система дозволяє передачу в ПТАХ. |
| AC-5 | API.ПТАХ повертає успішну відповідь. | У документі зберігається ptah_document_id. |
| AC-6 | API.ПТАХ повертає помилку. | Система зберігає помилку та не втрачає документ. |
| AC-7 | Документ вже був переданий. | Система не створює дубль без окремого підтвердження. |
21.3. Підписання та відправка
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-8 | Документ створено в ПТАХ. | Система дозволяє ініціювати підписання, якщо це підтримується API. |
| AC-9 | Підписання виконано успішно. | Статус документа змінюється на Signed. |
| AC-10 | Документ підписано. | Система дозволяє відправку документа. |
| AC-11 | Відправка виконана успішно. | Статус документа змінюється на Sent. |
21.4. Статуси
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-12 | Worker запускає синхронізацію. | Статуси документів оновлюються автоматично. |
| AC-13 | ПТАХ повертає новий статус. | Внутрішній статус документа змінюється. |
| AC-14 | ПТАХ повертає невідомий статус. | Raw-статус зберігається, створюється подія UnknownStatus. |
21.5. Квитанції та файли
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-15 | Документ прийнято. | Система завантажує квитанцію або результат обробки. |
| AC-16 | Документ відхилено. | Система зберігає причину відхилення. |
| AC-17 | Користувач відкриває картку документа. | Він бачить всі пов'язані файли та статуси. |
22. MVP
До MVP входить:
- REST API для створення документа;
- збереження документа;
- базова валідація;
- Ptah Integration Client;
- передача документа в ПТАХ;
- збереження зовнішнього ID;
- ручний запуск синхронізації статусу;
- журнал подій;
- базова обробка помилок.
До MVP не входить:
- webhook-інтеграція;
- інтеграція напряму з ДПС;
- власний модуль КЕП;
- складний UI;
- автоматичне оновлення XSD;
- підтримка всіх типів звітності;
- автоматичне створення декларацій з бухгалтерських даних.
23. Етапи реалізації
Етап 1. Базова структура Python-сервісу
- створити FastAPI-проєкт;
- налаштувати PostgreSQL;
- створити моделі tax_reports, tax_report_events, tax_report_files;
- реалізувати конфігурацію через environment variables;
- реалізувати healthcheck endpoint.
Етап 2. Робота з документами
- реалізувати створення документа;
- реалізувати збереження файлу;
- реалізувати валідацію;
- реалізувати статуси;
- реалізувати журнал подій.
Етап 3. Ptah Integration Client
- реалізувати авторизацію;
- реалізувати upload_tax_report;
- реалізувати create_document;
- реалізувати get_document_status;
- реалізувати download_document;
- реалізувати download_receipts;
- реалізувати обробку помилок;
- реалізувати retry.
Етап 4. Передача документів
- реалізувати endpoint send-to-ptah;
- зберігати ptah_document_id;
- оновлювати статуси;
- логувати API-взаємодію.
Етап 5. Підписання та відправка
- реалізувати sign endpoint;
- реалізувати send endpoint;
- обробити помилки КЕП;
- обробити помилки відправки;
- фіксувати всі етапи в журналі.
Етап 6. Синхронізація статусів
- реалізувати background worker;
- реалізувати періодичне оновлення статусів;
- реалізувати мапінг статусів;
- реалізувати обробку невідомих статусів.
Етап 7. Квитанції та результати обробки
- реалізувати завантаження квитанцій;
- реалізувати збереження PDF/XML/receipt-файлів;
- реалізувати прив'язку файлів до документа;
- реалізувати перегляд історії.
Етап 8. Production hardening
- додати Dockerfile;
- додати docker-compose;
- додати structured logging;
- додати metrics;
- додати alerting;
- додати rate limiting;
- додати security review.
24. Ризики
| Ризик | Опис | Як зменшити |
|---|---|---|
| Непідтверджений сценарій подання звітності до ДПС | Публічно API.ПТАХ описаний як API для ЕДО, але сценарій податкової звітності потрібно підтвердити. | Отримати офіційну API-документацію та підтвердження від постачальника. |
| Неповна або закрита API-документація | Частина методів може бути доступна лише за договором або в окремому тарифі. | Отримати офіційну документацію та тестовий доступ. |
| Зміна API | Endpoint-и або формати відповіді можуть змінюватися. | Інкапсулювати API в окремому PtahClient. |
| Невідомі статуси | ПТАХ може повертати статуси, яких немає в системі. | Зберігати raw-статус та мати UnknownStatus. |
| Дублювання документів | Повторна відправка може створити дубль. | Перевіряти ptah_document_id перед відправкою. |
| Помилки авторизації | Доступ до API може бути неправильним або простроченим. | Додати healthcheck інтеграції та повідомлення адміністратору. |
| Недоступність ПТАХ | Платформа або мережа можуть бути тимчасово недоступні. | Використовувати retry та чергу задач. |
| Помилки КЕП | Можливі проблеми з ключами, паролями або сертифікатами. | Відображати зрозумілу помилку та дозволяти повторне підписання. |
| Персональні дані | Документи можуть містити РНОКПП, ЄДРПОУ, фінансові дані. | Маскувати логи та обмежити доступ. |
25. Відкриті питання
- Який саме продукт використовується: ПТАХ, API.ПТАХ або інтеграція через інший продукт Linkos Group?
- Чи підтримує ПТАХ сценарій подання податкової звітності до ДПС?
- Який базовий URL API?
- Який механізм авторизації використовується?
- Які endpoint-и використовуються для створення документа?
- Які endpoint-и використовуються для підписання?
- Які endpoint-и використовуються для відправки?
- Які endpoint-и використовуються для отримання статусів?
- Які endpoint-и використовуються для отримання квитанцій?
- Який формат документа підтримується: XML, PDF, ZIP, JSON?
- Чи Python-сервіс має сам формувати XML, чи отримує готовий XML з ERP?
- Де виконується КЕП: у Python-сервісі, у ПТАХ або користувачем у веб-інтерфейсі?
- Чи потрібна підтримка ФОП, юридичних осіб або обох варіантів?
- Які типи звітів підтримуються першими?
- Чи є тестове середовище?
- Чи підтримуються webhook-и?
- Який SLA по оновленню статусів?
- Де зберігати файли: локально, S3, MinIO, DMS?
- Хто має доступ до API key?
- Чи потрібно робити UI, чи тільки backend API?
26. Приклад структури Python-проєкту
tax_reporting_ptah_service/
app/
main.py
config.py
api/
routes/
tax_reports.py
health.py
core/
security.py
logging.py
exceptions.py
db/
session.py
models.py
migrations/
services/
tax_report_service.py
validation_service.py
status_sync_service.py
receipt_service.py
signing_service.py
integrations/
ptah/
client.py
schemas.py
status_mapper.py
exceptions.py
repositories/
tax_report_repository.py
event_repository.py
file_repository.py
workers/
sync_statuses.py
download_receipts.py
storage/
file_storage.py
tests/
unit/
integration/
Dockerfile
docker-compose.yml
pyproject.toml
README.md
27. Технічні вимоги до Python
| Компонент | Рекомендація |
|---|---|
| Python | 3.11 або вище. |
| Web framework | FastAPI. |
| HTTP client | httpx. |
| Validation | Pydantic. |
| ORM | SQLAlchemy. |
| DB | PostgreSQL. |
| Migrations | Alembic. |
| Background jobs | Celery, RQ або APScheduler. |
| Tests | pytest. |
| Containers | Docker. |
| Logging | structlog або стандартний logging у JSON-форматі. |
28. Definition of Done
Задача вважається завершеною, якщо:
- Python-сервіс розгортається через Docker;
- API створення документа працює;
- документ зберігається у БД та файловому сховищі;
- документ проходить валідацію;
- документ передається в ПТАХ;
- зовнішній ID документа зберігається;
- статус документа оновлюється;
- помилки API обробляються;
- retry-механізм працює;
- журнал подій заповнюється;
- написані unit-тести для ключових сервісів;
- написані інтеграційні тести для PtahClient з mock API;
- документація для запуску додана в README;
- фінальні endpoint-и ПТАХ винесені в конфігурацію;
- отримано підтвердження сценарію подання звітності до ДПС через ПТАХ або зафіксовано альтернативний сценарій.
29. Джерела
- https://edi.com.ua/
- https://fossdoc.com/sed-docs/ptah
- https://medoc.ua/news/api-ptah-vash-prostij-shljah-do-edo
- https://edo.linkos.ua/cases/vprovadzhennja-edo-z-apiptah
- https://cabinet.tax.gov.ua/help/api.html