Payments Training Hub

ISO 20022 Message and Mapping Lab

14 practical exercises. Each one gives you a real message problem, a valid XML sample and an invalid XML sample, and explains exactly why the invalid one fails. Work through the task, check your answer against the expected answer, and use the field table to see which elements are schema mandatory, optional or conditional. The XML samples and the answers start hidden so you work the problem first.

0 of 14 exercises marked done.

EX-01: Business Application Header versus Document

Concept. The Business Application Header, head.001, is the envelope around an ISO 20022 business message. It carries routing and identification data only: sender, receiver, message name, message definition identifier, business service, creation time, business message identifier, and a copy duplicate flag. The Document carries the business content, such as the pacs.008 payment instruction with debtor, creditor, amount, and settlement data. A receiving system reads the header first to decide where to route the message and which schema version to validate against, without opening the payment data. Keeping routing in the header and business data in the Document lets routing, logging, and duplicate checks work the same way for every message type. The six fields shown in the valid example are the minimum routing subset, not the whole header: head.001.001.02 has 15 elements, and under CBPR+ the business service element BizSvc is mandatory and must carry swift.cbprplus.03. Other optional elements exist in the full header, such as MktPrctc (market practice) and Rltd (related business message), and are used only where the relevant usage guideline requires them.

Task. Study the valid head.001 AppHdr below and list every element it contains. Then inspect the invalid version and identify each business element that was wrongly placed inside the header. Write down, for each element, whether it belongs in the AppHdr or in the Document, and explain why a router that only reads the header must never need the amount or the creditor name.

FieldMeaningCardinalityMandatory
FrSender of the business message, as a financial institution identifier1..1schema mandatory
ToReceiver of the business message, as a financial institution identifier1..1schema mandatory
BizMsgIdrUnique identifier for the whole business message1..1schema mandatory
MsgDefIdrMessage definition identifier, for example pacs.008.001.081..1schema mandatory
CreDtCreation date and time of the business message, with UTC offset1..1schema mandatory
CpyDplctFlag showing whether this message is a resend of an earlier copy0..1optional
BizSvcBusiness service, mandatory under CBPR+ with value swift.cbprplus.03; identifies the service the message belongs to0..1mandatory under CBPR+

EX-02: InstrId, EndToEndId, TxId and UETR

Concept. Four identifiers travel with a payment, and each has a different owner and a different job. InstrId is assigned by the instructing party and identifies one instruction inside one message. EndToEndId is chosen by the debtor, usually an invoice reference such as INV-2026-1147, and travels unchanged from debtor to creditor so the creditor can match the receipt. TxId is assigned by the instructing agent to identify the transaction in its own systems. UETR is a globally unique reference generated once for a cross border payment and carried unchanged across every bank in the chain for tracking. Reusing InstrId creates a duplicate, changing EndToEndId breaks creditor matching, and dropping UETR breaks end to end tracking.

Task. Trace all four identifiers in the valid pacs.008 below from debtor to creditor. Then examine the invalid version, where the same InstrId and the same UETR appear on two different transactions. Explain which system would flag each duplicate, what status it would return, and how you would assign fresh values that keep EndToEndId unchanged for the creditor.

FieldMeaningCardinalityMandatory
InstrIdInstruction identifier assigned by the instructing party for one instruction0..1business mandatory
EndToEndIdDebtor reference that travels unchanged to the creditor for matching0..1business mandatory
TxIdTransaction identifier assigned by the instructing agent for its own records0..1optional
UETRGlobally unique end to end transaction reference for cross border tracking0..1business mandatory
MsgIdUnique identifier for the whole message in the group header1..1schema mandatory

EX-03: Group Header versus transaction level data

Concept. GrpHdr describes the message as a whole, while CdtTrfTxInf describes one payment inside it. The group header carries MsgId, creation time, number of transactions, control sum, and settlement information that applies to the group. Each transaction carries its own payment identification, amount, debtor, creditor, agents, charge bearer, purpose, and remittance information. In a pain.001 salary file with five thousand payments totalling EUR 8,400,000, the header states the count and the total, and the receiver checks those totals before processing any single payment. If the count or the sum does not match the transactions that follow, the whole message is rejected because a payment may have been lost or duplicated.

Task. Read the single transaction amount in the invalid pacs.008 below and compare it with its GrpHdr CtrlSum and its NbOfTxs. Write down the correct CtrlSum value, state which level each field belongs to, and explain why the receiver must check the header totals before it credits any single transaction in the group.

