top of page

Digital Lending Journey with Java Microservices,Azure Cloud ,KYC/CDD/EDD Compliance with Fenergo, AML/Financial Crime with Actimize + Real Esatate Builder integration -Customer Amit R Journey

  • Writer: Anand Nerurkar
    Anand Nerurkar
  • Sep 18
  • 9 min read

Full event-driven lending journey with:

  • Customer: Amit R

  • Builder: Prestige Group

  • Platform: Kafka + Java Microservices + Azure (CosmosDB, Redis, Blob, ELK)

  • Compliance: Fenergo (KYC/CDD/EDD), Actimize (AML/CTR/STR/NTR/CBWR)

  • Integration: CBS (TCS BaNCS), Builder portal

  • Data: Relational tables (transactional), CosmosDB (event read model), Redis (fast access)

  • Security: Idempotency, correlation IDs, encryption, tokenization, audit logs, RBAC

Let’s break it step by step.

🔹 Customer Journey Flow (End-to-End)

1. UI / Customer Interaction

  1. Amit R visits ABC Bank portal → login via Azure AD SSO (OAuth2/JWT token).

  2. Clicks “Apply Loan”.

  3. Enters loan details (amount, term).

  4. Consent screen appears for:

    • KYC / CDD / EDD (Fenergo)

    • Credit Score (CIBIL/Experian)

    • Fraud Score (Experian Hunter, Feedzai)

    • AML / Financial Crime (Actimize)

    • Data sharing consent

  5. Uploads documents: PAN, Aadhaar, income proof.

  6. Clicks Submit Loan Application. (post to /loan )


Security at UI: TLS, Input validation, CAPTCHA, PII masking.


2. Loan Service (/loan)/ Backend (Microservices)

  1. Loan Service  get called for /loan and creates a loan_application entry with:

    • idempotencyKey, requestId, correlationId, msgKey

    • Status: Submitted

    • Saves:

      • loan_application table (core details).

      • consent_table (one row per consent type).

      • outbox_event (status=pending, type=loan-initiated).

    • Transaction is atomic → ensures no partial writes.

Customer sees:👉 “Your loan application ref# XXXX is received and under process.”


3. Outbox → Kafka

  • Outbox Poller:

    • Scans outbox every few seconds (not 15 min, real-time for UX).

    • Publishes loan-initiated event to Kafka.

    • Marks outbox row processed.

  • Event enriched with:

    • {LoanAppID, CorrelationID, RequestID, IdempotencyKey, Timestamp}.

  • Kafka config:

    • Topics encrypted (AES-256).

    • ACLs & mTLS enforced.

    • DLQ for poison messages.

Security: Database role-based access, TLS Kafka, message signing for integrity.


4. Event Consumers (CQRS Style)

Every business event is consumed by:

  1. RedisCacheConsumer

    • Updates Redis with latest state (loanAppID → current status).

    • TTL enforced (to auto-expire stale apps).

  2. CosmosDBConsumer

    • Writes raw immutable event → loan_events container.

    • Schema:

      { "eventId": "...", "loanAppId": "...", "eventType": "kyc-requested", "timestamp": "...", "correlationId": "...", "payloadHash": "...", "status": "PENDING|DONE|FAILED" }

    • Acts as read model for dashboards:

      • Ops dashboard → KYC/AML/STR pipeline progress.

      • CXO dashboard → Loan pipeline KPIs.

  3. AuditConsumer

    • Pushes event to ELK (Elasticsearch + Logstash + Kibana).

    • Provides immutable audit trail with correlation ID.

    • Enables RBI/SEBI/FIU-IND audit queries.


5. KYC/AML & Risk Checks

5.1 KYC Service (Fenergo)

  1. Listens to "loan-initiated" event

  2. Inserts "kyc-requested" into outbox_event (status = PENDING)

  3. Poller publishes "kyc-requested" to Kafka

  4. KYC Service calls Fenergo Adapter - that call Fenergo API (for KYC/CDD/EDD) and return respone as kyc-done

  5. Writes result to kyc_result table

  6. Inserts "kyc-done" into outbox_event (status = PENDING)

  7. Poller publishes "kyc-done"

5.2 Credit Service (CIBIL / Experian)

  1. Listens to "loan-initiated"

  2. Inserts "credit-score-requested" into outbox_event

  3. Poller publishes credit-score-requested

  4. Calls CIBIL/Experian API

  5. Writes credit_result table

  6. Inserts "credit-score-done" into outbox_event with status =pending

  7. Poller publishes credit-score-done

