Технічне завдання: отримання банківських виписок з Приват24 для Python
Головна ідея: розробити Python-сервіс, який автоматично отримує банківські виписки з Приват24 для бізнесу, зберігає операції, виконує дедублікацію та передає дані в ERP / бухгалтерську систему.
Важливо: основний сценарій інтеграції для бізнес-рахунків — через сервіс «Інтеграція / Автоклієнт» у Приват24 для бізнесу. Фінальні endpoint-и, формат авторизації та доступні поля виписки потрібно підтвердити в API-налаштуваннях конкретного клієнта ПриватБанку.
Технічний стек: Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Docker.
1. Мета
Метою задачі є створення Python-сервісу для автоматичного отримання банківських виписок з Приват24 для бізнесу.
Сервіс повинен забезпечити:
- підключення до API Приват24 / Автоклієнта;
- отримання списку доступних рахунків;
- отримання банківських операцій за рахунками;
- отримання виписки за період;
- регулярну синхронізацію виписок;
- збереження операцій у локальній БД;
- дедублікацію банківських транзакцій;
- обробку помилок API;
- ведення журналу синхронізації;
- передачу виписок в ERP / бухгалтерську систему.
2. Область застосування
Функціонал використовується для автоматизації імпорту банківських операцій з Приват24 для бізнесу в ERP або бухгалтерську систему.
До області задачі входить:
- створення Python API для керування інтеграцією;
- створення клієнта інтеграції з Приват24 / Автоклієнтом;
- отримання виписок за рахунками;
- отримання виписок за період;
- збереження raw-відповідей банку;
- нормалізація операцій;
- дедублікація операцій;
- фонове оновлення виписок;
- журнал синхронізації;
- retry-механізм;
- експорт даних у ERP.
До першої версії не входить:
- створення платежів;
- підписання платіжних доручень;
- відправка платежів у банк;
- валютний контроль;
- бухгалтерське проведення операцій;
- автоматичне рознесення оплат по рахунках;
- UI для повного банківського клієнта;
- інтеграція з картками фізичних осіб, якщо задача стосується лише бізнес-рахунків.
3. Джерела інтеграції
| Компонент | Призначення | Коментар |
|---|---|---|
| Приват24 для бізнесу | Основний кабінет клієнта для роботи з бізнес-рахунками. | У ньому підключається сервіс інтеграції. |
| Інтеграція / Автоклієнт | API-канал для автоматизації отримання виписки та надсилання платежів. | Основний рекомендований сценарій для бізнес-рахунків. |
| Відкрита виписка | Сервіс доступу до виписок за вибраними рахунками. | Може використовуватись як альтернативний або додатковий сценарій. |
| Python-сервіс | Інтеграційний шар між Приват24 та ERP. | Реалізується в межах цього ТЗ. |
| ERP / бухгалтерська система | Система-отримувач банківських операцій. | Наприклад K2 ERP або інша облікова система. |
4. Передумови
Для реалізації задачі необхідно отримати:
- доступ до Приват24 для бізнесу;
- доступ до потрібної компанії / ФОП;
- підключений сервіс «Інтеграція / Автоклієнт»;
- API credentials для Автоклієнта;
- перелік рахунків, за якими потрібно отримувати виписки;
- валюту рахунків;
- правила доступу користувачів;
- базовий URL API;
- формат авторизації;
- формат відповіді API;
- правила обмеження запитів;
- тестовий доступ або тестовий рахунок, якщо доступний.
5. Терміни та скорочення
| Термін | Опис |
|---|---|
| Python-сервіс | Окремий backend-сервіс або модуль для отримання виписок з Приват24. |
| Приват24 для бізнесу | Інтернет-банк ПриватБанку для ФОП та юридичних осіб. |
| Автоклієнт | Інтеграційний сервіс Приват24 для бізнесу для роботи з виписками та платежами. |
| Виписка | Перелік банківських операцій за рахунком за певний період. |
| Транзакція | Окрема банківська операція у виписці. |
| Polling | Періодичне опитування API для отримання нових операцій. |
| Webhook | Механізм отримання подій від зовнішньої системи, якщо підтримується. |
| Дедублікація | Виявлення та пропуск операцій, які вже були імпортовані. |
| ERP | Система, у яку передаються банківські операції. |
6. Архітектура рішення
6.1. Загальна схема
Приват24 для бізнесу / Автоклієнт
|
| 1. API виписок
v
Privat24 Integration Client
|
| 2. Отримання raw-виписки
v
Python Bank Statement Service
|
| 3. Нормалізація операцій
v
Validation & Deduplication Layer
|
| 4. Збереження в БД
v
PostgreSQL / File Storage
|
| 5. Передача в ERP
v
ERP / Accounting System
6.2. Основні компоненти Python-сервісу
| Компонент | Опис |
|---|---|
| API Layer | REST API для керування інтеграцією та запуску синхронізації. |
| Privat24 Client | Python-клієнт для роботи з API Приват24 / Автоклієнта. |
| Account Sync Service | Отримує та оновлює список рахунків. |
| Statement Sync Service | Отримує банківські виписки за рахунками. |
| Transaction Normalizer | Перетворює raw-операції банку у внутрішній формат. |
| Deduplication Service | Перевіряє, чи операція вже була імпортована. |
| ERP Export Service | Передає нормалізовані операції в ERP. |
| Audit Logger | Фіксує всі запити, відповіді, помилки та результати синхронізації. |
| Background Worker | Виконує регулярну синхронізацію за розкладом. |
7. User Story
7.1. Отримання виписки вручну
Як бухгалтер, я хочу запустити отримання виписки за вибраним рахунком і періодом, щоб швидко імпортувати банківські операції в ERP.
7.2. Автоматична синхронізація
Як бухгалтер, я хочу, щоб система автоматично отримувала нові банківські операції, щоб не завантажувати виписки вручну з Приват24.
7.3. Дедублікація операцій
Як користувач ERP, я хочу, щоб повторна синхронізація не створювала дублікати операцій, щоб бухгалтерський облік залишався коректним.
7.4. Контроль помилок
Як адміністратор, я хочу бачити журнал помилок інтеграції з Приват24, щоб швидко знаходити та виправляти проблеми.
7.5. Передача в ERP
Як бухгалтер, я хочу бачити отримані банківські операції в ERP, щоб виконувати звірку оплат і формувати проводки.
8. Функціональні вимоги
8.1. Налаштування інтеграції
Система повинна дозволяти зберігати налаштування підключення до Приват24.
Мінімальний набір параметрів:
| Поле | Тип | Обов'язковість | Опис |
|---|---|---|---|
| integration_name | string | Так | Назва інтеграції. |
| company_id | string | Так | Ідентифікатор компанії / ФОП у локальній системі. |
| privat24_client_id | string | Ні | Ідентифікатор клієнта, якщо використовується. |
| api_key | secret | Так | Ключ або токен доступу до API. |
| base_url | string | Так | Базова адреса API. |
| is_active | boolean | Так | Ознака активності інтеграції. |
| sync_interval_minutes | integer | Так | Інтервал автоматичної синхронізації. |
| default_date_from | date | Ні | Дата початку первинного імпорту. |
8.2. Отримання списку рахунків
Система повинна мати можливість отримати або зберегти перелік рахунків, за якими імпортується виписка.
Логічний endpoint Python-сервісу:
POST /api/v1/bank-integrations/{integration_id}/sync-accounts
Очікувана дія:
- Виконати запит до API Приват24.
- Отримати список доступних рахунків.
- Нормалізувати рахунки.
- Зберегти або оновити рахунки в локальній БД.
- Записати результат у журнал.
8.3. Отримання виписки за період
Система повинна дозволяти отримати виписку за конкретним рахунком та періодом.
Логічний endpoint Python-сервісу:
POST /api/v1/bank-accounts/{account_id}/sync-statement
Приклад тіла запиту:
{
"date_from": "2026-05-01",
"date_to": "2026-05-07",
"force": false
}
Очікувана дія:
- Перевірити доступ до рахунку.
- Перевірити коректність періоду.
- Виконати запит до API Приват24.
- Отримати raw-виписку.
- Зберегти raw-відповідь.
- Нормалізувати операції.
- Виконати дедублікацію.
- Зберегти нові операції.
- Передати операції в ERP, якщо увімкнено експорт.
- Записати результат у журнал.
8.4. Автоматична синхронізація
Система повинна мати background worker для автоматичного отримання нових операцій.
Рекомендований алгоритм:
1. Знайти всі активні інтеграції. 2. Для кожної інтеграції знайти активні рахунки. 3. Для кожного рахунку визначити дату останньої успішної синхронізації. 4. Запитати виписку з останньої дати до поточної дати. 5. Зберегти нові операції. 6. Оновити last_successful_sync_at. 7. Записати результат у журнал.
8.5. Нормалізація операцій
Raw-операція Приват24 повинна бути перетворена у внутрішню модель.
Мінімальний набір полів операції:
| Поле | Тип | Опис |
|---|---|---|
| transaction_id | string | Унікальний ID операції з банку або сформований hash. |
| account_id | uuid | Внутрішній ID рахунку. |
| account_number | string | IBAN або номер рахунку. |
| operation_date | date | Дата операції. |
| value_date | date | Дата валютування, якщо доступна. |
| amount | decimal | Сума операції. |
| currency | string | Валюта операції. |
| direction | string | debit або credit. |
| balance_after | decimal | Залишок після операції, якщо доступний. |
| counterparty_name | string | Назва контрагента. |
| counterparty_account | string | Рахунок контрагента. |
| counterparty_code | string | ЄДРПОУ / РНОКПП контрагента, якщо доступно. |
| payment_purpose | text | Призначення платежу. |
| document_number | string | Номер платіжного документа. |
| raw_payload | jsonb | Оригінальна відповідь банку. |
8.6. Дедублікація
Система повинна не допускати дублювання операцій.
Пріоритетні ключі дедублікації:
- Унікальний ID операції від банку.
- Комбінація: рахунок + дата + сума + номер документа + призначення платежу.
- Hash від нормалізованих ключових полів.
- Raw reference / bank reference, якщо доступний.
Приклад hash-ключа:
sha256(account_number + operation_date + amount + currency + document_number + payment_purpose)
8.7. Передача операцій в ERP
Система повинна підтримувати передачу операцій в ERP.
Режими передачі:
| Режим | Опис |
|---|---|
| Push | Python-сервіс сам передає операції в ERP після синхронізації. |
| Pull | ERP самостійно забирає операції через API Python-сервісу. |
| Manual export | Користувач експортує виписку у CSV / JSON / XML. |
9. Статуси інтеграції та операцій
9.1. Статуси синхронізації
| Статус | Опис |
|---|---|
| NotConfigured | Інтеграція ще не налаштована. |
| Active | Інтеграція активна. |
| Disabled | Інтеграція вимкнена. |
| AuthError | Помилка авторизації. |
| Syncing | Виконується синхронізація. |
| SyncSuccess | Синхронізацію завершено успішно. |
| SyncFailed | Синхронізацію завершено з помилкою. |
9.2. Статуси банківських операцій
| Статус | Опис |
|---|---|
| Imported | Операцію імпортовано з банку. |
| Duplicate | Операція визначена як дубль. |
| ExportedToERP | Операцію передано в ERP. |
| ExportFailed | Помилка передачі в ERP. |
| Ignored | Операцію пропущено за правилом. |
| Matched | Операцію зіставлено з документом в ERP. |
| Posted | Операцію проведено в обліку. |
10. API Python-сервісу
10.1. Створення інтеграції
POST /api/v1/bank-integrations
Приклад тіла запиту:
{
"integration_name": "Privat24 Main Company",
"company_id": "company-001",
"provider": "privat24_business",
"base_url": "https://api.privatbank.ua/...",
"api_key": "SECRET_VALUE",
"sync_interval_minutes": 30,
"is_active": true
}
Очікувана відповідь:
{
"id": "f4d2758e-9a97-4e64-80fb-443b9b864b01",
"status": "Active",
"message": "Integration created"
}
10.2. Перевірка підключення
POST /api/v1/bank-integrations/{integration_id}/check-connection
Очікувана відповідь:
{
"integration_id": "f4d2758e-9a97-4e64-80fb-443b9b864b01",
"status": "Active",
"message": "Connection successful"
}
10.3. Синхронізація рахунків
POST /api/v1/bank-integrations/{integration_id}/sync-accounts
Очікувана відповідь:
{
"integration_id": "f4d2758e-9a97-4e64-80fb-443b9b864b01",
"accounts_created": 2,
"accounts_updated": 1
}
10.4. Синхронізація виписки
POST /api/v1/bank-accounts/{account_id}/sync-statement
Приклад тіла запиту:
{
"date_from": "2026-05-01",
"date_to": "2026-05-07",
"force": false
}
Очікувана відповідь:
{
"account_id": "a5f0e82b-efb6-4f3a-8e08-4abefbb58c45",
"date_from": "2026-05-01",
"date_to": "2026-05-07",
"imported": 42,
"duplicates": 3,
"errors": 0
}
10.5. Отримання списку операцій
GET /api/v1/bank-accounts/{account_id}/transactions?date_from=2026-05-01&date_to=2026-05-07
10.6. Експорт операцій в ERP
POST /api/v1/bank-accounts/{account_id}/export-to-erp
10.7. Отримання журналу синхронізації
GET /api/v1/bank-integrations/{integration_id}/sync-events
11. Privat24 Integration Client
11.1. Призначення
Privat24 Integration Client — це Python-клас або пакет, який інкапсулює роботу з API Приват24 / Автоклієнта.
11.2. Основні методи
class Privat24Client:
def check_connection(self) -> "Privat24ConnectionResponse":
pass
def get_accounts(self) -> list["Privat24Account"]:
pass
def get_statement(
self,
account_number: str,
date_from: date,
date_to: date,
) -> "Privat24StatementResponse":
pass
def get_transaction_details(
self,
transaction_id: str,
) -> "Privat24TransactionResponse":
pass
11.3. Конфігурація клієнта
from pydantic_settings import BaseSettings
class Privat24Settings(BaseSettings):
base_url: str
api_key: str
client_id: str | None = None
company_id: str | None = None
timeout_seconds: int = 30
retry_count: int = 3
retry_backoff_seconds: int = 5
verify_ssl: bool = True
Приклад змінних середовища:
PRIVAT24_BASE_URL=https://api.privatbank.ua/... PRIVAT24_API_KEY=******** PRIVAT24_CLIENT_ID=******** PRIVAT24_COMPANY_ID=company-001 PRIVAT24_TIMEOUT_SECONDS=30 PRIVAT24_RETRY_COUNT=3 PRIVAT24_RETRY_BACKOFF_SECONDS=5
Заборонено: зберігати API key, client secret, токени або банківські credentials у коді, Git-репозиторії чи відкритих логах.
12. Отримання виписки
12.1. Логічний процес
1. Отримати рахунок з БД. 2. Перевірити, що інтеграція активна. 3. Визначити період синхронізації. 4. Викликати Privat24Client.get_statement(). 5. Зберегти raw-відповідь банку. 6. Нормалізувати операції. 7. Виконати дедублікацію. 8. Зберегти нові операції. 9. Передати операції в ERP, якщо увімкнено auto_export. 10. Оновити дату останньої синхронізації. 11. Записати результат у журнал.
12.2. Приклад Python-логіки
from datetime import date
from uuid import UUID
def sync_statement(
account_id: UUID,
date_from: date,
date_to: date,
db: "Session",
) -> "StatementSyncResult":
account = bank_account_repository.get_by_id(db, account_id)
integration = bank_integration_repository.get_by_id(
db,
account.integration_id,
)
if not integration.is_active:
raise IntegrationDisabledError("Privat24 integration is disabled")
response = privat24_client.get_statement(
account_number=account.account_number,
date_from=date_from,
date_to=date_to,
)
raw_statement_repository.save(
db=db,
account_id=account.id,
date_from=date_from,
date_to=date_to,
payload=response.raw_payload,
)
imported = 0
duplicates = 0
for raw_operation in response.operations:
operation = transaction_normalizer.normalize(
account=account,
raw_operation=raw_operation,
)
if transaction_repository.exists_by_unique_key(
db,
operation.unique_key,
):
duplicates += 1
continue
transaction_repository.create(db, operation)
imported += 1
account.last_successful_sync_at = datetime.utcnow()
sync_event_repository.create(
db=db,
integration_id=integration.id,
account_id=account.id,
event_type="STATEMENT_SYNC_SUCCESS",
payload={
"date_from": str(date_from),
"date_to": str(date_to),
"imported": imported,
"duplicates": duplicates,
},
)
db.commit()
return StatementSyncResult(
imported=imported,
duplicates=duplicates,
errors=0,
)
13. Автоматична синхронізація
13.1. Рекомендований режим
Для бізнес-рахунків рекомендовано виконувати синхронізацію:
| Тип синхронізації | Інтервал | Опис |
|---|---|---|
| Поточний день | кожні 15–30 хвилин | Отримання нових операцій за поточний день. |
| Попередній день | 1 раз на день | Контрольна синхронізація для операцій, які могли з'явитися із затримкою. |
| Архівний період | вручну | Завантаження історичних виписок за вибраний період. |
13.2. Приклад worker-а
from datetime import date, timedelta
def sync_all_active_accounts() -> None:
accounts = bank_account_repository.get_active_accounts()
for account in accounts:
try:
date_to = date.today()
date_from = account.last_successful_sync_at.date() \
if account.last_successful_sync_at else date_to
sync_statement(
account_id=account.id,
date_from=date_from,
date_to=date_to,
db=session_factory(),
)
except Exception as exc:
sync_event_repository.create(
db=session_factory(),
integration_id=account.integration_id,
account_id=account.id,
event_type="STATEMENT_SYNC_FAILED",
payload={"error": str(exc)},
)
14. Модель даних
14.1. bank_integrations
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | Внутрішній ID інтеграції. |
| provider | varchar | privat24_business. |
| integration_name | varchar | Назва інтеграції. |
| company_id | varchar | ID компанії в ERP. |
| base_url | varchar | Базова адреса API. |
| api_key_encrypted | text | Зашифрований API key. |
| client_id | varchar | ID клієнта, якщо використовується. |
| is_active | boolean | Ознака активності. |
| sync_interval_minutes | integer | Інтервал синхронізації. |
| last_check_at | timestamp | Дата останньої перевірки підключення. |
| last_successful_sync_at | timestamp | Дата останньої успішної синхронізації. |
| created_at | timestamp | Дата створення. |
| updated_at | timestamp | Дата оновлення. |
14.2. bank_accounts
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | Внутрішній ID рахунку. |
| integration_id | uuid | ID інтеграції. |
| company_id | varchar | ID компанії в ERP. |
| account_number | varchar | IBAN або номер рахунку. |
| account_name | varchar | Назва рахунку. |
| currency | varchar | Валюта рахунку. |
| bank_mfo | varchar | МФО банку. |
| is_active | boolean | Чи синхронізується рахунок. |
| last_successful_sync_at | timestamp | Дата останньої успішної синхронізації. |
| created_at | timestamp | Дата створення. |
| updated_at | timestamp | Дата оновлення. |
14.3. bank_transactions
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | Внутрішній ID операції. |
| account_id | uuid | ID рахунку. |
| unique_key | varchar | Унікальний ключ для дедублікації. |
| bank_transaction_id | varchar | ID операції від банку, якщо доступний. |
| operation_date | date | Дата операції. |
| value_date | date | Дата валютування. |
| amount | numeric | Сума операції. |
| currency | varchar | Валюта. |
| direction | varchar | debit або credit. |
| balance_after | numeric | Залишок після операції. |
| counterparty_name | varchar | Контрагент. |
| counterparty_account | varchar | Рахунок контрагента. |
| counterparty_code | varchar | ЄДРПОУ / РНОКПП контрагента. |
| payment_purpose | text | Призначення платежу. |
| document_number | varchar | Номер документа. |
| status | varchar | Статус операції. |
| raw_payload | jsonb | Raw-відповідь банку. |
| imported_at | timestamp | Дата імпорту. |
| exported_to_erp_at | timestamp | Дата передачі в ERP. |
14.4. bank_sync_events
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID події. |
| integration_id | uuid | ID інтеграції. |
| account_id | uuid | ID рахунку. |
| event_type | varchar | Тип події. |
| status | varchar | Результат. |
| date_from | date | Початок періоду. |
| date_to | date | Кінець періоду. |
| imported_count | integer | Кількість імпортованих операцій. |
| duplicate_count | integer | Кількість дублів. |
| error_count | integer | Кількість помилок. |
| payload | jsonb | Технічні дані події. |
| created_at | timestamp | Дата події. |
15. Обробка помилок
15.1. Типи помилок
| Тип помилки | Опис | Дія системи |
|---|---|---|
| Privat24AuthError | Помилка авторизації. | Зупинити синхронізацію, повідомити адміністратора. |
| Privat24ApiError | API повернув помилку. | Записати відповідь API, дозволити повтор. |
| Privat24TimeoutError | Перевищено час очікування. | Виконати retry. |
| Privat24RateLimitError | Перевищено ліміт запитів. | Збільшити інтервал повтору. |
| AccountAccessError | Немає доступу до рахунку. | Вимкнути рахунок або повідомити адміністратора. |
| StatementParseError | Неможливо розібрати відповідь банку. | Зберегти raw-відповідь і помилку. |
| DuplicateTransactionError | Операція вже існує. | Позначити як Duplicate або пропустити. |
| ErpExportError | Помилка передачі в ERP. | Зберегти операцію та дозволити повторний експорт. |
15.2. Retry-логіка
Retry застосовується для:
- timeout;
- тимчасової недоступності API;
- HTTP 429;
- HTTP 500;
- HTTP 502;
- HTTP 503;
- HTTP 504;
- тимчасових мережевих помилок.
Retry не застосовується для:
- неправильного API key;
- відсутності доступу до рахунку;
- некоректного періоду;
- помилок валідації налаштувань;
- операцій, які вже імпортовані.
16. Безпека
Система повинна забезпечити:
- зберігання API key тільки у змінних середовища або secret storage;
- шифрування API key у БД;
- заборону логування API key;
- маскування номерів рахунків у технічних логах за потреби;
- маскування персональних даних контрагентів у логах;
- контроль доступу до виписок;
- журналювання всіх операцій синхронізації;
- HTTPS для всіх API-запитів;
- перевірку SSL-сертифіката;
- обмеження доступу до адміністративних endpoint-ів;
- резервне копіювання виписок і журналів.
17. Налаштування
17.1. Змінні середовища
APP_ENV=production DATABASE_URL=postgresql+psycopg://user:password@db:5432/bank_statements FILE_STORAGE_PATH=/data/bank-statements PRIVAT24_BASE_URL=https://api.privatbank.ua/... PRIVAT24_API_KEY=******** PRIVAT24_CLIENT_ID=******** PRIVAT24_COMPANY_ID=company-001 PRIVAT24_TIMEOUT_SECONDS=30 PRIVAT24_RETRY_COUNT=3 PRIVAT24_RETRY_BACKOFF_SECONDS=5 STATEMENT_SYNC_ENABLED=true STATEMENT_SYNC_INTERVAL_SECONDS=1800 ERP_EXPORT_ENABLED=true
17.2. Конфігурація синхронізації
bank_statement_sync:
provider: privat24_business
default_period_days: 3
sync_current_day: true
sync_previous_day_daily: true
deduplication:
strategy: bank_id_or_hash
hash_fields:
- account_number
- operation_date
- amount
- currency
- document_number
- payment_purpose
export_to_erp:
enabled: true
mode: push
18. Логування та аудит
Система повинна логувати:
| Подія | Що зберігати |
|---|---|
| Створення інтеграції | ID, користувач, дата, provider. |
| Перевірка підключення | Результат, дата, технічний статус. |
| Синхронізація рахунків | Кількість створених і оновлених рахунків. |
| Запит виписки | Рахунок, період, час запиту. |
| Успішна синхронізація | Кількість імпортованих операцій і дублів. |
| Помилка API | HTTP-код, тіло відповіді, correlation ID. |
| Дедублікація | Кількість пропущених операцій. |
| Експорт в ERP | Кількість переданих операцій, результат. |
| Помилка експорту | Текст помилки, ID операції, дата. |
19. Acceptance Criteria
19.1. Налаштування інтеграції
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-1 | Адміністратор створює інтеграцію з Приват24. | У системі створюється запис bank_integrations. |
| AC-2 | Адміністратор перевіряє підключення. | Система повертає успішний або помилковий результат. |
| AC-3 | API key неправильний. | Система показує AuthError і не запускає синхронізацію. |
19.2. Отримання рахунків
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-4 | Запущено sync-accounts. | Система отримує та зберігає рахунки. |
| AC-5 | Рахунок уже існує. | Система оновлює його дані, а не створює дубль. |
19.3. Отримання виписки
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-6 | Користувач запускає sync-statement за період. | Система отримує виписку з Приват24. |
| AC-7 | У виписці є нові операції. | Система зберігає нові операції в bank_transactions. |
| AC-8 | У виписці є вже імпортовані операції. | Система не створює дублікати. |
| AC-9 | API Приват24 повертає помилку. | Система зберігає помилку в журналі. |
19.4. Автоматична синхронізація
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-10 | Worker запущено. | Система автоматично синхронізує активні рахунки. |
| AC-11 | Синхронізація успішна. | Оновлюється last_successful_sync_at. |
| AC-12 | Синхронізація завершилась помилкою. | Помилка записується в bank_sync_events. |
19.5. Передача в ERP
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-13 | Увімкнено ERP export. | Нові операції передаються в ERP. |
| AC-14 | ERP повертає успіх. | Операції отримують статус ExportedToERP. |
| AC-15 | ERP повертає помилку. | Операції отримують статус ExportFailed. |
20. MVP
До MVP входить:
- REST API для створення інтеграції;
- збереження API credentials;
- перевірка підключення;
- отримання списку рахунків;
- отримання виписки за період;
- збереження raw-відповіді;
- нормалізація операцій;
- дедублікація;
- збереження операцій у PostgreSQL;
- ручний запуск синхронізації;
- журнал подій;
- базова обробка помилок.
До MVP не входить:
- створення платежів;
- підписання платежів;
- webhook-інтеграція;
- складний UI;
- автоматичне рознесення оплат;
- підтримка всіх банків;
- валютний контроль;
- прогнозування платежів.
21. Етапи реалізації
Етап 1. Базова структура Python-сервісу
- створити FastAPI-проєкт;
- налаштувати PostgreSQL;
- створити моделі bank_integrations, bank_accounts, bank_transactions, bank_sync_events;
- реалізувати конфігурацію через environment variables;
- реалізувати healthcheck endpoint.
Етап 2. Налаштування інтеграції
- реалізувати створення інтеграції;
- реалізувати зберігання credentials;
- реалізувати шифрування API key;
- реалізувати check-connection;
- реалізувати журнал налаштувань.
Етап 3. Privat24 Integration Client
- реалізувати авторизацію;
- реалізувати get_accounts;
- реалізувати get_statement;
- реалізувати обробку помилок;
- реалізувати retry;
- написати mock-тести.
Етап 4. Синхронізація рахунків
- реалізувати sync-accounts;
- зберігати рахунки;
- оновлювати існуючі рахунки;
- дозволити активувати / деактивувати рахунки.
Етап 5. Синхронізація виписок
- реалізувати sync-statement;
- зберігати raw-відповіді;
- нормалізувати операції;
- реалізувати дедублікацію;
- зберігати операції.
Етап 6. Автоматична синхронізація
- реалізувати background worker;
- реалізувати періодичне оновлення виписок;
- реалізувати контроль останньої успішної синхронізації;
- реалізувати повторну синхронізацію після помилки.
Етап 7. Передача в ERP
- реалізувати export-to-erp;
- реалізувати статуси експорту;
- обробити помилки ERP;
- додати повторний експорт.
Етап 8. Production hardening
- додати Dockerfile;
- додати docker-compose;
- додати structured logging;
- додати metrics;
- додати alerting;
- додати rate limiting;
- додати security review.
22. Ризики
| Ризик | Опис | Як зменшити |
|---|---|---|
| Неповна API-документація | Частина параметрів Автоклієнта може бути доступна тільки після підключення в Приват24 для бізнесу. | Отримати credentials і технічні налаштування в кабінеті клієнта. |
| Зміна API | Формат відповіді або endpoint-и можуть змінюватися. | Інкапсулювати API в окремому Privat24Client. |
| Дублювання операцій | Повторна синхронізація може створити дублікати. | Реалізувати кілька рівнів дедублікації. |
| Затримка операцій | Деякі операції можуть з'являтися у виписці із затримкою. | Щодня повторно синхронізувати попередній день. |
| Помилки авторизації | API key може бути неправильним або зміненим. | Додати check-connection і сповіщення адміністратора. |
| Rate limit | API може обмежувати частоту запитів. | Додати backoff і контроль інтервалів. |
| Персональні дані | Виписки містять фінансові та персональні дані. | Маскувати логи, шифрувати secrets, обмежити доступ. |
23. Відкриті питання
- Який саме канал використовується: Автоклієнт, Відкрита виписка або інший API ПриватБанку?
- Який базовий URL API для конкретного клієнта?
- Який механізм авторизації використовується?
- Які рахунки потрібно синхронізувати?
- Чи потрібна підтримка ФОП, юридичних осіб або обох варіантів?
- Чи потрібна підтримка валютних рахунків?
- Який максимальний історичний період потрібно імпортувати?
- Як часто потрібно оновлювати виписки?
- Чи потрібно передавати операції в ERP автоматично?
- Чи потрібно реалізувати ручний експорт CSV / JSON?
- Які поля операції обов'язкові для ERP?
- Який алгоритм дедублікації вважати основним?
- Чи потрібно зберігати raw-відповіді банку?
- Хто має доступ до API key?
- Чи потрібен UI, чи тільки backend API?
24. Приклад структури Python-проєкту
privat24_statement_service/
app/
main.py
config.py
api/
routes/
bank_integrations.py
bank_accounts.py
bank_transactions.py
health.py
core/
security.py
logging.py
exceptions.py
db/
session.py
models.py
migrations/
services/
account_sync_service.py
statement_sync_service.py
transaction_normalizer.py
deduplication_service.py
erp_export_service.py
integrations/
privat24/
client.py
schemas.py
exceptions.py
repositories/
bank_integration_repository.py
bank_account_repository.py
bank_transaction_repository.py
sync_event_repository.py
workers/
sync_statements.py
storage/
raw_statement_storage.py
tests/
unit/
integration/
Dockerfile
docker-compose.yml
pyproject.toml
README.md
25. Технічні вимоги до 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-форматі. |
| Secrets | Vault, Doppler, AWS Secrets Manager або аналог. |
26. Definition of Done
Задача вважається завершеною, якщо:
- Python-сервіс розгортається через Docker;
- API створення інтеграції працює;
- API key зберігається безпечно;
- check-connection працює;
- список рахунків отримується або зберігається вручну;
- виписка за період отримується;
- raw-відповідь зберігається;
- операції нормалізуються;
- дедублікація працює;
- операції зберігаються в БД;
- автоматична синхронізація працює;
- помилки API обробляються;
- retry-механізм працює;
- журнал подій заповнюється;
- написані unit-тести для ключових сервісів;
- написані інтеграційні тести для Privat24Client з mock API;
- документація для запуску додана в README;
- фінальні endpoint-и Приват24 винесені в конфігурацію.
27. Джерела
- https://privatbank.ua/business/intehratsiya
- https://privatbank.ua/business/openstatement
- https://api.privatbank.ua/
- https://privatbank.ua/business/app-pryvat24
- https://privatbank.ua/business/vse-servisy-ucheta-i-otchetnosti