---
title: Parse callback and remittance XML
summary: Provides typed, read-only field access over four XML payload shapes received from US Bank — real-time payment confirmations, real-time nonpayment notifications, batch remittance documents, and their individual remitted-payment detail rows.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.EPay.USBank
reference_type: package
operation_id: OP-EPAY-08
trigger: Caller constructs RealTimePaymentConfirmation, RealTimeNonPaymentNotification, or RemittanceDocument from XML received from US Bank
---

# Parse callback and remittance XML

This operation covers four small, closely related types that all do the same job — turn inbound XML from US Bank into typed .NET values — without performing any SOAP calls or database access. `RealTimePaymentConfirmation` and `RealTimeNonPaymentNotification` parse individual callback payloads; `RemittanceDocument` parses a batch remittance file and yields a `RemittedPayment` per detail row. All four are pure, lazily-evaluated readers over an in-memory `XElement`/`XDocument`.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-EPAY-08 |
| **Trigger** | Caller constructs `New RealTimePaymentConfirmation(xml)`, `New RealTimeNonPaymentNotification(xml)`, or `New RemittanceDocument(xDocument)` from XML received from US Bank |
| **Inputs** | Raw XML text (payment confirmation, nonpayment notification) or an `XDocument` (remittance document) |
| **Outputs** | Typed, read-only properties: user ID, payment amount, policy number, transaction mode/frequency/duration/amount-type enums, confirmation ID, effective/business dates, product, payment network, card type (confirmation); user ID, policy number, product, unsuccessful-event description and timestamp (nonpayment notification); process date, biller ID, and a list of `RemittedPayment` rows (remittance document), each exposing confirmation ID, product, payment network, card type, amount, effective date, policy number, saved-balance ID, transaction type, user ID, and ACH return details |
| **Primary components** | `RealTimePaymentConfirmation` (structure), `RealTimeNonPaymentNotification` (structure), `RemittanceDocument`, `RemittedPayment` |
| **Entry point** | `Business\SAIF.Business.EPay.USBank\RealTimePaymentConfirmation.vb` |

## Steps

1. **Load the root element lazily.** Both `RealTimePaymentConfirmation` and `RealTimeNonPaymentNotification` store the raw XML string in the constructor and defer parsing: the private `Root` property calls `XElement.Load` only the first time any property is read, caching the result for subsequent reads.
2. **Read simple scalar fields.** Properties such as `UserId`, `PaymentAmount`, `TransactionModeCode`, `BillerProductCode`, and `UnsuccessfulEvent` read a single named child element's value directly off `Root`.
3. **Read parameter-style fields.** `PolicyNumber` and `SavedBalanceId` (confirmation) and `PolicyNumber` (notification) search the `Parameter` child elements for one whose `ParameterName` matches, then return its `ParameterValue`; `SavedBalanceId` returns an empty string when no matching parameter exists instead of throwing.
4. **Classify the transaction mode.** `TransactionMode` inspects the root element's local name (`PaymentInfo` vs. `RecurringPaymentInfo`) and maps the transaction-mode code to the matching enum member, defaulting to `Other` for any unrecognized combination.
5. **Derive recurring-specific fields.** `IsRecurring` is true when the mode is `StartRecurring`, `EditRecurring`, or `StopRecurring`; `ConfirmationId` reads `RecurringReferenceId` when recurring or `ConfirmationId` otherwise; `PaymentEffectiveDate` reads `FirstScheduledPaymentDate` when recurring or `PaymentEffectiveDate` otherwise; `Frequency` and `Duration` are only meaningful (non-`Other`) when recurring.
6. **Derive biller identifiers from the confirmation ID.** `BillerGroupId` and `BillerId` are computed by taking fixed-width substrings (first 3 characters, next 3 characters) of `ConfirmationId`.
7. **Resolve enums shared with the rest of the library.** `Product` calls the shared `ConvertEPaymentServiceProduct`/`GetSaifProductCode` helpers (from `Enums.vb`) against the raw biller product code; `PaymentNetwork` calls `ConvertPaymentNetwork`; `CardType` maps a raw code string to the `CardTypes` enum, defaulting to `Unknown`.
8. **Parse fixed-format dates.** `ConvertYYYMMDDToDate`/`ConvertUSBankDateStringToDate` slice a fixed-width `YYYYMMDD`-style string into year/month/day components and construct a `Date`.
9. **Load a remittance document.** `RemittanceDocument`'s constructor stores the caller-supplied `XDocument`; `ProcessDate` and `BillerId` are read from the `Header` element nested under `Remittance`.
10. **Enumerate remitted payments.** `RemittedPayments` iterates every `Detail` element in the document and constructs one `RemittedPayment` per element, passing along the parsed `BillerGroupId` and `BillerId` from the header so each payment can compute its own confirmation-ID suffix.
11. **Read remitted-payment fields.** Each `RemittedPayment` exposes the same category of typed accessors as the confirmation structure (product, payment network, card type, transaction type) plus ACH-specific fields (`ACHReturnCode`, `ReturnReasonDescription`, `ReturnDate`) and a computed `ConfirmationIdWithoutBillerGroupAndBiller` that strips the leading biller-group/biller prefix and parses the remainder as a decimal.

