# ISO-20022 Mapping Handbook This document provides detailed guidance on ISO-20022 message processing and mapping to canonical formats. ## Message Type Overview | Message Type | Direction | Purpose | Trigger Action | |-------------|-----------|---------|----------------| | `pain.001` | Outbound | Customer Credit Transfer Initiation | `validateAndLock()` → `markSubmitted()` | | `pacs.008` | Outbound | FIToFICustomerCreditTransfer | `validateAndLock()` → `markSubmitted()` | | `pacs.009` | Outbound | FinancialInstitutionCreditTransfer | `validateAndLock()` → `markSubmitted()` | | `camt.054` | Inbound | BankToCustomerDebitCreditNotification | `confirmSettled()` (mint tokens) | | `pacs.002` | Inbound | Payment Status Report | `confirmSettled()` or `confirmRejected()` | | `pacs.004` | Return | Payment Return | `confirmRejected()` (release escrow) | | `camt.056` | Cancellation | FIToFIPaymentCancellationRequest | `confirmCancelled()` (release escrow) | ## Field Mapping ### pain.001 Mapping ```yaml instructionId: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/PmtId/InstrId endToEndId: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/PmtId/EndToEndId amount: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/InstdAmt currency: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/InstdAmt/@Ccy debtorAccount: Document/CstmrCdtTrfInitn/PmtInf/DbtrAcct/Id/Othr/Id creditorAccount: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/Othr/Id ``` ### pacs.008 Mapping ```yaml instructionId: Document/FIToFICstmrCdtTrf/GrpHdr/MsgId endToEndId: Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId/EndToEndId amount: Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt currency: Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/@Ccy ``` ### pacs.002 Status Mapping | Status Code | Meaning | Action | |------------|---------|--------| | `ACSC` | AcceptedSettlementCompleted | `confirmSettled()` | | `RJCT` | Rejected | `confirmRejected()` | | `PNDG` | Pending | Wait for final status | | `CANC` | Cancelled | `confirmCancelled()` | ## Processing Flow ### Outbound Flow 1. Client submits `pain.001` or `pacs.008` via `/v1/iso/outbound` 2. ISO Router normalizes message to canonical format 3. Orchestrator creates trigger in `CREATED` state 4. Orchestrator validates and locks funds (`VALIDATED` state) 5. Adapter submits to rail (`SUBMITTED_TO_RAIL` state) 6. Trigger moves to `PENDING` state 7. Rail adapter receives `pacs.002` or `camt.054` 8. Orchestrator confirms settled/rejected (`SETTLED`/`REJECTED` state) ### Inbound Flow 1. Rail adapter receives `camt.054` or `pacs.002` 2. Adapter submits via `/v1/iso/inbound` (mTLS) 3. ISO Router normalizes message 4. Orchestrator creates trigger 5. For `camt.054` with credit: mint tokens and `confirmSettled()` 6. For `pacs.002` with `RJCT`: `confirmRejected()` ## Idempotency All ISO-20022 message submissions are idempotent by `instructionId`. Duplicate submissions with the same `instructionId` are rejected. ## Payload Storage - Full ISO-20022 XML payloads stored off-chain - Only `payloadHash` stored on-chain in trigger - Payloads can be retrieved via API for reconciliation ## Reconciliation Use `instructionId` and `endToEndId` for end-to-end reconciliation: ```bash GET /v1/triggers?instructionId=0x1234... GET /v1/triggers?endToEndId=0xabcd... ``` ## Error Handling Invalid ISO-20022 messages trigger `confirmRejected()` with appropriate reason codes: - Schema validation errors → `CONFIG_ERROR` - Missing required fields → `CONFIG_ERROR` - Invalid amounts → `CONFIG_ERROR`