| Тип сервісу
|
Хмарний кваліфікований електронний підпис. SEO-опис
</syntaxhighlight>
|
payload={"smartid_session_id": response.session_id},
"callback_context": {
|
== 17. Валідація документа перед підписом ==
|
-
|
document_version_id
|
uuid
|
реліз системи документа. SEO-опис
12.2. Основні компоненти Python-сервісу
Критично критично: якщо офіційний API SmartID недоступний для конкретного бізнес-сценарію, потрібно передбачити альтернативний режим: користувач системи підписує документ вручну у Приват24 / SmartID, а платформа приймає підписаний файл або p7s на завантаження та виконує перевірку підпису. |-
|
document_number
|
varchar
|
-
|
Кінцева платформа
|
MANUAL_REVIEW. |-
|
entity_id
|
uuid
|
ID сутності. SEO-опис
=== 8.3. Адміністратор перевіряє помилки ===
) -> "SignatureFile":
'''критично:''' точні API endpoint-и. |}
router = APIRouter()
<div style="border-left: 6px solid #2e7d32; background: #e8f5e9; padding: 12px 16px; margin: 16px 0;">
entity_type="signature_session",
pass
"file_id": "file-001",
|-
| AC-21
| Керівник відкриває dashboard. Очікуваний результат
SMARTID_SERVICE_CERTIFICATE_PATH=/run/secrets/smartid_service_cert.pem
<pre>
GET /api/v1/smartid-signature/signature-requests/{request_id}/status
! |-
| source
| varchar
| SMARTID_API або MANUAL_UPLOAD. | style="background:#fff9c4;" | Жовтий
|-
| Очікує результат
| WAITING_RESULT
| Підписання підтверджено, платформа очікує результат. |}
=== 8.1. користувач системи підписує документ ===
</div>
* автоматичне створення сесії підписання через SmartID API;
* ручне завантаження підписаного документа, якщо API недоступне або користувач системи підписав документ поза системою. | style="background:#c8e6c9;" | Зелений
|-
| Відхилено користувачем
| DECLINED_BY_USER
| користувач системи не підтвердив підписання. |-
| mime_type
| varchar
| MIME type. №
},
)
payload=result.raw_payload,
"file_name": "contract_123.pdf",
return
! Створити сесію підписання. Тип
! |-
| Підтвердження користувачем
| Статус сесії, час. Код
except Exception as exc:
request.document.status = "VERIFIED"
"raw_response": response.raw_payload,
raise BusinessError("Document cannot accept signature in current status")
audit_logger.log(
new_status="SIGN_ERROR",
{| class="wikitable"
<div style="border-left: 6px solid #6a1b9a; background: #f3e5f5; padding: 12px 16px; margin: 16px 0;">
SMARTID_PRIVATE_KEY_PATH=/run/secrets/smartid_private_key.pem
[[Категорія:Інтеграції]]
платформа повинна:
! | Статус стає VERIFIED. |-
| Отримання підпису
| file_id, hash підпису, час. платформа повинна забезпечити:
"idempotency_key": command.idempotency_key,
=== 30.7. Dashboard ===
Після отримання результату підписання платформа повинна виконати перевірку. |-
| new_status
| varchar
| Новий статус. Код
! |-
| file_hash_sha256
| Hash файлу. | style="background:#ffcc80;" | Помаранчевий
|-
| Прострочено
| EXPIRED
| Строк сесії підписання минув. |-
| signature_request_id
| uuid
| Заявка. |-
| SmartID Client
| Python-клієнт для API SmartID. |-
| AC-18
| Callback повторився. "tax_id": "1234567890"
db: "Session",
"signed_at": result.signed_at,
== 16. Приклад запиту на створення заявки на підпис ==
audit_logger.log(
"smartid_session_id": response.session_id,
)
payload={"external_document_id": command.external_document_id},
<div style="border-left: 6px solid #1565c0; background: #e3f2fd; padding: 12px 16px; margin: 16px 0;">
pass
! | Ідемпотентність callback. Показник
! |-
| Нагадування про прострочення
| Низький
| Фоновий бізнес-процес. |-
| Audit Event
| Подія журналу. |-
| smartid_session_id
| varchar
| ID сесії SmartID. # Чи потрібен fallback зі ручним завантаженням p7s? | Не створювати сесію. |-
| AC-8
| користувач системи підтверджує підпис. |-
| status
| varchar
| Статус заявки. Статус
=== 22.2. Пріоритети задач ===
)
! |-
| AC-17
| Callback має правильний підпис/секрет. |-
| AC-5
| Документ перевищує ліміт розміру. |-
| event_type
| varchar
| Тип події. response = await smartid_client.create_session(payload)
v
я хочу бачити кількість документів на підписі, підписаних, відхилених і прострочених,
! |-
| signed_at
| timestamp
| Час підписання. | інтеграційні функції ERP зберігається в системі. ! | Версіонування і hash документа. },
щоб контролювати електронний документообіг. |-
| is_active
| boolean
| Активність. |-
| document_version_id
| реліз системи документа. | style="background:#fff9c4;" | Жовтий
|-
| Завершена
| COMPLETED
| Сесія завершена успішно. Сутність
! Компонент
це Python-клас або пакет, який інкапсулює роботу з API ПриватБанку / SmartID виступає ключовою рисою SmartID Client. | style="background:#ef9a9a;" | Червоний
|-
| Потребує ручної перевірки
| MANUAL_REVIEW
| Неможливо автоматизовано визначити результат. | style="background:#f3e5f5;" | Контроль
|-
| Ручне завантаження
| Підписи, завантажені користувачем вручну. | Очікує підпису, активна сесія. |-
| created_at
| timestamp
| Дата створення. # Чи потрібно перевіряти РНОКПП / ЄДРПОУ підписанта? |}
"document_version_id": document.current_version_id,
=== 23.4. signature_requests ===
{| class="wikitable"
signature_verification_repository.create(
Для реалізації задачі необхідно отримати:
|-
| id
| uuid
| ID події. Статус
db.commit()
pass
{{SEO
|title=Технічне завдання: Накладення електронного підпису за допомогою Приват24 / SmartID для Python
|description=Технічне завдання на реалізацію Python-сервісу для накладення електронного підпису за допомогою КЕП ПриватБанку / SmartID: документи, hash, сесії підписання, callback, p7s, перевірка підпису, журналювання, dashboard та безпека.
|keywords=Python, Приват24, ПриватБанк, SmartID, КЕП, електронний підпис, хмарний підпис, підписання документів, FastAPI, K2 ERP, p7s, електронний документообіг
}}
SMARTID_CALLBACK_URL=https://example.com/api/v1/smartid/callback
# Перевірка callback signature / secret залежить від офіційної документації SmartID. | style="background:#ef9a9a;" | Червоний
|-
| Прострочений сертифікат
| CERT_EXPIRED
| Сертифікат підписанта недійсний на момент перевірки. Задача
</pre>
{| class="wikitable"
__TOC__
partner_secret: str | None = None
{| class="wikitable"
! SEO-опис
|-
| API Layer
| REST API для створення заявок на підпис. |-
| Signer
| Підписант. Поле
</pre>
платформа повинна логувати:
=== 6.3. Підписання документа клієнтом ===
== 2. Область сценарії використання ==
! |-
| signer_identifier
| varchar
| Ідентифікатор підписанта, якщо доступний. |-
| Document Version
| реліз системи документа, яка передана на підпис. |-
| AC-19
| Callback невалідний. користувач системи натискає «Підписати через Приват24 / SmartID». |-
| file_type
| varchar
| signature, signed_container, signed_pdf. | Відхилено, прострочено. KPI
! Дія
! Перевести заявку у WAITING_SIGNATURE. Тип
! '''Критично критично:''' платформа не повинна зберігати пароль користувача до КЕП, приватний ключ або секрети підпису. Тип помилки
)
<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">
== 35. Джерела ==
! | Перевести в SIGN_ERROR або NEEDS_RETRY. Тип
request = signature_request_repository.get_by_id(db, signature_request_id)
SmartID у межах цього ТЗ розглядається як хмарний КЕП ПриватБанку, який користувач системи створює та використовує через Приват24. Поле
)
* приймати тільки HTTPS-запити;
* перевіряти підпис або секрет callback, якщо передбачено API;
* перевіряти session_id;
* перевіряти request_id;
* перевіряти idempotency callback;
* зберігати raw payload;
* оновлювати статус сесії;
* зберігати файл підпису або посилання на результат;
* запускати перевірку підпису;
* повертати коректний HTTP status. |-
| result
| varchar
| VALID, INVALID, HASH_MISMATCH тощо. API SmartID / ПриватБанк
! K2 ERP / CRM / Website
signature_queue.enqueue(
=== 15.7. Завантаження підписаного документа ===
=== 27.2. Приклад dashboard ===
"signature_file_id": str(signature_file.id),
=== 30.4. Ручне завантаження ===
=== Етап 2. Базовий Python-сервіс ===
! | style="background:#fff9c4;" | Жовтий
|-
| Очікує підтвердження
| WAITING_USER_CONFIRMATION
| користувач системи має підтвердити підпис у Приват24 / SmartID. Документ
=== 6.2. Підписання пакета документів ===
|
| 3. Повторне отримання одного й того самого результату не повинно дублювати підпис або некоректно змінювати фінальний статус. try:
"email": "client@example.com",
'''Технічний стек:''' Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker, S3-compatible file storage. | style="background:#ef9a9a;" | Критично
|-
| Ручна перевірка
| Потрібне втручання адміністратора. Очікуваний результат
* наявність external_document_id;
* наявність idempotency_key;
* наявність файлу документа;
* файл доступний у сховищі;
* файл не порожній;
* розмір файлу не перевищує ліміт;
* MIME type дозволений;
* документ не був змінений після створення заявки;
* hash документа збережений;
* підписант визначений;
* строк підписання не минув;
* документ ще не підписаний цим підписантом;
* бізнес-процес дає можливість підписання;
* користувач системи має право ініціювати підписання;
* телефон або ідентифікатор підписанта відповідає даним користувача, якщо це потрібно для SmartID-сценарію. |-
| current_version_id
| uuid
| Поточна реліз системи. |-
| Канал користувача
| Приват24 / Приват24 для бізнесу / SmartID. | платформа створює заявку на підпис. |}
! ! Пріоритет
result = await smartid_client.get_signature_result(session.smartid_session_id)
SMARTID_RETRY_COUNT=3
! | Статус стає EXPIRED. | style="background:#e3f2fd;" | інформаційні матеріали
|-
| Очікують підпису
| Документи з активною сесією. Тип
! |-
| certificate_info
| jsonb
| інформаційні дані сертифіката. | style="background:#c8e6c9;" | Норма
|-
| Відхилено
| користувач системи відмовився. SEO-опис
я хочу бачити статус підписання документа,
! # Який точний формат результату підписання: p7s, ASIC, PDF з підписом або інший? |-
| created_at
| timestamp
| Дата створення.=== 24.5. Ручне завантаження підпису ===
* невалідного документа;
* документа, який змінився;
* простроченої сесії;
* відхилення користувачем;
* невірного callback signature;
* невідповідності підписанта;
* вже фінального статусу VERIFIED. |-
| Рекомендація
| Використовувати як fallback-сценарій. | Retry, якщо безпечно. SEO-опис
smartid_session_id=payload ["session_id"],
== 8. User Story ==
"expires_at": response.expires_at,
GET /api/v1/smartid-signature/documents/{document_id}/signed-file
if not callback_security_service.is_valid(request, payload):
4. | style="background:#ffcc80;" | Потрібна дія
|-
| Помилки
| Помилки підписання або callback. request=request,
def upload_manual_signature(
== 6. Основні сценарії інтеграції ==
=== 5.3. Варіант 3. Комбінована схема ===
[[Категорія:API]]
! |}
SmartID Adapter
{| class="wikitable"
)
"expires_at": "2026-05-07T14:30:00+03:00"
</pre>
|-
| id
| uuid
| ID документа. |-
| created_at
| timestamp
| Дата створення. |-
| style="background:#ffcc80;" | Помаранчевий
| #ffcc80
| Потрібна дія або виступає як ризик. | Помилка підписання, помилка перевірки. |-
| id
| uuid
| ID перевірки. | style="background:#c8e6c9;" | Зелений
|-
| Невалідний
| INVALID
| Підпис не пройшов перевірку. №
! SEO-опис
SMARTID_TIMEOUT_SECONDS=30
except Exception as exc:
SMARTID_PARTNER_SECRET=********
! |-
| signature_request_id
| uuid
| Заявка. |}
POST /api/v1/smartid-signature/documents/{document_id}/verify
15.6. Callback від SmartID)
13. SmartID Client
| id
|
uuid
|
ID версії. Як зменшити
27.3. Проблемні документи
private_key_path: str | None = None
partner_id: str
service_certificate_path: str | None = None
pass
},
15.9. Ручне завантаження підпису
6. | DRAFT, archived. Параметр
db.commit()
27. Dashboard керівника
32. Етапи реалізації
document_version = document_version_repository.get_by_id(db, request.document_version_id)
Головна ідея: розробити Python-сервіс, який дає можливість користувачам підписувати документи за допомогою електронного підпису ПриватБанку / SmartID / Приват24 із подальшим збереженням документа, файлу підпису, статусу підписання, журналу дій і результату перевірки підпису. |-
|
partner_secret_encrypted
|
text
|
Зашифрований секрет. SEO-опис
|
| AC-1
|
Створення сесії, підписання. Критерій
|
| ValidationError
|
-
|
created_at
|
timestamp
|
style="background:#fff9c4;" | Увага
|
| Підписано
|
Підпис отримано. Критерій
Управлінський результат: відповідальна особа повинна бачити, які документи очікують підпису через Приват24 / SmartID, які підписані, які відхилені, які прострочені, які мають помилки підписання, які потребують повтору або ручної перевірки. |-
|
id
|
uuid
|
ID заявки. "document_name": "Договір поставки №123",
- додати rate limiting;
- додати alerting;
- додати dead letter queue;
- додати backup файлів;
- додати моніторинг callback / polling;
- додати безпечне зберігання секретів. Очікуваний результат
"document_number": "123",
task_name="create_smartid_signature_session",
POST /api/v1/smartid-signature/integrations/{integration_id}/check-connection
|
-
|
AC-2
|
Уточнити формат за документацією SmartID. K2 ERP отримує фінальний статус. :contentReference [oaicite:1]{index=1}
|
async def smartid_signature_callback(request: Request):
- реалізувати get_service_certificate;
- реалізувати create_session;
- реалізувати create_signature_request;
- реалізувати get_session_status;
- реалізувати get_signature_result;
- реалізувати обробку помилок. Що зберігати
document_file_id=document_version.file_id,
|
| AC-4
|
-
|
Помилка
|
-
|
Polling Worker
|
-
|
service_certificate_path
|
varchar
|
Шлях до сертифіката сервісу. # Чи потрібна інтеграційні функції ERP з K2 ERP? finally:
платформа підтримує обидва режими:
class SmartIDSignatureSettings(BaseSettings):
7. | Вони підсвічуються фіолетовим. |}
24.1. Створення заявки на підпис
5. |}
data={
33. Ризики
event_type="SMARTID_SIGNATURE_SESSION_ERROR",
)
15.2. Перевірка підключення
async def create_smartid_signature_session(signature_request_id: str, db: "Session") -> None:
15.1. Створення інтеграції
8. Тип
SMARTID_PARTNER_ID=********
19.1. Callback-сценарій
Етап 7. Перевірка підпису
|
}
1. Мета
POST /api/v1/smartid-signature/documents
"result": result.code,
2. !
if new_status == "COMPLETED":
def create_session(self, payload: "CreateSessionPayload") -> "SignatureSessionResponse":
if session.status in ["COMPLETED", "DECLINED", "EXPIRED", "ERROR"]:
26. Retry-логіка
signature_file = signature_storage.save_signature_result(
11. Єдина логіка кольорів
|
style="background:#c8e6c9;" | Зелений
|
| Відхилена
|
DECLINED
|
}
audit_logger.log(
callback_id = callback_service.get_callback_id(payload)
|
-
|
Signature File
|
-
|
Рекомендація
|
базовий production-сценарій, якщо API доступний. SEO-опис
SMARTID_SESSION_TTL_MINUTES=15
|
-
|
конкурентні переваги
|
-
|
updated_at
|
timestamp
|
платформа не дублює результат. |-
|
Confirmation Service
|
Керує сесією підтвердження підпису користувачем.== Див. 36. так само ==
|
-
|
created_at
|
timestamp
|
-
|
Обмеження
|
Статус стає VERIFY_ERROR. | платформа отримує результат і зберігає підпис. |}
24.3. Polling статусу сесії
entity_id=request.id,
- timeout;
- HTTP 429;
- HTTP 500;
- HTTP 502;
- HTTP 503;
- HTTP 504;
- тимчасової помилки створення сесії;
- тимчасової помилки отримання статусу;
- тимчасової помилки отримання результату;
- тимчасової помилки перевірки підпису;
- повторного callback з тим самим callback_id. |-
|
status
|
varchar
|
-
|
base_url
|
varchar
|
-
|
AC-15
|
-
|
Callback Event
|
style="background:#fff9c4;" | Жовтий
|
| Підписується
|
SIGNING
|
Передбачити fallback: ручне завантаження підпису. |-
|
Помилка перевірки
|
-
|
smartid_session_id
|
платформа приймає callback. |-
|
AC-3
|
-
|
Audit Logger
|
Заявка не створюється. | style="background:#bbdefb;" | Блакитний
|
| Активна
|
ACTIVE
|
Сесія розроблена та очікує дії користувача. Результат
)
=== 15.10. Перевірка підпису ===
current_user: "User",
payload={"signature_request_id": str(request.id)},
=== 15.4. Створення заявки на підпис ===
{| class="wikitable"
"source": "MANUAL_UPLOAD",
! ! |-
| Document Service
| Робота з документами та версіями. |-
| AC-13
| Підпис не відповідає документу. |}
if existing:
{| class="wikitable"
)
! Поле
Перед створенням заявки платформа повинна перевірити:
)
pass
}
<pre>
return existing
! # Чи потрібне пакетне підписання? | платформа показує AuthError і не створює сесії. |-
| VerificationError
| Підпис не пройшов перевірку. Ключ
event_type="SIGNATURE_REQUEST_CREATED",
idempotency_key=command.idempotency_key,
signature_file = signature_file_repository.get_by_id(db, signature_file_id)
== 30. Acceptance Criteria ==
! |-
| file_hash_sha256
| varchar
| Hash файлу. Поле
{| class="wikitable"
{| class="wikitable"
! №
"file_hash_sha256": stored_file.sha256,
! Подія
v
def get_session_status(self, session_id: str) -> "SignatureSessionStatusResponse":
{{DISPLAYTITLE:Технічне завдання: Накладення електронного підпису за допомогою Приват24 / SmartID для Python}}
=== 15.5. Отримання статусу заявки ===
=== Варіант 1. 5.1. Пряма API-інтеграція зі SmartID ===
== 21. Дедублікація ==
|-
| 07.05.2026
| Договір №123
| Іван Петренко
| style="background:#ffcc80;" | Прострочено
| користувач системи не завершив підписання
| Створити нову заявку
|-
| 07.05.2026
| Акт №45
| Олена Сидоренко
| style="background:#ef9a9a;" | Помилка перевірки
| Hash документа не збігається
| Ручна перевірка
|-
| 07.05.2026
| Заява №77
| ТОВ «Альфа»
| style="background:#f3e5f5;" | Ручна перевірка
| Неможливо автоматизовано визначити підписанта
| Перевірити сертифікат
|}
return {"status": "ok"}
щоб оперативно знаходити причини невдалого підписання. Очікуваний результат
* створює задачу на підпис;
* показує її у списку задач K2 ERP;
* контролює строк підписання;
* нагадує про прострочення;
* зберігає аудит дій. |-
| Невідповідність підписанта
| Документ підписала не та особа. |-
| конкурентні переваги
| Не потребує повної інтеграції з API SmartID. Критерій
signature_file: "UploadedFile",
new_status="MANUAL_REVIEW",
! # Чи потрібно підписувати PDF, XML, DOCX або будь-який файл? | style="background:#ef9a9a;" | Червоний
|-
| Ручна перевірка
| MANUAL_REVIEW
| Потрібна перевірка адміністратором. # Який строк дії сесії підписання? |-
| idempotency_key
| Унікальний ключ заявки. |-
| created_at
| timestamp
| Дата створення. |-
| TimeoutError
| API недоступне або timeout. | Статус стає MANUAL_REVIEW або VERIFY_ERROR. HTML
payload={
new_status="ACTIVE",
| -
|
Document
|
Документ, який потрібно підписати. Колір
клієнт ERP отримує посилання на документ.
</syntaxhighlight>
- отримати офіційну технічну документацію;
- отримати тестові credentials;
- погодити callback URL або polling-сценарій;
- перевірити тестовий сценарій;
- визначити формат результату підписання;
- визначити правила перевірки підпису. SEO-опис
|
-
|
document_date
|
date
|
Дата документа.=== Етап 5. Callback / polling та підпис ===
payload={"error": str(exc)},
|
Перевірка даних сертифіката. Тип
Можливі результати:
Рекомендовано для K2 ERP: реалізувати базовий режим через API SmartID, а так само резервний режим ручного завантаження p7s / підписаного контейнера з подальшою перевіркою. "file_mime_type": "application/pdf",
- масове підписання великого пакета документів;
- складний UI документообігу;
- власний кваліфікований надавач електронних довірчих послуг;
- повна юридична експертиза документів;
- інтеграційні функції ERP з усіма зовнішніми ЕДО-системами;
- автоматичне виправлення документів;
- архів довгострокового зберігання за окремими регламентами. Тип
document_version=document_version,
"raw_request": payload,
|
-
|
signature_request_id
|
uuid
|
Заявка.Як менеджер,
async def poll_smartid_session(signature_session_id: str, db: "Session") -> None:
платформа:
if callback_repository.exists(callback_id):
* цілісність документа;
* відповідність підпису конкретній версії документа;
* валідність підпису;
* валідність сертифіката;
* інформаційні дані підписанта;
* час підписання;
* статус відкликання сертифіката, якщо доступно;
* чи відповідає підписант очікуваному користувачу;
* чи не минув строк сесії;
* чи не змінювався документ після підпису. |-
| callback_url
| varchar
| Callback URL. |-
| created_at
| Дата створення версії. data={
db=db,
"k2_entity_id": "contract-001"
== 31. MVP ==
session.status = "COMPLETED"
=== Етап 8. Dashboard та аудит ===
"document_type": "CONTRACT",
},
{| class="wikitable"
payload={"uploaded_by": str(current_user.id)},
== 3. Що таке SmartID / електронний підпис Приват24 у межах інтеграції ==
def cancel_session(self, session_id: str) -> "CancelSessionResponse":
=== 13.2. Основні методи ===
До MVP не входить:
{| class="wikitable"
Retry заборонений для:
|-
| Прийом callback
| Критичний
| Не можна втрачати результат підписання. task_name="verify_manual_signature",
|
| Документів за день
|
184
|
інформаційні матеріали
|
| Очікують підпису
|
32
|
Увага
|
| Підписано через SmartID
|
118
|
Норма
|
| Завантажено вручну
|
10
|
інформаційні матеріали
|
| Перевірено
|
126
|
Норма
|
| Відхилено
|
8
|
Потрібна дія
|
| Прострочено
|
10
|
Потрібна дія
|
| Помилки callback/API
|
3
|
Критично
|
| Ручна перевірка
|
2
|
Контроль
|
підписання документів забезпечується через ПриватБанк описує SmartID як КЕП, що здатна використовуватись; так само реалізовано звітів, підтвердження особистості й отримання послуг онлайн. SEO-опис
6.1. Підписання одного документа
|
|
-
|
Результат
|
-
|
Polling статусу
|
-
|
document_type
|
varchar
|
CONTRACT, ACT, APPLICATION тощо. Запустити перевірку підпису. Параметр
19.2. Polling-сценарій
db=db,
|
-
|
Callback втрачено
|
MANUAL_REVIEW і аудит. | Вони підсвічуються червоним.=== 23.8. signature_events ===
4. )
verification_queue.enqueue(
document = document_repository.get_by_external_id(
<pre>
|-
| Немає API-доступу SmartID
| Без доступу неможливо реалізувати повну автоматичну інтеграцію. №
</div>
{| class="wikitable"
! Критерій
|-
| Signature Integration
| конфігурація підключення до SmartID / Приват24. SEO-опис
|-
| Документів створено
| Загальна кількість документів. Результат підписання
"full_name": "Іван Петренко",
== 12. технічна архітектура рішення для бізнесу ==
|
| 6. Перевіряти статус кожні N секунд. * Технічна документація SmartID API, яка надається після підключення. # Чи потрібна інтеграційні функції ERP з ЕДО-системами після підписання? |-
| AC-22
| виступає як помилки підписання. |}
pass
! Коментар
Сервіс повинен забезпечити:
v
def check_connection(self) -> "ConnectionStatus":
=== 13.1. Призначення ===
=== 23.2. sign_documents ===
},
== 28. Безпека ==
)
=== 8.2. Менеджер контролює підписання ===
! K2 ERP створює документ. №
щоб знати, чи клієнт ERP або співробітник підписав документ. | style="background:#ef9a9a;" | Червоний
|-
| Не той підписант
| SIGNER_MISMATCH
| Підписант не відповідає очікуваному. ! | style="background:#ffcc80;" | Помаранчевий
|-
| Прострочена
| EXPIRED
| Сесія не завершена у строк.=== 6.4. Підписання документа співробітником ===
"document_id": str(document.id),
|-
| id
| uuid
| ID сесії. pass
</div>
Retry дозволений для:
session = signature_session_repository.create(
[[Категорія:Електронний документообіг]]
callback_url: str | None = None
{| class="wikitable"
"document_id": document.id,
session = signature_session_repository.get_by_id(db, signature_session_id)
=== 23.7. signature_verifications ===
Python Privat24 / SmartID Signature Service
== 19. Callback або polling ==
Як адміністратор,
! |-
| raw_response
| jsonb
| Відповідь SmartID. |-
| raw_result
| jsonb
| Повний результат перевірки. | платформа повертає помилку і записує подію.=== 30.5. Перевірка ===
{
<syntaxhighlight lang="json">
v
},
22. Черга обробки
task_name="verify_signature",
def get_service_certificate(self) -> "ServiceCertificateResponse":
Співробітник компанії підписує внутрішній документ. |-
|
AC-12
|
Підпис відповідає документу. Поле
6. |-
|
created_at
|
timestamp
|
-
|
Створення заявки
|
Попередня заявка стає INVALIDATED або скасовується. | style="background:#f3e5f5;" | Фіолетовий
|
Етап 6. Ручне завантаження підпису
POST /api/v1/smartid-signature/callback
signature_file_id=signature_file.file_id,
def get_signature_result(self, session_id: str) -> "SignatureResultResponse":
|
Callback retry, polling статусу, журнал raw events. * Законодавчі вимоги до КЕП і електронного документообігу. |-
|
AC-10
|
-
|
Signature Storage
|
Зберігання підпису, контейнера, документа. SEO-опис
"signer_name": result.signer_name,
db=db,
|
| Створення документа
|
Тип, номер, реліз системи, hash. SEO-опис
! Реальні endpoint-и, шифрування, payload і response потрібно взяти з офіційної документації ПриватБанку / SmartID. Стан
request.status = "SIGN_ERROR"
entity_id=document.id,
db.commit()
signature_request_id=session.signature_request_id,
! |-
| raw_request
| jsonb
| Запит до SmartID. |-
| оновлення версій dashboard
| Середній
| Контроль. №
|-
| Чернетка
| DRAFT
| Документ створений, але ще не готовий до підпису. |-
| document_id
| uuid
| ID документа. |}
! Приклад hash:
=== Етап 9. Production hardening ===
платформа:
! Callback Controller або Polling Worker отримує результат.<pre>
"signature_request_id": str(session.signature_request_id),
db=db,
"signature_request_id": request.id,
Перевіряється:
=== Етап 4. Документи ===
Приват24 / SmartID
! |-
| provider
| varchar
| privatbank_smartid. # Чи потрібні email/SMS-нагадування? |-
| Обмеження
| Менше автоматизації, більше ручних дій. Очікуваний результат
{| class="wikitable"
* створити пакет документів;
* перевірити всі документи;
* створити окрему заявку на кожен документ або одну пакетну заявку, якщо це підтримується API;
* отримати результат по кожному документу;
* показати частково підписані або помилкові документи;
* не втратити статус окремого документа. | Перевести в SIGN_ERROR. |-
| Signature Request
| Заявка на підписання.<pre>
POST /api/v1/smartid-signature/integrations
)
! {| class="wikitable"
Callback endpoint повинен:
=== 5.2. Варіант 2. Ручне підписання у Приват24 + завантаження підпису в систему ===
signature_record = signature_file_repository.create(
GET /api/v1/smartid-signature/dashboard?date_from=2026-05-01&date_to=2026-05-31
"signature_request_id": None,
document_version = document_version_repository.get_by_id(db, request.document_version_id)
stored_file = file_storage.save(signature_file)
! |}
=== 22.1. Логіка черги ===
request.status = "VERIFIED"
Для кожного документа потрібно зберігати:
def create_signature_request(command: "CreateSignatureRequestCommand", db: "Session") -> "SignatureRequest":
</syntaxhighlight>
|-
| id
| uuid
| ID файлу підпису. |-
| file_size
| Розмір файлу. | Відхилити callback і записати подію. # Чи потрібно підписувати документи клієнтами, співробітниками або обома? |-
| signer_name
| varchar
| ПІБ підписанта з сертифіката. |-
| Збереження підпису
| Критичний
| Юридично значущий результат.<pre>
* договорів;
* актів виконаних робіт;
* рахунків;
* заяв;
* анкет;
* кадрових документів;
* первинних документів;
* податкових і бухгалтерських документів;
* документів ЕДО;
* документів K2 ERP;
* документів CRM;
* документів особистого кабінету клієнта;
* підтвердження юридично значущих дій користувача. |-
| AC-9
| користувач системи відхиляє підписання. |-
| SignatureResultError
| Не вдалося отримати результат підпису. SEO-опис
* Офіційна сторінка SmartID ПриватБанку. Значення
=== 15.11. Dashboard ===
[[Категорія:Python]]
entity_id=request.id,
! |-
| document_id
| uuid
| Документ. |}
try:
v
=== 23.1. smartid_signature_integrations ===
payload = await request.json()
'''Критично критично:''' callback і polling повинні бути ідемпотентними. |-
| Ручне завантаження
| Хто завантажив, файл, hash. |-
| AC-24
| виступає як документи на ручній перевірці. ! Оновити K2 ERP. db.commit()
session.signature_request.status = smartid_status_mapper.to_request_status(new_status)
entity_type="signature_request",
* приймає файл підпису або підписаний контейнер;
* перевіряє hash вихідного документа;
* перевіряє підпис;
* визначає підписанта;
* змінює статус документа;
* зберігає результат перевірки. №
return {"status": "unknown_session"}
{| class="wikitable"
3. Причина
платформа повинна не допускати дублювання заявок і підписів. |-
| file_size
| integer
| Розмір файлу. Підписант
я хочу натиснути кнопку «Підписати через Приват24 / SmartID»,
)
|-
| id
| uuid
| ID інтеграції. SMARTID_BASE_URL=https://acsk.privatbank.ua/cloud/api/back
* реалізувати Verification Service;
* реалізувати статуси перевірки;
* реалізувати ручну перевірку;
* реалізувати журнал перевірок. K2 ERP / Dashboard / електронний документообіг
{| class="wikitable"
До MVP входить:
<pre>
<syntaxhighlight lang="python">
else:
=== 15.8. Завантаження файлу підпису ===
== 34. Відкриті питання ==
},
|-
| Підходить для
| Автоматизованого підписання документів у бізнес-процесі K2 ERP. |-
| file_name
| varchar
| Назва файлу. |}
! | TTL, нагадування, повторна заявка. |-
| file_id
| uuid
| Файл документа.== 25. Обробка помилок ==
"status": "CREATING",
data={
== 20. Перевірка підпису ==
<pre>
Python-сервіс напряму інтегрується з API SmartID. |-
| Status Sync Service
| оновлення версій статусів у K2 ERP.=== 6.5. Ручне завантаження підпису ===
== 15. API Python-сервісу ==
request.status = "MANUAL_REVIEW"
!</pre>
=== 23.3. sign_document_versions ===
session_ttl_minutes: int = 15
== 10. Статуси сесії підписання ==
== 9. Статуси документа ==
! * HTTPS для всіх endpoint-ів;
* перевірку SSL;
* зберігання секретів тільки в secret storage;
* шифрування файлів підпису;
* шифрування документів або контроль доступу до них;
* обмеження доступу до callback endpoint;
* перевірку callback signature / secret;
* ідемпотентність callback;
* журнал усіх дій;
* маскування персональних даних у логах;
* контроль доступу до документів;
* окремі права на створення заявки;
* окремі права на повторне підписання;
* окремі права на ручне завантаження підпису;
* окремі права на ручну перевірку;
* заборону підписання зміненої версії документа;
* заборону зберігання пароля користувача до SmartID. |-
| Перевірка підпису
| Високий
| Потрібна для фінального статусу. Критерій
! | Зупинити інтеграцію і повідомити адміністратора. |-
| document_name
| varchar
| Назва документа. |-
| Ручна перевірка
| хто перевірив, рішення для бізнесу, коментар. if not signature_session:
! |-
| file_hash_sha256
| Hash документа.<pre>
</pre>
<pre>
платформа:
)
retry_backoff_seconds: int = 5
payload={"error": str(exc)},
audit_logger.log(
! Поле
elif new_status in ["DECLINED", "EXPIRED", "ERROR"]:
! Значення
event_type="SIGNATURE_VERIFY_EXCEPTION",
"signer": {
{| class="wikitable"
result = signature_verifier.verify(
=== 30.1. інтеграційні функції ERP ===
== 24. Приклад Python-логіки ==
signature_validator.validate_document_for_signing(document, command)
! class SmartIDSignatureClient:
* [[Python]]
* [[FastAPI]]
* [[K2 ERP]]
* [[Приват24]]
* [[ПриватБанк]]
* [[SmartID]]
* [[КЕП]]
* [[Електронний підпис]]
* [[Електронний документообіг]]
* [[Callback]]
* [[Webhook]]
* [[p7s]]
* [[Підписання документів]]
* [[API інтеграція]]
"k2_entity": "contract",
request.status = "VERIFY_ERROR"
{| class="wikitable"
{| class="wikitable"
base_url: str
Приклад `.env`:
я хочу бачити callback-и, помилки API та технічний журнал,
external_document_id=command.external_document_id,
|
|