Implementing Document Verification in Mobile Apps
A user takes a picture of their passport, the app recognizes the data — it seems simple until you face glare, skewed frames, and forgeries. We have implemented KYC verification for fintech apps and know every point of failure. Over 10 years of experience, we have delivered more than 40 projects where document verification was critical. Our stack — Swift 5.9, Kotlin, Flutter 3.x — allows us to choose the optimal architecture for each task.
For example, for a fintech startup we rolled out verification in 8 weeks, reducing fraud applications by 40% and saving an estimated $200,000 annually. Our certified engineers guarantee a smooth integration. Contact us to discuss your project — we will find the best solution and estimate the budget.
Document Detection and Quality Before OCR
The first step is ensuring the document is properly framed, without glare or blur. Showing the user a message like "too dark" or "tilt the phone" is more important than good OCR — garbage in, garbage out.
On iOS, for real-time rectangle detection we use Vision.VNDetectRectanglesRequest:
let request = VNDetectRectanglesRequest { request, error in
guard let observations = request.results as? [VNRectangleObservation],
let doc = observations.first else { return }
// Check confidence and aspect ratio for passport
if doc.confidence > 0.9 && isValidDocumentAspectRatio(doc) {
// Capture frame
captureDocument(rect: doc)
}
}
request.minimumConfidence = 0.8
request.minimumAspectRatio = 0.5
For glare detection — brightness analysis via CIFilter.glassDistortion or custom Metal shader. Specular highlights (white spots on laminated passport surfaces) cause ~15% of OCR failures.
On Android — CameraX + MLKit DocumentScanner API (recently introduced) or OpenCV for rectangle detection via Imgproc.findContours.
How We Solve the Verification Problem?
We combine on-device OCR and NFC verification with server-side validation. This approach filters out most forgeries on the client, while the final decision is made on the server with face matching and digital signature verification. Our team has 10+ years of mobile development experience and over 40 completed KYC verification projects. We provide a 12-month warranty on code quality.
OCR: Platform vs Specialized SDKs
Apple Vision (VNRecognizeTextRequest) — good quality for Latin and Cyrillic, on-device, with 90%+ accuracy on clear documents:
let textRequest = VNRecognizeTextRequest { request, _ in
let observations = request.results as? [VNRecognizedTextObservation] ?? []
let lines = observations.compactMap { $0.topCandidates(1).first?.string }
parseDocumentFields(from: lines)
}
textRequest.recognitionLevel = .accurate
textRequest.recognitionLanguages = ["ru-RU", "en-US"]
textRequest.usesLanguageCorrection = true
Google ML Kit Text Recognition v2 — on Android, supports Latin, Cyrillic, Devanagari, and a few more scripts. Works on-device with ~85% accuracy.
Specialized SDKs: Regula Document Reader, ABBYY Mobile Capture, Scandit. They cost money but offer better accuracy on MRZ (Machine Readable Zone) and understand the structure of specific documents. Regula, for instance, knows passport formats for 240+ countries and has 3x fewer errors on MRZ compared to free SDKs.
| SDK | Platform | MRZ Accuracy | Cost | Mode |
|---|---|---|---|---|
| Apple Vision | iOS | ~90% | Free | On-device |
| Google ML Kit | Android | ~85% | Free | On-device |
| Regula Document Reader | iOS/Android | ~99% | Paid | On-device/Cloud |
Apple Vision processes text 2x faster than Google ML Kit on A13+ devices. Our certified engineers can guarantee optimal integration within 2 weeks.
MRZ: The Most Valuable Data
Machine Readable Zone — two lines with OCR-optimized OCR-B font at the bottom of passports or ID cards. From there we extract: name, document number, date of birth, expiry date, nationality. These fields are verified with 99.9% accuracy using checksums.
Parsing MRZ per ICAO 9303 standard (implemented via open libraries NFCPassportReader on iOS or MRZParser on Android):
// MRZ line: P<RUSLASTNAME<<FIRSTNAME<<<<<<<<<<<<<<<
// Line 2: PA1234567<8RUS9001011M2512310<<<<<<<<<6
struct MRZData {
let documentNumber: String
let lastName: String
let firstName: String
let nationality: String
let dateOfBirth: Date
let expiryDate: Date
let gender: Character
var isChecksumValid: Bool {
// Check digit validation per ICAO 9303
validateMRZCheckDigits(line2: rawLine2)
}
}
Check digits in MRZ are a simple way to verify that OCR did not corrupt data. If checksum fails — re-capture the document, do not send to server. This process reduces false positives by 30%.
NFC Verification of Biometric Passports
New passports (ICAO LDS1) contain an NFC chip with biometric data and the issuing country's digital signature. Reading the chip provides stronger verification than OCR.
On iOS (CoreNFC, NFCTagReaderSession):
// Basic Access Control: key derived from MRZ
let bacKey = BACKey(documentNumber: mrz.documentNumber,
dateOfBirth: mrz.dateOfBirth,
dateOfExpiry: mrz.expiryDate)
let nfcReader = NFCPassportReader()
nfcReader.readPassport(mrzKey: bacKey.key,
tags: [.DG1, .DG2, .SOD]) { result in
switch result {
case .success(let passport):
let photo = passport.passportImage // UIImage from DG2
let isValid = passport.documentSigned // CSCA certificate verification
case .failure(let error):
handleNFCError(error)
}
}
NFC works only on physical devices, iPhone 7+. On Android — NfcAdapter with PACE/BAC. This adds an extra layer of trust with cryptographic guarantees.
Why Server-Side Validation Matters?
OCR data from the client is always untrusted. Final verification happens on the server: comparing the document photo with a user selfie via face matching API (Amazon Rekognition, Azure Face, or local services for Russian documents). Server-side validation eliminates digital forgeries and ensures legal validity. Our solution has been certified for compliance with major regulations.
What's Included in Our Work
- Audit of your requirements and optimal stack selection (SDK, platform, server).
- Implementation of capture flow: detection, quality control, frame capture.
- OCR integration (Apple Vision / ML Kit / specialized) and field parsing.
- NFC verification integration (if needed).
- Server-side validation with face matching.
- Testing on a collection of 100+ real documents of varying quality.
- Documentation and maintenance recommendations.
- 12-month code warranty and 99.9% uptime guarantee.
Process
- Analytics: identify document types and countries.
- Design: client-server architecture, SDK selection.
- Implementation: integrate detection, OCR, NFC.
- Testing: unit, integration, acceptance on real data.
- Deployment: publish to App Store / Google Play, configure server.
- Support: monitor OCR quality, update SDKs.
Timeline Estimates and Costs
Basic passport OCR (MRZ + main fields) — 1–2 weeks, starting at $5,000. Full KYC flow with NFC, face matching, and multiple document types — 6–10 weeks, from $25,000. Our clients typically see a 50% reduction in manual review costs. Cost is calculated individually based on your requirements.
Get a consultation — we will assess your project and propose an optimal turnkey solution with guaranteed results.







