EKYC 3.0 — Stage 11: Final Validation

Backend-Only Developer Implementation Guide • 7-Check Sequence + STP/Non-STP Decision Engine
Stage ID: FINAL_VALIDATION Trigger: Customer taps “Review & Proceed” BRD Section: 18 — Stage 11 Version: 1.0

Table of Contents

  1. Stage 11 Objective
  2. Preconditions
  3. The 7 Checks
  4. Check Execution Order
  5. STP Decision Logic
  6. Backend Validations
  7. Existing Stored Procedure Mapping
  8. Error / Drop Codes
  9. Exit State
  10. Vendor & Integration Calls
  11. Database Tables
  12. Implementation Notes

1. Stage 11 Objective

Stage 11 is the platform’s final automated gate before the account opening form (AOF) is generated. When the customer taps “Review & Proceed”, the backend executes 7 checks in strict sequence. The customer sees a loading screen while these checks run — there is no polling or partial-result display.

Hard Failure Rule A single hard failure at any check immediately terminates the journey. The customer is shown a drop screen with the relevant drop code. There is no retry or skip for hard-stop checks.

2. Preconditions

ConditionDetailFailure Behaviour
lead.state = DETAILS_DONE All prior stages (1–10) must be completed. Lead must be in the DETAILS_DONE state. Return 400 with message “Lead not in valid state for final validation.”
All name-match scores present aadhaar_name_match, bank_name_match, and face_match scores must already be computed and stored in the database. Return 400 with message “Missing prerequisite match scores.”
Customer taps “Review & Proceed” This is a customer-initiated action. The frontend sends a POST request to the final validation endpoint. N/A — endpoint is not called until the customer triggers it.

3. The 7 Checks

Critical: Each check is documented below with its failure type. “Hard Stop” means the journey is terminated and the lead is dropped. “CS Journey” means the lead is routed to the Customer Service assisted journey for manual completion.
# Check Name What It Does Vendor / Source Failure Type Failure Action
1 PAN Validity Re-check Re-verifies PAN status with NSDL/Protean. Ensures PAN is still active and not deactivated, surrendered, or flagged since Stage 2. NSDL / Protean Hard Stop Drop lead — DROP_FINAL_PAN
2 PAN Name Re-verify Re-checks the name associated with the PAN. Only runs if 5+ days have elapsed since the original PAN verification at Stage 2. Detects name changes at NSDL after initial check. NSDL / Protean Hard Stop Drop lead — DROP_FINAL_PAN_CHANGED
3 Negative List Re-check Re-checks mobile number, PAN, and Aadhaar against the internal negative/blocked list. Catches entries added after initial Stage 2 check. Internal Negative List API Hard Stop Drop lead — DROP_FINAL_NEGLIST
4 Dedupe Re-check Re-checks PAN, email, mobile, bank account, and Aadhaar for duplicate accounts. Catches duplicates created after initial Stage 2 dedupe. Internal Dedupe API Hard Stop Drop lead — DROP_FINAL_DEDUPE
5 Data Completeness Validates that all mandatory fields across all stages are present and non-null. Checks personal details, bank details, nominee, income proof, signature, and address. Internal validation CS Journey or Hard Stop If recoverable: route to CS Journey. If critical fields missing: hard stop — BE_FINAL_INCOMPLETE
6 STP / Non-STP Decision Evaluates all match scores, income proof type, C-SAFE result, PEP declaration, and AML flags to produce the STP or NON_STP decision. Always produces a result — never fails. Internal — StpDecisionService.Evaluate() N/A Always produces STP or NON_STP with reason codes.
7 AOF Pre-check Validates all prerequisites for PDF generation of the Account Opening Form: photo present, signature present, address proof, PAN copy, income proof document. Ensures the AOF can be assembled. Internal validation CS Journey Route to CS Journey — CS_AOF_FAIL

4. Check Execution Order

The 7 checks do not all run sequentially. The execution order is optimized for fail-fast and parallelism where checks are independent.

