Conversion Tracking for Fintech: KYC Funnel Optimisation
KYC drop-off is the silent killer of fintech startups. Here's how to instrument your onboarding funnel, identify where users abandon, and run experiments that lift completion rates.
The KYC Problem in Numbers
Identity verification is a legal requirement for most fintech products. Payments, lending, investing, and crypto all require it. It's also the most drop-off-prone part of any onboarding funnel.
Industry benchmarks for KYC completion rates vary widely, but 40–60% drop-off during identity verification is common. For a fintech product with strong acquisition metrics, this is often the single largest growth lever: if you can get ten more percentage points of users through KYC, your revenue grows proportionally.
Most fintech teams know this is a problem. Few are instrumenting it with enough granularity to fix it.
The Three Layers of KYC Analytics
Layer 1: Funnel Completion by Step
The minimum viable measurement is step-by-step drop-off through the KYC flow:
// Track every step entry and completion
function trackKycStep(step: string, action: "started" | "completed" | "abandoned") {
analytics.track("kyc_step", {
step,
action,
session_id: getSessionId(),
// Include any A/B test variants active for this user
experiment_variants: getActiveVariants(),
});
}
// Usage in your KYC flow components
useEffect(() => {
trackKycStep("document_upload", "started");
return () => {
if (!completed) trackKycStep("document_upload", "abandoned");
};
}, []);
Track separately for each sub-step: personal details entry, document type selection, document upload, selfie capture, processing wait, and result display. These are often treated as one "KYC step" in funnels when they're actually five distinct drop-off points.
Layer 2: Error and Rejection Attribution
A significant portion of KYC abandonment isn't intentional. It's users hitting errors and giving up. Track every error state:
type KycError =
| "document_quality_low"
| "document_expired"
| "selfie_mismatch"
| "name_mismatch"
| "unsupported_document_type"
| "provider_timeout"
| "manual_review_required";
function trackKycError(error: KycError, context: Record<string, unknown>) {
analytics.track("kyc_error", {
error_type: error,
...context,
// Is this user currently in a retry flow?
is_retry: context.attempt_number > 1,
});
}
Segment your drop-off by error type. If 30% of your rejections are document_quality_low on mobile, you have a camera UX problem, not a compliance problem. That's fixable.
Layer 3: Time-to-Completion and Abandonment Timing
When users abandon matters as much as where they abandon:
const kycStartTime = useRef<number>(Date.now());
function trackKycAbandonment(step: string) {
analytics.track("kyc_abandoned", {
step,
time_elapsed_seconds: Math.round((Date.now() - kycStartTime.current) / 1000),
// Long waits at processing step indicate provider latency issues
is_processing_wait: step === "processing",
});
}
Users who drop off after 30+ seconds on the processing screen are experiencing provider latency, not form fatigue. That's an infrastructure fix, not a copy fix.
The Experiments Worth Running
Once you have baseline data, here are the experiments that consistently move KYC completion rates:
Progress Indicators
KYC flows with visible step indicators (Step 2 of 4) consistently outperform flows without them. Users abandon unknown-length processes at much higher rates.
Pre-KYC Expectation Setting
Show users exactly what they'll need before starting (ID document, selfie, 3–5 minutes) and your completion rate improves. Users who understand what's coming are less likely to bounce mid-flow.
Mobile Camera Optimisation
On mobile, document capture quality errors are often caused by suboptimal camera guidance. Adding real-time quality feedback (lighting warnings, alignment guides) before capture submission materially reduces document_quality_low rejections.
Retry Flow vs. Abandonment
When a KYC submission fails, most apps show an error and a retry button. A significantly better UX is a guided retry flow that explains specifically what failed and shows the user what a good submission looks like. Instrument your retry flows separately to measure conversion.
Email Recovery for Abandoned KYC
Users who start KYC and abandon are warm leads. An email sequence triggered by kyc_abandoned events (with a direct link back to the exact step they left) typically recovers 15–25% of abandoned sessions within 48 hours.
Provider Latency and Its Impact
Manual review queues and provider processing times are often invisible to product teams but highly visible to users. Track:
// Time between submission and result
analytics.track("kyc_provider_result", {
provider: "onfido" | "jumio" | "persona",
result: "approved" | "rejected" | "manual_review",
processing_time_seconds: processingTime,
// Long processing times correlate with higher support ticket volume
user_waited: processingTime > 30,
});
If your approval time frequently exceeds 30 seconds, test whether showing an intermediate "we're reviewing your documents" state with an estimated wait time reduces abandonment.
Building the KYC Dashboard
A weekly KYC dashboard should answer:
- What is today's KYC completion rate vs. 7-day and 30-day averages?
- Which step has the highest drop-off this week?
- What percentage of rejections are retriable errors (quality, expiry) vs. policy rejections?
- Is completion rate different by acquisition source? (Users from paid channels often have lower completion intent)
If you're building or optimising a fintech product and want to set up conversion tracking that actually tells you what to fix, let's talk.
Related Articles
The Startup Analytics Stack: Picking the Right Tools
Picking the wrong analytics tool early wastes months of data. We compare the top analytics platforms for early-stage startups, and show you how to instrument your app for full-funnel visibility from day one.
Setting Up PostHog for a New Product: Our Playbook
From first install to a working dashboard in a day. The events we track, the funnels we build, and the session recordings that actually help.