Logo de FaacilFaacil

Escanear de Documentos

Nuestra solución de escaneo de documentos permite capturar automáticamente la zona MRZ (Machine Readable Zone) de pasaportes, cédulas y visas, validar su autenticidad mediante checksums ICAO 9303 y, opcionalmente, leer el chip NFC de pasaportes electrónicos. Toda la información se puede exportar a tu backend a través de una API REST con imágenes en formato multipart.

Tipos de Documentos Soportados

  • Pasaportes (TD3): 2 líneas de 44 caracteres. Compatible con cualquier país que siga el estándar ICAO 9303. Soporte para lectura NFC (BAC/PACE).
  • Cédulas de Identidad (TD1): 3 líneas de 30 caracteres. Ej: cédula colombiana moderna, DNI de varios países.
  • Visas (TD2): 2 líneas de 36 caracteres.
  • Documentos sin MRZ (fallback): Mediante OCR libre se pueden extraer datos de licencias de conducción, cédulas antiguas y otros documentos colombianos (heurísticas específicas).

Proceso de Escaneo

  • Detección inteligente: La cámara detecta rectángulos con dimensiones de documento y utiliza una ventana deslizante de 4 frames para estabilizar la captura.
  • Auto‑captura: Cuando se confirma la presencia del documento, se captura automáticamente el frame con mayor calidad.
  • Procesamiento de imagen: Corrección de perspectiva, escala de grises, ajuste de exposición y contraste, y aumento de nitidez para optimizar el OCR.
  • OCR con Vision Framework: Extracción de las líneas MRZ (modo preciso) o búsqueda de texto libre en modo fallback.
  • Parsing y validación: El MRZ se descompone según el formato (TD1/TD2/TD3). Se calculan los 5 checksums (pesos 7‑3‑1) y se valida cada campo contra el dígito verificador.
  • Multi‑captura y consenso: Se toman entre 3 y 8 fotos en rápida sucesión. Los resultados se combinan mediante un sistema de votación ponderada por calidad de imagen para maximizar la precisión.
  • Lectura NFC (solo pasaportes): Utilizando la librería NFCPassportReader, se conecta al chip del pasaporte, lee los Data Groups (DG1, DG2, DG11, DG12, SOD) y compara los datos del chip con el MRZ escaneado.

Exportación de Datos al API

Una vez finalizado el escaneo, la aplicación puede enviar los datos extraídos y las imágenes a tu servidor mediante una petición POST con contenido multipart/form-data. A continuación se detalla el formato.

Endpoint

POST https://tu-servidor.com/api/documents

Estructura del Body (multipart/form-data)

--MRZScannerBoundary-<UUID>
Content-Disposition: form-data; name="document_data"
Content-Type: application/json

{ ... JSON payload ... }

--MRZScannerBoundary-<UUID>
Content-Disposition: form-data; name="front_image"; filename="front.jpg"
Content-Type: image/jpeg

<JPEG binario>

--MRZScannerBoundary-<UUID>
Content-Disposition: form-data; name="back_image"; filename="back.jpg"
Content-Type: image/jpeg

<JPEG binario>  (solo para documentos de doble cara)

--MRZScannerBoundary-<UUID>--

Campo document_data (JSON)

Objeto con la siguiente estructura (basada en el modelo MRZDocument):

{
  "document_type": "P" | "I" | "V" | "O",       // Tipo según MRZ
  "scanned_type": "PASAPORTE" | "CEDULA_MODERNA" | "LICENCIA" | ...,
  "data_source": "MRZ" | "OCR_FREE" | "NFC",
  "format": "TD3 (2 líneas - Pasaporte)" | "TD1 (3 líneas - Cédula)" | "OCR Libre",

  // Datos personales
  "document_number": "string",
  "first_name": "string",
  "last_name": "string",
  "full_name": "string",
  "nationality": "string (ISO 3166-1 Alpha-3)",
  "date_of_birth": "dd/MM/yyyy" | null,
  "sex": "Masculino" | "Femenino" | "<",
  "issuing_country": "string",
  "expiration_date": "dd/MM/yyyy" | null,
  "personal_number": "string" | null,

  // Estado y metadatos
  "is_expired": boolean,
  "overall_validity": boolean,        // true si todos los checksums son válidos
  "confidence_score": number,         // 0.0 - 1.0
  "capture_date": "2026-02-17T10:30:00Z",  // ISO 8601 UTC
  "mrz_lines": ["línea1", "línea2", ...],

  // Datos extendidos para Colombia (solo si aplica)
  "colombian_data": {
    "nuip": "string" | null,
    "blood_type": "string" | null,    // ej: "O+"
    "place_of_birth": "string" | null,
    "height": "string" | null,        // ej: "175 cm"
    "license_category": "string" | null,
    "restrictions": "string" | null
  } | null,

  // Validaciones de checksums ICAO
  "checksums": [
    {
      "field": "Número de Documento",
      "valid": boolean,
      "expected": number | null,
      "calculated": number | null
    },
    // ... más campos (fecha nacimiento, expiración, personal, compuesto)
  ]
}

Campos de Imagen

  • front_image: Siempre incluida. Imagen del anverso del documento en formato JPEG, calidad 60% (tamaño aproximado 150‑400 KB).
  • back_image: Incluida solo si el documento tiene reverso (cédulas, licencias) y fue escaneado. Mismas características que front_image.

Ejemplo de Petición (con cédula colombiana)

POST /api/documents HTTP/1.1
Host: tu-servidor.com
Content-Type: multipart/form-data; boundary=xxx

--xxx
Content-Disposition: form-data; name="document_data"
Content-Type: application/json

{
  "document_type": "I",
  "scanned_type": "CEDULA_MODERNA",
  "data_source": "MRZ",
  "format": "TD1 (3 líneas - Cédula)",
  "document_number": "1020304050",
  "first_name": "JUAN CAMILO",
  "last_name": "GARCIA LOPEZ",
  "full_name": "JUAN CAMILO GARCIA LOPEZ",
  "nationality": "COL",
  "date_of_birth": "15/03/1990",
  "sex": "Masculino",
  "issuing_country": "COL",
  "expiration_date": "15/03/2030",
  "personal_number": null,
  "is_expired": false,
  "overall_validity": true,
  "confidence_score": 0.95,
  "capture_date": "2026-02-17T10:30:00Z",
  "mrz_lines": [
    "IDCOL1020304050<<<<<<<<<<<<<<<",
    "9003150M3003159COL<<<<<<<<<<<6",
    "GARCIA<LOPEZ<<JUAN<CAMILO<<<<<"
  ],
  "colombian_data": {
    "nuip": "1020304050",
    "blood_type": "O+",
    "place_of_birth": "BOGOTA D.C.",
    "height": "175 cm",
    "license_category": null,
    "restrictions": null
  },
  "checksums": [
    { "field": "Número de Documento", "valid": true, "expected": 5, "calculated": 5 },
    { "field": "Fecha de Nacimiento", "valid": true, "expected": 0, "calculated": 0 },
    { "field": "Fecha de Expiración", "valid": true, "expected": 9, "calculated": 9 },
    { "field": "Checksum Compuesto", "valid": true, "expected": 6, "calculated": 6 }
  ]
}
--xxx
Content-Disposition: form-data; name="front_image"; filename="front.jpg"
Content-Type: image/jpeg

<... binario JPEG ...>
--xxx
Content-Disposition: form-data; name="back_image"; filename="back.jpg"
Content-Type: image/jpeg

<... binario JPEG ...>
--xxx--

Respuesta Esperada

La aplicación considera exitosa cualquier respuesta con código HTTP 2xx. El cuerpo de la respuesta es ignorado. Se recomienda devolver un JSON con confirmación, por ejemplo:

{
  "status": "received",
  "document_id": "uuid-generado-por-servidor",
  "message": "Documento procesado correctamente"
}

Integración Empresarial

La funcionalidad de escaneo es una aplicación adicional que se encuentra en la App Store, tiene un costo único independiente por país.

Correo: contacto@faacil.com