Execution Pipeline

1
PAN Validity Re-check — Runs first. If PAN is invalid, the journey stops immediately. No other checks are executed.
2
PAN Name Re-verify — Runs only if Check 1 passes. Additionally, this check is skipped entirely if fewer than 5 days have elapsed since the original PAN verification. If the name has changed, the journey stops.
PARALLEL BLOCK
3
Negative List Re-check — Runs in parallel with Check 4. Checks mobile + PAN + Aadhaar against the negative list.
4
Dedupe Re-check — Runs in parallel with Check 3. Checks PAN + email + mobile + bank account + Aadhaar for duplicates.
SEQUENTIAL BLOCK
5
Data Completeness — Validates all mandatory fields. If incomplete and recoverable, routes to CS Journey. If critical fields are missing, hard stop.
6
STP / Non-STP Decision — Evaluates all 8 flags via StpDecisionService.Evaluate(). Always produces a result; never blocks the pipeline.
7
AOF Pre-check — Validates PDF generation prerequisites. On failure, routes to CS Journey rather than dropping the lead.
Parallel Execution Note Checks 3 and 4 execute concurrently. Both must pass before proceeding to Check 5. If either fails, the journey stops with the corresponding drop code. If both fail, the first failure encountered (by response order) is used as the drop reason.

5. STP Decision Logic

Check 6 uses StpDecisionService.Evaluate() which inspects 8 independent flags. Every flag must evaluate to STP for the lead to qualify for straight-through processing. A single NON_STP flag routes the lead to operations review.

Rule: ALL flags must be STP for straight-through processing. A single NON_STP flag on any dimension routes the entire lead to operations/manual review. There is no partial STP.
Flag STP Condition NON_STP Condition Special Rules
aadhaar_name_match Score ≥ 70 Score 1–69 Score = 0 means the lead was already dropped at Stage 5 (Aadhaar verification). This value should never be seen at Stage 11.
bank_name_match Score ≥ 70 Score < 70
face_match Score ≥ 70 Score < 70
income_proof Auto-fetched (e.g., ITR via DigiLocker) Always NON_STP if manual upload Manual upload of income proof always triggers NON_STP because the document requires human verification.
csafe_result CLEAR FLAGGED = NON_STP always If C-SAFE returns FLAGGED, the lead is always NON_STP and is escalated to the compliance team for review.
pep_declared No (customer declares they are not a PEP) Yes = NON_STP always If the customer declares PEP status (Yes), the lead is always NON_STP and is escalated to the compliance team.
aml_pep_mismatch No mismatch (C-SAFE PEP flag agrees with customer declaration) Mismatch = NON_STP If C-SAFE flags the customer as PEP but the customer declared pep = No, this is a mismatch. Results in NON_STP + compliance escalation. This is a serious discrepancy.
esign_mismatch No mismatch detected Mismatch detected Post-eSign check: verifies that the name/details used during eSign match the lead data. Mismatch triggers NON_STP.
Compliance Escalation Flags Three conditions trigger mandatory compliance team escalation in addition to NON_STP routing: (1) csafe_result = FLAGGED, (2) pep_declared = Yes, (3) aml_pep_mismatch = true. These are logged separately and generate compliance workflow tickets.

STP Decision Pseudocode