FieldMeaningCardinalityMandatory
GrpHdr.MsgIdUnique identifier for the whole message group1..1schema mandatory
GrpHdr.NbOfTxsCount of transactions carried in the message group0..1business mandatory
GrpHdr.CtrlSumSum of all transaction amounts in the group0..1business mandatory
CdtTrfTxInf.IntrBkSttlmAmtSettlement amount for one single transaction1..1schema mandatory
CdtTrfTxInf.PmtIdPayment identification for one single transaction1..1schema mandatory
GrpHdr.CreDtTmCreation date and time for the whole message group1..1schema mandatory

EX-04: Static and dynamic agent roles

Concept. DbtrAgt and CdtrAgt identify the banks that hold the debtor and creditor accounts, but how those roles are fixed depends on the rail and the payment model. On a domestic rail with a fixed clearing member, the debtor agent may be static for every payment from one customer, because the same bank always sends it. On a cross border correspondent payment, the creditor agent is assigned per payment from the creditor IBAN or BIC, and an intermediary agent may be added when no direct account relationship exists. Swapping the two agents reverses the flow and sends money to the wrong bank.

Task. In the valid pacs.008 below, name the debtor agent and the creditor agent and state which account each one holds. Then inspect the invalid version, where the two BICs are swapped, and explain what would happen at settlement, which bank would debit the wrong account, and how a cover payment would need an extra intermediary agent instead of a simple swap.

FieldMeaningCardinalityMandatory
DbtrAgtBank holding the debtor account and sending the payment onward1..1schema mandatory
CdtrAgtBank holding the creditor account and receiving the payment1..1schema mandatory
IntrmyAgt1Intermediary bank used when sender and receiver have no direct account link0..1conditional
DbtrAcctAccount of the debtor from which funds are debited0..1optional
CdtrAcctAccount of the creditor to which funds are credited0..1optional
SttlmInf.SttlmMtdSettlement method that decides which agent account moves the funds1..1schema mandatory

EX-05: INGA, INDA, COVE and CLRG settlement methods

Concept. SttlmMtd states how interbank settlement moves, and each value implies a different account movement. INGA means settlement through the instructing agent, so the instructing agent debits its own account with the next bank. INDA means settlement through the instructed agent, so the instructed agent debits the account it holds for the instructing agent. CLRG means settlement through a clearing system, so funds move through the clearing house account on the settlement date. COVE means the payment is a cover, so the funds travel on a separate pacs.009 while the customer instruction travels on pacs.008. Choosing the wrong method tells the wrong bank to move money, and settlement then fails or posts to the wrong nostro account.

Task. Compare the four settlement methods in the concept and decide which one fits a direct payment from NatWest to Deutsche Bank, which one fits a payment through a clearing system, and which one fits a cover payment. Then inspect the invalid pacs.008, find the settlement method that cannot work with its stated accounts, and rewrite the SttlmInf block with the correct method and account.

FieldMeaningCardinalityMandatory
SttlmMtdCode stating how interbank settlement will occur1..1schema mandatory
SttlmAcctAccount to be used for settlement when the method requires one0..1conditional
ClrSysClearing system used when the settlement method is CLRG0..1conditional
IntrBkSttlmAmtAmount settled between banks under the chosen method1..1schema mandatory
IntrBkSttlmDtDate on which the interbank settlement takes place0..1optional

EX-06: Schema validation versus business validation

Concept. Schema validation and business validation check different things, and passing one does not guarantee passing the other. Schema validation checks the message against its XSD: element order, data types, lengths, and allowed code values. A message with a correctly typed decimal amount and a valid code passes this check even when the business facts are wrong. Business validation then checks the values themselves: currency precision, IBAN check digits, working day dates, account existence, limits, sanctions screening, and duplicate checks. A payment of EUR 8,750.005 has a valid decimal type for the schema, but it fails business validation because EUR allows only two decimal places. Both layers must pass before a payment is released.

Task. Validate the valid pacs.008 below against its schema rules in your head: check element order, the decimal amount, and the SHAR code. Then do the same for the invalid version, which uses EUR 8,750.005, and decide which layer passes and which layer fails. Write down the exact business rule that fails and the corrected amount that would pass both layers.