## Process flow

The following diagram visualizes the lazy-parse pattern shared by the confirmation/notification structures and the remittance document's per-row expansion.

```mermaid
flowchart TD
	Start{Which payload?}
	Start -->|Payment confirmation| CLoad[Store XML string;<br>defer XElement.Load]
	CLoad --> CRead[Read scalar and parameter fields<br>on first property access]
	CRead --> CMode[Classify TransactionMode<br>from root name + code]
	CMode --> CDerive[Derive recurring flags,<br>confirmation ID, dates, enums]
	Start -->|Nonpayment notification| NLoad[Store XML string;<br>defer XElement.Load]
	NLoad --> NRead[Read scalar and parameter fields]
	Start -->|Remittance document| RLoad[Store XDocument]
	RLoad --> RHeader[Read ProcessDate, BillerId<br>from Header element]
	RHeader --> RLoop[For each Detail element:<br>construct a RemittedPayment]
	RLoop --> RFields[Expose typed fields<br>per remitted payment]
	CDerive --> Done([Typed values returned<br>to caller on demand])
	NRead --> Done
	RFields --> Done
```

## Failure and edge-case behavior

- All property reads assume the expected element is present; a missing element (other than the explicitly guarded `SavedBalanceId` and `PaymentTypeAttempt`/`PaymentAmount` cases) raises an unhandled null-reference-style exception from `XElement` navigation rather than a handled parsing error.*
- `SavedBalanceId` on `RealTimePaymentConfirmation` and `PaymentTypeAttempt`/`PaymentAmount` on `RealTimeNonPaymentNotification` are the only fields with explicit missing-element handling, returning an empty string or zero instead of throwing.
- `RecurringRefId` only reads a value when `TransactionMode = Declined`; for every other mode it returns an empty string without checking whether the underlying element exists.
- Because `Root` is cached after first access, constructing one of these structures with malformed XML defers the parse failure until the first property is actually read, not at construction time.*
- `RemittedPayment`'s constructor is `Friend`, so instances can only be created by `RemittanceDocument` within this library — there is no public way to construct a `RemittedPayment` directly from a caller-supplied XML fragment.

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

## Sources

- `Business\SAIF.Business.EPay.USBank\RealTimePaymentConfirmation.vb`
- `Business\SAIF.Business.EPay.USBank\RealTimeNonPaymentNotification.vb`
- `Business\SAIF.Business.EPay.USBank\RemittanceDocument.vb`
- `Business\SAIF.Business.EPay.USBank\RemittedPayment.vb`
- `Business\SAIF.Business.EPay.USBank\Enums.vb`
