---
title: SAIF.Business.Payment.EFT business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Payment.EFT
reference_type: package
---

# SAIF.Business.Payment.EFT business rules

This page captures business rules enforced by this library.

## BR-EFT-01: EFT authorization gates electronic payment eligibility

| Field | Value |
| --- | --- |
| **Statement** | A payee cannot receive EFT payment without a corresponding `clsEFTAuthorization` record in `PAYMENT_AUTHORIZATION`.* |
| **Trigger** | A payment detail is created or an EFT payment is initiated for a payee. |
| **Enforcement** | `clsEFTAuthorization.InsertSQL` / `BeforeInsert` inserts the authorization record; downstream payment-processing logic is expected to verify authorization existence before proceeding.* |
| **Outcome** | Payment cannot be electronically disbursed to a payee lacking an active authorization record.* |
| **Tables** | [PAYMENT_AUTHORIZATION](database-tables.md#payment_authorization) |
| **SQL** | [SQL-013](sql/SQL-013-saif-business-payment-eft.md), [SQL-045](sql/SQL-045-saif-business-payment-eft.md) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsEFTAuthorization.vb` |

---

## BR-EFT-02: Debit-card payment eligibility governed by AllowDebitCard

| Field | Value |
| --- | --- |
| **Statement** | On `clsPaymentPreference`, `AllowDebitCard` returns `True` only when the payee is a worker (`Payee.PayeeType = iPayee.PayeeTypes.Worker`); providers are evaluated by the equivalent property on `clsProviderPaymentPreference`. |
| **Trigger** | The calling application reads `AllowDebitCard` while presenting payment-method options for a payee. |
| **Enforcement** | `clsPaymentPreference.AllowDebitCard` get accessor: `Return Payee.PayeeType = iPayee.PayeeTypes.Worker`. |
| **Outcome** | The debit-card payment option is offered only to injured-worker payees on the claimant preference object; provider payees are governed separately by `clsProviderPaymentPreference`. |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsPaymentPreference.vb`, `Business\SAIF.Business.Payment.EFT\clsProviderPaymentPreference.vb` |

---

## BR-EFT-03: Returned EFT payment classified by NACHA return reason code

| Field | Value |
| --- | --- |
| **Statement** | A returned EFT payment is classified by a `clsPaymentReturnReasonCode` (NACHA return code) and may drive subsequent handling such as revocation of the EFT authorization.** |
| **Trigger** | An EFT payment is returned by the bank (e.g., bad routing number, closed account).* |
| **Enforcement** | `clsPaymentReturn.InsertSQL` persists the return with a `PAYMENT_RETURN_REASON_CODE`; the precise state-transition rule determining which return reasons trigger revocation was not traced in this pass.** |
| **Outcome** | Return record created; revocation of `clsEFTAuthorization` may follow depending on the return reason code.** |
| **Tables** | [PAYMENT_RETURN](database-tables.md#payment_return), [PAYMENT_RETURN_REASON_CODE](database-tables.md#payment_return_reason_code) |
| **SQL** | [SQL-020](sql/SQL-020-saif-business-payment-eft.md), [SQL-066](sql/SQL-066-saif-business-payment-eft.md) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsPaymentReturn.vb`, `Business\SAIF.Business.Payment.EFT\clsPaymentReturnReasonCode.vb` |

---

## BR-EFT-04: Bank account soft-delete preserves record integrity

| Field | Value |
| --- | --- |
| **Statement** | Deleting a bank account sets `BANK_ACCOUNT_STATUS_CODE` to the "DELETED" constant rather than physically removing the row.* |
| **Trigger** | `clsBankAccount.DeleteSQL` / `BeforeDelete` is invoked. |
| **Enforcement** | `DeleteSQL` issues an `UPDATE BANK_ACCOUNT Set BANK_ACCOUNT_STATUS_CODE = :BankAccountStatusCode ... Where BANK_ACCOUNT.BANK_ACCOUNT_SEQ_NUM = :BankAccountID`; `RowsAffected = 1` is required or an error is raised.* |
| **Outcome** | Bank account row is marked as deleted but retained in the database; historical linkage to payment authorizations and payment details is preserved.* |
| **Tables** | [BANK_ACCOUNT](database-tables.md#bank_account) |
| **SQL** | [SQL-088](sql/SQL-088-saif-business-payment-eft.md) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsBankAccount.vb` |

---

## BR-EFT-05: Insert/update operations require exactly one affected row

| Field | Value |
| --- | --- |
| **Statement** | All transactional insert and update operations verify that exactly one row was affected; a different count raises a contention-style error.* |
| **Trigger** | `AfterInsert` or `AfterUpdate` executes after any transactional write. |
| **Enforcement** | `If RowsAffected <> 1 Then Me.AddErrorMessage(...)` pattern present across `clsBankAccount`, `clsDebitCardEnrollmentRequest`, `clsEFTAuthorization`, `clsPaymentDetail`, `clsPaymentAllocation`, `clsPaymentAddenda`, `clsPaymentReturn`, and other transactional BOs.* |
| **Outcome** | Business object adds an error message and does not mark itself as saved if the affected row count is not exactly 1.* |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsBankAccount.vb`, `Business\SAIF.Business.Payment.EFT\clsPaymentDetail.vb`, `Business\SAIF.Business.Payment.EFT\clsEFTAuthorization.vb`, `Business\SAIF.Business.Payment.EFT\clsPaymentReturn.vb` |

---

## BR-EFT-06: Debit card enrollment excludes terminated enrollments by default

| Field | Value |
| --- | --- |
| **Statement** | Debit-card enrollment retrieval excludes terminated enrollments (where `CARD_TERM_DATE IS NULL`) unless the `:IncludeTerminatedEnrollment` parameter is set to `'Y'`.* |
| **Trigger** | `clsDebitCardEnrollmentRequest.BeforeRetrieve` is invoked.* |
| **Enforcement** | `RetrieveSQL` includes: `AND ((:IncludeTerminatedEnrollment = 'N' AND CARD_TERM_DATE IS NULL) OR :IncludeTerminatedEnrollment <> 'N')`.* |
| **Outcome** | Terminated debit-card enrollments are hidden from standard retrieval unless explicitly requested.* |
| **Tables** | [DEBIT_CARD_ENROLLMENT_REQUEST](database-tables.md#debit_card_enrollment_request) |
| **SQL** | [SQL-043](sql/SQL-043-saif-business-payment-eft.md) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsDebitCardEnrollmentRequest.vb` |

---

## BR-EFT-07: Return reason description is culture-aware

| Field | Value |
| --- | --- |
| **Statement** | Return reason code descriptions are retrieved with a culture-code override from `PAYMENT_RETURN_REASON_GCODE`; the base `PAYMENT_RETURN_REASON_CODE.CODE_DESCR` is used when no culture-specific override exists.* |
| **Trigger** | `clsPaymentReturnReasonCode.BeforeRetrieve` or `clsPaymentReturn.BeforeRetrieve` is invoked.* |
| **Enforcement** | SQL uses `CASE WHEN prrcG.code_descr IS NULL THEN CAST(prrc.CODE_DESCR AS nvarchar2(2000)) ELSE prrcG.code_descr END`.* |
| **Outcome** | Return reason descriptions are localized when a culture-specific record exists, falling back to the base description otherwise.* |
| **Tables** | [PAYMENT_RETURN_REASON_CODE](database-tables.md#payment_return_reason_code), [PAYMENT_RETURN_REASON_GCODE](database-tables.md#payment_return_reason_gcode) |
| **SQL** | [SQL-064](sql/SQL-064-saif-business-payment-eft.md), [SQL-066](sql/SQL-066-saif-business-payment-eft.md) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsPaymentReturn.vb`, `Business\SAIF.Business.Payment.EFT\clsPaymentReturnReasonCode.vb` |

---

## BR-EFT-08: Authorization status is derived from bank account and prenote state

| Field | Value |
| --- | --- |
| **Statement** | `clsEFTAuthorization.AuthorizationStatus` is a computed value, not a stored column: if `RevokeDate` is set, the status is always "Revoked"; otherwise it is derived from the linked bank account's status (card-enrollment period, provider 14-day wait period, or active) and, when active, from whether the account still requires a prenote. |
| **Trigger** | Any caller reads `AuthorizationStatus` on an `clsEFTAuthorization` instance (e.g., to display authorization state or gate payment eligibility). |
| **Enforcement** | If `RevokeDate` is empty: when `BankAccount.BankAccountStatus.IsActive` and `PrenoteRequiredFlag = "N"`, status is "Valid"; if `PrenoteRequiredFlag = "Y"`, status is "Pre-Note" until `PrenoteSuccessDate` is set, then "Valid". Else if `BankAccount.BankAccountStatus.IsCardEnrollmentPeriod`, status is "Card Enrollment Period"; else if `IsProviderWaitPeriod`, status is "Provider 14 Day Wait Period"; otherwise "Revoked". If `RevokeDate` is set, status is always "Revoked" regardless of bank-account state. |
| **Outcome** | Callers see one of five status values (`Valid`, `Revoked`, `Card Enrollment Period`, `Pre-Note`, `Provider 14 Day Wait Period`) computed at read time from the current bank-account status and prenote fields, not persisted directly. |
| **Tables** | [PAYMENT_AUTHORIZATION](database-tables.md#payment_authorization), [BANK_ACCOUNT](database-tables.md#bank_account) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsEFTAuthorization.vb` |

---

## BR-EFT-09: Selecting an authorization type cascades default bank-account attributes

| Field | Value |
| --- | --- |
| **Statement** | Setting `clsEFTAuthorization.AuthorizationTypeCode` to the claim-debit-card code sets the linked bank account's status to the card-enrollment period, its consumer/business code to consumer, its account type to checking, and its holder name/bank name to the fixed ReliaCard/US Bank debit-card values; setting it to the provider-direct-deposit code on a new bank account instead sets the account status to the provider wait period; any other authorization type resets the bank-account status to unused. |
| **Trigger** | `clsEFTAuthorization.AuthorizationTypeCode` property setter is invoked with a new code that differs from the current value. |
| **Enforcement** | Setter branches on the new code: `CLAIMDEBITCARD` → `BankAccount.BankAccountStatusCode = CARD_ENROLLMENT_PERIOD`, `BusinessConsumerCode = CONSUMER`, `BankAccountTypeCode = CHECKING`, `BankAccountHolderName = "ReliaCard Debit Card"`, `BankName = "US BANK"`; `PROVIDERDIRECTDEPOSIT` and `BankAccount.IsNew` → `BankAccountStatusCode = PROVIDER_WAIT_PERIOD`; all other values → `BankAccountStatusCode = UNUSED`. If the resolved `AuthorizationType.DefaultBankRoutingNum` is non-empty, the bank account's routing number is also set from it and `NewRoutingNumVerified` is forced to `True`. |
| **Outcome** | The bank account tied to an authorization is automatically reconfigured to match the payment channel implied by the authorization type, rather than requiring the caller to set each bank-account field independently. |
| **Tables** | [PAYMENT_AUTHORIZATION](database-tables.md#payment_authorization), [BANK_ACCOUNT](database-tables.md#bank_account) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsEFTAuthorization.vb` |

---

## BR-EFT-10: ACH standard entry class code is required only for ACH banking-network accounts

| Field | Value |
| --- | --- |
| **Statement** | On `clsPaymentDetail`, the ACH standard entry class code must be populated when the linked authorization's bank account belongs to an ACH banking network, and must be blank otherwise. |
| **Trigger** | `IsValid`/`CheckRules` evaluates the `ValidAchStdEntryClassCode` rule on a payment detail. |
| **Enforcement** | Custom rule checks `EFTAuthorization.BankAccount.BankAccountType.BankingNetwork.IsACH`: if true, `AchStdEntryClassCode` must be non-blank; if false, it must be blank — an inverse pair of conditions on the same field. |
| **Outcome** | A payment detail fails validation if its ACH entry class code is missing for an ACH-network account, or unexpectedly populated for a non-ACH-network account. |
| **Tables** | [PAYMENT_DETAIL](database-tables.md#payment_detail), [BANK_ACCOUNT](database-tables.md#bank_account) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsPaymentDetail.vb` |

---

## BR-EFT-11: Bank account deletion supports an explicit hard-purge path

| Field | Value |
| --- | --- |
| **Statement** | Deleting a bank account performs the default soft-delete (see BR-EFT-04) unless the caller sets `PurgeRecord = True` on the `clsBankAccount` instance first, in which case `BeforeDelete` issues a physical `DELETE` against `BANK_ACCOUNT` instead. |
| **Trigger** | `clsBankAccount.BeforeDelete` is invoked with `PurgeRecord` already set by the caller. |
| **Enforcement** | `BeforeDelete` branches on `PurgeRecord`: `True` → `SQLStatement = MyCriteria.PurgeSQL` (`Delete BANK_ACCOUNT Where BANK_ACCOUNT.BANK_ACCOUNT_SEQ_NUM = :BankAccountID`); `False` (default) → `SQLStatement = MyCriteria.DeleteSQL` (soft-delete update). |
| **Outcome** | Most deletes leave a `DELETED`-status row in place for historical linkage; only callers who explicitly opt into `PurgeRecord` remove the row physically. |
| **Tables** | [BANK_ACCOUNT](database-tables.md#bank_account) |
| **SQL** | [SQL-088](sql/SQL-088-saif-business-payment-eft.md) |
| **Source** | `Business\SAIF.Business.Payment.EFT\clsBankAccount.vb` |

---

## Notes
- Exact business-rule trigger/enforcement/outcome detail for all ~30 business objects in this library requires deeper per-class analysis; only rules substantiated by Phase 1, Phase 1b, and per-operation source tracing are captured here.
- [BR-EFT-03](#br-eft-03-returned-eft-payment-classified-by-nacha-return-reason-code) is partially confirmed; the full state-transition rule determining which return reasons trigger authorization revocation was not traced to source — `clsPaymentReturn` was confirmed to read, but never write, authorization/revocation data.

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with `**` could not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [API reference](api/index.md)
- [Configuration](configuration.md)

## Sources
- `Business\SAIF.Business.Payment.EFT\clsBankAccount.vb`
- `Business\SAIF.Business.Payment.EFT\clsPaymentPreference.vb`
- `Business\SAIF.Business.Payment.EFT\clsProviderPaymentPreference.vb`
- `Business\SAIF.Business.Payment.EFT\clsEFTAuthorization.vb`
- `Business\SAIF.Business.Payment.EFT\clsDebitCardEnrollmentRequest.vb`
- `Business\SAIF.Business.Payment.EFT\clsPaymentDetail.vb`
- `Business\SAIF.Business.Payment.EFT\clsPaymentReturn.vb`
- `Business\SAIF.Business.Payment.EFT\clsPaymentReturnReasonCode.vb`