function StpDecisionService.Evaluate(leadId):
    flags = []

    // 1. Aadhaar name match
    if aadhaar_name_match >= 70:  flags.push(STP)
    else:                          flags.push(NON_STP, reason="AADHAAR_NAME_LOW")

    // 2. Bank name match
    if bank_name_match >= 70:     flags.push(STP)
    else:                          flags.push(NON_STP, reason="BANK_NAME_LOW")

    // 3. Face match
    if face_match >= 70:          flags.push(STP)
    else:                          flags.push(NON_STP, reason="FACE_MATCH_LOW")

    // 4. Income proof
    if income_proof.source == AUTO_FETCH:  flags.push(STP)
    else:                                   flags.push(NON_STP, reason="MANUAL_INCOME_PROOF")

    // 5. C-SAFE
    if csafe_result == CLEAR:     flags.push(STP)
    else:
        flags.push(NON_STP, reason="CSAFE_FLAGGED")
        escalateToCompliance(leadId, "CSAFE_FLAGGED")

    // 6. PEP declared
    if pep_declared == false:     flags.push(STP)
    else:
        flags.push(NON_STP, reason="PEP_DECLARED")
        escalateToCompliance(leadId, "PEP_DECLARED")

    // 7. AML/PEP mismatch
    if csafe_pep_flag == customer_pep_declaration:  flags.push(STP)
    else:
        flags.push(NON_STP, reason="AML_PEP_MISMATCH")
        escalateToCompliance(leadId, "AML_PEP_MISMATCH")

    // 8. eSign mismatch
    if esign_name_matches_lead:   flags.push(STP)
    else:                          flags.push(NON_STP, reason="ESIGN_MISMATCH")

    // Final decision
    if ALL flags == STP:
        return { decision: "STP", reason_codes: [] }
    else:
        return { decision: "NON_STP", reason_codes: [all NON_STP reasons] }

6. Backend Validations

Scenario Check # Action Code Customer Impact
PAN re-check fails (inactive / deactivated / surrendered) 1 Drop lead immediately DROP_FINAL_PAN Journey terminated. Drop screen shown.
PAN name changed since Stage 2 verification 2 Drop lead immediately DROP_FINAL_PAN_CHANGED Journey terminated. Drop screen shown with message indicating PAN name discrepancy.
Negative list match found 3 Drop lead immediately DROP_FINAL_NEGLIST Journey terminated. Generic drop screen (no details about negative list revealed).
Dedupe match found 4 Drop lead immediately DROP_FINAL_DEDUPE Journey terminated. Drop screen indicating existing account found.
Data incomplete (recoverable) 5 Route to CS Journey BE_FINAL_INCOMPLETE Customer is routed to CS-assisted journey for manual completion of missing fields.
Data incomplete (critical / non-recoverable) 5 Hard stop BE_FINAL_INCOMPLETE Journey terminated. This should be rare as prior stages enforce mandatory fields.
NSDL / Protean API unavailable 1, 2 Route to CS Journey CS_NSDL_DOWN Customer is routed to CS-assisted journey. PAN validation deferred to manual process.
Negative List API down 3 Proceed with SKIPPED flag Journey continues. Check result recorded as SKIPPED. Ops team alerted for post-facto review.
Dedupe API down 4 Proceed with SKIPPED flag Journey continues. Check result recorded as SKIPPED. Ops team alerted for post-facto review.
API Downtime Strategy NSDL downtime is treated more seriously (CS Journey redirect) because PAN validity is a regulatory requirement. Negative list and dedupe API downtimes allow the journey to proceed with a SKIPPED flag because these are internal systems that can be retroactively checked by the ops team.

7. Existing Stored Procedure Mapping

The following stored procedures in the existing system handle the logic that Stage 11 encapsulates. These must be analysed for business rules during migration.

Stored Procedure Purpose Maps To
USP_CHECK_ALL_VALIDATIONS_SJET SP Master validation orchestrator. Runs all final checks including PAN re-verify, negative list, dedupe, and data completeness in sequence. Checks 1–5 (overall orchestration)
USP_AUTO_APPROVE_PROOF_SJET SP Evaluates whether income proof and other documents can be auto-approved or require manual review. Check 6 (income_proof flag in STP decision)
USP_JOINT_STP_NONSTP_LOGIC_SJET SP STP/Non-STP logic for joint account applications. Contains the multi-applicant scoring logic. Check 6 (joint account variant of STP logic)
USP_STP_NONSTP_SUPERAPP_SJET SP STP/Non-STP logic for SuperApp channel. Contains channel-specific scoring thresholds and rules. Check 6 (SuperApp channel variant)
USP_ALLOW_ESIGN_SJET SP Determines if the lead is eligible for eSign based on validation results. Pre-eSign eligibility gate. Check 7 (AOF pre-check / eSign readiness)
USP_INSERT_UPDATE_STP_FLAG_SJET SP Persists the STP/Non-STP decision and all associated reason codes to the database. Check 6 result persistence