FieldMeaningCardinalityMandatory
IntrBkSttlmAmtSettlement amount as a decimal with a currency attribute1..1schema mandatory
ChrgBrCharge bearer code, checked against the external code set0..1optional
IntrBkSttlmDtSettlement date, checked against the currency business calendar0..1optional
CdtrAcct.IBANCreditor IBAN, checked for format and check digits in business validation0..1optional
Purp.CdPurpose code, checked against the published purpose code set0..1optional

EX-07: Mandatory versus optional versus conditional fields

Concept. The same element can be mandatory, optional, or conditional depending on the rail and the scenario, so a field list without context is misleading. A mandatory field must always be present, such as MsgId and IntrBkSttlmAmt. An optional field may be present or absent, such as UltmtCdtr when creditor and ultimate creditor are the same party. A conditional field is required only when its condition is true, such as ClrSys when SttlmMtd is CLRG, under the CBPR+ Usage Guidelines for pacs.008. Conditional mandatoriness only has meaning against a named usage guideline, so always cite the guide and the exact condition. Under CBPR+, IntrBkSttlmDt is mandatory, not conditional. Professionals must read the rail guide, not just the global schema, because a pacs.008 through a clearing system without ClrSys is incomplete.

Task. List the fields in the valid pacs.008 below and mark each one as mandatory, optional, or conditional for a direct correspondent payment. Then inspect the invalid version, where SttlmMtd is CLRG but ClrSys is missing, and explain why that omission is a conditional failure, which guide states the condition, and what value you would add to fix it.

FieldMeaningCardinalityMandatory
GrpHdr.MsgIdMessage identifier, always required in every message1..1schema mandatory
ClrSysClearing system identification, required only when SttlmMtd is CLRG, per the CBPR+ Usage Guidelines for pacs.0080..1conditional under CBPR+ UG
UltmtCdtrUltimate creditor, needed only when different from the creditor0..1conditional
RmtInfRemittance information explaining the payment to the creditor0..1optional
PurpCoded purpose of the payment for reporting and screening0..1optional
IntrBkSttlmDtInterbank settlement date, mandatory under CBPR+1..1mandatory under CBPR+

EX-08: External code sets

Concept. ISO 20022 uses external code sets, which are published lists of allowed values maintained outside the XML schema, so banks cannot invent their own codes. The charge bearer set allows only DEBT, CRED, SHAR, and SLEV. The purpose set includes SUPP for supplier payment, SALA for salary, and GDDS for goods, among others. The return reason set includes AC01 for a wrong account number, AC04 for a closed account, and MS03 for no reason specified. A value outside the set is rejected, and a value inside the set but wrong for the payment misleads the receiver. Teams must check codes against the current published list, because sets change and an old code can be retired without warning.

Task. Check the Purp code and the ChrgBr code in the valid pacs.008 below against the published sets described in the concept. Then inspect the invalid version, find the code that is not in any published set, name the set it claims to belong to, and replace it with the correct published code for a supplier payment with shared charges.

FieldMeaningCardinalityMandatory
Purp.CdPurpose code from the published external purpose code set0..1optional
ChrgBrCharge bearer code from the set DEBT, CRED, SHAR, SLEV0..1optional
SttlmInf.SttlmMtdSettlement method code from the published settlement method set1..1schema mandatory
RtrRsnInf.Rsn.CdReturn reason code from the published return reason set0..1conditional
TxStsTransaction status code from the published status code set1..1schema mandatory

EX-09: Currency precision

Concept. Amounts in ISO 20022 are decimal values with a currency code, never floating point numbers, because floating point arithmetic can introduce tiny errors that leave ledgers out of balance. Each currency has a fixed number of minor units: EUR, GBP, and USD use two decimals, JPY uses zero decimals, and BHD, KWD, and OMR use three decimals. A payment of JPY 125,000 is valid, while JPY 125,000.50 is not, and BHD 1,250.500 is valid while BHD 1,250.50 is incomplete. The canonical model stores the amount as a decimal with its currency attached and validates the decimal count against the currency table before release, so rounding rules are the same in every system that touches the payment.

Task. State the minor unit count for EUR, JPY, and BHD from the concept. Then inspect the invalid pacs.008, where a JPY amount was written with a comma and two decimals, and explain why that format fails, what the correct JPY amount should look like, and why a decimal type must never be replaced by a floating point number in code.

