Provider bank account retrieval¶
clsProviderBankAccountCollection.GetProviderBankAccounts finds every bank account linked to a provider through that provider's locations' payment authorizations, excluding deleted accounts. Each returned clsProviderBankAccount is a thin wrapper that only carries a BankAccountSeqNum; its nickname, routing number, account number, and masked account number are resolved lazily, one property access at a time, from the shared clsBankAccount object. Both the collection query and the per-account field resolution are documented together because the second only exists to serve callers of the first.
| Field | Value |
|---|---|
| Operation ID | OP-PP-06 |
| Trigger | clsProviderBankAccountCollection.GetProviderBankAccounts(dpi, providerID) |
| Inputs | ProviderSeqNum |
| Outputs | Populated clsProviderBankAccountCollection of clsProviderBankAccount (sequence number only); decrypted/masked field values on subsequent property access |
| Primary components | clsProviderBankAccountCollection.GetProviderBankAccounts, clsProviderBankAccount.BankAccountNickName, clsProviderBankAccount.BankRoutingNumber, clsProviderBankAccount.BankAccountNumber, clsProviderBankAccount.MaskedBankAccountNumber, clsProviderBankAccount.BankAccount |
| Entry point | Business\SAIF.Business.Provider.PaymentPreference\clsProviderBankAccounts.vb |
Steps¶
- Query candidate accounts.
GetProviderBankAccounts(dpi, providerID)selectsBANK_ACCOUNT_SEQ_NUMfromBANK_ACCOUNTwhere the account is not statusDELET(BR-14) and its sequence number appears inPAYMENT_AUTHORIZATIONrows whosecustomer_idmatches one of the provider's location sequence numbers (SQL-004, BANK_ACCOUNT, PAYMENT_AUTHORIZATION, PROVIDER_LOCATION). - The query does not filter on
revoke_date is null— a commented-out line in source shows this filter was considered and removed, so bank accounts tied to a revoked payment authorization are still returned by this query.* - Load and mark each row. Each matched row is loaded into a
clsProviderBankAccountcarrying onlyBankAccountSeqNum, and the object is marked Old on load — there is no create/update/delete path on this class; it is read-only. - Resolve the underlying bank account on demand. The private
BankAccountproperty callsclsBankAccount.GetBankAccount(MyCriteria.DataPortalInfo, BankAccountSeqNum)every time it is accessed — it is not cached on the object. Each of the four public properties below independently triggers this call: BankAccountNickNamereturnsBankAccount.BankAccountNickNameunmodified.BankRoutingNumberreturnsSAIF.Security.clsSecureEncrypt.DecryptString(BankAccount.BankRoutingNumber)— the routing number is decrypted from its stored encrypted form before being returned.BankAccountNumberreturnsSAIF.Security.clsSecureEncrypt.DecryptString(BankAccount.BankAccountNumber)— likewise decrypted.MaskedBankAccountNumberreturnsBankAccount.MaskedBankAccountNumber— pre-masked by the underlying object, not decrypted.
Origin:
clsBankAccountand itsGetBankAccount/masking logic are implemented inSAIF.Business.Payment.EFTand executed on behalf of this operation. That library is documented in the previous format, so no per-operation page exists; see Bank account management in theSAIF.Business.Payment.EFTdocumentation set. Decryption itself is performed bySAIF.Security.clsSecureEncrypt, delivered via the localSAIFEncrypt.dllper this library's dependency documentation.
Process flow¶
flowchart TD
Start([Caller requests provider bank accounts]) --> Query[Select BANK_ACCOUNT_SEQ_NUM<br>where status <> DELET and linked via<br>PAYMENT_AUTHORIZATION to a provider location]
Query --> Load[Load each row as clsProviderBankAccount,<br>MarkOld]
Load --> Collection([Populated clsProviderBankAccountCollection])
Collection --> Access{Caller reads a field?}
Access -->|BankAccountNickName| Fetch1[GetBankAccount lookup] --> Nick([Return nickname])
Access -->|BankRoutingNumber| Fetch2[GetBankAccount lookup] --> Decrypt1[DecryptString] --> Routing([Return routing number])
Access -->|BankAccountNumber| Fetch3[GetBankAccount lookup] --> Decrypt2[DecryptString] --> AcctNum([Return account number])
Access -->|MaskedBankAccountNumber| Fetch4[GetBankAccount lookup] --> Masked([Return masked number])
Failure and edge-case behavior¶
- Each of the four field properties calls
clsBankAccount.GetBankAccountindependently and without caching; reading all four properties for the same object issues four separate underlying lookups rather than one, a potential N+1-style performance cost when iterating a large collection.* - The class's
Criteria.CreateSQL/RetrieveSQL/InsertSQL/UpdateSQL/DeleteSQLproperties all throwApplicationException(InvalidSQLProperty)when accessed. SinceclsProviderBankAccountis only ever populated viaLoad()from the collection's inline SQL (never through the standard DataPortal Fetch/BeforeRetrieve/Create/Update/Delete path in normal use),BeforeRetrieve/AfterRetrieveon the individual object and all of these criteria SQL properties are effectively unreachable in the traced code paths.* - Because the
DELETstatus filter is the only exclusion applied, a bank account whose payment authorization has been revoked (see EFT payment location assignment) can still be returned by this query and have its fields resolved normally.*
Related documentation¶
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
Business\SAIF.Business.Provider.PaymentPreference\clsProviderBankAccounts.vb