Org Web Adapter

pages/mmpy_70_api_for_routing_confirmation.org

ID
741771f4-b78c-4abf-a587-4a1ebfebca04

MMPY-70 API for routing confirmation

- source :: https://multimediallc.atlassian.net/browse/MMPY-70

- tags :: Falcon Nest Project Story Falcon Nest Project

- epic :: MMPY-225 ACH Account Creator Interface

- sprint :: MM Sprint 26

- status :: Status - Complete

Background

When collecting Direct Deposit fields, we want to ensure that there aren’t errors. Many services offer ACH routing number validation and we should incorporate that into our work.

Requirements

DONE See how far Claude can get us with a new app

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
6ee9737b-af86-7a57-37c9-003bad922e78

DONE Tweak data model from Claude and test interface

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
ce6da97a-1a14-04d6-8290-df5ad096171e

DONE Add a proper LN client to implementation

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
ed00c4a0-e152-8985-1f78-325b12cf96b5

Turns out we need to a user/pass auth flow to get a time-limited token to make

requests. So probably, we should have a proper client that exposes methods for

things like `authenticate` and `validate` that do the network-y stuff of

hitting the endpoints. The model can then just call the:

#+begin_src python

ln_client = LexisNexisClient(user, pass)

response = ln_client.validate("country_code", "routing_number")

#+end_src

And so forth.

DONE Add tests for new client and models

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
2aa355c0-9bfb-0696-643a-ca849bec13ab

DONE Restructure API calls to be all bank info through one

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
28b99b5f-ed01-c3c5-51e2-f2ad20ca4ed9

DONE Add tests for new client and models

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
74461159-c866-193f-3164-1df95f985c66

DONE Fix linting issues

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
c971458e-5110-f9f8-bd87-9bbcf4f0ce5c

DONE Fix PR issues

multimediallcmmpy70mmpy225falconnestsprint26accountsbankachfeaturework
ID
c5d28f99-be78-5913-8071-ab1ba17617b8

GIVEN

A routing number is submitted for check

WHEN

the routing number passes basic validation for 9-char length and digit-only characters

THEN

Look up the routing number at lexis nexis https://beta.validate.bankersalmanac.com/validateweb/result and return the bank name if a bank is found

Example

https://api.validate.bankersalmanac.com/swagger-ui/index.html#/

Use the validation endpoint and provide the following two data points

{

"countryCode": "<2char iso>",

"nationalId": "<routing>"

}

If the recommendedNatId returns something other than the nationalId passed, update the recommendedNatId in the interface.

If the status is not PASS return an error to the interface: “The routing number provided is not valid. Please check the number and enter it again”. This will show in the UI in MMPY-69

Display the Branch Details Name & Address in the bank information box in the UI. This will show in the UI in MMPY-69

Example response:

{

"countryCode": "US",

"nationalId": "036001808",

"accountNumber": "",

"status": "PASS",

"comment": "Account number not entered (08an)",

"recommendedNatId": "036001808",

"recommendedAcct": "",

"recommendedBIC": "NRTHUS33XXX",

"ref": "20251105172818586",

"group": "",

"branchDetails": [

{

"bankName": "TD Bank National Association",

"branch": "19th and Tilghman",

"street": "1828 W Tilghman Street",

"city": "Allentown",

"postZip": "18104",

"region": "Pennsylvania",

"country": "UNITED STATES",

"codeDetails": {

"codeName1": "BIC",

"codeValue1": "",

"codeName2": "CHIPS",

"codeValue2": "",

"codeName3": "BIC-4",

"codeValue3": "",

"codeName4": "ABA",

"codeValue4": "036001808"

},

"sepaDetails": {

"ctStatus": "NO",

"ddStatus": "NO",

"bbStatus": "NO"

},

"additionalData": {

"ssiAvailable": "Y",

"payServiceAvailable": "Y",

"contactsAvailable": "N",

"messageAvailable": "Y",

"holidayAvailable": "Y"

},

"bankToken": ""freeToken": "<token>",

"sanctionsDetails": {

"euSanctions": "N",

"hmtSanctions": "N",

"ofacSanctions": "N",

"unSanctions": "N"

}

}

],

"headOfficeDetails": {

"bankName": "TD Bank National Association",

"branch": "",

"street": "2035 Limestone Rd",

"city": "Wilmington",

"postZip": "19808",

"region": "Delaware",

"country": "UNITED STATES",

"codeDetails": {

"codeName1": "BIC",

"codeValue1": "NRTHUS33XXX",

"codeName2": "CHIPS",

"codeValue2": "",

"codeName3": "BIC-4",

"codeValue3": "NRTH",

"codeName4": "ABA",

"codeValue4": "031101266"

},

"additionalData": {

"ssiAvailable": "Y",

"payServiceAvailable": "Y",

"contactsAvailable": "N",

"messageAvailable": "Y",

"holidayAvailable": "Y"

},

"sanctionsDetails": {

"euSanctions": "N",

"hmtSanctions": "N",

"ofacSanctions": "N",

"unSanctions": "N"

}

},

"paymentBicDetails": {

"branchTypeLabel": "Payment BIC Branch",

"bankName": "TD Bank National Association",

"branch": "",

"street": "2035 Limestone Rd",

"city": "Wilmington",

"postZip": "19808",

"region": "Delaware",

"country": "UNITED STATES",

"codeDetails": {

"codeName1": "BIC",

"codeValue1": "NRTHUS33XXX",

"codeName2": "CHIPS",

"codeValue2": "",

"codeName3": "BIC-4",

"codeValue3": "NRTH",

"codeName4": "ABA",

"codeValue4": "031101266"

},

"additionalData": {

"ssiAvailable": "Y",

"payServiceAvailable": "Y",

"contactsAvailable": "N",

"messageAvailable": "Y",

"holidayAvailable": "Y"

},

"sanctionsDetails": {

"euSanctions": "N",

"hmtSanctions": "N",

"ofacSanctions": "N",

"unSanctions": "N"

}

},

"bic8": "N",

"dataStore": "N",

"noBranch": "N",

"payBranchType": "D",

"freeToken": "<token>"

}

Validation takes a username and password, then provides a short-lived (30 mins?) token.

The Lexis Nexis validation endpoint is a little expensive, so we should cache routing information for a year, as it does not change frequently.