Документація
Загальний опис
Метою розробки є інтеграція з ЄДР для автоматизації та централізації отримання даних про КБВ (кінцевого бенефеціарного власника) для учасників що є юридичними особами. Даний інформація може бути обовʼязковим/не обовʼязковим для певних процедур (наразі розробка інтеграції відбувається тільки для процедур де є документ з типом x_ultimateBeneficiaryInfo).
Для реалізації цієї інтеграції необхідно виконати дії:
- Додати до базової моделі award необовʼязкову до заповнення поле beneficiaries моделю даних beneficiariesGeneralInfo (модель даних наведено нижче)
- Налаштувати інтеграцію з ЄДР де після відпраки запиту заповнюється модель beneficiariesGeneralInfo
- При внесенні інформації змінюємо award.dateModified, dateModified (procedure) та systemDateModified
- Майданчики відображають дану інформацію організатору в його кабінеті. Відображення в інших місцях не є обовʼязковою (портал, кабінети учасників)
- Модель даних beneficiariesGeneralInfo
Технічна назва Бізнес назва (x-legalName) Тип Read only Обовʼязковість (потребує уточнень) Коментар uk_UA en_US beneficiaries Інформація про кінцевого бенефеціарного влсника Information about the ultimate beneficial owner list of objects true false beneficiariesGeneralInfo
object true false beneficialName ПІБ кінцевого бенефеціарного власника Full name of the ultimate beneficial owner string (multilang) true true В запиті Прізвище це відповідь на один запит, Імʼя та По батькові - відповідь на інший запит address Адреса Address model true true beneficiariesType
Тип бенефіціарного володіння Type of beneficiaries
string (multilang) true true role Роль КБВ по відношенню до пов’язаного суб’єкта string true true Відповідь на запит текстове відображення ролі (roleText) interest
Відсоток частки статутного капіталу або відсоток права голосу float true true indirectInterest
Відсоток частки статутного капіталу або відсоток права голосу у разі непрямого впливу float true true otherImpact
Інший характер та міру впливу beneficiaryFalse
Ознака можливої недостовірності інформації про КБВ excluded
Ознака виключення відомостей про КБВ за вказівкою Міністерства юстиції України isMissing
Ознака відсутності КБВ юридичної особи reason
Причина відсутності КБВ юридичної особи informationDate Дата отримання даних Date of information string ($dateTime) true true
Технічні вимоги до автоматичного збагачення award даними КБВ з ЄДР
- Майданчик, залучає користувача до участі в аукціоні де звіт з інформацією про КБВ (x_ultimateBeneficiaryInfo) визначений як тип документу
- Учасник є юридичною особою
- Учасник подає заявку на участь
- Майданчик активує заявку на участь
- Заявка на участь перейшла в кваліфікацію
- Під час створення award (асинхронний запит)ЦБД направляє запит в ЄДР з авторизаційним ключем і даними для пошуку де виконуються умови:
- Для award в статусах: pending_waiting, pending_admission, pending
- Для award.bidders.identifier.UA-EDR
- Для процедур де x_ultimateBeneficiaryInfo є типом документу. Перелік процедур
- LLE, LLD, LLP - Оренда за законом
- LRE - Земельні торги - оренда
- LSE + LSP - Земельні торги - продаж/продаж з переважним правом
- REM - Процедури розподілу квот
- SSW - Продаж майна приватних компаній (Закриті пропозиції)
- SPE + SPD - Мала приватизація
- LPE - Велика приватизація
- LAE + LAP + LAW - Продаж арештованої землі
- APE + APD - Арештовані активи АРМА
- SAE + SAD - Санкційне майно
- SUE+SUD - Спеціальні дозволи на користування надрами
- Процедури, яких немає в переліку не використовують даний функціонал - РО попереджено що додавання нових напрямків йде через розробку
- ЦБД отримує дані з ЄДР
- Перевіряє отримані дані:
- Якщо в отриманій відповіді містяться дані, які не можна внести в award → ЦБД не вносить дані в award
- Якщо в отриманій відповіді містяться дані, які можна внести в award → ЦБД вносить дані в award
- При внесенні даних змінюється:
- award.dateModified
- dateModified (procedure)
- systemDateModified
- При внесенні даних змінюється:
- Перевіряє отримані дані:
Ключові бізнес-правила
- Інтеграція тригериться тільки при створенні award
- Запит асинхронний
- Дані записуються тільки якщо валідні
- Запис — атомарний (все або нічого)
- Можливі декілька КБВ
- Retry (3 рази) тільки для:
- 500
- 502
- Slack alert тільки для:
- 4xx + 429
- Fallback текст при недоступності ЄДР
- У разі отримання першої відповіді від ЄДР з HTTP статусом 402 або 429 ЦБД має призупинити направлення всіх наступних запитів до сервісу ЄДР до моменту ручного або автоматичного відновлення інтеграції після внесення коштів / відновлення ліміту.
- Якщо не вдається отримати відповідь виводимо в поле текст "Не вдалось отримати інформацію з сервісу"
Статуси інтеграції (В разі якщо будемо виносити в Адмінку та або будемо в принципі зупиняти запити в разі отримання помилок)
| Статус | Опис |
|---|---|
active | Запити до ЄДР виконуються |
payment_required | Отримано 402, запити зупинено |
rate_limit_exceeded | Отримано 429, запити зупинено |
suspended | Загальний статус призупинення |
restored | Інтеграцію відновлено |
Як працює сервіс ЄДР
Сервіс ЄДР реалізований як API для автоматичного отримання даних для внесення інформації про КБВ учасника торгів що кваліфікується. Взаємодія працює по протоколу HTTP з використанням авторизації через JWT. Загальна логіка процесу: спочатку через метод авторизації отримуємо access та refresh токени, а потім використовуємо їх для виклику ендпоінту отримання даних для заповнення інформації про КБВ за кодом ЄДРПОУ юридичною особи. - Детальніше буде додано після отримання тестового ключа
Дія тестового ключа 6 місяців
Доступні ендпоінти (Потребує перевірки та доповнення після отримання тестових ключей)
Авторизація (отримання токенів)
Оновлення access_token
Метод отримання унікального ідентифікатора
Метод: POST
Ендпоінт: https://targetServer/1.0/subjects?code=ХХХХХХХХ, де code - код ЄДРПОУ учасника
Приймає на вхід:
- Обовʼязковий query-параметр: code
Приклад запиту:
Приклади відповіді:
Якщо code знайдено, а також токен авторизації є валідним:
Якщо code не знайдено:
Якщо сплив термін дії токена авторизації:
Якщо сервіс наразі недоступний:
Також можливий кейс, що АРІ поверне 403 помилку, якщо, наприклад, ЄДР змінить права доступу нашого акаунту.
Перелік кодів помилок
Коди помилок та відповідей:
Коди відповідей HTTP
Код | Текст | Пояснення |
|---|---|---|
200 | OK | Запит успішно оброблено і повернуто результат |
400 | Bad Request | Запит має помилку або не може бути оброблений. Відповідне повідомлення з поясненнями додане до відповіді. |
401 | Unauthorized | Параметри авторизації не правильні, або не вказані взагалі. |
402 | PaymentRequired | Для виконання запиту необхідна оплата. |
403 | Forbidden | Запит вірний але в обробці відмовлено. Відповідне повідомлення з поясненнями додано до відповіді. |
404 | Not Found | Адреса не правильна або ресурс до якого йде запит не існує. |
406 | Not Acceptable | Дані передані в запиті мають не зрозумілий формат. |
429 | Many Requests | API повертає таку відповідь коли вичерпано обмеження запитів до ресурсу. |
500 | Internal Server Error | Щось зламалось. |
502 | Bad Gateway | Сервіс вимкнено або проходить оновлення. |
Повідомлення з інформацією про помилку.
У разі помилки API повертає відповідь з поясненням, формат - JSON, наприклад:
{"errors":[{"message":"Invalid or expired token","code":2}]}
Перелік кодів помилок
У відповіді, окрім повідомлення з поясненням, додатково надається код помилки, який можна використовувати для автоматизованої обробки. Протягом часу, текстове повідомлення може модифікуватись, але код залишається незмінним.
Код | Текст | Пояснення |
1 | Could not authenticate you або Authentication credentials were not provided | Помилка аутентифікації. |
2 | Invalid or expired token | Недіючий або некоректний токен. |
3 | Your account is not permitted to access this resource | Відповідь надається разом із HTTP статусом 403. Користувач, з використанням токену якого було виконано аутентифікацію, не має достатніх прав для виконання запиту. |
4 | Sorry, that page does not exist | Відповідь надається разом із HTTP статусом 404. Сторінка до якої виконується запит не знайдена. |
5 | Paiment required | Відповідь надається разом із HTTP статусом 402. Недостатньо коштів для виконання платного запиту. |
6 | Parse Error або `search_date` has wrong format | Відповідь надається разом із HTTP статусом 400. Не правильний формат одного або декількох параметрів запиту. |
9 | Rate limit exceeded | Відповідь надається разом із HTTP статусом 429. Вичерпано кількість запитів, дозволених виконати протягом проміжку часу. |
10 | `code` or `passport` parameter must be provided. | У запиті не надано параметрів необхідних для виконання пошуку. |
11 | `passport` parameter has wrong value. | Один або більше параметрів запиту має невірний формат. |
20 | Internal error | Відповідь надається разом із HTTP статусом 500. |
Правила обробки помилок
| HTTP code | Дія системи |
|---|---|
| 400 | Slack alert, дані не записуються |
| 401 | Slack alert, спроба оновити token |
| 402 | Slack alert, дані не записуються |
| 403 | Slack alert, дані не записуються |
| 404 | Slack alert, дані не записуються |
| 406 | Slack alert, дані не записуються |
| 429 | Slack alert, дані не записуються |
| 500 | Retry до 3 разів |
| 502 | Retry до 3 разів |
User Story 1
| Як | ЦБД Prozorro.Sale |
| я хочу | автоматично отримувати та зберігати інформацію про кінцевих бенефіціарних власників (КБВ) з ЄДР при створенні award |
| щоб | забезпечити актуальність, централізацію та зменшити залежність від ручного введення даних |
USE CASE 1 — Успішне отримання та збереження КБВ
Назва | Отримання та запис КБВ з ЄДР в award |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат | award містить список КБВ (може бути декілька) |
Acceptance Criteria
1 | Given | Всі умови виконані |
When | Створюється award | |
Then | Відправляється запит до ЄДР | |
2 | Given | ЄДР повернув валідні дані |
When | Дані проходять валідацію | |
Then | Вони записуються в award.beneficiaries | |
3 | Given | Дані записані |
Then | оновлюються всі dateModified:
|
USE CASE 2 — Дані не можуть бути внесені
Назва | Відмова у записі КБВ |
| Актори |
|
| Передумови | Отримано HTTP код: |
| Основний сценарій |
|
| Результат | award без змін |
Acceptance Criteria
1 | Given | Дані не відповідають моделі |
When | Виконується валідація | |
Then | Дані не записуються |
USE CASE 3 — Retry при помилках 500 / 502
Назва | Повторна спроба отримання даних |
| Актори |
|
| Передумови | Отримано HTTP код: |
| Основний сценарій |
|
| Альтернативний сценарій | після 3 невдалих спроб → fallback |
| Результат |
|
Acceptance Criteria
1 | Given | Отримано 500/502 |
When | Виконується retry | |
Then | Система повторює запит до 3 разів | |
2 | Given | Всі retry невдалі |
Then | Записується повідомлення: |
USE CASE 4 — Логування помилок в Slack
Назва | Моніторинг інтеграції з ЄДР |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | Отримано помилку зі списку |
When | Обробляється відповідь | |
Then | Відправляється повідомлення в Slack |
USE CASE 5 — Інтеграція не запускається
Назва | Неініціювання запиту до ЄДР |
| Актори |
|
| Передумови | Будь-яка з умов НЕ виконується:
|
| Основний сценарій |
|
| Результат | Жодних запитів до ЄДР |
Acceptance Criteria
1 | Given | Умови не виконані |
When | Створюється award | |
Then | запит до ЄДР не виконується |
USE CASE 6 — Обробка множинних КБВ
Назва | Запис кількох бенефіціарів |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат | Збережено всі КБВ |
Acceptance Criteria
1 | Given | ЄДР повертає кілька КБВ |
When | Відбувається запис | |
Then | Всі КБВ зберігаються в масиві |
User Story 2. Зупинка запитів в разі отримання помилок 402 або 429
| Як | ЦБД Prozorro.Sale |
| я хочу | зупиняти направлення запитів до ЄДР після першого отримання помилки 402 або 429 |
| щоб | не створювати зайве навантаження на сервіс, не витрачати ліміти та уникати повторних неуспішних запитів до моменту відновлення доступу/поповнення коштів. |
| додатково | Після внесення коштів або відновлення ліміту система має відновити направлення запитів до ЄДР. |
USE CASE 7 — Зупинка запитів після отримання 402
Назва | Автоматичне призупинення інтеграції з ЄДР при помилці 402 Payment Required |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | ЦБД отримала від ЄДР відповідь 402 |
When | Система обробляє відповідь | |
Then | Інтеграція з ЄДР переходить у статус призупинення. | |
2 | Given | Інтеграція має статус призупинення через |
When | Створюється новий award, який відповідає умовам інтеграції | |
Then | ЦБД не направляє запит до ЄДР. | |
3 | Given | Отримано 402 |
| When | Система фіксує помилку | |
Then | Повідомлення надсилається в Slack канал. |
USE CASE 8 — Зупинка запитів після отримання 429
Назва | Автоматичне призупинення інтеграції з ЄДР при помилці 429 Many Requests |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | ЦБД отримала відповідь 429 |
When | Система обробляє відповідь | |
Then | Направлення нових запитів до ЄДР зупиняється. | |
2 | Given | Інтеграція призупинена через |
When | Створюється новий award | |
Then | ЦБД не направляє запит до ЄДР | |
3 | Given | Отримано 429 |
| When | Система обробляє помилку | |
Then | Повідомлення надсилається в Slack канал. |
USE CASE 9 — Відновлення запитів після внесення коштів
Назва | Ручне або автоматичне відновлення інтеграції з ЄДР після внесення коштів |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | Інтеграція призупинена через 402 |
| And | Кошти внесено | |
When | Адміністратор активує інтеграцію | |
Then | Статус інтеграції змінюється на active. | |
2 | Given | Інтеграція активна після відновлення |
When | Створюється новий award | |
Then | ЦБД направляє запит до ЄДР | |
3 | Given | ЄДР після відновлення повертає 200 |
| When | ЦБД отримує валідні дані | |
Then | Дані записуються в |
USE CASE 10 — Відновлення після вичерпання ліміту запитів
Назва | Відновлення інтеграції після помилки 429 |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат |
|
Acceptance Criteria
1 | Given | Інтеграція призупинена через 429 |
When | Ліміт запитів відновлено | |
And | Адміністратор активує інтеграцію | |
Then | ЦБД знову направляє запити до ЄДР | |
2 | Given | Інтеграція активована після |
When | Створюється award | |
Then | Запит до ЄДР виконується |
User Story 3. Обробка помилок інтеграції з ЄДР та забезпечення стабільності системи
| Як | ЦБД Prozorro.Sale |
| я хочу | коректно обробляти всі типи помилок від ЄДР (400, 401, 403, 404, 406, 500, 502) |
| щоб | забезпечити стабільну роботу системи, не втрачати дані та мати можливість відновлення інтеграції |
USE CASE 1 — Успішне отримання та збереження КБВ
Назва | Отримання та запис КБВ з ЄДР в award |
| Актори |
|
| Передумови |
|
| Основний сценарій |
|
| Результат | award містить список КБВ (може бути декілька) |
Acceptance Criteria
1 | Given | Всі умови виконані |
When | Створюється award | |
Then | Відправляється запит до ЄДР | |
2 | Given | ЄДР повернув валідні дані |
When | Дані проходять валідацію | |
Then | Вони записуються в award.beneficiaries | |
3 | Given | Дані записані |
Then | оновлюються всі dateModified:
|
🧩 USER STORY (для обробки помилок ЄДР)
Назва:
User Story:
Як ЦБД
я хочу
щоб
🔐 USE CASE 1 — Обробка 401 (Unauthorized)
Назва
Автоматичне оновлення токена при помилці 401
Актори
- ЦБД
- ЄДР
- Slack
Передумови
- Запит до ЄДР виконано
- Отримано
401 Unauthorized
Основний сценарій
- ЦБД отримує
401 - Визначає, що токен невалідний / протермінований
- Виконує запит на оновлення
access_tokenчерезrefresh_token - Отримує новий токен
- Повторює запит до ЄДР (1 раз)
- Якщо успішно → стандартний сценарій (запис даних)
Альтернативи
- Refresh token невалідний → перейти до помилки критичного рівня
Результат
- Інтеграція відновлюється без втручання людини
Acceptance Criteria
- Given отримано 401
When токен протермінований
Then система виконує refresh token - Given токен оновлено
Then запит повторюється 1 раз - Given повторний запит успішний
Then дані записуються в award
❗ USE CASE 2 — Помилка 400 (Bad Request)
Назва
Обробка некоректного запиту до ЄДР
Причина
- неправильний формат параметрів
- неправильний code
Основний сценарій
- ЦБД отримує
400 - Аналізує помилку
- Визначає:
- помилка у формуванні запиту
- НЕ виконує retry
- Логує помилку
- Надсилає повідомлення в Slack
Рішення
- виправлення формату запиту (dev fix)
Результат
- запит не повторюється
- потрібне втручання розробника
Acceptance Criteria
- Given отримано 400
When обробляється помилка
Then retry не виконується
And Slack отримує повідомлення
🚫 USE CASE 3 — Помилка 403 (Forbidden)
Назва
Обробка відсутності прав доступу
Причина
- змінились права доступу до API
- акаунт не має доступу
Основний сценарій
- ЦБД отримує
403 - Фіксує помилку
- НЕ виконує retry
- Відправляє alert в Slack
- (опційно) переводить інтеграцію в статус
restricted
Рішення
- перевірка прав доступу
- перевидача ключів / ролей
Результат
- інтеграція не працює до виправлення
Acceptance Criteria
- Given отримано 403
Then retry не виконується
And Slack повідомляється
🔍 USE CASE 4 — Помилка 404 (Not Found)
Назва
Обробка відсутності суб’єкта в ЄДР
Причина
- ЄДРПОУ не знайдено
Основний сценарій
- ЦБД отримує
404 - Визначає, що суб'єкт відсутній
- НЕ виконує retry
- НЕ записує beneficiaries
- (опційно) записує reason:
- "Суб'єкт не знайдено в ЄДР"
Результат
- award без КБВ
Acceptance Criteria
- Given отримано 404
Then retry не виконується
And дані не записуються
⚠️ USE CASE 5 — Помилка 406 (Not Acceptable)
Назва
Обробка помилки формату даних
Причина
- некоректний формат request/response
Основний сценарій
- ЦБД отримує
406 - Фіксує помилку
- НЕ виконує retry
- Відправляє alert в Slack
Рішення
- перевірка контракту API
- виправлення формату
Результат
- інтеграція потребує доопрацювання
Acceptance Criteria
- Given отримано 406
Then retry не виконується
And Slack повідомляється
🔄 USE CASE 6 — Помилки 500 / 502 (Server errors)
(у тебе вже частково є, але тут — повна версія)
Назва
Retry при серверних помилках ЄДР
Основний сценарій
- ЦБД отримує
500або502 - Виконує retry (до 3 разів)
- Якщо успіх → стандартний сценарій
- Якщо всі retry fail:
- записує fallback текст
- НЕ падає
Рішення
- автоматичне повторення
- graceful fallback
Результат
- система стабільна навіть при падінні ЄДР
Acceptance Criteria
- Given 500/502
Then retry до 3 разів - Given retry fail
Then записується fallback повідомлення
🧠 ЗВЕДЕНА ТАБЛИЦЯ (ДУЖЕ ВАЖЛИВО ДЛЯ ТЗ)
| Код | Retry | Зупинка інтеграції | Slack | Дія |
|---|---|---|---|---|
| 400 | ❌ | ❌ | ✅ | баг у запиті |
| 401 | 🔁 (1 раз) | ❌ | ❌ | refresh token |
| 402 | ❌ | ✅ | ✅ | чекати оплату |
| 403 | ❌ | ⚠️ (можливо) | ✅ | перевірити доступ |
| 404 | ❌ | ❌ | ❌ | немає суб'єкта |
| 406 | ❌ | ❌ | ✅ | формат |
| 429 | ❌ | ✅ | ✅ | ліміт |
| 500 | 🔁 (3 рази) | ❌ | ❌ | тимчасова помилка |
| 502 | 🔁 (3 рази) | ❌ | ❌ | сервіс недоступний |
🧩 ГЛОБАЛЬНЕ БІЗНЕС-ПРАВИЛО
Система повинна диференційовано обробляти помилки ЄДР:
- технічні помилки (500, 502) → retry
- авторизаційні (401) → refresh token
- бізнес/доступ (402, 403, 429) → зупинка або alert
- помилки даних (400, 404, 406) → без retry, з логуванням
Система не повинна виконувати безкінечні повторні запити.