KYC/KYB Verification Implementation in Mobile App
KYC (Know Your Customer) and KYB (Know Your Business) — not just "upload photo of passport". Complex technical and regulatory requirements: identity verification, liveness detection, sanctions list screening, AML check, data storage and audit. Mobile app — data collection point and process orchestration. Mistakes here cost — license revocation or regulator fines.
Provider Choice vs Self-Implementation
Self-service KYC — rare. Document processing, liveness detection with attack protection (photos, deepfake video, 3D masks), sanctions screening (OFAC, EU, UN) — separate product requiring years of development and continuous updates.
Market has mature SDKs: Onfido, Jumio, Sumsub, IDnow, Veriff, Stripe Identity. Choice depends on user geography, document types, regulator requirements, pricing model.
We integrate SDK provider into mobile app, configure server webhook for results, build UI flow, handle all verification states.
Sumsub Integration Example
Sumsub — popular for CIS and Europe. iOS SDK (SumSubSDK) and Android (com.sumsub.sns:core).
General flow:
-
Backend creates applicant via Sumsub API:
POST /resources/applicantswithexternalUserId. -
Backend generates access token for SDK:
POST /resources/accessTokenswithapplicantIdandlevelName. - Mobile app gets access token from backend (not directly from Sumsub — never store API secret on client).
- SDK launched with this token.
// iOS
import IdensicMobileSDK
let sdk = SNSMobileSDK.init(
accessToken: receivedToken,
baseUrl: "https://api.sumsub.com",
flowName: "basic-kyc",
locale: "en"
)
sdk.onStatusDidChange = { sdk, prevStatus in
switch sdk.status {
case .ready: break
case .incomplete: self.handleIncomplete()
case .pending: self.showPendingScreen()
case .approved: self.handleApproved()
case .declined: self.handleDeclined()
case .failed: self.handleError(sdk.failReason)
@unknown default: break
}
}
sdk.present(from: self)
// Android
val sdk = SNSMobileSDK.Builder(this)
.withAccessToken(token, onTokenExpiration = { callback ->
// refresh token and call callback(newToken)
viewModel.refreshApplicantToken { newToken -> callback(newToken) }
})
.withLocale(Locale("en"))
.build()
sdk.launch()
Token expiration handler — important: Sumsub access token lives 10 minutes. If user gets stuck on photo step longer — token expires. SDK calls this callback waiting for new token.
Liveness Detection: Technical Details
Modern liveness detection — passive (user just looks at camera) or active (blink, turn head). Passive on ML models, active — motion detection.
Camera requirements: minimum 720p, autofocus. Low lighting — common failure cause. Onfido, Jumio SDKs have real-time feedback: "Improve lighting", "Hold phone steady". Sumsub similarly.
Liveness attacks:
- Photo — basic protection in all SDK.
- Video replay — more complex protection.
- 3D masks — enterprise-class SDK protect (Jumio, Onfido).
- DeepFake — active development area, not all SDK protect.
Protection level depends on provider tier. For financial licenses (EMI, bank) — need enterprise level.
Document Scanning
All SDKs support automatic capture: detect document edges, check blur, reflections, readability. User doesn't click — SDK takes photo when quality threshold reached. Critical: manual capture gives 30–40% bad photos, automatic — 5–8%.
Supported documents depend on SDK and region. Sumsub covers 220+ countries. Onfido — 195. Each SDK has database of supported documents with type precision.
MRZ (Machine Readable Zone) — passport bottom strip with encrypted data. SDK extracts from MRZ and compares with visual zone — extra validation.
KYB: Business Verification
KYB more complex than KYC: need company registration documents, address proof (utility bill not older than 3 months), KYC of beneficial owners (UBO — 25%+ stake).
Sumsub Business Verification and Jumio KYB support KYB flow with wizard for document collection. Feature: each UBO passes full KYC separately. Three beneficiaries — three KYC checks, may proceed asynchronously.
Mobile app must support async flow: user submitted company documents, awaiting UBO-1 verification, UBO-2 in process, UBO-3 not started. Build status dashboard with each participant progress.
Webhooks and Polling
Verification — async (minutes to days with manual review). After document submission SDK reports pending status. Real result via webhook on backend.
Backend receives webhook (applicantReviewed, applicantPending), updates user status, sends push to mobile app.
Mobile app shows "Under review" status with animation. Polling every 30–60 seconds — fallback if push missed.
Storage and GDPR Compliance
Document images not stored on our servers — only at provider. We store only applicantId, status, check date. User rights to deletion (GDPR Article 17) — implement via provider API: DELETE /resources/applicants/{applicantId}.
Retention policy: most providers store 5–7 years (AML/FATF requirements). On deletion from provider, document for audit — provider data deleted.
Work Phases
Requirements analysis, provider choice → backend integration (applicant creation, token generation, webhooks) → mobile SDK integration → UI flow (start verification, waiting, result) → handling all statuses (approved, declined, incomplete) → testing on real documents in sandbox → security review → audit prep.
Timeline: 15–25 work days. Depends on provider SDK specifics, regulator requirements (some require specific document types or extra checks), KYB component presence.
Server part (webhook handling, AML integration, audit trail) — separate backend assessment.