8. Error / Drop Codes

Code Type Description Check # Customer Message
DROP_FINAL_PAN DROP PAN is no longer valid at NSDL. PAN may have been deactivated, surrendered, or flagged since Stage 2. 1 “We are unable to proceed with your application. Please contact support.”
DROP_FINAL_PAN_CHANGED DROP PAN-associated name has changed at NSDL since the original verification. Name mismatch with application data. 2 “Your PAN details have changed. Please re-apply with updated information.”
DROP_FINAL_NEGLIST DROP Mobile, PAN, or Aadhaar found in the negative/blocked list. 3 “We are unable to proceed with your application at this time.”
DROP_FINAL_DEDUPE DROP Duplicate account detected on PAN, email, mobile, bank account, or Aadhaar. 4 “An existing account was found matching your details. Please contact support.”
BE_FINAL_INCOMPLETE ERROR One or more mandatory fields are missing or invalid. May be recoverable (CS Journey) or critical (hard stop). 5 CS Journey: “We need a few more details. Our team will assist you.” Hard stop: “Unable to complete your application.”
CS_AOF_FAIL CS ROUTE AOF PDF generation prerequisites not met. Missing photo, signature, or document required for the account opening form. 7 “We need a few more details to complete your form. Our team will assist you.”
CS_NSDL_DOWN CS ROUTE NSDL/Protean API is unavailable. PAN verification cannot be completed electronically. 1, 2 “We are experiencing a temporary issue. Our team will complete your verification shortly.”

9. Exit State

On successful completion of all 7 checks, the following state is written:

Field Value Storage
lead.state FINAL_VALIDATION leads table
stp_decision STP or NON_STP leads table
stp_reason_codes JSON array of reason codes (empty for STP, populated for NON_STP) leads table
final_validation_timestamp UTC timestamp of when all checks completed leads table
All 7 check results Individual pass/fail/skip result for each check, with vendor response payloads final_validations table
Successful Exit After Stage 11, the lead is ready for AOF generation and eSign. The STP decision determines whether the account is auto-approved or routed to the ops review queue.

Exit State Pseudocode

// After all 7 checks pass
UPDATE leads SET
    state              = 'FINAL_VALIDATION',
    stp_decision       = @stpDecision,          -- 'STP' or 'NON_STP'
    stp_reason_codes   = @stpReasonCodesJson,   -- '[]' or '["AADHAAR_NAME_LOW","MANUAL_INCOME_PROOF"]'
    final_validation_ts = GETUTCDATE(),
    updated_at         = GETUTCDATE()
WHERE lead_id = @leadId;

INSERT INTO final_validations (lead_id, check_number, check_name, result, vendor_response, created_at)
VALUES
    (@leadId, 1, 'PAN_VALIDITY',     @check1Result, @check1Response, GETUTCDATE()),
    (@leadId, 2, 'PAN_NAME_VERIFY',  @check2Result, @check2Response, GETUTCDATE()),
    (@leadId, 3, 'NEGATIVE_LIST',    @check3Result, @check3Response, GETUTCDATE()),
    (@leadId, 4, 'DEDUPE',           @check4Result, @check4Response, GETUTCDATE()),
    (@leadId, 5, 'DATA_COMPLETENESS',@check5Result, @check5Response, GETUTCDATE()),
    (@leadId, 6, 'STP_DECISION',     @check6Result, @check6Response, GETUTCDATE()),
    (@leadId, 7, 'AOF_PRECHECK',     @check7Result, @check7Response, GETUTCDATE());

10. Vendor & Integration Calls

