13 - FAQ & Glossary

Common questions + glossary of domain terms used throughout the eKYC flow.

Frequently Asked Questions

FAQWhy not BLoC / Riverpod / Provider?

eKYC is a one-way linear journey. Each stage screen owns its local state (_isLoading, _verifiedBank, form controllers). There's no need to share reactive state across 5 screens at once. Vanilla setState is sufficient and reduces file count.

Cross-stage state (leadId, token, sessionId) lives in the StorageService singleton - that's the only "global" state the app has.

See 04 - Architecture and 12 - Code Notes.

FAQWhy is mock mode backend-driven?

Putting a mock flag on the client is insecure (tamperable) and causes client/server drift. The backend's GlobalMockEnabled setting is the single source of truth. When enabled, the backend returns fake redirect URLs; the client detects these and skips external launches - but only in dev builds, guarded by ApiConfig.isDev (a compile-time constant).

See 02 - Mock Mode.

FAQWhere's the Razorpay API key?

The backend returns it in the paymentDefaults response at Stage 15. The mobile app uses this key with the Razorpay SDK. The web app ignores the key and uses the redirect URL flow instead. rzp_test_placeholder is the test key used in dev.

See flutter_app/lib/screens/stage15_congrats.dart for the dual-path code.

FAQWhy is Stage 10 just a redirect to Stage 9?

Income Proof used to be a separate screen. The latest BRD merged it into Stage 9 (Personal Details) under the F&O activation section. Stage 10 exists as a thin auto-navigate for backwards compatibility with the stage numbering.

FAQWhere does Annual Income Range get collected?

Stage 9 Personal Details screen, inside the "Personal Details" accordion (top section). Per the latest BRD, it was previously on Stage 6 Bank but is now on Stage 9.

FAQHow does Decentro bank auto-verify work?

Decentro's mobile-to-bank API is triggered at Stage 2 (after OTP verification) for first-time leads. If Decentro returns an active savings account, the backend stores it in the bank_auto_verifies table. When the user reaches Stage 6, GetBankDetailsAsync checks this table and auto-promotes the data to a verified BankAccount. The user lands directly on the Bank Verified screen with the pre-filled details. Clicking "Change bank" takes them to manual entry.

If Decentro returned a non-active-savings account or failed, the user goes through the normal UPI/manual flow.

See backend: backend/src/MO.Ekyc.Infrastructure/Services/Common/BankAutoVerifyService.cs

FAQWhat's the difference between STP and Non-STP?

STP (Straight-Through Processing): The account is created immediately at Stage 14. The user sees their Client ID and DP ID on Stage 15.

Non-STP: The application requires manual verifier review. The user sees a "Thank You - application submitted" message on Stage 15 and will receive updates via SMS/email.

Determined by backend compliance checks at Stage 11 (Final Validation). The decision is based on name match scores, C-SAFE results, PAN/Aadhaar match, and risk scoring.

FAQCan I skip stages during testing?

Sort of. The app resumes from where it left off - if your lead is at Stage 6 and you restart, you'll land on Stage 6. But you can't jump forward past stages you haven't completed. The backend enforces stage progression via RequiresStage filters on controllers.

For dev convenience: manually update the lead's current_state in the leads table to whatever stage you want, then restart the Flutter app.

FAQHow do I reset my test journey?

Three options:

  1. Clear browser localStorage (web): Chrome DevTools → Application → Storage → Clear site data
  2. Clear in-app: call await (await StorageService.getInstance()).clearAll(); then restart
  3. Nuclear option: WarRoom dashboard → "Reset All Journeys" button (requires password)
FAQHow does KRA customer detection work?

At Stage 2 (OTP verified), the backend fires a background KRA lookup (CVL KRA + NDML KRA). If the PAN is already KRA-validated, the Stage 5 (DigiLocker) check returns isKraCustomer: true and the Flutter app skips Stage 5 entirely, jumping straight to Stage 6.

See stage5_digilocker.dart - the _loadAadhaarDetails method handles the skip.

FAQWhy are some files >1000 lines?

api_service.dart is ~1100 lines because it aggregates all ~60 backend endpoints. Splitting would fragment the network layer across 13+ files. Stage 9 (stage9_personal.dart) is ~1000 lines because it has 4 accordion sections + nominees + income proof. This is deliberate - all related UI and logic in one place.

If you find a specific section annoying, use your editor's "Fold All" feature (VS Code: Ctrl+K Ctrl+0) to collapse everything and navigate by method name.

