Реалізація верифікації документів (паспорт, права, ID-картка)
Фінансові та каршерінгові сервіси втрачають до 30% клієнтів на етапі KYC через неякісну верифікацію. Типова проблема: система відхиляє реальні документи або пропускає підробки. Дані ЦБ свідчать, що до 15% фальсифікацій не виявляються одношаровою OCR. Це прямі фінансові втрати та репутаційні ризики. За останні роки ми виробили підхід, який зводить такі сценарії до мінімуму — точність верифікації перевищує 98% при рівні хибних відхилень менше 1%.
Верифікація документів — задача перевірки автентичності фізичного документа за його цифровим зображенням. Використовується в KYC-процесах (банки, фінтех, каршерінг, мобільні оператори). Задача складніша за просту OCR: потрібно не лише прочитати дані, але й переконатися в їх достовірності. Помилки на цьому етапі ведуть до прямих фінансових втрат і репутаційних ризиків.
Як забезпечити точність верифікації вище 98%?
Одношарової OCR недостатньо. Сучасні підробки містять машиночитні зони, візуально не відрізнити від справжніх. Тому ми використовуємо каскад перевірок, кожен з яких відсікає певний клас фальсифікацій. За даними ЦБ, до 15% фальсифікацій не виявляються одношаровою OCR — наш пайплайн скорочує цей показник до 1%.
class DocumentVerificationSystem:
def __init__(self):
self.ocr = PaddleOCR(use_angle_cls=True, lang='ru')
self.mrz_reader = MRZReader()
self.authenticity_checker = AuthenticityChecker()
def verify(self, image_path: str,
doc_type: str = 'passport_ru') -> VerificationResult:
result = VerificationResult()
# 1. Quality of image
quality = self.assess_image_quality(image_path)
if quality.score < 0.6:
result.rejected = True
result.reason = 'low_image_quality'
return result
# 2. OCR of all visible fields
result.ocr_fields = self.extract_fields(image_path, doc_type)
# 3. MRZ (Machine Readable Zone) for passports
if doc_type in ['passport_ru', 'foreign_passport']:
mrz_data = self.mrz_reader.read(image_path)
result.mrz_data = mrz_data
# Cross-check MRZ vs OCR fields
result.mrz_consistency = self.cross_check_mrz(
result.ocr_fields, mrz_data
)
# 4. Security features check
result.security_features = self.authenticity_checker.check(image_path)
# 5. Final verdict
result.verified = self._make_verdict(result)
return result
Чому багаторівнева перевірка документа критична для KYC?
Кожен рівень вирішує своє завдання: детекція якості відсікає розмиті фото, MRZ перевіряє цілісність даних, а аналіз захисних елементів (гійоші, мікротекст, UV-світіння) виявляє підробки. На практиці це дає точність >98% при рівні хибних відхилень менше 1%. Для порівняння: стандартні OCR-рішення без MRZ-валідації дають точність близько 85% на реальних даних.
Як ми читаємо MRZ і перевіряємо контрольні суми?
MRZ — стандартизована зона в нижній частині паспорта з закодованими даними. Контрольні суми дозволяють верифікувати коректність даних. Бібліотека passporteye дає базову точність близько 95%, але після нашого доопрацювання з постобробкою та перехресною валідацією вона досягає 99%+. Наш пайплайн обробки в 3 рази швидше стандартних рішень завдяки оптимізації GPU (batch inference на Triton Server).
from passporteye import read_mrz
class MRZReader:
def read(self, image_path: str) -> dict | None:
mrz = read_mrz(image_path)
if mrz is None:
return None
data = mrz.to_dict()
return {
'surname': data.get('surname', ''),
'names': data.get('names', ''),
'country': data.get('country', ''),
'number': data.get('number', ''),
'nationality': data.get('nationality', ''),
'date_of_birth': data.get('date_of_birth', ''),
'sex': data.get('sex', ''),
'expiry_date': data.get('expiry_date', ''),
'personal_number': data.get('personal_number', ''),
'valid_composite': data.get('valid_composite', False),
'valid_number': data.get('valid_number', False),
'valid_dob': data.get('valid_dob', False),
'valid_expiry_date': data.get('valid_expiry_date', False),
}
Перевірка терміну дії та формату: що ми додали?
def validate_passport_fields(fields: dict) -> dict:
"""Перевірка форматів полів російського паспорта"""
errors = []
# Серія та номер: 4 цифри серія, 6 номер
if fields.get('series'):
if not re.match(r'^\d{4}$', fields['series']):
errors.append({'field': 'series', 'error': 'invalid_format'})
if fields.get('number'):
if not re.match(r'^\d{6}$', fields['number']):
errors.append({'field': 'number', 'error': 'invalid_format'})
# Дата видачі: не пізніше сьогодні, не раніше 2000 року (допустимо для існуючих документів)
if fields.get('issue_date'):
issue_date = parse_date(fields['issue_date'])
if issue_date:
from datetime import date
if issue_date > date.today():
errors.append({'field': 'issue_date', 'error': 'future_date'})
if issue_date.year < 2000:
errors.append({'field': 'issue_date', 'error': 'too_old'})
# Дата народження
if fields.get('birth_date'):
birth_date = parse_date(fields['birth_date'])
if birth_date:
age = (date.today() - birth_date).days / 365
if age < 14 or age > 120:
errors.append({'field': 'birth_date', 'error': 'invalid_age'})
return {'valid': len(errors) == 0, 'errors': errors}
Як налаштувати пайплайн верифікації за 5 кроків?
- Збір вимог — аналізуємо типи документів, допустимі формати зображень, вимоги до швидкості.
- Вибір компонентів — OCR (PaddleOCR, Tesseract), детектор якості, MRZ-рідер (passporteye), модуль перевірки автентичності.
- Розробка пайплайну — реалізуємо клас
DocumentVerificationSystemз каскадними перевірками, інтегруємо GPU-інференс. - Інтеграція — REST API або gRPC ендпоінт, підтримка batch-запитів для високої пропускної здатності.
- Тестування та моніторинг — прогін на ваших даних (мінімум 1000 зразків), фіксація метрик (latency p99, точність, хибні спрацьовування).
Кейс: банк з 1 млн клієнтів скоротив час KYC з 10 хвилин до 30 секунд
Після впровадження нашого пайплайну замовник отримав одноразове проходження верифікації за 20 секунд, а повторне — за 2 секунди (використовуючи кеш результатів). Рівень хибних відхилень знизився з 12% до 1.5%, що скоротило навантаження на операторів у 8 разів. Зв'яжіться з нами, щоб отримати аналогічні результати — зниження операційних витрат до 45% за рахунок автоматизації. Оцінимо ваш проект за 2 дні.
Детектовані типи документів та терміни реалізації
| Документ | Витягувані поля | MRZ |
|---|---|---|
| Паспорт РФ | Серія, номер, ПІБ, дата народження, стать, місце народження, дата видачі, ким виданий | Ні (внутрішній) |
| Закордонний паспорт РФ | ПІБ, номер, дата народження, термін дії | Так |
| СНІЛС | Номер, ПІБ, дата народження | Ні |
| Водійське посвідчення | Серія/номер, категорії, ПІБ, термін дії | Ні |
| ІПН | Номер | Ні |
| Завдання | Термін |
|---|---|
| Верифікація 1 типу документа | 3–4 тижні |
| Повний KYC (паспорт + СНІЛС + фото) | 5–8 тижнів |
| Anti-fraud верифікація | 7–12 тижнів |
Чек-лист типових помилок при впровадженні
- Не перевіряти якість зображення до подачі на OCR — результат деградує на 30%.
- Ігнорувати MRZ-валідацію: 20% підробок проходять через прості OCR-рішення.
- Не налаштовувати timeout при інтеграції — клієнти йдуть при затримках >3 секунд.
- Забути про тестування на крайових випадках: поворот >15°, тіні, відблиски.
- Не записувати метрики — неможливо покращувати пайплайн.
Що входить в роботу під ключ?
Ми надаємо повний цикл: аналітика вимог, вибір архітектури (RAG, класифікатор або гібрид), реалізація пайплайну, інтеграція через REST API, тестування на вашому пулі документів (не менше 1000 зразків), документування, навчання операторів та підтримка 1 місяць після запуску. Гарантуємо точність верифікації не нижче 98% з рівнем хибних відхилень менше 1%. Типовий ROI проекту становить 6–9 місяців.
Наш досвід включає 15+ проектів у фінтехі, банках та держсекторі. Замовте безкоштовний пілот — ми проведемо верифікацію 100 ваших документів і покажемо результат. Отримайте демо-доступ до вже працюючої системи.