Vendor / System Used In Check Purpose Fallback
NSDL / Protean Check 1, Check 2 PAN validity verification and PAN name lookup. Primary vendor for PAN services. UTI (fallback vendor for PAN verification)
UTI (fallback) Check 1, Check 2 Fallback PAN verification vendor if NSDL/Protean is unavailable. Route to CS Journey (CS_NSDL_DOWN)
Internal Negative List API Check 3 Checks mobile, PAN, and Aadhaar against the internal negative/blocked list database. Proceed with SKIPPED flag; ops team alerted
Internal Dedupe API Check 4 Checks PAN, email, mobile, bank account, and Aadhaar for existing duplicate accounts. Proceed with SKIPPED flag; ops team alerted
CleverTap Post-validation Event tracking: final validation outcome, STP decision, drop events. Used for analytics and customer engagement. Fire-and-forget; failure does not block journey
Zoho Post-validation CRM update: lead status update, STP/Non-STP flag, compliance escalation tickets if applicable. Fire-and-forget; failure does not block journey
CDP Post-validation Customer Data Platform event push: final validation event with all check results and STP decision. Fire-and-forget; failure does not block journey
Datalake Post-validation Raw event and payload logging for audit trail, analytics, and compliance reporting. Fire-and-forget; failure does not block journey

11. Database Tables

Table Access Purpose in Stage 11
final_validations WRITE NEW Stores results of all 7 checks for each lead. Each check is a separate row with check number, result (PASS/FAIL/SKIP), vendor response payload, and timestamp.
leads READ WRITE Read: Current state, lead data for validation. Write: state, stp_decision, stp_reason_codes, final_validation_timestamp.
pan_verifications READ WRITE Read: Original PAN verification timestamp (to determine if 5+ days elapsed for Check 2). Write: Re-verification result from Check 1/2.
aadhaar_verifications READ Read Aadhaar number for negative list check (Check 3) and dedupe check (Check 4). Read aadhaar_name_match score for STP decision (Check 6).
bank_accounts READ Read bank account details for dedupe check (Check 4). Read bank_name_match score for STP decision (Check 6).
liveness_verifications READ Read face_match score for STP decision (Check 6).
signature_verifications READ Read signature presence for AOF pre-check (Check 7). Verify signature document exists.
personal_details READ Read all personal details for data completeness check (Check 5). Read PEP declaration for STP decision (Check 6).
csafe_checks READ Read C-SAFE result and C-SAFE PEP flag for STP decision (Check 6). Used in AML/PEP mismatch detection.
negative_list_entries READ WRITE Read: Check if mobile/PAN/Aadhaar exists in negative list (Check 3). Write: Log the re-check result and timestamp.

12. Implementation Notes

StpDecisionService.Evaluate() Check 6 uses StpDecisionService.Evaluate() which inspects exactly 8 flags: aadhaar_name_match, bank_name_match, face_match, income_proof, csafe_result, pep_declared, aml_pep_mismatch, and esign_mismatch. All 8 must evaluate to STP for straight-through processing.
PAN Re-verify Elapsed Time Check 2 (PAN Name Re-verify) only executes if 5 or more days have elapsed since the original PAN verification at Stage 2. This threshold is configurable via system configuration (e.g., config.pan_reverify_days_threshold). If fewer than 5 days have elapsed, Check 2 is recorded as SKIPPED with reason WITHIN_THRESHOLD and the pipeline proceeds directly to Checks 3+4.
Loading Screen Duration The customer waits on a loading screen while all 7 checks execute. Typical execution time is 3–8 seconds depending on vendor response times. Implement a client-side timeout of 30 seconds. If the backend does not respond within 30 seconds, the frontend should display a “Please wait” message and retry once.
Post-Validation Event Dispatch After all checks complete and the state is written, fire analytics events to CleverTap, Zoho, CDP, and Datalake asynchronously. These are fire-and-forget — failures do not block the customer journey or roll back the validation result.