5.3 Fraud Service (Experian Hunter / Feedzai)

  • Similar flow:

    • "fraud-score-requested" → poller → API call → fraud_result → "fraud-score-done" → poller

5.4 AML & Financial Crime Service (Actimize)

  • "aml-score-requested" → poller → Actimize → aml_result → "aml-done" → poller

  • "fincrime-score-requested" → poller → Actimize → financial_crime_result → "fincrime-done" → poller


6. Loan Evaluation

  • Loan Eval Service consumes all *-done events.

  • Aggregates results from result_table.

  • Rule engine decides:

    • Approve → loan-approved

    • Reject → loan-rejected (with reason)

    • Borderline → manual-review.

6. Manual Review (if required)

  • Ops Dashboard (powered by CosmosDB read model + ELK search):

    • Ops user sees flagged loans.

    • Manually approves/rejects.

  • Decision → published as manual-approve-done.


7. Loan Agreement & CBS Account Creation

  • On approval:

  • Loan Agreement MS:

    • Generates digitally signed loan contract (PKI, Aadhaar eSign).

    • Publishes loan-agreement-created.

  • Loan Account MS:

    • Consumes → integrates with CBS (TCS BaNCS) via secured API Gateway.

    • CBS creates Loan A/c

    • Publishes loan-account-created.

  • Notification MS:

    • Notify Amit R: “Loan approved. Loan A/C: 67890 created”

    • Notify Builder (Prestige Group): “Customer loan account setup complete”.

    • send notification to cusotmer/builder for loan approval,loan acount setup,disbursement done.

8. Loan Account Creation

  • Upon approval, Loan Account Service calls CBS (TCS BaNCS / Finacle).

  • Inserts loan_account table entry.

  • Emits loan-account-created event.

  • Customer notified: loan account created.

  • Builder notified: customer loan account set up.

Security: TLS + VPN / Private Network for CBS integration.

9. Builder Disbursement Request

  1. Builder (Prestige Group) submits milestone-based disbursement request.

  2. Uploads milestone proof (e.g., plinth completion) to blob storage.

  3. Metadata stored in builder_disbursement_request table.

  4. Event: builder-disbursement-requested emitted.

Security: RBAC, document encryption at rest (Azure Blob Storage).

10. Customer Approval for Disbursement

  • Customer reviews builder request → approves.

  • Event: customer-approval-for-disbursement emitted.

11. Loan Officer Validation

  • Loan officer validates milestone (photo verification, plinth completion).

  • Inserts into disbursement_validation table.

  • Event: disbursement-validation-done emitted.

12. Disbursement Service / CBS Integration

  1. Upon validation, disbursement service:

    • Initiates Saga to CBS for fund transfer to builder.

    • Generates EMI schedule for approved disbursed amount.

  2. Inserts disbursement table entry, emits disbursement-done event.

Security: End-to-end TLS, logging, idempotency check using idempotencyKey.

13. Compliance Reporting Pipeline

Compliance Type

Service

Frequency

Flow

KYC / CDD / EDD

Fenergo

Daily / On-demand

Fenergo generates report → Bank Compliance Officer reviews → Upload to RBI portal

CTR / NTR / STR / CBWR

Actimize

Daily / Weekly

Batch job → Flat file → SFTP → Actimize ETL → Rules segregation → Generate reports → Bank PO uploads to FIU-IND

  • Actimize processes all AML / Financial Crime events.

  • Fenergo handles all KYC/CDD/EDD events.

  • All reports signed, encrypted, and audited.

14. Event & DB Key Tracking

  • Every table and event has:

    • idempotencyKey → ensures duplicate prevention

    • requestId → maps to user/API request

    • correlationId → tracks end-to-end journey

    • msgKey → unique Kafka message key

  • Redis and CosmosDB store events per idempotencyKey, read models updated for dashboard.

  • Audit table captures every event consumed/published.

15. Read Models / Dashboard

Per-event read models: kyc_read_model, credit_read_model, fraud_read_model, aml_read_model, financial_crime_read_model, loan_evaluation_read_model, builder_disbursement_read_model, disbursement_read_model.

Aggregated dashboard model example (CosmosDB / MongoDB):

