Real NCRP-CFCFRMS integration to the I4C-MHA API Specification 2.0, alongside the existing demo module (new paths under /v1/i4c, /v1/i4c/admin, /v1/i4c/cases). - Inbound token and complaint APIs (Bearer / Basic / body auth, CryptoJS AES, IP allowlist), Section 5 / Section 7 acks, idempotent repeat pushes. - Complaint processing: account and transaction matching, automatic hold of the disputed amount with prospective top-up, onward trace, Section 6 response via an outbox with retry, optional ack callback, API log for the periodic review. - Holds register: 90-day review, maker-checker release (full or partial), freeze / unfreeze, unfreeze-and-release. - Automatic customer intimation (email active, SMS / WhatsApp configurable) with manual recording and history. - GRM grievance register (EDD, GR id, nodal, IO / DGRO / SGRO decisions, deadlines, escalation) and MRM restoration register (assessment, pro-rata, victim request and papers, bank actions, restoration to the victim through a restoration pool, victim-bank cases), documents with SHA-256, statements. - Paged, filterable officer lists with date ranges; local I4C simulator. - Migrations 0610-0613, jobs I4C Dispatch and I4C Hold Review, runbook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
28 KiB
CFCFRMS: I4C-MHA API Integration (Banks ↔ I4C 2.0)
This is the runbook for the bank's real-time integration with the NCRP-CFCFRMS platform of I4C (Ministry of Home Affairs), built to the I4C-MHA "Banks API Integration Specification 2.0". It covers what the integration does, how to configure and test it, and what an officer does with it day to day.
The work is required by RBI letter CO.DOS.KYC.No.S6675/11-01-006/2025-26 (05 Dec 2025). It asks banks, including Primary UCBs, to:
- integrate by API for real-time action on cyber-fraud complaints;
- cover every system and delivery channel;
- periodically review the integration's performance to minimise failures.
The older CFCFRMS demo (/v1/cfcfrms/*, /v1/simulator/cfcfrms/* and the Angular mock interceptor) is untouched. This integration lives beside it under /v1/i4c/*.
1. What happens to a complaint
I4C ──POST /auth/token──────────────► bank checks username/password (plain or CryptoJS-encrypted) → access_token
I4C ──POST /complaints (Bearer)─────► bank checks token + source IP → validates → stores → ack {00, job_id}
│ (after commit, on the I4C worker pool)
▼
for each incident (own transaction):
find the account (savings, then current)
layer 0 → find the debit, report where the money went
layer ≥1 → hold up to the disputed amount at once,
trace onward debits for any shortfall,
keep the rest as a prospective hold
▼
bank ──POST <I4C auth>───────────────► I4C token
bank ──POST <I4C response> (Bearer)──► I4C section 6 message: acknowledgement_no, job_id, transactions[]
(outbox: retried with backoff until delivered)
Response types produced
| txn_type_id | txn_type | When |
|---|---|---|
| 1 | Transaction Put on Hold | Money held on the account here. A 0.00 entry with remarks means nothing could be held yet; the amount is prospective. |
| 3 | Money Transfer To | The money went on by outward IMPS/NEFT/RTGS (payee IFSC, account, UTR and I4C bank code), or to another account in this bank. |
| 14 | Withdrawal through Cheque | Withdrawn at the branch against a cheque (clerk register or CTS clearing). A branch cash withdrawal above Rs 500 is also reported here, with remarks saying so (see §8). |
| 17 | Others Less than equal to 500 | An untraced debit of Rs 500 or less. |
| status_code 01 | Record not found | The account does not exist in this CBS. |
| status_code 02 | Invalid RRN | The account exists, but no debit/credit of that amount near that date. |
| 70010 | (in remarks) | The incident could not be processed after 5 attempts. It is reported so I4C is not left waiting, and is handled manually. |
Types 5 (ATM), 6 (AEPS) and 11 (POS) are built to the specification's field lists, but are not produced today, because this CBS has no ATM, AEPS or POS channel. A channel that records those debits only has to classify them as ATM_WITHDRAWAL / AEPS_WITHDRAWAL / POS_WITHDRAWAL in I4cTransactionTracer, with the ATM / merchant details.
The Money Transfer To entry carries the payee reference under both rrn (the section 6 table) and rrn_transaction_id (the section 6 sample), with the same value.
Rules applied to holds
These follow the MHA SOP for NCRP-CFCFRMS (02.01.2026) and RBI's draft KYC Amendment Directions on debit holds (Sep 2026).
- Only the disputed amount is held as an amount hold (
AMOUNT_HOLD). The rest of the balance stays usable. Every debit path honours the hold: counter, transfer, standing instruction, CTS inward and NACH. - Prospective hold: what the balance cannot cover is recorded as a shortfall. The I4C Hold Review job tops it up from later credits.
- Full debit freeze is never automatic. An officer asks for it (savings only) and a different officer approves it.
- Review date is set on every hold: 90 days by default. The register flags holds 15 days before it.
- Customer intimation deadline: 24 hours by default ("by the end of the next day"). It is tracked in the register until an officer records how the customer was told.
- Release always goes through maker-checker and records the reason and order:
- IO order;
- GRM decision (IO / DGRO / SGRO);
- MRM restoration;
- court order;
- LEA direction;
- 90-day review;
- wrong account.
2. Endpoints
Called by I4C (outside the Fineract login; see SecurityConfig)
| Method | Path | Spec section |
|---|---|---|
| POST | /fineract-provider/api/v1/i4c/auth/token |
2: returns {"access_token":"…","token_type":"Bearer","expires_in":900} or 401 {"message":"You are not authorized to access"}. Credentials may come as JSON username/password or client_id/client_secret, as a form body, or as an Authorization: Basic header. |
| POST | /fineract-provider/api/v1/i4c/complaints |
4 and 5: returns {"meta":{"response_code":"00","response_message":"Success"},"data":{"acknowledgement_no":"…","job_id":"BANKS-…"}}, or code 11 "Structure validation failed" (HTTP 400) |
I4C sends no tenant header. These paths are served by the tenant in fineract.i4c.tenant-identifier.
Other refusals:
- 503 with code
70004while the integration is disabled; - 403 from an IP not on the allowlist;
- 413 (
70005) above 1 MB; - 429 (
70006) above 600 calls/minute from one IP; - 400 (
60015) when an encrypted envelope cannot be decrypted.
How a push may authenticate (section 2 names "Basic Auth / Auth 2.0" and credentials "in every request"). fineract.i4c.inbound.auth-modes lists the allowed ones; every one checks the same credentials and the same IP allowlist:
| Mode | What I4C sends |
|---|---|
TOKEN |
Authorization: Bearer <access_token> from /auth/token |
BASIC |
Authorization: Basic base64(username:password) |
BODY |
username / password (or client_id / client_secret) inside the complaint JSON. They are removed from the message before it is stored. |
Each credential may be plain, plain Base64 (the specification's text), or CryptoJS-encrypted (its samples).
Refused pushes. With ack.code-style=SECTION5 the ack is always 11 "Structure validation failed". With SECTION7 it carries the specific section 7 code: 40001 invalid account number, 40004 invalid amount, 40005 invalid date (also a transaction_date more than ack.max-future-days ahead).
A repeat push with the same acknowledgement number and the same incidents is never processed twice. With ack.duplicate-mode=SAME_JOB it gets 00 and the original job_id. With CODE_50003 it gets HTTP 409 and 50003 "Duplicate Transaction", still with the original job_id.
Separate ack call. The ack is always the reply to the push. If I4C also wants it as a call of its own (section 5 is titled "Ack Request Message from BANKS to I4C-MHA"), set outbound.ack-path. The ack is then queued with the request and delivered before the response.
Officer API (ordinary login): /v1/i4c/admin/*
| Path | Permission |
|---|---|
GET dashboard, requests, requests/{id}, holds, holds/{id}, hold-actions, outbox, api-log, api-log/{id}, bank-master, configuration |
READ_I4C |
POST holds/{id}/actions (RELEASE with an optional amount for a partial release, UNFREEZE_AND_RELEASE, FREEZE, UNFREEZE) |
REQUESTACTION_I4CHOLD |
POST hold-actions/{id}/approve, .../reject |
APPROVEACTION_I4CHOLD (never your own request) |
POST holds/{id}/intimation (record by hand), POST holds/{id}/intimation/send (send now on the automatic channels) |
INTIMATE_I4CHOLD |
GET intimation-channels |
READ_I4C |
PUT intimation-channels/{channel}, POST intimation-channels/{channel}/test |
CONFIGURE_I4C |
POST outbox/{id}/retry, requests/{id}/reprocess |
RETRY_I4C |
Every list (requests, holds, hold-actions, outbox, api-log, bank-master) is paged: it takes offset and limit (default 20, at most 500) and returns {totalFilteredRecords, pageItems}. Each list also takes fromDate / toDate (yyyy-MM-dd, both days included; not for bank-master) and its own filters, which are listed in the Swagger summary of each endpoint.
GRM / MRM API (ordinary login): /v1/i4c/cases/*
| Path | Permission |
|---|---|
GET grievances, grievances/{id}, restorations, restorations/{id}, pro-rata, mrm-balance-report, mrm-balance-report.csv, holds/{id}/statement.csv, documents, documents/{id}/content |
READ_I4C |
POST holds/{id}/grievances, grievances/{id}/edd, …/submit, …/nodal, …/events, …/investigation, …/decision, …/escalate, …/withdraw |
MANAGE_I4CGRIEVANCE |
POST grievances/{id}/action (raise the account change an order needs) |
MANAGE_I4CGRIEVANCE + REQUESTACTION_I4CHOLD |
POST holds/{id}/restorations (assess), PUT restorations/{id}/request, POST restorations/{id}/bank-action, …/mrm-updated, victim-cases, restorations/{id}/receipt, …/victim-status |
MANAGE_I4CRESTORATION (bank action COMPLIED also needs REQUESTACTION_I4CHOLD) |
POST restorations/{id}/retry-outward |
APPROVEACTION_I4CHOLD |
POST documents |
MANAGE_I4CGRIEVANCE / MANAGE_I4CRESTORATION / REQUESTACTION_I4CHOLD by owner |
In the UI: CFCFRMS → I4C Live. Its tabs are Dashboard, Complaints from I4C, Holds Register, Approvals, GRM Grievances, MRM Restorations, MRM Balance Report, Responses & API Log, Bank Code Master, and Intimation Settings. A hold's GRM / MRM & Documents tab opens a grievance or an MRM assessment, downloads the account statement and holds the IO / court orders.
3. Configuration (application.properties, all values from the environment)
| Key / env var | Meaning |
|---|---|
fineract.i4c.enabled / FINERACT_I4C_ENABLED |
Master switch. Default false. |
fineract.i4c.tenant-identifier / FINERACT_I4C_TENANT |
Tenant that serves I4C's calls. |
fineract.i4c.bank-code / FINERACT_I4C_BANK_CODE |
This bank's code in the I4C Bank Code Master (root_bankid). |
fineract.i4c.bank-name |
Name reported for internal transfers. Defaults to the master's name for the code. |
…inbound.username / FINERACT_I4C_INBOUND_USERNAME |
Username the bank issues to I4C. |
…inbound.password-hash / FINERACT_I4C_INBOUND_PASSWORD_HASH |
bcrypt hash of that password (production). |
…inbound.password / FINERACT_I4C_INBOUND_PASSWORD |
Plain password. Used only when no hash is set (UAT). |
…inbound.token-ttl-seconds |
Token lifetime. Default 900. |
…inbound.allowed-ips / FINERACT_I4C_ALLOWED_IPS |
Comma-separated I4C source IPs. Blank allows any IP, which is for UAT only. |
…inbound.trust-forwarded-for |
Set true only behind a reverse proxy that sets X-Forwarded-For. |
…inbound.auth-modes / FINERACT_I4C_AUTH_MODES |
TOKEN,BASIC,BODY (default). List only the forms I4C uses. |
…inbound.client-name / FINERACT_I4C_CLIENT_NAME |
Client name registered with I4C. The client ID and secret are the inbound username and password. |
…crypto.mode / FINERACT_I4C_CRYPTO_MODE |
FIELDS (username/password encrypted, as in the spec), ENVELOPE (whole body as {"data":"…"}), or NONE. |
…crypto.passphrase / FINERACT_I4C_CRYPTO_PASSPHRASE |
The "encryption logic" passphrase I4C shares. |
…outbound.base-url / FINERACT_I4C_OUTBOUND_BASE_URL |
I4C's base URL (from I4C). internal-simulator routes to the local simulator. |
…outbound.auth-path, …outbound.response-path |
Paths under the base URL. Defaults /auth/token, /bank/response. Confirm with I4C. |
…outbound.ack-path / FINERACT_I4C_OUTBOUND_ACK_PATH |
Path for a separate ack call. Blank (default) = none. |
…outbound.username, …outbound.password |
Credentials I4C issues to the bank. |
…outbound.timeout-ms, …outbound.max-attempts |
Defaults 15000 ms and 8 attempts (backoff 30 s → 1 h). |
…match.date-window-days |
± days for amount/date matching. Default 2. |
…ack.code-style / FINERACT_I4C_ACK_CODE_STYLE |
SECTION5 (always 11) or SECTION7 (40001 / 40004 / 40005). Default SECTION5. |
…ack.duplicate-mode / FINERACT_I4C_ACK_DUPLICATE_MODE |
SAME_JOB (00 + original job_id) or CODE_50003. Default SAME_JOB. |
…ack.max-future-days |
A transaction_date further ahead than this is refused (40005). Default 1. |
…hold.review-days, …hold.intimation-hours |
Defaults 90 and 24. |
…restoration.pool-account-no / FINERACT_I4C_RESTORATION_POOL_ACCOUNT |
Bank-owned savings account (of a bank client) that outward MRM restorations leave from. Blank = only restorations to accounts in this bank. |
…restoration.fir-threshold |
MRM: above this amount in one complaint the IO must give an FIR. Default 50000. |
…simulator.enabled |
Local stand-in for I4C. Never true in production. |
To generate the bcrypt hash: htpasswd -bnBC 10 "" 'the-password' | tr -d ':\n' (or any bcrypt tool). Paste the result as FINERACT_I4C_INBOUND_PASSWORD_HASH.
Jobs (Scheduler Jobs screen)
- I4C Dispatch, every minute:
- processes complaints the immediate worker did not finish;
- sends responses waiting in the outbox;
- purges expired tokens.
- I4C Hold Review, every 15 minutes: tops up prospective holds, retries automatic intimation, and settles outward MRM restorations the fund-transfer module has finished.
- Both do nothing while the integration is disabled.
Database
- Migration
0610_cfcfrms_i4c_integration.xml:- tables
m_i4c_access_token,m_i4c_request,m_i4c_incident,m_i4c_finding,m_i4c_hold,m_i4c_hold_txn,m_i4c_hold_action_request,m_i4c_outbox,m_i4c_api_log,m_i4c_bank_master; - five permissions;
- two jobs.
- tables
- Migration
0611_i4c_bank_master_seed.xml:- the specification's Bank Code Master (491 entries);
- the IFSC prefixes of 57 banks whose prefix is certain.
- Migration
0612_i4c_intimation_channels.xml:m_i4c_intimation_channel(EMAIL switched on with a default subject and message; SMS and WHATSAPP switched off);m_i4c_intimation_log(every notice sent, failed or recorded, per hold);- column
m_i4c_hold.auto_intimation_attempts; - permission
CONFIGURE_I4C.
- Migration
0613_i4c_grm_mrm.xml:m_i4c_grievance,m_i4c_grievance_event(GRM),m_i4c_restoration(MRM, beneficiary and victim bank),m_i4c_document(files, with SHA-256);- columns
m_i4c_hold.released_amount,restored_amount;m_i4c_hold_action_request.amount,restoration_id,grievance_id; - permissions
MANAGE_I4CGRIEVANCE,MANAGE_I4CRESTORATION.
GRM: grievances against a hold
GRM and MRM are I4C web portals with no API. Officers act there; the CBS keeps the bank's record, the deadlines and the documents, and carries orders out on the account through maker-checker.
- The customer asks the branch to remove the hold / unfreeze. Open a grievance on the hold (Holds Register → hold → GRM / MRM).
- EDD: KYC re-verified, the customer's explanation of the credit, risk, and whether the bank supports the request.
- Raise it on GRM with the KYC, application, photograph and bank statement (attach the same here; the statement downloads from the hold), then record the GR id. Stage NODAL_REVIEW.
- The bank's GRM nodal officer approves (stage WITH_IO, 7 days) or rejects.
- The IO decides; if the IO investigates (notice, VC, Samanvaya) record it (+15 days). VC requests and information sought are noted in the history.
- Decision as GRM shows it: remove put on hold, unfreeze, hold continues, unfreeze and remove hold, keep a smaller amount (partial), rejected, or seek information. An allowing decision needs the order number and the signed order copy, and starts a 48-hour compliance clock.
- Raise the account change: the request goes to a second officer on Approvals; approval changes the account and closes the grievance.
- Rejected: escalate to the District GRO, then the State GRO (15 days each); after the State GRO the customer may go to court.
MRM: money restoration
Beneficiary bank (the money is held here):
- Assess each complaint (hold → GRM / MRM → Assess for MRM): possible by attribution, possible pro-rata (the calculator splits what is held on an account by disputed amount), or not possible (already refunded / no balance / other) with the reason. Enter the same on MRM; the MRM Balance Report page gives every held account's balances for MRM's Update Account Balance (CSV).
- When the victim's request comes from the IO, record the MR id, the refund account (IFSC blank = this bank), the IO, and the papers: a court order, or the IO's BNSS 106 notice with the victim's indemnity bond, plus the FIR above Rs 50,000. Attach their copies.
- Bank action: Compliance checks the papers and raises a RESTORE request; not complied and refer back to LEA need the bank statement; refer back to victim bank and consensus are recorded for MRM.
- A second officer approves the RESTORE on Approvals. In the same transaction the amount is released from hold and leaves the suspect account: straight to the victim's account if it is here (RESTORED at once, transaction id
CBS-<id>), otherwise to the restoration pool (IN_POOL) and on by NEFT / IMPS / RTGS through the fund-transfer module (its limits, time window, screening and approval apply). TRANSFER_PENDING becomes RESTORED when the transfer settles (Hold Review job). A failed or refused outward leaves the money in the pool for Send again, possibly to a corrected account; it never goes back to the suspect. - Enter amount, transaction id / UTR and time on MRM, then mark Entered on MRM to close.
Victim bank (our customer lost the money, layer 0): open a victim-bank case with the complaint's ack no., record restored money received (amount, UTR, date, account), or why none is expected (already refunded through bank / police notice / court order, declined, declined to pursue, received through court, not reachable).
Automatic customer intimation
- Where it is set: CFCFRMS → I4C Live → Intimation Settings. Each channel (Email, SMS, WhatsApp) has an on/off switch, an order, and an editable message. Placeholders such as
{customerName},{amountHeld},{ackNo}and{reviewDate}are filled per hold. Email has a "Send test email" box. - What happens: right after the response for a complaint goes to I4C, each new hold with money held is sent to the switched-on channels in order. The first one that reaches the customer marks the hold intimated (mode, "Sent automatically to …", user
system). - When it does not reach the customer (no email on file, mail server down): the attempt is logged as FAILED or SKIPPED_NO_DESTINATION, and the Hold Review job retries up to 3 times. After that, or when no channel is switched on, the hold stays "not yet told". An officer then calls the customer (or writes, or meets them) and records it on the hold's Customer Intimation tab.
- Today: only Email is in use. It goes through the CBS mail settings (
spring.mail.*), the same ones the KYC notices use. SMS and WhatsApp use the CBS notification gateways and should be switched on only once those gateways are live. - Phone, letter and in-person notices can never be sent by the system. They are always recorded by hand.
4. Onboarding checklist
- Nodal officer / SPOC registered with I4C. I4C emails them:
- user ids and passwords (both directions);
- the encryption logic / passphrase;
- its public IPs;
- UAT URLs.
- Give I4C what it needs from the bank:
- the endpoint base:
https://<bank-host>/fineract-provider/api/v1/i4c; - the bank's public IP;
- the client name, client id and client secret it asks for (the inbound username/password above).
- the endpoint base:
- Connectivity. The C-DOT AWS Client VPN SOP (IAM Identity Center SSO + MFA) is for people: developers and officers testing against UAT. A server cannot run it unattended. For the CBS server, ask C-DOT/I4C for IP whitelisting of the bank's egress IP, or a site-to-site tunnel. Open the firewall both ways:
- inbound from I4C's IPs to the CBS on 443;
- outbound from the CBS to I4C.
- Set the environment variables in §3, with
fineract.i4c.enabled=true, and restart. Check I4C Live → Dashboard → Setup still needed: it lists anything missing. - Grant permissions:
READ_I4Cto the fraud cell and branch managers;REQUESTACTION_I4CHOLDto makers;APPROVEACTION_I4CHOLDto checkers (different people);INTIMATE_I4CHOLDto branch staff;RETRY_I4Cto IT operations.
- Set the branch IFSCs in Branch Profile (
m_office_profile.ifsc_code). They are reported asifsc_code/root_ifsc_code. - Test in UAT with I4C (§5), then switch to production URLs and credentials.
5. Testing without I4C (local / UAT)
Set:
FINERACT_I4C_ENABLED=true
FINERACT_I4C_SIMULATOR_ENABLED=true
FINERACT_I4C_OUTBOUND_BASE_URL=internal-simulator
FINERACT_I4C_INBOUND_USERNAME=i4c-test
FINERACT_I4C_INBOUND_PASSWORD=i4c-test-pass
FINERACT_I4C_BANK_CODE=<your code>
Then, with a funded active savings account 000000012345:
H='https://localhost:8443/fineract-provider/api/v1'
# 1. Simulate a layer-1 push (fraud money credited to this account)
curl -k -X POST "$H/i4c-sim/push" -H 'Content-Type: application/json' \
-d '{"accountNumber":"000000012345","amount":"2500.00","disputedAmount":"2500.00","rrn":"612345678901","transactionDate":"2026-10-20","layer":"1"}'
# 2. Or go through the real inbound API exactly as I4C would
TOKEN=$(curl -sk -X POST "$H/i4c/auth/token" -H 'Content-Type: application/json' \
-d '{"username":"i4c-test","password":"i4c-test-pass"}' | sed 's/.*"access_token":"\([^"]*\)".*/\1/')
curl -k -X POST "$H/i4c/complaints" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d @complaint.json
# 3. See what the bank sent "I4C"
curl -k -X POST "$H/i4c-sim/received"
What to check:
- The ack is
00with ajob_id. - The account shows an Amount Hold transaction, and its available balance dropped by the held amount.
- A withdrawal above the remaining balance is refused.
- I4C Live → Complaints shows the complaint as PROCESSED, with the response SENT.
- Holds Register shows the hold. Raise a release as one user. Approving it as the same user is refused; approving it as a second user releases the amount on the account.
The backend unit tests are under fineract-provider/src/test/java/org/apache/fineract/portfolio/cfcfrms/i4c/:
./gradlew :fineract-provider:test --tests "org.apache.fineract.portfolio.cfcfrms.i4c.*"
6. Daily operations
-
Dashboard. Watch these figures:
- Customer intimation overdue;
- Holds due for 90-day review;
- Release / freeze awaiting approval;
- Responses failed.
The API performance table (calls, failures, average and max ms in each direction, average complaint-to-response time) is the RBI para 4 periodic review. Export it monthly for the Board / IT committee.
-
Holds Register:
- customer intimation: check the automatic notice in the hold's intimation history, press Send now to resend, or call the customer and record it;
- raise releases on IO / court orders (in full, or the amount the order releases); GRM and MRM orders are raised from their records;
- raise a full debit freeze only on an explicit direction.
-
GRM Grievances / MRM Restorations: filter Past deadline only every morning; carry out allowed orders within 48 hours; send pooled restorations again; mark restorations entered on MRM.
-
Approvals: a second officer approves or rejects. Approval acts on the account immediately. If the account refuses (closed, hold already released at the counter), the request becomes FAILED with the reason.
-
Responses & API Log:
- retry FAILED responses;
- open any call to see the masked request and response.
7. Security notes
- I4C's token is 32 random bytes. Only its SHA-256 hash is stored. It expires after
token-ttl-seconds. - Every inbound call checks the token and the source IP allowlist.
- Credentials, tokens and PANs are masked in the API log and in the stored payload.
- The inbound password should be supplied as a bcrypt hash. All secrets come from environment variables; none are committed defaults.
- Holds placed automatically are attributed to the CBS system user. Releases and freezes are attributed to the approving officer, with the maker recorded.
- The simulator endpoints answer 404 unless
fineract.i4c.simulator.enabled=true.
8. Known limits of this CBS (stated honestly)
- No RRN/UTR on account transactions.
- A reported credit is matched by RRN only where the CBS holds one: outward fund transfers (
m_fund_transfer.utr/txn_ref), or an RRN quoted in a transaction note or transfer description. - Otherwise it is matched by account, exact amount and date ± window. The match method is shown per incident.
- Inbound IMPS is a stub that posts no credit.
- Follow-up: store the UTR/RRN on inward postings.
- A reported credit is matched by RRN only where the CBS holds one: outward fund transfers (
- No UPI, ATM, POS or AEPS channels. The response formats for ATM (5), AEPS (6) and POS (11) are built and tested, but nothing produces them until such a channel exists.
- Branch cash withdrawals have no specification type. Above Rs 500 they are reported as type 14 with an empty cheque number and remarks "Cash withdrawal at branch counter (no cheque)". Confirm with I4C.
- Current accounts: the amount hold works, but the CBS's current-account debit block does not reach the account, so a full debit freeze is offered on savings accounts only.
- Current-account transfer legs are not linked transaction-to-transaction, so onward tracing from a current account is limited to counter withdrawals.
- Payee bank name: only IFSC prefixes in the seeded list map to an I4C bank code. Others are reported with code 0 and the IFSC in full.
- GRM and MRM are I4C portal modules with no published API. Officers act there and record it here; nothing is sent to the portals automatically.
- Outward restorations go only from a savings pool account (the fund-transfer module debits savings accounts only); the pool must be configured, and its client's transfer limits must allow the amounts.
- Current accounts cannot be debit-frozen (above); GRM unfreeze orders apply to savings accounts only.
9. Questions to settle with I4C / C-DOT
- Exact URL paths for the bank → I4C token, response and (if any) ack calls, and the token lifetime.
- Is the section 5 ack the synchronous HTTP response to the push, or also a separate call? Both are supported; set
outbound.ack-pathfor the second. - Encryption: only username/password (assumed,
FIELDS), or the whole payload? Is it the CryptoJS/OpenSSL passphrase format (AES-256-CBC, EVP_BytesToKey-MD5) as the samples suggest? - Which code set does the ack use,
00/11(section 5) or the section 7 codes (40001…)? Both are supported (ack.code-style). And does a repeat push get00or50003(ack.duplicate-mode)? Which auth form will I4C use: token, Basic, or credentials in the message (inbound.auth-modes)? - The specification's samples have typos (
mode_of _payment,acknowledment_no,approval_code.). Which spelling will I4C actually send? The parser accepts all of them. - The date format for
transaction_datetime(yyyy-MM-dd HH:mm:ssassumed). - How to report branch cash withdrawals and debits of unknown channel.
- For layer ≥ 1, is
payer_account_numberthe account at the receiving bank (assumed)? - Production IP whitelisting or site-to-site connectivity in place of the user VPN.