Construct the three-level message hierarchy: a single GrpHdr element containing MsgId (unique per file), CreDtTm, NbOfTxs (total transaction count), and CtrlSum (sum of all payment amounts); one or more PmtInf blocks grouping transactions by debtor account, payment method, and requested execution date; and one CdtTrfTxInf element per individual credit transfer
Populate the GrpHdr/InitgPty with your legal entity name and LEI if required by the receiving bank; populate each PmtInf/Dbtr with debtor name and PmtInf/DbtrAcct/Id/IBAN, and PmtInf/DbtrAgt/FinInstnId/BICFI with the debtor bank BIC
In each CdtTrfTxInf set: PmtId/EndToEndId (your unique payment reference, max 35 characters, passed through to the beneficiary), Amt/InstdAmt with Ccy attribute, CdtrAgt/FinInstnId/BICFI, Cdtr/Nm, CdtrAcct/Id/IBAN, and RmtInf structured or unstructured remittance data
Set PmtInf/ReqdExctnDt to the target execution date in YYYY-MM-DD format; for same-day execution confirm the bank's pain.001 submission cutoff time and ensure you submit before that threshold
Validate the file against the bank's specific Message Implementation Guide (MIG) — banks publish their own MIGs with mandatory vs. optional field rules that are stricter than the base ISO 20022 schema
Submit the file via the bank's accepted channel (SFTP, SWIFT FileAct, or REST API upload) and await a pain.002 payment status report; parse the pain.002 TxInfAndSts/TxSts codes (ACCP accepted, RJCT rejected, PDNG pending) and surface any RJCT reason codes from RjctRsn/Rsn/Cd
Known gotchas
EndToEndId in the PmtId block is limited to 35 characters and must be unique per transaction within a file and ideally globally — truncating UUIDs or reusing IDs across retries causes the bank to reject or misroute the payment
NbOfTxs in GrpHdr must equal the exact count of CdtTrfTxInf elements and CtrlSum must equal the precise sum of InstdAmt values; a single rounding error or off-by-one count causes the entire file to be rejected at the gateway before any individual payment is processed
Banks often accept only specific pain.001 version variants (e.g., pain.001.001.03 vs pain.001.001.09) and will silently reject files whose XML namespace declaration uses a version they have not onboarded — always confirm the target namespace URI with the bank before integration
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp