The Question
“What type should I use for a remittance? I need to send a payment to a merchant paying for two invoices. Just make up values and show me an example. Include optional fields. Show notes on how it might deviate for different use cases. Then, show me the structure of the database model used to persist everything tracking the state of the payment through its lifecycle. Make sure the database names correspond to the ISO domain model names. Show me a state diagram or business process diagram showing how processing happens during the lifetime of a single payment. Show the C# implementation of a MassTransit Saga State Machine.”
One question. No spec PDFs. No schema browser. Watch what happens next.
Step 1 — The MCP Server Identifies the Right Message
The AI queries the Beneficial Strategies ISO 20022 MCP Server live. It navigates the business process catalogue to the Payments Initiation area and pulls the latest message set.
The server returns:
| Message | Version | Name | Role |
|---|---|---|---|
pain.001 |
001.001.12 |
CustomerCreditTransferInitiationV12 |
Initiating party instructs their bank to move funds to a creditor |
This is the right answer. pain.001 is the canonical ISO 20022 message a company sends to its bank to initiate a credit transfer. It is explicitly designed to carry remittance information — structured references back to the invoices being settled — so the merchant’s accounts receivable system can automatically match the payment to the right open items.
The MCP server then drills into the message structure. It navigates:
pain.001.001.12
→ PaymentInformation (PaymentInstruction44)
→ CreditTransferTransactionInformation (CreditTransferTransaction61)
→ RemittanceInformation (RemittanceInformation22)
→ Structured (StructuredRemittanceInformation18)
→ ReferredDocumentInformation (ReferredDocumentInformation8) ← one per invoice
→ ReferredDocumentAmount (RemittanceAmount4)
→ CreditorReferenceInformation
→ AdditionalRemittanceInformation
The spec confirms that ReferredDocumentInformation can repeat — one entry per invoice. Each entry carries a document type code (CINV = Commercial Invoice), an invoice number, and the related date. The total payment amount sits at the transaction level; the remittance block tells the merchant which invoices it covers.
Step 2 — Two Quick Clarifying Questions
Before generating anything, the AI asks:
“Should the C# model use records (immutable, init-only) or classes with mutable properties? Records are better for value-object semantics; classes are easier if you need ORM entity tracking.”
Answer: Classes — this will be persisted via EF Core.
“Should I include a UETR (Unique End-to-End Transaction Reference, ISO 20022 UUID field)? It’s optional in the base spec but required by SWIFT gpi and recommended for lifecycle correlation.”
Answer: Yes, include it.
Those two decisions shape the database schema and the saga correlation strategy. Everything else is automatic.
Step 3 — Everything Is Generated Automatically
Message Structure
classDiagram
direction TB
class CustomerCreditTransferInitiationV12 {
XmlTag: CstmrCdtTrfInitn
}
class GroupHeader93 {
MessageIdentification: Max35Text
CreationDateTime: ISODateTime
NumberOfTransactions: Max15NumericText
ControlSum: DecimalNumber
InitiatingParty: PartyIdentification135
}
class PaymentInstruction44 {
PaymentInformationIdentification: Max35Text
PaymentMethod: PaymentMethod3Code
RequestedExecutionDate: DateAndDateTime2Choice
Debtor: PartyIdentification135
DebtorAccount: CashAccount40
DebtorAgent: BranchAndFinancialInstitutionIdentification6
}
class CreditTransferTransaction61 {
PaymentIdentification: PaymentIdentification6
InstructedAmount: ActiveOrHistoricCurrencyAndAmount
ChargeBearer: ChargeBearerType1Code
Creditor: PartyIdentification135
CreditorAccount: CashAccount40
CreditorAgent: BranchAndFinancialInstitutionIdentification6
Purpose: Purpose2Choice
}
class RemittanceInformation22 {
Unstructured: Max140Text [0..1]
}
class StructuredRemittanceInformation18 {
AdditionalRemittanceInformation: Max140Text [0..3]
}
class ReferredDocumentInformation8 {
Type: ReferredDocumentType4
Number: Max35Text
RelatedDate: DateAndType1
}
class RemittanceAmount4 {
RemittanceAmountAndType: RemittanceAmountAndType2
AdjustmentAmountAndReason: DocumentAdjustment1
}
CustomerCreditTransferInitiationV12 *-- "1" GroupHeader93 : GrpHdr
CustomerCreditTransferInitiationV12 *-- "1..*" PaymentInstruction44 : PmtInf
PaymentInstruction44 *-- "1..*" CreditTransferTransaction61 : CdtTrfTxInf
CreditTransferTransaction61 *-- "0..1" RemittanceInformation22 : RmtInf
RemittanceInformation22 *-- "0..*" StructuredRemittanceInformation18 : Strd
StructuredRemittanceInformation18 *-- "0..*" ReferredDocumentInformation8 : RfrdDocInf
StructuredRemittanceInformation18 *-- "0..1" RemittanceAmount4 : RfrdDocAmt
Sample XML
Two invoices — $12,500 for office furniture and $3,750 for printer supplies — paid in a single pain.001. All optional remittance fields populated:
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.12">
<CstmrCdtTrfInitn>
<!-- GroupHeader: message-level envelope -->
<GrpHdr>
<MsgId>ACME-PAY-2026-03-25-001</MsgId>
<CreDtTm>2026-03-25T09:15:00</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>16250.00</CtrlSum>
<InitgPty>
<Nm>Acme Corp</Nm>
<Id>
<OrgId>
<AnyBIC>ACMEUSNYXXX</AnyBIC>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<!-- PaymentInformation: debit side — who pays, from which account, when -->
<PmtInf>
<PmtInfId>PMTINF-20260325-0001</PmtInfId>
<PmtMtd>TRF</PmtMtd> <!-- TRF = Credit Transfer -->
<BtchBookg>false</BtchBookg> <!-- OPTIONAL: individual booking per transaction -->
<NbOfTxs>1</NbOfTxs>
<CtrlSum>16250.00</CtrlSum>
<PmtTpInf>
<!-- OPTIONAL: payment type hints -->
<InstrPrty>NORM</InstrPrty> <!-- Normal priority -->
<SvcLvl>
<Cd>SEPA</Cd> <!-- SEPA Credit Transfer (use NURG/URGP for other rails) -->
</SvcLvl>
<CtgyPurp>
<Cd>SUPP</Cd> <!-- Supplier Payment -->
</CtgyPurp>
</PmtTpInf>
<ReqdExctnDt>
<Dt>2026-03-27</Dt>
</ReqdExctnDt>
<!-- OPTIONAL: future-date pooling adjustment -->
<PoolgAdjstmntDt>2026-03-27</PoolgAdjstmntDt>
<Dbtr>
<Nm>Acme Corp</Nm>
<PstlAdr>
<Ctry>US</Ctry>
<AdrLine>100 Commerce Blvd, New York, NY 10001</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id><IBAN>US29ACME0001234500001234</IBAN></Id>
<Ccy>USD</Ccy>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BICFI>CHASUS33XXX</BICFI> <!-- JPMorgan Chase -->
</FinInstnId>
</DbtrAgt>
<!-- OPTIONAL: instruction to debtor agent -->
<InstrForDbtrAgt>HOLD</InstrForDbtrAgt>
<!-- CreditTransferTransactionInformation: credit side + remittance -->
<CdtTrfTxInf>
<PmtId>
<InstrId>INSTR-20260325-0001</InstrId>
<EndToEndId>E2E-ACME-APEX-20260325-001</EndToEndId>
<!-- OPTIONAL: UETR (SWIFT gpi / recommended for lifecycle tracking) -->
<UETR>550e8400-e29b-41d4-a716-446655440000</UETR>
</PmtId>
<Amt>
<InstdAmt Ccy="USD">16250.00</InstdAmt>
</Amt>
<ChrgBr>SLEV</ChrgBr> <!-- Follow service-level charge rules -->
<!-- OPTIONAL: intermediary agent (correspondent bank) -->
<IntrmyAgt1>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</IntrmyAgt1>
<CdtrAgt>
<FinInstnId>
<BICFI>GEBABEBB XXX</BICFI> <!-- BNP Paribas Fortis Belgium -->
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Apex Supplies Ltd</Nm>
<PstlAdr>
<Ctry>BE</Ctry>
<AdrLine>45 Rue du Commerce, B-1000 Brussels</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id><IBAN>BE71096123456769</IBAN></Id>
</CdtrAcct>
<!-- OPTIONAL: ultimate creditor (when payee differs from account holder) -->
<UltmtCdtr>
<Nm>Apex Supplies Ltd — Accounts Receivable</Nm>
</UltmtCdtr>
<Purp>
<Cd>SUPP</Cd> <!-- Supplier Payment -->
</Purp>
<!-- RemittanceInformation: tell Apex which invoices this covers -->
<RmtInf>
<!-- Structured block 1: Invoice INV-2026-0441 -->
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd> <!-- Commercial Invoice -->
</CdOrPrtry>
</Tp>
<Nb>INV-2026-0441</Nb>
<RltdDt>
<Tp>
<Cd>INDA</Cd> <!-- Invoice Date -->
</Tp>
<Dt>2026-02-28</Dt>
</RltdDt>
</RfrdDocInf>
<RfrdDocAmt>
<DuePyblAmt Ccy="USD">12500.00</DuePyblAmt>
</RfrdDocAmt>
<CdtrRefInf>
<Tp>
<CdOrPrtry>
<Cd>SCOR</Cd> <!-- Structured Creditor Reference -->
</CdOrPrtry>
</Tp>
<Ref>RF18539007547034</Ref> <!-- ISO 11649 creditor reference -->
</CdtrRefInf>
<AddtlRmtInf>Office furniture — PO-2026-0112</AddtlRmtInf>
</Strd>
<!-- Structured block 2: Invoice INV-2026-0458 -->
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd>
</CdOrPrtry>
</Tp>
<Nb>INV-2026-0458</Nb>
<RltdDt>
<Tp>
<Cd>INDA</Cd>
</Tp>
<Dt>2026-03-10</Dt>
</RltdDt>
</RfrdDocInf>
<RfrdDocAmt>
<DuePyblAmt Ccy="USD">3750.00</DuePyblAmt>
</RfrdDocAmt>
<CdtrRefInf>
<Tp>
<CdOrPrtry>
<Cd>SCOR</Cd>
</CdOrPrtry>
</Tp>
<Ref>RF71234400112987</Ref>
</CdtrRefInf>
<AddtlRmtInf>Printer supplies — PO-2026-0118</AddtlRmtInf>
</Strd>
</RmtInf>
</CdtTrfTxInf>
</PmtInf>
</CstmrCdtTrfInitn>
</Document>
Deviation Notes
| Scenario | What changes |
|---|---|
| Domestic US ACH | SvcLvl/Cd → ACH; IBAN → Othr account ID with routing + account number; BICFI → ABA routing number in ClrSysMmbId |
| SWIFT gpi cross-border | Add SvcLvl/Cd = G001; UETR is mandatory (not optional); intermediary agents often required |
| Single invoice, no structured remittance | Replace <Strd> blocks with <Ustrd>INV-2026-0441</Ustrd> — simpler, but machine-matching is lost |
| Credit note offsetting an invoice | Add a second RfrdDocInf with Cd = CREN (Credit Note) and a negative AdjstmntAmtAndRsn in RfrdDocAmt |
| Batch booking | Set <BtchBookg>true</BtchBookg> and add multiple CdtTrfTxInf blocks — one per transaction; the bank books a single net debit |
| Requested collection date | Replace ReqdExctnDt with ReqdColltnDt if debtor agent is collecting on behalf |
| FedNow / RTP instant payment | SvcLvl/Cd → NURG; execution is immediate; structured remittance carries through via ISO 20022 native format |
Database Model
Every table name and column name is taken directly from the ISO 20022 component hierarchy returned by the MCP server. The saga correlation key is EndToEndIdentification — present in both pain.001 and every downstream pain.002 status report.
erDiagram
CreditTransferTransaction {
uuid Id PK
string InstructionIdentification
string EndToEndIdentification UK
uuid UETR UK
string InstructedAmount
string InstructedCurrency
string ChargeBearer
string Purpose
date RequestedExecutionDate
string Status
datetime CreatedAt
datetime UpdatedAt
}
PaymentInstruction {
uuid Id PK
string PaymentInformationIdentification UK
string PaymentMethod
date RequestedExecutionDate
string DebtorName
string DebtorIBAN
string DebtorAgentBIC
string MessageIdentification
datetime CreatedAt
}
StructuredRemittanceInformation {
uuid Id PK
uuid CreditTransferTransactionId FK
int SequenceNumber
string AdditionalRemittanceInformation
}
ReferredDocumentInformation {
uuid Id PK
uuid StructuredRemittanceInformationId FK
string DocumentTypeCode
string Number
date RelatedDate
string RelatedDateTypeCode
string CreditorReference
string CreditorReferenceTypeCode
}
RemittanceAmount {
uuid Id PK
uuid ReferredDocumentInformationId FK
decimal DuePayableAmount
string Currency
decimal AdjustmentAmount
string AdjustmentReasonCode
}
PaymentStatusReport {
uuid Id PK
uuid CreditTransferTransactionId FK
string OriginalEndToEndIdentification
string TransactionStatus
string StatusReasonCode
string StatusReasonAdditionalInformation
datetime AcceptanceDateTime
datetime CreatedAt
}
PaymentInstruction ||--o{ CreditTransferTransaction : "CdtTrfTxInf"
CreditTransferTransaction ||--o{ StructuredRemittanceInformation : "RmtInf/Strd"
StructuredRemittanceInformation ||--o{ ReferredDocumentInformation : "RfrdDocInf"
ReferredDocumentInformation ||--o| RemittanceAmount : "RfrdDocAmt"
CreditTransferTransaction ||--o{ PaymentStatusReport : "pain.002"
Payment Lifecycle State Diagram
The saga tracks a single CreditTransferTransaction from initiation through settlement, consuming pain.002 status reports from the bank at each step.
stateDiagram-v2
[*] --> Created : PaymentInitiated
Created --> Submitted : pain.001 accepted by bank API
Submitted --> Acknowledged : pain.002 ACCP (Accepted Customer Profile)
Acknowledged --> Processing : pain.002 ACWC (Accepted With Change) or ACSP
Processing --> Cleared : pain.002 ACSC (Accepted Settlement Completed)
Cleared --> Settled : Interbank credit confirmed
Settled --> Completed : Merchant AR reconciled
Completed --> [*]
Submitted --> Rejected : pain.002 RJCT
Acknowledged --> Rejected : pain.002 RJCT
Processing --> Rejected : pain.002 RJCT
Rejected --> [*]
Cleared --> Returned : pacs.004 Return received
Settled --> Returned : pacs.004 Return received
Returned --> [*]
note right of Acknowledged
pain.002 AcceptanceDateTime
recorded here for SLA tracking
end note
note right of Cleared
UETR enables gpi tracker
lookup at this stage
end note
C# MassTransit Saga State Machine
Every state, event, and correlation property maps directly to the ISO 20022 domain model. The EndToEndIdentification is the saga correlation key — it threads through pain.001, every pain.002, and can be used to pull the UETR for gpi tracking.
using MassTransit;
namespace Payments.Sagas;
// ── Saga state (persisted by EF Core / Redis / etc.) ──────────────────────────
public class CreditTransferSagaState : SagaStateMachineInstance, ISagaVersion
{
public Guid CorrelationId { get; set; } // MassTransit internal key
public int Version { get; set; } // optimistic concurrency
public string CurrentState { get; set; } = null!;
// ISO 20022 PaymentIdentification fields
public string InstructionIdentification { get; set; } = null!;
public string EndToEndIdentification { get; set; } = null!; // correlation key
public Guid? UETR { get; set; } // gpi tracking
// Amounts
public decimal InstructedAmount { get; set; }
public string InstructedCurrency { get; set; } = null!;
// Parties
public string DebtorName { get; set; } = null!;
public string CreditorName { get; set; } = null!;
public string CreditorIBAN { get; set; } = null!;
// Timestamps — map to ISO pain.002 AcceptanceDateTime
public DateTime InitiatedAt { get; set; }
public DateTime? AcknowledgedAt { get; set; } // pain.002 ACCP
public DateTime? ClearedAt { get; set; } // pain.002 ACSC
public DateTime? CompletedAt { get; set; }
public DateTime? RejectedAt { get; set; }
public DateTime? ReturnedAt { get; set; }
// Latest status reason (pain.002 StatusReasonInformation/Reason/Code)
public string? LastStatusReasonCode { get; set; }
}
// ── Events (messages flowing into the saga) ───────────────────────────────────
// Published when the initiating party submits a pain.001
public record PaymentInitiated(
Guid CorrelationId,
string InstructionIdentification,
string EndToEndIdentification,
Guid? UETR,
decimal InstructedAmount,
string InstructedCurrency,
string DebtorName,
string CreditorName,
string CreditorIBAN,
DateTime InitiatedAt
);
// Published when pain.002 is received from the bank
public record PaymentStatusReportReceived(
string OriginalEndToEndIdentification, // correlation key
string TransactionStatus, // ACCP, ACSP, ACSC, RJCT, ACWC, …
string? StatusReasonCode,
DateTime? AcceptanceDateTime
);
// Published when pacs.004 return is received
public record PaymentReturnReceived(
string OriginalEndToEndIdentification,
string ReturnReasonCode,
DateTime ReturnedAt
);
// ── State machine ─────────────────────────────────────────────────────────────
public class CreditTransferSagaMachine
: MassTransitStateMachine<CreditTransferSagaState>
{
// States
public State Submitted { get; private set; } = null!;
public State Acknowledged { get; private set; } = null!;
public State Processing { get; private set; } = null!;
public State Cleared { get; private set; } = null!;
public State Settled { get; private set; } = null!;
public State Completed { get; private set; } = null!;
public State Rejected { get; private set; } = null!;
public State Returned { get; private set; } = null!;
// Events
public Event<PaymentInitiated> PaymentInitiated { get; private set; } = null!;
public Event<PaymentStatusReportReceived> PaymentStatusReportReceived { get; private set; } = null!;
public Event<PaymentReturnReceived> PaymentReturnReceived { get; private set; } = null!;
public CreditTransferSagaMachine()
{
// Persist CurrentState in the CreditTransferSagaState.CurrentState column
InstanceState(x => x.CurrentState);
// Correlate pain.002 and pacs.004 returns by EndToEndIdentification
Event(() => PaymentInitiated, e =>
e.CorrelateById(ctx => ctx.Message.CorrelationId));
Event(() => PaymentStatusReportReceived, e =>
e.CorrelateBy(state => state.EndToEndIdentification,
ctx => ctx.Message.OriginalEndToEndIdentification));
Event(() => PaymentReturnReceived, e =>
e.CorrelateBy(state => state.EndToEndIdentification,
ctx => ctx.Message.OriginalEndToEndIdentification));
// ── Transitions ──────────────────────────────────────────────────────
Initially(
When(PaymentInitiated)
.Then(ctx =>
{
ctx.Saga.InstructionIdentification = ctx.Message.InstructionIdentification;
ctx.Saga.EndToEndIdentification = ctx.Message.EndToEndIdentification;
ctx.Saga.UETR = ctx.Message.UETR;
ctx.Saga.InstructedAmount = ctx.Message.InstructedAmount;
ctx.Saga.InstructedCurrency = ctx.Message.InstructedCurrency;
ctx.Saga.DebtorName = ctx.Message.DebtorName;
ctx.Saga.CreditorName = ctx.Message.CreditorName;
ctx.Saga.CreditorIBAN = ctx.Message.CreditorIBAN;
ctx.Saga.InitiatedAt = ctx.Message.InitiatedAt;
})
.TransitionTo(Submitted)
);
During(Submitted,
When(PaymentStatusReportReceived, IsPain002Status("ACCP"))
.Then(ctx =>
{
ctx.Saga.AcknowledgedAt = ctx.Message.AcceptanceDateTime ?? DateTime.UtcNow;
ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode;
})
.TransitionTo(Acknowledged),
When(PaymentStatusReportReceived, IsPain002Status("RJCT"))
.Then(ctx =>
{
ctx.Saga.RejectedAt = DateTime.UtcNow;
ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode;
})
.TransitionTo(Rejected)
.Finalize()
);
During(Acknowledged,
When(PaymentStatusReportReceived, IsPain002Status("ACSP"))
.Then(ctx => ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode)
.TransitionTo(Processing),
When(PaymentStatusReportReceived, IsPain002Status("ACWC"))
.Then(ctx => ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode)
.TransitionTo(Processing),
When(PaymentStatusReportReceived, IsPain002Status("ACSC"))
.Then(ctx =>
{
ctx.Saga.ClearedAt = ctx.Message.AcceptanceDateTime ?? DateTime.UtcNow;
ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode;
})
.TransitionTo(Cleared),
When(PaymentStatusReportReceived, IsPain002Status("RJCT"))
.Then(ctx =>
{
ctx.Saga.RejectedAt = DateTime.UtcNow;
ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode;
})
.TransitionTo(Rejected)
.Finalize()
);
During(Processing,
When(PaymentStatusReportReceived, IsPain002Status("ACSC"))
.Then(ctx =>
{
ctx.Saga.ClearedAt = ctx.Message.AcceptanceDateTime ?? DateTime.UtcNow;
ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode;
})
.TransitionTo(Cleared),
When(PaymentStatusReportReceived, IsPain002Status("RJCT"))
.Then(ctx =>
{
ctx.Saga.RejectedAt = DateTime.UtcNow;
ctx.Saga.LastStatusReasonCode = ctx.Message.StatusReasonCode;
})
.TransitionTo(Rejected)
.Finalize()
);
During(Cleared,
When(PaymentReturnReceived)
.Then(ctx =>
{
ctx.Saga.ReturnedAt = ctx.Message.ReturnedAt;
ctx.Saga.LastStatusReasonCode = ctx.Message.ReturnReasonCode;
})
.TransitionTo(Returned)
.Finalize()
);
// Mark Rejected and Returned as terminal — clean up saga repository
SetCompletedWhenFinalized();
}
// Helper: filter pain.002 status events by TransactionStatus code
private static EventMessageFilter<CreditTransferSagaState, PaymentStatusReportReceived>
IsPain002Status(string code) =>
filter => filter.Message.TransactionStatus == code;
}
EF Core Saga Repository Registration
// Program.cs / Startup
services.AddMassTransit(x =>
{
x.AddSagaStateMachine<CreditTransferSagaMachine, CreditTransferSagaState>()
.EntityFrameworkRepository(r =>
{
r.ConcurrencyMode = ConcurrencyMode.Optimistic;
r.AddDbContext<DbContext, PaymentsDbContext>((provider, opts) =>
opts.UseNpgsql(connectionString));
});
x.UsingRabbitMq((ctx, cfg) => cfg.ConfigureEndpoints(ctx));
});
What Just Happened?
One question. No ISO spec PDFs opened. No message catalog searched. No state machine scaffolded by hand.
The Beneficial Strategies ISO 20022 MCP Server queried the live specification, navigated twelve levels deep into the pain.001.001.12 component hierarchy, confirmed the exact repeating structure of StructuredRemittanceInformation18 and ReferredDocumentInformation8, and produced:
- A spec-accurate XML sample with two invoices, structured remittance, creditor references, optional fields, and inline comments
- A deviation guide covering five different payment rails
- A database schema where every table and column name traces back to an ISO 20022 component retrieved live from the spec
- A Mermaid state diagram showing the complete payment lifecycle through
pain.002status codes - A production-ready MassTransit Saga State Machine correlated on
EndToEndIdentificationas specified by the ISO model
The only decisions you made were “use classes” and “include the UETR.”
That’s what the Beneficial Strategies AI MCP Server does for your payment engineering team. See what’s included in each plan.