How to read a pain.002#

When your bank answers a pain.001 or pain.008, the pain.002 Customer Payment Status Report carries a status at up to three levels — group (GrpSts), payment information block (PmtInfSts), and individual transaction (TxSts) — plus zero or more status reason codes explaining any non-acceptance. The codes come from the ISO 20022 External Code Sets (ExternalStatusReason1Code), which is the canonical registry; this page covers the codes payment-operations teams actually meet, with the usual cause and the practical fix.

01. Status codes: how bad is it?#

Status Meaning What to do
RCVD Received — arrived, not yet checked Nothing yet.
ACTC Accepted, technical validation passed Nothing — syntax and schema are fine.
ACCP Accepted, customer profile checks passed Nothing.
ACSP Accepted, settlement in process Nothing.
ACSC Accepted, settlement completed Done — reconcile against camt.053.
ACWC Accepted with change — the bank altered something Read the changes; fix your source data so the bank stops "helping".
PART Partially accepted — some transactions rejected Check per-transaction TxSts; resubmit only the rejected ones.
PDNG Pending — further checks ongoing Wait; investigate only if it persists past the bank's stated window.
RJCT Rejected Read the reason codes below; repair; resubmit.

02. Format and schema failures#

The rejections Pain001 exists to make impossible — every one of these is caught by the validation gate before submission:

Code Name Typical cause Fix
FF01 Invalid file format Wrong schema version, malformed XML, wrong namespace Validate against the exact XSD your bank profiles (pain001 --dry-run).
AM10 Invalid control sum CtrlSum doesn't match the sum of amounts Never hand-compute totals — Pain001 recomputes NbOfTxs/CtrlSum from the records.
AM01 Zero amount An amount of 0 slipped through Filter zero rows at source.
AM02 Amount not allowed Above a scheme or account limit Check scheme ceilings and account mandates.
AM03 Currency not allowed Currency not supported on the account/scheme SEPA schemes are EUR-only; use the cross-border rulebook otherwise.
AM09 Wrong amount Amount disagrees with a referenced mandate/agreement Reconcile against the mandate.
DT01 Invalid date Execution date malformed, in the past, or a non-banking day ISO 8601, forward-dated, banking-day adjusted.
CH03 Execution date too far in future Beyond the bank's forward window (often 1 year) Shorten the horizon.
TM01 Cut-off time File arrived after the bank's processing cut-off Automate submission earlier; know each bank's cut-offs.
DU01DU03 Duplicate message / payment info / transaction ID Re-used MsgId, PmtInfId, or EndToEndId Generate unique IDs per submission; never resubmit a file unchanged.

03. Account and identifier failures#

Code Name Typical cause Fix
AC01 Incorrect account number IBAN fails validation or doesn't exist Mod-97 check before submission — the demo shows this live.
AC03 Invalid creditor account Creditor IBAN wrong or closed Verify against the invoice/master data.
AC04 Closed account Account has been closed Contact the counterparty for current details.
AC06 Blocked account Account blocked for this transaction type Counterparty must resolve with their bank.
RC01 Bank identifier incorrect Malformed or unknown BIC ISO 9362 structure check + directory lookup.
AG01 Transaction forbidden Payment type not allowed on this account Wrong account or missing product agreement.
AG02 Invalid bank operation code Wrong local instrument / service level combination Match your bank's implementation guide.

04. Party, mandate, and regulatory failures#

Code Name Typical cause Fix
BE01 Inconsistent with end customer Name doesn't match the account Fix creditor master data; this is what Verification of Payee checks pre-submission.
BE04 Missing creditor address Address absent where required From 14 Nov 2026, CBPR+ requires structured or hybrid addresses — see the roadmap.
BE05 Unrecognised initiating party Initiating party not authorised on the account Check the bank mandate for the submitting entity.
MD01 No mandate Direct debit without a valid mandate Collect/register the mandate before collecting funds.
MD02 Missing mandate information Mandate data incomplete in the pain.008 Populate all mandate-related fields.
MD07 End customer deceased Close the mandate.
RR01RR04 Regulatory reasons Missing debtor/creditor identification, name, address, or other regulatory data Populate the party data your corridor requires; structured addresses solve most of these.
AM04 Insufficient funds Not a format problem Treasury, not toolchain.
MS02 / MS03 Reason not specified (customer / bank generated) The bank chose not to say Call the bank; often accompanies sanctions or internal-policy holds.
NARR Narrative Free-text explanation in AddtlInf Read the narrative field.

05. Close the loop automatically#

Pain001 parses pain.002 responses into structured data, so your pipeline can route rejections without a human reading XML:

pip install pain001
from pain001.pain002 import parse_pain002

report = parse_pain002("bank-response.xml")
for tx in report.transactions:
    if tx.status == "RJCT":
        print(tx.end_to_end_id, tx.reason_code, tx.additional_info)

The MCP server exposes the same parser to AI agents as parse_pain002, and the payment-lifecycle guide shows where status handling sits in the full pipeline.

Canonical source. Code definitions live in the ISO 20022 External Code Sets, maintained at iso20022.org/catalogue-messages/additional-content-messages/external-code-sets and revised quarterly. Bank implementation guides may narrow — but not contradict — these meanings. Spot an inaccuracy? Report it.