1. Stage 4 Objective
Customer confirms their PAN. The KRA RESTRICTED check surfaces here as the entry gate — a RESTRICTED status results in immediate rejection before any PAN data is shown to the customer. The ekyc_name is determined and locked at this stage. NSDL validates the PAN against the government database.
PAN Pre-fetch from Stage 2
If PAN was successfully pre-fetched during Stage 2 (via Zintlr → Hyperverge pipeline), it is shown to the customer for confirmation. If not pre-fetched, the customer enters their PAN manually.
KRA RESTRICTED is a Hard Block
The KRA RESTRICTED check fires FIRST before any PAN data is shown or any processing begins. If kra_status_pan_stage = RESTRICTED, the lead is immediately rejected with DROP_KRA_RESTRICTED. There is no bypass.
2. Preconditions
| Condition | Detail |
lead.state = EMAIL_VERIFIED | Lead must have completed Stage 3 (email verification) with state EMAIL_VERIFIED |
kra_status_pan_stage must be set | The KRA status result from Stage 2 background checks must be available. Values: RESTRICTED, INVALID_PAN, KRA_VALIDATED, KRA_MOD, NON_KRA, or API_DOWN |
| KRA RESTRICTED check fires FIRST | Before any PAN data is displayed or processed, the entry gate check must execute against kra_status_pan_stage |
3. Entry Check (Before Any Processing)
The entry gate check evaluates kra_status_pan_stage before any PAN data is shown to the customer or any processing begins:
kra_status_pan_stage | Action | Result |
RESTRICTED |
Immediate block. Set lead.state = REJECTED. |
DROP_KRA_RESTRICTED — Journey terminated. No PAN data shown. |
INVALID_PAN (999) |
Discard any pre-fetched PAN data from Stage 2. |
Blank PAN entry screen. Customer must enter PAN manually. |
KRA_VALIDATED |
Normal flow. Pre-fetched PAN data (if available) shown for confirmation. |
Continue to PAN confirmation/entry. |
KRA_MOD |
Normal flow. Pre-fetched PAN data (if available) shown for confirmation. |
Continue to PAN confirmation/entry. |
NON_KRA |
Normal flow. Pre-fetched PAN data (if available) shown for confirmation. |
Continue to PAN confirmation/entry. |
API_DOWN |
Normal flow. Pre-fetched PAN data (if available) shown for confirmation. |
Continue to PAN confirmation/entry. |
4. Backend Flow
1
Check kra_status_pan_stage entry gate. Evaluate the KRA status stored from Stage 2. If RESTRICTED → immediate rejection (DROP_KRA_RESTRICTED), set lead.state = REJECTED, terminate journey. If INVALID_PAN (999) → discard all pre-fetched PAN data, force manual entry.
2
Display PAN for confirmation or manual entry. If PAN was pre-fetched at Stage 2 (via Zintlr → Hyperverge) → show PAN for customer confirmation. If not pre-fetched (Zintlr failed, INVALID_PAN, etc.) → present blank PAN entry for manual input.
3
PAN format validation. Validate PAN structure: exactly 10 characters, first 5 alphabetic (A-Z), next 4 numeric (0-9), last 1 alphabetic (A-Z). The 4th character must be 'P' (indicating Individual PAN type). Reject with BE_PAN_001 if format is invalid.
4
Employee PAN check. Check submitted PAN against employee_pan_master table. If PAN matches an employee record, redirect the customer to the staff/employee onboarding flow. Drop code: DROP_EMPLOYEE_CONTACT_USED.
5
Franchise PAN whitelist check. Check submitted PAN against franchise PAN whitelist. If PAN is on the whitelist, allow the journey to continue but tag the lead as a franchise-associated account for downstream processing.
6
PAN duplicate check. Check PAN against post-eSign leads (active/completed journeys) and client_master (existing clients). If duplicate found → reject with BE_PAN_003. Only post-eSign leads are considered duplicates; pre-eSign leads are not blocking.
7
Hyperverge name + DOB fetch. If name and DOB were not already pre-fetched at Stage 2 (e.g., Zintlr failed, manual PAN entry), call Hyperverge now with the submitted PAN to retrieve pan_name and pan_dob from Income Tax records.
8
NSDL validation (with UTI fallback). Validate PAN against NSDL/Protean database. If NSDL is down or returns error → trigger UTI fallback. If both NSDL and UTI fail → route to CS Journey (manual verification hold). Drop code: CS_NSDL_DOWN.
9
Age validation. Calculate age from pan_dob. If age < 18 → minor, journey stopped with DROP_MINOR_AGE. If age > 100 → redirect to branch visit with DROP_AGE_OVER_100.
10
KRA name match for ekyc_name determination. Compare KRA name with PAN name using fuzzy match. If match score ≥ 70 → use KRA name as ekyc_name. If score < 70 or no KRA name available → use PAN name as ekyc_name.
11
Journey path determination. Based on KRA status and address usability, determine: DIGILOCKER_REQUIRED (customer must complete DigiLocker) or DIGILOCKER_SKIP (KRA address is usable, DigiLocker can be bypassed).
12
Set lead.state = PAN_VERIFIED, lock ekyc_name. Persist all validated data: pan_hash, ekyc_name, ekyc_name_source, pan_dob, customer_age, nsdl_pan_valid, pan_name_dob_match, kra_name_match_score, and journey_path. The ekyc_name is now locked and cannot be changed in subsequent stages.
CS Journey Hold
If both NSDL and UTI fail (Step 8), the lead is placed in a CS Journey hold state (CS_NSDL_DOWN). A customer service agent manually validates the PAN and resumes the journey. The lead is not dropped — it is held.
5. Backend Validations
| # | Check | Condition | Result | Blocking? |
| 1 |
KRA RESTRICTED |
kra_status_pan_stage = RESTRICTED |
lead.state = REJECTED, DROP_KRA_RESTRICTED |
Yes — immediate termination |
| 2 |
PAN NSDL validity |
NSDL/UTI returns PAN as invalid or not found |
BE_PAN_001 — PAN rejected as invalid |
Yes — cannot proceed |
| 3 |
PAN + Name + DOB mismatch |
PAN details from NSDL do not match submitted/Hyperverge data |
BE_PAN_002 — mismatch error |
Yes — must resolve |
| 4 |
PAN type individual |
4th character of PAN is not 'P' |
BE_PAN_001 — only Individual PAN type accepted |
Yes — format rejected |
| 5 |
PAN post-eSign duplicate |
PAN found in post-eSign leads or client_master |
BE_PAN_003 — duplicate PAN |
Yes — cannot proceed |
| 6 |
Employee PAN detection |
PAN found in employee_pan_master |
DROP_EMPLOYEE_CONTACT_USED — redirect to staff flow |
Yes — redirect |
| 7 |
Franchise contact restriction |
PAN on franchise whitelist |
Allow but tag as franchise-associated |
No — tagged, not blocked |
| 8 |
Age < 18 (minor) |
Calculated age from pan_dob is below 18 |
DROP_MINOR_AGE — journey stopped |
Yes — journey terminated |
| 9 |
Age > 100 |
Calculated age from pan_dob exceeds 100 |
DROP_AGE_OVER_100 — redirect to branch visit |
Yes — redirect |
| 10 |
Max 3 PAN attempts |
Customer has submitted PAN 3 times and all failed validation |
DROP_PAN_MAX_ATTEMPTS — journey terminated |
Yes — journey terminated |
| 11 |
NSDL + UTI both down |
Both NSDL and UTI APIs fail or are unreachable |
CS_NSDL_DOWN — route to CS Journey hold |
Yes — held for CS |
6. ekyc_name Determination Logic
The ekyc_name is determined by comparing the KRA name with the PAN name using a fuzzy matching algorithm. The name selected here is locked and used throughout the rest of the journey.
| KRA Name Available? | Match Score | ekyc_name Source | ekyc_name_source Value |
| Yes |
Score ≥ 70 |
KRA name used as ekyc_name |
KRA_NAME |
| Yes |
Score 1–69 |
PAN name used as ekyc_name (KRA name too divergent) |
PAN_NAME |
| Yes |
Score 0 |
PAN name used as ekyc_name (no match at all) |
PAN_NAME |
| No (NON_KRA / API_DOWN) |
N/A |
PAN name used as ekyc_name (no KRA name to compare) |
PAN_NAME |
Name Match Scoring
The fuzzy match is performed by AiNXT/Claude. A score of 70+ indicates sufficient similarity to trust the KRA name. Below 70, the PAN name (from Hyperverge/NSDL) is preferred as it comes directly from government records.
7. Journey Path Determination
Based on the KRA status and address data quality, the system determines whether the customer must complete DigiLocker verification or can skip it:
| KRA Status | Address Condition | Journey Path | Rationale |
KRA_VALIDATED |
Usable address on record |
DIGILOCKER_SKIP |
KRA-validated customer with current address; DigiLocker not needed |
KRA_VALIDATED |
Outdated / unusable address |
DIGILOCKER_REQUIRED |
KRA-validated but address is stale; need fresh address proof via DigiLocker |
KRA_MOD |
Usable address on record |
DIGILOCKER_SKIP |
KRA record with modifications but address is still usable |
KRA_MOD |
Outdated / unusable address |
DIGILOCKER_REQUIRED |
KRA record with modifications and stale address; DigiLocker needed |
NON_KRA |
Any (no KRA record) |
DIGILOCKER_REQUIRED |
No KRA registration; must collect identity and address via DigiLocker |
API_DOWN |
Any (unknown KRA status) |
DIGILOCKER_REQUIRED |
KRA status unknown due to API failure; default to DigiLocker for safety |
DIGILOCKER_SKIP Criteria
DigiLocker is only skipped when the customer is KRA_VALIDATED or KRA_MOD AND has a usable (non-outdated) address on their KRA record. All other combinations require DigiLocker verification.
8. Existing Stored Procedure Mapping
8.1 Old Stored Procedures
| Old SP Name | What It Did | New Backend Equivalent |
CHECK_STAFF_PAN |
Staff PAN detection. Checked PAN against MOSL_SDLC_EMPLOYEEDETAILS table to identify employee PANs. |
Query employee_pan_master table |
USP_CHECKPANDEATILSMATCH_SJET |
PAN + DOB match validation. Included OCR character conversion (e.g., 'O' to 'Q') for misread characters. (Note: OCR PAN 'O'/'Q' correction removed per Product team — not required.) |
PAN + DOB match service with character normalization |
USP_CHECK_OLD_NEW_PAN_SJET |
Old vs new PAN check. Verified whether a PAN has been superseded by a newer PAN number. |
PAN versioning check in validation pipeline |
USP_CHECKPANWITHOCR_SJET |
OCR PAN validation. Also handled staff PAN detection and DigiLocker PAN flag setting. |
PAN validation service (OCR path removed in new flow) |
USP_INSERT_OCR_PANDETAILS_SJET |
Stored OCR-extracted PAN details into the database. |
PAN verification record insert |
USP_PANVALIDATION_REQUEST_RESPONSE_LOG_SJET |
Logged all PAN validation API requests and responses for audit trail. |
Structured logging in pan_verifications table |
USP_GET_PAN_RELATED_FLAG_SJET |
Retrieved PAN-related flags (validated, duplicate, staff, etc.) for a given lead. |
PAN flags derived from pan_verifications + leads |
USP_UPDATEKRACUSTFLAG_SJET |
Updated KRA customer flag after PAN confirmation and KRA name matching. |
KRA record update in kra_records table |
USP_BA_IFA_PMS_MOCBPL_PAN_ALLOW_SJET |
BA/IFA/PMS PAN allow check. Verified if a PAN is whitelisted for franchise/partner onboarding. |
Query franchise_pan_whitelist table |
8.2 Old External APIs
| Old API Call | Purpose | New Backend Equivalent |
PanAPI.VerifyPAN_NSDL() |
NSDL PAN validation with UTI fallback. Primary PAN validation against government database. |
NSDL/Protean API call with UTI fallback service |
PanAPI.GetPanDetailsHyperverge() |
Hyperverge Income Tax lookup. Fetches name and DOB from Income Tax records using PAN. |
Hyperverge API integration service |
PanAPI.CallMobileToPanDetailsAsync() |
Zintlr phone-to-PAN lookup. Resolves mobile number to associated PAN number. |
Zintlr API integration (Stage 2 background pipeline) |
8.3 Old Reference Tables
| Old Table | Purpose | New Backend Equivalent |
MOSL_SDLC_EMPLOYEEDETAILS |
Staff PAN database. Contains all employee PAN numbers for staff detection. |
employee_pan_master |
TBL_OAO_DETAILS |
PAN, DOB, and KRA flags storage. Central table for onboarding application details. |
leads + pan_verifications + kra_records |
TBL_CLIENT_PERSONALDETAILS |
Name parsing (FNAME / MNAME / LNAME). Stored client name components separately. |
leads table with ekyc_name (single field, parsed as needed) |
TBL_OCR_PAN_RESPONSE |
OCR PAN data storage. Stored extracted PAN details from OCR processing. |
pan_verifications (OCR path deprecated in new flow) |
TBL_CLIENT_PROOFULOAD |
Uploaded PAN proof documents. Stored file references for PAN card images. |
Document storage service (if applicable in new flow) |
9. Error / Drop Codes
| Code | Type | Trigger | Action |
DROP_KRA_RESTRICTED |
Drop |
kra_status_pan_stage = RESTRICTED at entry gate |
lead.state = REJECTED. Journey terminated. No recovery. |
BE_PAN_001 |
Error |
PAN format invalid (wrong length, wrong pattern, 4th char not 'P') or NSDL returns invalid |
Return error to customer. Allow retry (up to 3 attempts). |
BE_PAN_002 |
Error |
PAN + Name + DOB mismatch between submitted data and NSDL/Hyperverge records |
Return mismatch error. Allow retry with corrected details. |
BE_PAN_003 |
Error |
PAN already exists in post-eSign leads or client_master |
Return duplicate error. Customer cannot proceed with this PAN. |
DROP_EMPLOYEE_CONTACT_USED |
Drop |
PAN found in employee_pan_master |
Redirect to staff/employee onboarding flow. |
DROP_MINOR_AGE |
Drop |
Calculated age from pan_dob is below 18 |
Journey stopped. Minor cannot open account online. |
DROP_AGE_OVER_100 |
Drop |
Calculated age from pan_dob exceeds 100 |
Redirect to branch visit for in-person verification. |
DROP_PAN_MAX_ATTEMPTS |
Drop |
Customer has exhausted all 3 PAN submission attempts |
Journey terminated. Customer must restart. |
CS_NSDL_DOWN |
Hold |
Both NSDL and UTI APIs are down or unreachable |
Route to CS Journey. Lead held for manual PAN validation by CS agent. |
10. Exit State
Upon successful completion of Stage 4, the following data is persisted:
| Field | Value | Description |
lead.state |
PAN_VERIFIED |
Lead advances to PAN_VERIFIED state, ready for next stage |
pan_hash |
SHA-256 hash of PAN |
PAN stored as hash only; plain PAN not persisted after verification |
ekyc_name |
Determined name (locked) |
The name used for the rest of the journey. Cannot be changed after this stage. |
ekyc_name_source |
KRA_NAME or PAN_NAME |
Indicates whether ekyc_name came from KRA record or PAN/Hyperverge |
pan_dob |
Date of birth from PAN |
DOB as returned by Hyperverge/NSDL for the validated PAN |
customer_age |
Calculated age (integer) |
Derived from pan_dob; must be 18–100 |
nsdl_pan_valid |
true |
PAN validated against NSDL (or UTI fallback) |
pan_name_dob_match |
true |
PAN name and DOB match confirmed between sources |
kra_name_match_score |
Integer (0–100) |
Fuzzy match score between KRA name and PAN name |
journey_path |
DIGILOCKER_REQUIRED or DIGILOCKER_SKIP |
Determines whether the customer must complete DigiLocker verification in the next stage |
Stage 4 Complete
After lead.state = PAN_VERIFIED, the customer proceeds to the next stage. The journey_path value determines whether DigiLocker is required or skipped.
11. Vendor & Integration Calls
| Vendor / System | Purpose | When Called | Fallback |
| Hyperverge |
PAN name + DOB fetch from Income Tax records |
If not already pre-fetched at Stage 2 (manual PAN entry path) |
Customer enters name/DOB manually |
| NSDL / Protean |
Primary PAN validation against government database |
Always called for PAN validation |
UTI fallback |
| UTI PAN (fallback) |
Backup PAN validation when NSDL is down |
Only when NSDL fails or is unreachable |
CS Journey hold (CS_NSDL_DOWN) |
| AiNXT / Claude |
Fuzzy name matching between KRA name and PAN name |
During ekyc_name determination (Step 10) |
Default to PAN name if matching service is unavailable |
| CleverTap |
Event tracking and customer engagement |
On PAN verification success/failure events |
Async; non-blocking |
| Zoho CRM |
Lead status sync to CRM |
On state change to PAN_VERIFIED or REJECTED |
Async; retried via queue |
| CDP |
Customer Data Platform event push |
On PAN verification completion |
Async; non-blocking |
| Datalake |
Analytics and reporting data push |
On stage completion for analytics pipeline |
Async; non-blocking |
12. Database Tables (New Backend)
12.1 Operational Tables
| Table | Purpose | Key Columns (Stage 4) |
leads |
Primary lead record. Updated with PAN_VERIFIED state and ekyc_name. |
state, ekyc_name, ekyc_name_source, pan_hash, pan_dob, customer_age, journey_path |
pan_verifications |
PAN validation audit trail. Stores all PAN validation attempts and API responses. |
lead_id, pan_hash, nsdl_pan_valid, pan_name, pan_dob, pan_name_dob_match, attempt_number, validation_source (NSDL/UTI) |
kra_records |
KRA data for the lead. Updated with name match score and ekyc_name determination result. |
lead_id, kra_status_pan_stage, kra_name, kra_name_match_score, kra_address_usable |
journey_stage_events |
Stage transition audit log. Records entry and exit of Stage 4 with timestamps. |
lead_id, stage, event_type, timestamp, metadata |
downstream_events |
Async event queue for downstream systems (CleverTap, Zoho, CDP, Datalake). |
lead_id, event_type, target_system, payload, status, retry_count |
cs_journey_holds |
CS Journey hold records. Created when both NSDL and UTI fail. |
lead_id, hold_reason (CS_NSDL_DOWN), created_at, resolved_at, resolved_by |
12.2 Reference Tables
| Table | Purpose | Access Pattern |
employee_pan_master |
Staff/employee PAN database. Used for employee PAN detection at Step 4. |
READ Lookup by PAN hash |
franchise_pan_whitelist |
Franchise/partner PAN whitelist. Used for franchise tagging at Step 5. |
READ Lookup by PAN hash |
client_master |
Existing client database. Used for PAN duplicate detection at Step 6. |
READ Lookup by PAN hash |
cvl_status_mapping |
KRA status code to internal status mapping. Maps raw CVL codes to RESTRICTED, KRA_VALIDATED, etc. |
READ Lookup by CVL response code |