Skip to content

Add a bank account

Add-a-bank-account submits a single ACH account (checking or savings, business or consumer) to US Bank so it can be referenced by a US Bank user ID in later payment or recurring-authorization calls. There is no local database persistence in this operation — the account itself lives only at US Bank, keyed by the account key returned in the response.

Field Value
Operation ID OP-EPAY-02
Trigger Caller invokes USBankAPIs.AddBankAccount(inBankAccount, inUSBankUser, inIsPolicyVoluntary)
Inputs IBankAccount (encrypted account number, encrypted routing number, nickname, business/consumer flag, checking/savings flag); IUSBankUser (US Bank user sequence number); policy voluntary/assigned-risk flag
Outputs AddBankAccountResults carrying a success flag and, on success, the US Bank-assigned account key
Primary components USBankAPIs.AddBankAccount, USBankAPIs.GetFilledUSBankBankAccountInfo, USBankAPIs.GetFilledAddBankAccountRequest
Entry point Business\SAIF.Business.EPay.USBank\USBankAPIs.vb

Steps

  1. Classify the account category. GetFilledUSBankBankAccountInfo sets accountCategory to Business or Consumer based on inBankAccount.IsBusiness/IsConsumer (BR-012).
  2. If neither flag is true: throw ApplicationException("Bank account must be business or consumer").
  3. Decrypt and normalize the account number. SAIF.Security.clsSecureEncrypt.DecryptString decrypts the stored account number, and spaces are stripped from the result.
  4. Classify the account type. accountType is set to Checking or Savings based on inBankAccount.IsChecking/IsSavings (BR-012).
  5. If neither flag is true: throw ApplicationException("Bank account must be checking or savings").
  6. Decrypt the routing number. The bank routing number is decrypted the same way as the account number.
  7. Normalize the nickname. The nickname has invalid characters stripped (RemoveInvalidUSBankAccountNickNameCharacters) and is truncated to 20 characters (BR-011).
  8. Build the add-account request. GetFilledAddBankAccountRequest wraps the normalized bank account, resolves the biller credential from the voluntary/assigned-risk flag, and sets the request's userID to the US Bank user's sequence number as a string.
  9. Call the SOAP client. AddBankAccount is invoked on the epayWebServiceService client obtained through the SAIF-certificate-authenticated GetWebService() helper.
  10. On a transport-level failure (exception): wrap and re-throw as an ApplicationException.
  11. Interpret the response code. If the response code is non-zero:
  12. If the code is 75 or 5025 (duplicate account): return AddBankAccountResults(False, String.Empty) — a handled, non-exceptional outcome (BR-013).
  13. Otherwise: concatenate all response messages and throw an ApplicationException.
  14. Return the success result. If the response code is zero, return AddBankAccountResults(True, AddBAResponse.accountKey).

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([AddBankAccount bankAccount, usBankUser, isVoluntary]) --> Category{Business or consumer?}
    Category -->|Neither| ErrCat([Throw: must be business or consumer])
    Category -->|One set| Decrypt[Decrypt account number and routing number]
    Decrypt --> Type{Checking or savings?}
    Type -->|Neither| ErrType([Throw: must be checking or savings])
    Type -->|One set| Nick[Normalize and shorten nickname]
    Nick --> Call[Call AddBankAccount SOAP operation]
    Call --> Code{Response code}
    Code -->|0| Success([Return Success = True, AccountKey])
    Code -->|75 or 5025| Dup([Return Success = False,<br>empty AccountKey])
    Code -->|Other non-zero| Fail([Throw ApplicationException<br>with response message])

Failure and edge-case behavior

  • Missing or ambiguous account category/type throws before any network call is made, so malformed metadata never reaches US Bank (BR-012).
  • Duplicate-account response codes (75, 5025) are the only response codes translated into a handled failure result; every other non-zero code is treated as an exceptional failure (BR-013).
  • The account number and routing number must already be encrypted with the SAIF encryption utility before this operation runs; decryption failure surfaces as whatever exception clsSecureEncrypt.DecryptString raises, uncaught by this method.*
  • There is no local persistence of the returned account key by this operation; callers are responsible for storing it if it needs to be reused.*

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.EPay.USBank\USBankAPIs.vb