Purpose
The purpose of Core Connections is the same as OLB aggregation, to provide data to the app so the user can browse their financial data. The way it goes about getting that data is vastly different. The apps in use are:
- API
- Che
- core-fetch
- core-fetch (above) connects to the ServiceGateway at JHA, which then communicates with the bank’s core (either 20/20, Episys, or Silverlake)
core-fetch serves as an abstraction over the various cores. With core-fetch, we don’t have to have projects that communicate with each core individually, we can have the same application communicating with every core. This is useful because there is comparatively less mental overhead for a developer to get into the project and understand how it works. You will note that this is much different from OLB Aggregation because Fetch is not used to log in to the site and scrape data. Instead, core-fetch asks for the data from the ServiceGateway, which retrieves it for us from the core. This is an improvement because any small website change will no longer break our ability to get at the user’s information since we’re just asking for it directly from the bank’s core.
Institution Onboarding
Setting up Postgres Tables
You should follow the Generating a uuid, Adding properties.json to grip-assets, and Inserting a Primary Institution into Postgres sections from the aggregation team’s institution setup page.
Following those postgres rows being setup you should insert the institution’s account types via schema migrations. Don’t worry, these are setup for you and all you need to do is call a function for the necessary type of banking core the institution has:
Adding a new JX Service Gateway Config (Institution Core Connection Config)
See Knowledge
Note: If the FI should be allowed to use ssn based signup (typically only for non-NetTeller FI’s through jXchange) we should flip the allow_ssn_signup boolean to true in their institution_abilities row.
Setting up FIs with NetTeller Cash Management
If an FI has NT Cash Management, you’ll need to insert the goDough config and update connection_config_defaults accordingly.
insert into godough_institution_configs
(institution_id, host, fi_number, shared_secret, created_at)
values
('', --institution_id
'https://aggregation.mobileapi.netteller.com/mobileapi', --goDough prod env host (for all banno envs)
'', --goDough fi_number
'', --goDough prod env shared_secret (for all banno envs)
now());
update connection_config_defaults
set has_netteller_cash_management=true, uses_netteller_for_entitlements=true
where institution_id='';
Setting up Transaction Codes
Each transaction we get from a core banking system has an element called TrnCodeCode on it. The value inside is FI independent and therefore we need to inquire about the monetary vs non-monetary types of transactions they use. (Sometimes there are transactions that are just an adjustment of an interest rate or an annual report.) We insert these codes into the db to be filtered out inside core-fetch.
You can enable the logging of these codes with the following sql query. An aggregation then needs to run to print them out. (Run the sql query with the setting to false once you’ve gotten the needed logs.)
update connection_config_defaults
set log_transaction_codes = true
where institution_id = '<insert-institution-id-here>'
;
Once you have the codes you’ll need to figure out which ones represent “non-monetary” transactions. This is a per-FI set of codes so it’s best to ask them. Once you have them, it’s easy enough to add them into the database. You can check out the smallint codes from the CoreModels.scala file in banno-remote-protocol under the CoreTransactionCodeTypes enumeration.
Codes typically come with a description from the xml. It’s good to add this in the sql, as shown below, so you can see what the bank refers to each code as.
<xsd:element name="TrnCodeCode" type="TrnCodeCode_Type" />
<xsd:element name="TrnCodeDesc" type="TrnCodeDesc_Type" />
insert into core_transaction_codes
('institution_id', 'code', 'description', 'transaction_code_type)
values
('<institution-id>', '<code>', '<description>', 2) -- 1 Stands for 'Other', but 2 represents 'NonMonetary'
;
Setting up Transfer Account Transaction Codes
Each institution has different transfer account transaction codes for each type of account when transferring to a specific type of account (checking, savings, etc…). There is a debit code for the type of account that is being transferred from and a credit code for the type of account that is being transferred to. These codes will need to be given to us by the institution since we do not have access to them in jsource.
To update or insert an institution’s codes, a one-off script can be run.
These codes are used on during the XferAddValidate and XferAdd requests.
The xml elements which these codes are passed are:
<xsd:element name="TrnCodeCode" type="TrnCodeCode_Type" />
<xsd:element name="DrTrnCodeCode" type="TrnCodeCode_Type" />
TrnCodeCode is for the credited account transfer code and DrTrnCodeCode is for the debited account transfer code.
Setting up an institution with Multi Factor Authentication
To set up an institution with the MFA feature, there are a couple of things that need done. The first would be to insert the institution’s MFA config:
insert into multifactorauth_institution_configs values(institution_id, number_of_questions_to_setup, multifactorauth_enabled) ('institution-id', 3, true);
The number_of_questions_to_setup set to three is the default for any institution. Unless the institution explicitly asks to configure the number of questions, this should be the value used for all institutions. If they do ask if they can configure the number of questions, the only amounts that we support are two, three and four.
They will also need the institution ability turned on:
update institution_abilities set mfa_question_edit = true where institution_id = 'institution-id';
Authentication
OOB (Out of Band)
When doing an OOB login, the first step is making a POST request to the /users endpoint on the API. The API will then send a StartCoreCreation event all the way through to core-fetch. core-fetch then sends the ServiceGateway a CustSrch message with the user’s SSN. The ServiceGateway will then return a CustId to core-fetch. core-fetch will then send the ServiceGateway a CustInq. core-fetch will also send a MFAAcctRiskInq message to the ServiceGateway, and the ServiceGateway responds with ColMFAInfo (to signal Che to ask the user for an OOB method). The API will then send a LoginOptionsEncountered to the phone, with options for either Email or SMS messages.
The user will select a login option, and a SelectedLoginOption is sent from the phone all the way through to core-fetch. A TaskEvent is sent to the phone from Che to alert the user to respond with the code they received in the email or SMS message the ServiceGateway sent to the user. Che is aware of the message being sent, but did not cause it to be sent. core-fetch will then expect a response from the ServiceGateway when (or if) the ServiceGateway receives the code sent to the user.
If the response shows the user validated successfully, then either FindAccts or UserCreated is sent back to the phone (depending on whether or not the user had an existing account(s)).
If the response shows the user did not successfully validate, the user will receive a LoginAnswerFailed and the ServiceGateway receives a message from core-fetch that the user failed to validate.
The sequence diagram for Core OOB is below:
