Skip to main content
Back to Insights
Payments11 min read

SEPA R-Transactions: A Technical Reference

Reject, Return, Refund, Reversal. Four distinct lifecycle events, each with different ledger impact, PSD2 timelines, and ISO reason codes.

Understanding SEPA R-Transactions: A Technical Guide for Payment Engineers


"The payment was returned." In SEPA, this sentence can mean four different things. Each has a different trigger, a different PSD2 timeline, a different settlement lifecycle, and a different treatment in the ledger. Most implementations treat them as a single "reversal" event with a reason code attached. This leads to incorrect holding period management, missed PSD2 deadlines, and reconciliation discrepancies that surface weeks after the fact.

SEPA R-transactions are not one concept. They are four.

Four Types, Not One

TypeTriggerWhenLegal BasisLedger Impact
RejectBank rejects before interbank settlementD+1 (before settlement)EPC rulebookNone, no money moved. Bank operations only.
ReturnBank returns after settlement, within holding periodD+5 (Core), D+2 (B2B)PSD2 Art. 71Reverse the settled amount. Mark RETURNED.
RefundPayer disputes after holding period expiresUp to 8 weeks (Core), no right (B2B)PSD2 Art. 76New debit against creditor. Not a reversal, a fresh claim.
ReversalOriginator requests cancellation after settlementNo fixed deadlinecamt.056Correction entry (Stornobuchung per HGB §239).

The distinction is not academic. It determines what the system must do with the money, when it must do it, and what the ledger entry looks like.

A Reject is silent from the creditor's perspective. The payment never settled. The debtor's bank rejected it pre-settlement (wrong IBAN, closed account, blocked account). The creditor's system may not even need to know, unless it was tracking the expected incoming payment.