FieldMeaningCardinalityMandatory
IntrBkSttlmAmtSettlement amount as a decimal value with a currency attribute1..1schema mandatory
IntrBkSttlmAmt.CcyThree letter currency code that fixes the allowed decimal places1..1schema mandatory
InstdAmtInstructed amount from the customer, with currency and precision rules1..1schema mandatory
ChrgsInf.AmtCharge amount, validated against the same currency precision table0..1optional
CtrlSumGroup control sum, summed in the same currency and precision0..1business mandatory

EX-10: UTC offsets

Concept. Every ISO 20022 timestamp carries a UTC offset, such as 2026-11-05T09:42:00+00:00 for London in winter or 2026-11-05T15:12:00+05:30 for Kolkata, so the receiving system knows the exact instant the event happened. Without an offset, the same clock reading could mean morning in London, afternoon in Mumbai, or evening in Singapore, and cutoff checks, value dating, and audit trails would all be ambiguous. A missing offset can push a payment past a cutoff, a wrong offset can record a release an hour early or late, and an audit trail without offsets cannot prove the order of events. Timestamps must therefore be stored with their offset, converted to UTC for comparison, and displayed in local time only for human reading.

Task. Read the CreDtTm in the valid pacs.008 below and convert it to UTC and to Kolkata time. Then inspect the invalid version, where the timestamp uses a space instead of the letter T and carries no offset, and explain which cutoff and audit checks would fail, and how you would rewrite the timestamp correctly for a 09:42 London event in November.

FieldMeaningCardinalityMandatory
GrpHdr.CreDtTmCreation date and time of the message, with UTC offset1..1schema mandatory
IntrBkSttlmDtSettlement date, interpreted with the settlement centre calendar0..1optional
AccptncDtTmAcceptance date and time reported in a status message, with offset0..1optional
ReqdExctnDtRequested execution date from the customer instruction1..1schema mandatory
CreDtTmCreation timestamp in the business header, with UTC offset1..1schema mandatory

EX-11: Version compatibility

Concept. A message name such as pacs.008.001.08 carries its version in the last segment, and the version decides which fields exist and which rules apply. The current version for cross border payments under CBPR+ and for SEPA is pacs.008.001.08, after coexistence with MT messages ended on 22 November 2025. An older version such as pacs.008.001.02 has a different structure, fewer fields, and different usage rules, so a counterparty that has moved to version 08 cannot process it as if it were version 08. Sending the wrong version is not a typing error: it is a compatibility failure, and the receiving system must reject it even when every business field looks correct, because it cannot trust the missing fields.

Task. Compare the namespace in the valid pacs.008.001.08 below with the namespace in the invalid pacs.008.001.02 below. List three things that can differ between versions, explain why the receiver cannot simply treat the older message as version 08, and write the migration steps a bank should follow before it switches a counterparty to the new version.

FieldMeaningCardinalityMandatory
MsgDefIdrMessage definition identifier stating family, number, and version1..1schema mandatory
Document namespaceXML namespace that fixes which schema version validates the message1..1schema mandatory
PmtId.UETRTracking reference present in current versions and absent in some older ones0..1business mandatory
GrpHdr.MsgIdMessage identifier, whose uniqueness rules can change by version1..1schema mandatory
SttlmInfSettlement information, whose allowed values can change by version1..1schema mandatory

EX-12: Data truncation and lossy mapping

Concept. Mapping MT103 field 70 to pacs.008 remittance information is lossy, because the two formats hold different amounts of text in different shapes. MT103 field 70 allows four lines of 35 characters, a total of 140 characters of free text, often mixing an invoice number, a description, and a month in one block. Pacs.008 unstructured remittance information also allows 140 characters, while structured remittance information splits the data into coded references, invoice numbers, and dates that a creditor system can match automatically. If copying the free text and cutting it at the limit loses the invoice number at the end, the creditor cannot reconcile the receipt. The safe mapping extracts the invoice reference first and records what was shortened.

Task. Read the MT103 field 70 text in the concept, which is INV-2024-0988 payment for consulting services October 2024, from a pre-migration MT103, and map it to pacs.008 remittance information. Then inspect the invalid version, where the unstructured text exceeds 140 characters, and explain what would be lost by truncation, how structured remittance information would preserve the invoice number, and what to log when text must be shortened.

