pain.001 โ CustomerCreditTransferInitiation
Overviewโ
pain.001 (Payment Initiation) is an ISO 20022 message sent by an Originator (Customer) to their Debtor Bank to instruct a credit transfer. It is the entry point of any outbound payment flow.
- Full name:
CustomerCreditTransferInitiationV09(or later versions) - Namespace:
urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 - Direction: Customer โ Debtor Bank
- Channel: Host-to-host file, API, banking portal
Message Structureโ
pain.001
โโโ GrpHdr (Group Header) โ 1..1
โ โโโ MsgId Message ID (unique per file)
โ โโโ CreDtTm Creation DateTime
โ โโโ NbOfTxs Number of transactions
โ โโโ CtrlSum Total amount of all transactions
โ โโโ InitgPty Initiating Party
โ
โโโ PmtInf (Payment Information) โ 1..n (one per batch/debit account)
โโโ PmtInfId Payment Info ID
โโโ PmtMtd Payment Method (TRF = Credit Transfer)
โโโ ReqdExctnDt Requested Execution Date
โโโ Dbtr Debtor (name, address)
โโโ DbtrAcct Debtor Account (IBAN / account number)
โโโ DbtrAgt Debtor Agent (BIC of debtor bank)
โ
โโโ CdtTrfTxInf โ 1..n (one per transaction)
โโโ PmtId
โ โโโ InstrId Instruction ID
โ โโโ EndToEndId End-to-End ID (carried through whole chain)
โโโ Amt
โ โโโ InstdAmt Ccy="AUD" Instructed Amount + Currency
โโโ CdtrAgt Creditor Agent (BIC of creditor bank)
โโโ Cdtr Creditor (name)
โโโ CdtrAcct Creditor Account
โโโ RmtInf Remittance Information (payment reference)
Key Fields Explainedโ
| Field | Description | Notes |
|---|---|---|
MsgId | Unique ID for the whole file | Must be unique per sender per day |
EndToEndId | Tracks payment from initiation to completion | Echoed back in camt.054 |
InstrId | Instruction ID assigned by initiating party | Used for internal tracking |
InstdAmt | Amount to be transferred | Currency must be explicit |
ReqdExctnDt | Date the debtor bank should execute | Future-dating supported |
Dbtr / DbtrAcct | Payer's name and account | Must match bank records |
Cdtr / CdtrAcct | Payee's name and account | IBAN or BBAN |
RmtInf | Payment description / invoice reference | Structured or Unstructured |
Batchingโ
pain.001 supports multiple PmtInf blocks, each grouping transactions per:
- Debit account
- Payment method
- Execution date
- Service level (e.g., URGP for urgent, NORM for normal)
1 pain.001 file
โโโ PmtInf[1] โ Debit Account A, 3 transactions
โโโ PmtInf[2] โ Debit Account A, 5 transactions (different date)
โโโ PmtInf[3] โ Debit Account B, 2 transactions
Validation Rulesโ
NbOfTxsmust equal total count ofCdtTrfTxInfacross allPmtInfCtrlSummust equal sum of allInstdAmtEndToEndIdmust be unique within aPmtInfCreDtTmmust not be in the future- Debtor account must exist and be active
- Currency must be supported by the debtor bank
Relationship to Other Messagesโ
pain.001 โโ(initiates)โโโบ pacs.008 (bank-to-bank transfer)
pain.001 โโ(confirmed by)โโโบ pain.002 (payment status report)
pain.001 โโ(notified by)โโโบ camt.054 (account notification on debit)
Routing Outcome: On-Us vs Off-Usโ
After a pain.001 is accepted, the debtor bank routes each transaction:
- On-us: beneficiary account is internal, so bank posts debit/credit directly
- Off-us: beneficiary bank is external, so bank constructs and sends
pacs.008through selected rail
Even in on-us cases, core controls still apply (sanctions, fraud, limits, and idempotency). Off-us adds clearing/settlement dependencies and richer exception handling.
pain.001 vs pain.008โ
| pain.001 | pain.008 | |
|---|---|---|
| Type | Credit Transfer Initiation | Direct Debit Initiation |
| Initiator | Payer (Debtor) | Payee (Creditor) |
| Flow | Push payment | Pull payment |
Java / Spring Integration Notesโ
// Typical pain.001 processing pipeline in Spring
@Service
public class Pain001ProcessingService {
// 1. Unmarshal incoming XML
// 2. Validate schema (XSD)
// 3. Validate business rules (CtrlSum, NbOfTxs)
// 4. Enrich with internal account details
// 5. Run sanctions & fraud checks
// 6. Persist to payment table
// 7. Route to pacs.008 builder or on-us handler
public void process(CustomerCreditTransferInitiationV09 pain001) {
validateGroupHeader(pain001.getGrpHdr());
pain001.getPmtInf().forEach(pmtInf -> {
pmtInf.getCdtTrfTxInf().forEach(tx -> {
PaymentOrder order = mapper.toPaymentOrder(pmtInf, tx);
sanctionService.screen(order);
fraudService.evaluate(order);
paymentRepository.save(order);
routingService.route(order);
});
});
}
}
Common Error Codes (pain.002 response)โ
| Code | Reason |
|---|---|
AC01 | Incorrect Account Number |
AC04 | Closed Account Number |
AC06 | Blocked Account |
AM04 | Insufficient Funds |
FF01 | Invalid File Format |
NARR | Free-text narrative reason |