Реалізація верифікації документів (паспорт, права, 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 ваших документів і покажемо результат. Отримайте демо-доступ до вже працюючої системи.