{
  loanAppId: "LA1001",
  customerId: "CUST123",
  customerName: "Amit R",
  builder: "Prestige Group",
  loanAmount: 7500000,
  term: "15Y",
  loanStatus: "Approved",
  kyc: {status: "Pass", provider: "Fenergo", score: 98},
  credit: {status: "Pass", score: 810, bureau: "CIBIL"},
  fraud: {status: "Pass", provider: "Experian", riskLevel: "Low"},
  aml: {status: "Pass", provider: "Actimize", score: "Low"},
  financialCrime: {status: "Pass", provider: "Actimize", riskLevel: "None"},
  loanAccountNo: "123456789",
  disbursement: {
     milestones: [
       {milestone: "Plinth", status: "Approved"},
       {milestone: "Roof", status: "Pending"}
     ],
     totalDisbursed: "25L",
     emiScheduleUrl: "blob://emi.pdf"
  },
  compliance: {
     kycReport: "Submitted to RBI",
     ctrReport: "Submitted to FIU-IND"
  },
  timestamps: {...},
  idempotencyKey: "IDEMP-001",
  requestId: "REQ-001",
  correlationId: "CORR-001",
  msgKey: "MSG-001"
}


🔹 DB Schema (Simplified)

. Write Model Tables
1.1 loan_application
loanAppId | customerId | amount  | term | status    | idempotencyKey | requestId | correlationId | msgKey  | createdAt
LA1001    | CUST123    | 7500000 | 15Y  | Submitted | IDEMP-001      | REQ-001   | CORR-001      | MSG-001 | 2025-09-17

1.2 consent
consentId  | loanAppId | kyc | cdd | edd | credit | fraud | aml | finCrime | status   | idempotencyKey | requestId | correlationId | msgKey
CONS-1001  | LA1001    | Y   | Y   | Y   | Y      | Y     | Y   | Y        | Accepted | IDEMP-001      | REQ-001   | CORR-001      | MSG-001