FieldMeaningCardinalityMandatory
RmtInf.UstrdUnstructured remittance text, limited to 140 characters0..1optional
RmtInf.StrdStructured remittance data with coded invoice references0..noptional
EndToEndIdDebtor reference copied from the invoice number for creditor matching0..1business mandatory
MT103 field 70Source remittance text, four lines of 35 characters in MT format0..1optional
PurpPurpose code that survives mapping even when free text is shortened0..1optional

EX-13: Partial batch rejection

Concept. A pain.001 batch can be partially accepted: some transactions pass validation and settle, while one fails and is rejected, and the status report must show that split exactly. The bank sends pain.002 to the customer, or pacs.002 between banks, with a group status of PART for partially accepted, then one TxInfAndSts block per transaction with its own status and reason code. A failed transaction with reason AC01 for a wrong account number does not stop the other transactions, and the customer resends only the failed item with a fresh instruction identifier. Treating the whole batch as rejected would delay good payments, while treating it as fully accepted would hide the failure and leave a supplier unpaid without explanation.

Task. Study the valid pacs.002 below, which reports a group of three transactions as PART, with two accepted and one rejected for AC01. Then inspect the invalid version, which reports the whole group as RJCT with no per transaction detail, and explain which transactions would wrongly be held, what the customer would resend in error, and how to rewrite the report correctly.

FieldMeaningCardinalityMandatory
OrgnlGrpInfAndSts.GrpStsGroup status, ACCP, RJCT, or PART for a partial batch0..1business mandatory
TxInfAndSts.TxStsStatus of one single transaction, such as ACCP or RJCT1..1schema mandatory
TxInfAndSts.OrgnlInstrIdOriginal instruction identifier linking the status to one payment1..1schema mandatory
StsRsnInf.Rsn.CdReason code for a rejection, such as AC01 for a wrong account0..1conditional
OrgnlEndToEndIdOriginal end to end reference copied into the status report0..1optional

EX-14: pain.001 to canonical model to pacs.008 transformation

Concept. A customer payment travels in three shapes: pain.001 from the customer to the bank, a canonical payment record inside the bank, and pacs.008 from the bank to the next bank. Emma Wilson sends pain.001 to pay Schneider GmbH EUR 8,750.00 for invoice INV-2026-1147, with execution date 6 November 2026, charge bearer SHAR, and debtor account GB29 NWBK 6016 1331 9268 19. This payment is sent via CBPR+ correspondent banking, not SEPA, and SHAR is the charge bearer for this CBPR+ payment. The same payment sent as a SEPA credit transfer would use SLEV instead, because SEPA permits only SLEV; the charge bearer depends on the rail, so always state which rail the example uses before judging whether a charge bearer is correct. The bank builds one canonical record, PAY-2026-1105-004821, with debtor, creditor, accounts, amount, currency, purpose SUPP, and end to end reference, then validates, enriches, and screens it. The canonical record then produces pacs.008 with the same instruction identifier, end to end reference, amount, parties, and purpose, so every value in the final message traces back to the original instruction.

Task. Using the Emma Wilson example in the concept, study the reference canonical record and the complete mapping table provided with this exercise. For each row, check the pain.001 field, its canonical record field, and its pacs.008 field, and note the transformation rule, the validation outcome, and the data loss or truncation risk. Pay attention to the lossy rows: the postal address is restructured into named elements, unstructured remittance text may be simplified, and the canonical record holds internal-only fields (canonical payment identifier, internal status, screening result) that never appear in pacs.008, while the pacs.008 group header fields are created by the sending bank and do not come from pain.001. Then inspect the invalid pacs.008, where the end to end reference was replaced and the charge bearer was changed, and explain which creditor matching and fee outcome would break, and how to restore the correct mapping.

FieldMeaningCardinalityMandatory
pain.001 Dbtr Nm to pacs.008 Dbtr NmDebtor name from customer instruction to interbank message, unchanged1..1schema mandatory
pain.001 CdtrAcct IBAN to pacs.008 CdtrAcct IBANCreditor IBAN from customer instruction to interbank message, unchanged1..1schema mandatory
pain.001 InstdAmt to pacs.008 IntrBkSttlmAmtInstructed amount mapped to interbank settlement amount, same currency1..1schema mandatory
pain.001 EndToEndId to pacs.008 EndToEndIdEnd to end reference carried unchanged for creditor matching0..1business mandatory
pain.001 ChrgBr to pacs.008 ChrgBrCharge bearer mapped from customer code to interbank code, same outcome0..1optional
Canonical payment identifierInternal canonical identifier linking all three layers for audit1..1business mandatory