Glossary

TermMeaning
eKYCElectronic Know Your Customer - digital identity verification for account opening
StageOne step in the 16-stage journey (Arrival → Registration → OTP → ... → Congrats)
LeadA single user's journey instance. Identified by leadId (Guid). Stored in the leads DB table.
SessionA time-bounded interaction. Identified by sessionId. 15-minute inactivity timeout.
OTPOne-Time Password. 4-digit code sent via SMS or email. Fixed at 1234 in mock mode.
PANPermanent Account Number. 10-character Indian tax ID (5 letters + 4 digits + 1 letter).
Aadhaar12-digit Indian national ID. Verified via DigiLocker at Stage 5.
KRAKYC Registration Agency (CVL KRA, NDML KRA). If user is already KRA-validated, Stage 5 is skipped.
DigiLockerIndian government digital document wallet. Used to fetch verified Aadhaar at Stage 5.
NSDLNational Securities Depository Limited. Used for PAN verification at Stage 4.
CVL / NDMLTwo KRA providers. Backend queries both at Stage 2 background check.
DecentroFintech aggregator. Used for mobile-to-bank auto-verify at Stage 2 (background).
HyperVergeLiveness + face match provider. Used at Stage 7 for selfie + liveness detection. Also provides Reverse Penny Drop for Stage 6.
RPDReverse Penny Drop. UPI-based bank verification where the user authorizes a ₹1 reverse debit. Used at Stage 6.
IFSCIndian bank routing code (11 chars). Format: [A-Z]{4}0[A-Z0-9]{6}.
eSignElectronic signature of the AOF document. Providers: eMudhra, HyperVerge. Used at Stage 13.
AOFAccount Opening Form. PDF generated at Stage 12, eSigned at Stage 13.
STPStraight-Through Processing. Account created instantly at Stage 14 without manual review.
Non-STPManual verifier review required. User sees "Thank You" at Stage 15 instead of instant credentials.
CBOSBackend system that creates the actual Demat account at Stage 14.
Client IDUnique identifier for a created Demat account. Shown on Stage 15 for STP users.
DP IDDepository Participant ID. Combined with Client ID to form the full account number.
UCIC / UCIDUnique Customer Identification Code. Backend-assigned ID across Motilal Oswal products.
F&OFutures & Options trading segment. Optional opt-in at Stage 9.
DDPIDemat Debit and Pledge Instruction. Permission for broker to pledge/debit shares.
DISDelivery Instruction Slip. Physical form used to transfer shares.
C-SAFEInternal MOSL compliance check system. Queried at Stage 11 Final Validation.
ZintlrBackground check provider (Stage 2 async). Fraud / reputation lookup by mobile number.
OneMoneyAccount Aggregator partner. Used at Stage 9 for fetching income proof from linked banks.
RazorpayPayment gateway. Used at Stage 15 for initial fund transfer into the Demat account.
LottieJSON-based animation format. Used throughout for loading, success, congrats animations.
SharedPreferencesFlutter's key-value storage API. Wraps NSUserDefaults (iOS), Android SharedPreferences, and localStorage (web).
--dart-defineFlutter build-time flag. Used to inject ENV=dev|uat|prod as compile-time constants.
setStateFlutter's built-in state update method. Schedules a rebuild of the widget.
ScaffoldFlutter Material layout widget providing AppBar, body, bottomNavigation slots.
WebViewEmbedded web browser widget. Used for DigiLocker (Stage 5) and eSign (Stage 13).

Where to Find Things

I need...Look in
Base URL for an environmentlib/config/api_config.dart
A specific API methodlib/services/api_service.dart (Ctrl+F the method name)
Stage 6 bank UIlib/screens/stage6_bank.dart
Session timeout valuelib/config/api_config.dart - sessionTimeout
Brand colorslib/config/theme.dart - AppTheme.primary etc.
An asset pathlib/config/assets.dart - AppAssets.xxx
A widget like LoadingOverlaylib/widgets/
A JSON modellib/models/
Mock mode settings (backend)backend/src/MO.Ekyc.Api/appsettings.Development.json
Backend controller for an endpointbackend/src/MO.Ekyc.Api/Controllers/StageN/*.cs
Backend business logicbackend/src/MO.Ekyc.Infrastructure/Services/StageN/*.cs
Old vs new UI comparisonui_old_and_new.html
Architecture diagramsfrontend_architecture.html
Related Backend Docs