1.3 outbox_event
eventId  | loanAppId | eventType                     | payloadRef | status  | idempotencyKey | requestId | correlationId | msgKey  | createdAt
EVT-001  | LA1001    | loan-initiated                | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-001 | 2025-09-17
EVT-002  | LA1001    | kyc-requested                 | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-002 | 2025-09-17
EVT-003  | LA1001    | kyc-done                      | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-003 | 2025-09-17
EVT-004  | LA1001    | credit-score-requested        | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-004 | 2025-09-17
EVT-005  | LA1001    | credit-score-done             | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-005 | 2025-09-17
EVT-006  | LA1001    | fraud-score-requested         | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-006 | 2025-09-17
EVT-007  | LA1001    | fraud-score-done              | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-007 | 2025-09-17
EVT-008  | LA1001    | aml-score-requested           | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-008 | 2025-09-17
EVT-009  | LA1001    | aml-done                      | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-009 | 2025-09-17
EVT-010  | LA1001    | fincrime-score-requested      | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-010 | 2025-09-17
EVT-011  | LA1001    | fincrime-done                 | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-011 | 2025-09-17
EVT-012  | LA1001    | loan-evaluated                | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-012 | 2025-09-17
EVT-013  | LA1001    | loan-account-created          | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-013 | 2025-09-17
EVT-014  | LACC-001  | builder-disbursement-requested| {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-014 | 2025-09-17
EVT-015  | BDR-01    | disbursement-validation       | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-015 | 2025-09-17
EVT-016  | LACC-001  | disbursement-done             | {...}      | PENDING | IDEMP-001      | REQ-001   | CORR-001      | MSG-016 | 2025-09-17

1.4 kyc_result
kycId    | loanAppId | provider | status | score | idempotencyKey | requestId | correlationId | msgKey
KYC-001  | LA1001    | Fenergo | Pass   | 98    | IDEMP-001      | REQ-001   | CORR-001      | MSG-003

1.5 credit_result
creditId | loanAppId | bureau   | score | status | idempotencyKey | requestId | correlationId | msgKey
CR-001   | LA1001    | CIBIL    | 810   | Pass   | IDEMP-001      | REQ-001   | CORR-001      | MSG-005

1.6 fraud_result
fraudId  | loanAppId | provider      | riskLevel | status | idempotencyKey | requestId | correlationId | msgKey
FR-001   | LA1001    | Experian      | Low       | Pass   | IDEMP-001      | REQ-001   | CORR-001      | MSG-007

1.7 aml_result
amlId    | loanAppId | provider  | score | status | idempotencyKey | requestId | correlationId | msgKey
AML-001  | LA1001    | Actimize | Low   | Pass   | IDEMP-001      | REQ-001   | CORR-001      | MSG-009

1.8 financial_crime_result
fcId     | loanAppId | provider  | riskLevel | status | idempotencyKey | requestId | correlationId | msgKey
FC-001   | LA1001    | Actimize | None      | Pass   | IDEMP-001      | REQ-001   | CORR-001      | MSG-011

1.9 loan_evaluation
evalId   | loanAppId | result   | remarks     | idempotencyKey | requestId | correlationId | msgKey
EVAL-01  | LA1001    | Approved | Good profile | IDEMP-001      | REQ-001   | CORR-001      | MSG-012

1.10 loan_account
loanAccId | loanAppId | cbsAccNo   | status | idempotencyKey | requestId | correlationId | msgKey
LACC-001  | LA1001    | 123456789  | Active | IDEMP-001      | REQ-001   | CORR-001      | MSG-013

1.11 builder_disbursement_request
reqId    | loanAccId | builder     | milestone | docUrl           | status   | idempotencyKey | requestId | correlationId | msgKey
BDR-01   | LACC-001  | PrestigeGrp | Plinth    | blob://plinth    | Pending  | IDEMP-001      | REQ-001   | CORR-001      | MSG-014

1.12 disbursement_validation
valId    | reqId  | officerId | photoUrl       | status   | idempotencyKey | requestId | correlationId | msgKey
VAL-01   | BDR-01 | OFFICER-1 | blob://photo1  | Approved | IDEMP-001      | REQ-001   | CORR-001      | MSG-015

1.13 disbursement
disbId   | loanAccId | amount | toAccount         | status | emiScheduleUrl   | idempotencyKey | requestId | correlationId | msgKey
DIS-01   | LACC-001  | 25L    | PrestigeGrp-ACC  | Done   | blob://emi.pdf   | IDEMP-001      | REQ-001   | CORR-001      | MSG-016

1.14 audit_log
auditId  | eventId | service      | action           | timestamp  | idempotencyKey | requestId | correlationId | msgKey
AUD-001  | EVT-001 | loan-service | event-published  | 2025-09-17 | IDEMP-001      | REQ-001   | CORR-001      | MSG-001
AUD-002  | EVT-002 | kyc-service  | event-consumed   | 2025-09-17 | IDEMP-001      | REQ-001   | CORR-001      | MSG-002
...

2. Read Models (Per Event)
2.1 kyc_read_model
loanAppId | status | score | provider | timestamp
LA1001    | Pass   | 98    | Fenergo  | 2025-09-17

2.2 credit_read_model
loanAppId | score | status | bureau | timestamp
LA1001    | 810   | Pass   | CIBIL  | 2025-09-17

2.3 fraud_read_model
loanAppId | riskLevel | status | provider | timestamp
LA1001    | Low       | Pass   | Experian | 2025-09-17

2.4 aml_read_model
loanAppId | score | status | provider | timestamp
LA1001    | Low   | Pass   | Actimize | 2025-09-17

2.5 financial_crime_read_model
loanAppId | riskLevel | status | provider | timestamp
LA1001    | None      | Pass   | Actimize | 2025-09-17

2.6 loan_evaluation_read_model
loanAppId | result   | remarks     | timestamp
LA1001    | Approved | Good profile| 2025-09-17

2.7 builder_disbursement_read_model
reqId   | milestone | status  | timestamp
BDR-01  | Plinth    | Approved| 2025-09-17

2.8 disbursement_read_model
disbId  | amount | toAccount        | status | emiScheduleUrl      | timestamp
DIS-01  | 25L    | PrestigeGrp-ACC  | Done   | blob://emi.pdf      | 2025-09-17

3. Aggregated Read Model (Dashboard)
{
  loanAppId: "LA1001",
  customerId: "CUST123",
  customerName: "Amit R",
  builder: "Prestige Group",
  loanAmount: 7500000,
  term: "15Y",
  loanStatus: "Approved",
  kyc: {status: "Pass", provider: "Fenergo", score: 98},
  credit: {status: "Pass", score: 810, bureau: "CIBIL"},
  fraud: {status: "Pass", provider: "Experian", riskLevel: "Low"},
  aml: {status: "Pass", provider: "Actimize", score: "Low"},
  financialCrime: {status: "Pass", provider: "Actimize", riskLevel: "None"},
  loanAccountNo: "123456789",
  disbursement: {
     milestones: [
       {milestone: "Plinth", status: "Approved"},
       {milestone: "Roof", status: "Pending"}
     ],
     totalDisbursed: "25L",
     emiScheduleUrl: "blob://emi.pdf"
  },
  compliance: {
     kycReport: "Submitted to RBI",
     ctrReport: "Submitted to FIU-IND"
  },
  timestamps: {...},
  idempotencyKey: "IDEMP-001",
  requestId: "REQ-001",
  correlationId: "CORR-001",
  msgKey: "MSG-001"
}

🔹 Event JSON (Samples)

loan-initiated

{
  "eventId": "evt-1001",
  "eventType": "loan-initiated",
  "loanId": "LN12345",
  "customerId": "CUST001",
  "amount": 500000,
  "tenure": 60,
  "requestId": "REQ-789",
  "correlationId": "CORR-123",
  "idempotencyKey": "IDEMP-456",
  "timestamp": "2025-09-17T10:00:00Z"
}

kyc-requested

{
  "eventId": "evt-1002",
  "eventType": "kyc-requested",
  "loanId": "LN12345",
  "customerId": "CUST001",
  "correlationId": "CORR-123",
  "requestId": "REQ-789",
  "idempotencyKey": "IDEMP-456",
  "timestamp": "2025-09-17T10:01:00Z"
}

kyc-done

{
  "eventId": "evt-1003",
  "eventType": "kyc-done",
  "loanId": "LN12345",
  "customerId": "CUST001",
  "kycStatus": "PASSED",
  "riskRating": "LOW",
  "provider": "Fenergo",
  "correlationId": "CORR-123",
  "timestamp": "2025-09-17T10:02:00Z"
}

👉 Similar JSON exists for:

  • creditscore-requested, creditscore-done

  • fraud-requested, fraud-done

  • aml-requested, aml-done

  • crime-requested, crime-done

  • loan-approved, loan-rejected, manual-review

  • agreement-created, agreement-signed

  • loan-account-created

  • disbursement-requested, disbursement-approved, disbursement-completed

🔹 CosmosDB Read Model (for Dashboard)

Each event stored as document:

{
  "eventId": "evt-1003",
  "loanId": "LN12345",
  "eventType": "kyc-done",
  "customerId": "CUST001",
  "payload": {
    "kycStatus": "PASSED",
    "riskRating": "LOW",
    "provider": "Fenergo"
  },
  "correlationId": "CORR-123",
  "requestId": "REQ-789",
  "idempotencyKey": "IDEMP-456",
  "timestamp": "2025-09-17T10:02:00Z"
}

👉 Dashboards query CosmosDB for:

  • Loan pipeline status (per stage).

  • SLA compliance (how long each check took).

  • CTR/STR/NTR counts.

  • Builder disbursement pipeline.

🔹 Security

  • All PII (Aadhaar, PAN) → tokenized + AES-256 encrypted in Blob & DB.

  • mTLS between services.

  • Kafka topics secured with SASL_SSL + ACLs.

  • RBAC for Ops dashboards.

  • Immutable audit logs in ELK.

  • Idempotency & correlation IDs ensure safe retries.

🔹 Risks & Mitigation

  • Business: Loan fraud → Mitigated via Experian fraud score + manual review.

  • Technology: Event duplication → Idempotency key + outbox pattern.

  • Data: PII leakage → Encryption + masking in dashboards.

  • Application: Service downtime → AKS auto-restart + retries.

  • Security: Insider misuse → RBAC + immutable audit.

  • Governance: RBI non-compliance → Automated FIU-IND reporting + audit trails.



✅ This architecture gives ABC Bank a foolproof, event-driven, compliant, secure lending journey.

This text-based flow covers:

  • UI → Azure AD → Microservices → Kafka → Adapters → CBS → Redis → CosmosDB → Audit → Compliance

  • All events with idempotency / correlation / request tracking

  • All DB write tables with schema & sample data

  • Per-event read models + aggregated dashboard model

  • Security & compliance at each hop

  • Builder milestone workflow & customer approval integrated


 
 
 

Recent Posts

See All
How to replan- No outcome after 6 month

⭐ “A transformation program is running for 6 months. Business says it is not delivering the value they expected. What will you do?” “When business says a 6-month transformation isn’t delivering value,

 
 
 
EA Strategy in case of Merger

⭐ EA Strategy in Case of a Merger (M&A) My EA strategy for a merger focuses on four pillars: discover, decide, integrate, and optimize.The goal is business continuity + synergy + tech consolidation. ✅

 
 
 

Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
  • Facebook
  • Twitter
  • LinkedIn

©2024 by AeeroTech. Proudly created with Wix.com

bottom of page