A Return is a reversal within the holding period. The money was settled (credited to the creditor's account in the clearing system), but during the holding period the debtor's bank sends a return. The creditor's ledger must reverse the credit. The funds transition from SETTLED_PENDING back to the debtor.

A Refund happens after the holding period has expired and the funds are SETTLED_AVAILABLE. The creditor has the money. The debtor disputes, within 8 weeks for SEPA Core Direct Debit (PSD2 Art. 76), with no dispute right for B2B. A refund is not a reversal of the original entry. It is a new, separate debit against the creditor. The original entry remains in the ledger, unchanged and immutable.

A Reversal is initiated by the originator (not the debtor's bank) via a camt.056 cancellation request. This typically happens when the originator discovers a duplicate or an error after settlement. In German accounting, this is a Stornobuchung, a correction entry that references the original via a correction_of foreign key. The original entry stays. The correction entry carries the same amount with opposite sign.

Holding Periods and Settlement Lifecycle

Between settlement and availability, funds pass through a holding period. The duration depends on the scheme:

SchemeHolding PeriodCalendar
SEPA Direct Debit Core5 TARGET2 business daysECB TARGET2 calendar
SEPA Direct Debit B2B2 TARGET2 business daysECB TARGET2 calendar

"Business days" is not "calendar days." TARGET2 has its own holiday calendar: weekends, New Year's, Good Friday, Easter Monday, May 1, Christmas Day, December 26. German national holidays that are not TARGET2 holidays do not count. Spanish national holidays that are not TARGET2 holidays do not count. The business day calculation must use the TARGET2 calendar, not a national calendar.

During the holding period, funds are in a SETTLED_PENDING state. The creditor's balance shows the credit, but the funds are not available for withdrawal or further transfer. After the holding period expires, funds transition to SETTLED_AVAILABLE. Returns are no longer possible (but Refunds still are, for Core DD).

Payment Received

Incoming SEPA Direct Debit credited to creditor account.

Holding period begins (5 TARGET2 days Core, 2 days B2B)
SETTLED_PENDING

Funds visible but not available for withdrawal. Returns are possible during this window.

Return received within holding period?
RETURNED

Credit reversed. Funds transition back to debtor. Settlement voided.

Holding period expires without return
SETTLED_AVAILABLE

Funds released and available. Returns no longer possible.

Refund claim within 8 weeks (Core DD only, PSD2 Art. 76)?
REFUNDED

New debit against creditor. Not a reversal, a separate claim. Original entry unchanged.

No further R-transactions
FINAL

Settlement complete. No further R-transactions possible.

ISO Reason Codes Drive the Logic

pacs.004 (Payment Return) carries a ReasonCode field from the ExternalStatusReason1Code enumeration. This is not free text. It is a closed set defined by ISO 20022 and constrained by EPC rulebooks.

The reason code determines the R-transaction type. The type determines the settlement action. The action determines the PSD2 timeline. The chain is deterministic.

Reason CodeMeaningClassification Logic
AC01Incorrect account numberPre-settlement → Reject; post-settlement → Return
AC04Closed account numberReturn
AC06Blocked accountReturn
AM05Duplicate paymentReturn
MD01No mandate (debtor denies)Return
MS02Refusal by debtor (no reason)Within holding period → Return; after → Refund
MS03Reason not specifiedReturn
SL01Specific service offered by debtor agentReturn
DUPLDuplicate sendingRefund (originator-initiated)
CUSTRequested by originatorReversal (via camt.056)
AGNTIncorrect agentReject (pre-settlement)
FOCRFollowing cancellation requestReversal (response to camt.056)

The classification function:

classify(reason_code, within_holding_period) → R-transaction type

  if pre_settlement(reason_code):     → REJECT
  if within_holding_period:           → RETURN
  if originator_initiated(reason_code): → REVERSAL
  else:                               → REFUND

When this classification is implemented directly on the ISO reason code, without an intermediate mapping table, the handling is deterministic. A new reason code in a future EPC rulebook version requires adding one enum variant. The compiler identifies every handler that doesn't cover it. No mapping table to update. No deployment to synchronize.

Implementation Architecture

Three responsibilities, three services. Each owns one concern.

Classification service: receives incoming pacs.004, extracts the reason code, classifies into Reject/Return/Refund/Reversal based on the code and the holding period status of the original transfer.

Settlement service: based on the classified type, executes the correct ledger operation:

  • Reject: no ledger action (the original transfer never settled).
  • Return: void the pending settlement. Transition from SETTLED_PENDING to RETURNED.
  • Refund: create a new debit transfer against the creditor. The original entry is untouched.
  • Reversal: create a correction entry (Stornobuchung) with a correction_of reference to the original transfer.

Audit service: logs every R-transaction with: type, reason code, original transfer reference (resolved by transfer_id → EndToEndId → external_id, fallback chain), PSD2 deadline, and DORA event ID.

The original transfer is resolved through three lookup paths:

  1. Direct transfer_id (if the R-transaction carries it)
  2. EndToEndId matching (the ISO end-to-end reference)
  3. External_id matching (the bank's reference)

The fallback chain handles the real-world reality that not all pacs.004 messages carry all reference fields. Some banks populate EndToEndId. Some use their own external reference. The system must handle all three.

The Stornobuchung (Correction Entry)

German commercial law (HGB §239) requires that corrections to ledger entries are recorded as new entries. Never as modifications to the original. Never as deletions.

A Reversal is not DELETE FROM transfers WHERE id = original_id. It is:

INSERT INTO transfers (
  debit_account_id,   -- original credit account (direction reversed)
  credit_account_id,  -- original debit account (direction reversed)
  amount,             -- same amount as original
  correction_of,      -- FK → original transfer
  code,               -- reversal code
  ...
)

The original entry remains in the ledger. Immutable. The correction entry references it. An auditor sees both: the original posting and its correction, linked by foreign key. The ledger balance reflects the net effect. The audit trail shows the complete history.

This is not a German peculiarity. It is sound accounting practice adopted by any system that takes immutability seriously. If the ledger allows modifications to historical entries, the audit trail is unreliable. If corrections are new entries that reference the original, the trail is complete and tamper-evident.

What Gets Wrong in Practice

Three common implementation mistakes:

1. Treating all R-transactions as reversals. A refund is not a reversal. A reversal reverses the original entry (correction posting). A refund is a new claim that creates a new debit. Conflating them leads to incorrect ledger entries and incorrect balance calculations.

2. Using calendar days for holding periods. SEPA holding periods are counted in TARGET2 business days. A payment settled on Wednesday before a TARGET2 holiday on Thursday: the holding period does not count Thursday. Using calendar days means releasing funds too early (regulatory risk) or too late (liquidity cost).

3. Ignoring the B2B vs. Core distinction. SEPA Direct Debit B2B has a 2-day holding period and no refund right (the debtor has no Art. 76 claim). SEPA Core has a 5-day holding period and an 8-week refund window. If the system applies Core rules to B2B transactions, it over-holds funds. If it applies B2B rules to Core transactions, it under-holds, and is exposed to returns it cannot cover.


Read more: Payments, Payment Orchestration | Connectivity, Financial Rails


Sources:

  • European Payments Council: EPC016-06 (SEPA Core Direct Debit Rulebook, v2024.1)
  • European Payments Council: EPC222-07 (SEPA B2B Direct Debit Rulebook)
  • PSD2, Directive 2015/2366, Art. 71 (Unauthorized transactions), Art. 76 (Refund rights for direct debits)
  • HGB §239, German Commercial Code, requirements for correction of accounting entries
  • ECB TARGET2 calendar (https://www.ecb.europa.eu/paym/target/target2/profuse/calendar/html/index.en.html)
  • ISO 20022 ExternalStatusReason1Code, pacs.004.001.11 reason code enumeration