Bank Selection using GET /banks v1
After you successfully register with Token.io as a TPP, you're ready to get started with API integration.
Base URLs
See Base URLs.
Headers
Selection Criteria
As you'll find in the Dashboard's Swagger reference, there are numerous filtering criteria you can configure to narrow your query. You can request a list of all banks supporting requested features or all banks in a specified country or countries supporting requested features. Then, upon identifying the bank or banks meeting your service request criteria, you can display the results for user selection. Obviously, if no matches are found, you can display that result to the user, as well, in accordance with your particular UI conventions.
Hence, in response to a successful request — for example, GET /banks?ids=gold — the payload returned in the response will take these forms:
{
"banks"
: [
{
"bankGroup"
: "xyz-bank-group"
,
"bic"
: "HLFXESMMXXX"
, // bank's BIC code
"countries"
: ["FR","DE"
],
"credentialFields"
: [ // if populated, user creds to be captured by TPP prior to request initiation
{
"description"
: "User authentication"
,
"displayName"
: "Client ID"
,
"id"
: "clientId"
,
"options"
: ["SMS"
, "Phone Call"
],
"password"
: true
//v1 only
}],
"id"
: "gold"
, // Token bankId
"name"
: "Gold Bank"
,
"logoUri"
: "https://s3-us-west-2.amazonaws.com/tokenio-assets/1.0.0/logos/gold/gold_square.png"
,
"fullLogoUri"
: "https://s3-us-west-2.amazonaws.com/tokenio-assets/1.0.0/logos/gold/gold_full.png"
,
"fieldsFormatInformation"
: [{ // bank-dependent formats indicating allowable characters
"name"
: "field name"
, // name of the field
"path"
: "path"
, // field location in request payload
"constraint"
: "^[A-Za-z0-9?:().\/,\u0027+\-\s]*$"
// regex indicating allowable characters
}],
"mandatory-fields"
: {
//populated request fields required by this bank
"pis"
{
// object.field names are bank-defined
"debtor-account"
: true
"debtor-name"
: true
"beneficiary-name"
: true
}
"supportsInformation"
: true
,
"requiresOneStepPayment
: false
.
"supportsSendPayment"
: true
,
"supportsFundsConfirmation"
: true
,
"provider"
: "Token"
,
"supportsScheduledPayment"
: true
,
"supportsStandingOrder"
: true
,
"supportsTransactionsDateFilter"
: false
,
"supportsReturnRefundAccount"
: true
,
"supportedTransferDestinationTypes"
: ["BIC"
, "FASTER_PAYMENTS"
, "SEPA"
]
"transactionHistoryLimit"
: -1
,
}],
"paging": {
"page": 1,
"perPage": 200,
"pageCount": 1
}
}
You can add query parameters to filter the results of your GET /banks request. Field descriptions and usage as a query parameter are listed in the following table.
Field | Description | Search-Filtering Example Values / Usage |
---|---|---|
bankGroup | Group name if the bank is part of a group |
|
bic* | Bank Identification Code. The BIC is composed of a 4-character bank code, a 2-character country code, a 2-character location code and an optional 3-character branch code. Length can be 8 or 11 characters | Usage: GET /banks?bics=DEUTITMMXXX&bics=BKTRGB2L example fetches Deutsche Bank S.P.A. – Milano and |
countries | ISO 3166-1 Alpha 2 country code in upper case; only banks located in these countries are returned | Usage: GET /banks?countries=FR&countries=GB |
credentialFields | Fields required as part of initial authorization at the bank | Usage: Bank-dependent |
id* | Token's unique bank identifier |
Usage: GET /banks?ids=ob-barclays&ids=ob-lloyds |
fieldsFormatInformation | Contains bank-imposed formatting restrictions, especially regarding the use of special characters | name
of the field path in response constraint ( indicating allowable characters) |
logoUri | URL for the bank's approved logo | |
mandatoryFields | Specific fields required by this particular bank for the request to be successful | See Mandatory Fields |
memberId | Member ID associated with a list of banks configured with the member's licence; returns only banks configured with the member's licence | Usage: GET /banks?memberId=m:213xyzabc3453434 |
name* | Name of the bank (e.g., "First National Bank") | Usage: GET /banks?search=buda example returns all banks with names beginning with "buda" plus all banks with a BIC string beginning with "buda" |
openBankingStandard | API standard adopted/supported by the bank |
Usage: GET /banks?openBankingStandard=polishAPI |
provider | Open Banking SaaS adapter or provider (e.g.,Token, FinApi) |
|
transactionHistoryLimit | If -1, the transaction history records limit per page is unlimited. A positive integer limits the number of records per page to the specified integer. | Usage: GET /banks?transactionHistoryLimit=-1 |
supports_variable_recurring_payment | If set to true, only banks that support variable recurring payments are in the response. | Usage: GET /banks?bank_features.supports_variable_recurring_payment.value=true |
Bank-supported Features | ||
requiresOneStepPayment | If set to true, bank requires 1-step payment flow. Set to false, bank supports 2-step payment. See Transmitting user Consent for additional details. | Usage: GET /banks?countries=FR&countries=GB&bank_features.requires_one_step_payment.value=true |
supportsGetConsent | If true, bank supports retrieval of consent object. Necessary only for TPPs supporting AIS using their own licence. Only CMA9 banks in the UK currently support this feature. | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supportsGetConsent.value=true |
supportsFundsConfirmation | If set to true, supports confirmation of available funds | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_funds_confirmation.value=true |
supportsInformation | If set to true, AIS is supported | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_information.value=true |
supportsScheduledPayment | If set to true, bank supports future-dated payments | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_schedule_payment.value=true |
supportsSendPayment | If set to true, single immediate payment is supported | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_send_payment.value=true |
supportsStandingOrder | If set to true, bank supports standing order for recurring payment | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_standing_order.value=true |
supportsTransactionsDateFilter | If set to true, supports filtering transactions by date range | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_transactions_date_filter.value=true |
supportsReturnRefundAccount | If true, bank supports returning of debtor account information | Usage: GET /banks?countries=FR&countries=GB&bank_ features.supports_return_refund_account.value=true |
transactionHistoryLimit | If -1, the transaction history records limit per page is unlimited. A positive integer limits the number of records allowed. | Usage: GET /banks?transactionHistoryLimit=-1 |
* The search parameter works to find partial string matches for name and bics. Using bics or ids as the query parameter will return exact (full string) matches only. Each bics parameter must have a string length of 8 or 11. Using a different length for a bics query will throw an error.
You can use bics and ids as query parameters multiple times, up to 1000. However, please note that the BIC for some banks may not yet have been updated in the system. Your best strategy is to combine search=full/partial bank name and/or another query parameter with your bics query for more robust filtering.
Mandatory fields are entirely bank-dependent and must therefore be handled on a bank-by-bank basis, as discussed next.
Mandatory Fields
A mandatoryFields object is a property for a specific bank included in the banks object within a GET /banks response from Token (see example above). It describes those fields which must be populated for the given bank when initiating payment or requesting account access. Only fields specifically required by the source bank, rather than fields more broadly required by all banks, will appear in mandatoryFields. Consequently, fields required for all banks (e.g., refId) or which are always optional (e.g., description) are not part of mandatoryFields.
As applicable, the mandatoryFields object is organized by service (e.g., pis, ais) and “instrument” (e.g., transfer, standingOrder, and so forth.). Each payment instrument is further organized according to the bank-adopted API standard — NextGenPSD2, PolishAPI, STET or CMA9 — for domestic and international transfers to create the following general structure:
When added within the bank object in the response example above, a particular bank's mandatoryFields might be populated like this:
: {
"transfer"
: {
"domestic"
: {
"fields"
: [
"transfer_body.instructions.transfer_destinations.customer_data.legal_names",
"transfer_body.instructions.source.bic",
"transfer_body.instructions.source.account_identifier"
],
"stetFields"
: [
"transfer_body.instructions.metadata.provider_transfer_metadata.stet_transfer_
metadata.beneficiary.creditor_agent"
],
"polishApiFields"
: [
"transfer_body.instructions.metadata.provider_transfer_metadata.polish_api_
transfer_metadata.delivery_mode"
]
},
"international"
{
"fields"
: ["transfer_body.instructions.transfer_destinations.customer_data.legal_names"],
"stet_fields"
: [
"transfer_body.instructions.metadata.provider_transfer_metadata.stet_transfer_
metadata.beneficiary.creditor_agent"
]}
},
"standing_order"
{
"domestic"
{
"fields"
: ["standing_order_body.instructions.transfer_destinations.customer_data.legal_names"]
"stet_fields"
: ["standing_order_body.instructions.metadata.provider_standing_order_
metadata.stet_standing_order_metadata.beneficiary.creditor_agent"]
},
"international"
{
"fields"
: ["standing_order_body.instructions.transfer_destinations.customer_data.legal_names"]
"stet_fields"
: ["standing_order_body.instructions.metadata.provider_standing_order_metadata
.stet_standing_order_metadata.beneficiary.creditor_agent"]
}
}
}
Heads up: mandatoryFields for a provider bank within the GET /banks response are specific to that bank and are required in token requests to that bank for the given instrument. Be sure to populate all bank-specific mandatoryFields in your token request or the request will be rejected.
See List of Possible Mandatory Fields for the complete list.
Mapping mandatoryFields from a GET /banks Response to Payment Request Fields
Certain mandatoryFields will need to be provided by the user, whilst others must be provided by the TPP. If the TPP uses the Token Web App, mandatoryFields not included in the token request will be captured from the user by the Web App. If the Web App is not used for showing initial consent, the TPP must ensure that bank-specific mandatoryFields are included in the token request when initiating a payment to the given bank.
Hence, if a user’s account is on the debtor side, the debtor name and debtor account details need to be captured from the user. If the beneficiary in the transaction is the TPP, the TPP should specify its account information on the creditor (beneficiary) side.
The following table lists the mapping from the respective mandatory field in the bank's GET /banks response call to the expected information required in a subsequent transfer request:
Mandatory Field | Maps to Info in Transfer Request | When Web App Used | When Web App NOT Used |
---|---|---|---|
transfer_body.instructions. source.customer_data.legal_names |
Debtor/Payer Name | TPP must provide only if TPP is the payer | TPP must provide; if TPP is not the payer, TPP must capture this information from the payer |
transfer_body.instructions. source.account_identifier |
Debtor Account Number | TPP must provide only if TPP is the payer | TPP must provide; if TPP is not the payer, TPP must capture this information from the payer |
transfer_body.instructions. source.bic |
Debtor BIC | TPP must provide only if TPP is the payer | TPP must provide; if TPP is not the payer, TPP must capture this information from the payer |
transfer_body.instructions. transfer_destinations.customer_data.legal_names |
Creditor/Beneficiary Name | TPP must provide only if TPP is the transaction beneficiary (payee) | TPP must provide; if TPP is not the payer, TPP must capture this information from the payer |
transfer_body.instructions. transfer_destinations.account_identifier |
Creditor Account Number | TPP must provide; if TPP is not the payee, TPP must capture this information from the payee | TPP must provide; if TPP is not the payee, TPP must capture this information from the payee |
transfer_body.instructions. transfer_destinations.bic |
Creditor BIC | TPP must provide; if TPP is not the payee, TPP must capture this information from the payee | TPP must provide; if TPP is not the payee, TPP must capture this information from the payee |
transfer_body.instructions.metadata. provider_transfer_metadata. stet_transfer_metadata.beneficiary.creditor_agent |
Creditor Agent information; required by STET-based banks | TPP must provide only if TPP is the transaction beneficiary (payee) | TPP must provide; if TPP is not the payee, TPP must capture this information from the beneficiary |
transfer_body.instructions.metadata. provider_transfer_metadata. stet_transfer_metadata.payment_type_information |
Payment Type Information; required by STET-based banks | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. stet_transfer_metadata.debtor_agent |
Debtor Agent Information; required by STET-based banks | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. stet_transfer_metadata.end_to_end_id |
End-to-end identifier; required by STET-based banks | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. stet_transfer_metadata.execution_rule |
Execution Rule; required by STET-based banks | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. polish_api_transfer_metadata.delivery_mode |
Delivery Mode; PolishApi-based banks only, where applicable | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. polish_api_transfer_metadata.hold |
Hold; PolishApi-based banks only, where applicable | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. next_gen_psd2_metadata.end_to_end_identification |
End-to-end identifier; NextGenPsd2-based banks only | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. next_gen_psd2_metadata.remittance_information_structured |
Remittance Information Structured; NextGenPsd2-based banks only | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. next_gen_psd2_ metadata.creditor_agent |
Creditor Agent information; NextGenPsd2-based banks only | TPP must provide only if TPP is the transaction beneficiary (payee) | TPP must provide; if TPP is not the payee, TPP must capture this information from the payee |
transfer_body.instructions.metadata. provider_transfer_metadata. next_gen_psd2_ metadata.creditor_agent_name |
Creditor Agent Name; NextGenPsd2-based banks only | TPP must provide only if TPP is the transaction beneficiary (payee) | TPP must provide; if TPP is not the payee, TPP must capture this information from the payee |
transfer_body.instructions.metadata. provider_transfer_metadata. cma9_transfer_ metadata.instruction_identification |
Instruction Identification; OBIE-based banks only | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. cma9_transfer_metadata.end_to_end_identification |
End-to-end identifier; OBIE-based banks only | TPP must provide | TPP must provide |
transfer_body.instructions.metadata. provider_transfer_metadata. cma9_transfer_metadata.risk |
Risk information; OBIE-based banks only | TPP must provide | TPP must provide |
Payment Initiation Flow with mandatoryFields using Token Web App
If you're using the Token Web App, the recommended PIS flow with mandatoryFields looks like this (click to enlarge):
For more on 1-step payment versus 2-step, see Transmitting user consent, as well as each supported payment type (Single Immediate, Future-dated, or Standing Order).
Payment Initiation Flow with mandatoryFields without using Token Web App
If you're using your own licence but you're not using the Token Web App, the recommended PIS flow with mandatoryFields looks like this:
- TPP ®Token: GET /banks to retrieve the bank details for a particular bank
- TPP ® Token: POST /token-requests with mandatory fields populated.
- Token ® TPP: Return token_request_id
- TPP ® Token: POST /token-requests/{token_request_id}/authorization - Pass in the credential fields required
- Bank ® TPP: If more credential fields are required, send additional credential fields required, else return redirect url
- TPP ® Bank: Capture fields from user if more credential fields are required and send to bank. If not, redirect user to bank
- Bank ® TPP: Send consent_id
- Token ® TPP: Returns token_id and transfer_id if available (1-step flow)
- TPP ® Token: POST /transfers (2-step only)
- Token ® TPP: Return transfer_id (2-step only)
- TPP ® Token: GET /transfers/{transfer_id}
Again, see Transmitting user consent, as well as each supported payment type (Single Immediate, Future-dated, or Standing Order) for more on 1-step payment versus 2-step.
Heads up: If the bank requires the TPP to provide user credentials for initial authentication of a token request as defined in the credentialFields object of the GET /banks response, you will need to prompt your user to provide this information prior to redirect.
Search and Sort
With the filtered information in hand (i.e., available within your processing environment), you can optionally perform additional internal filtering before displaying the results to the user for final selection. However, when retrieving the list of banks for which search text is provided in a GET /banks?field=search-string call, an alphabetical sort of search results, if specified in the call, is applied to the search results before they are returned to the caller. This makes applying additional sort criteria to the search results returned redundant and therefore unnecessary.
authorization Models
When users are redirected to a bank to authorize a payment or authorize access to their account(s), they are typically asked to login before proceeding to accept or decline consent for the TPP's AIS or PIS request. Certain banks, however, expect the TPP to capture this information from the user before the user is redirected to the bank. In some cases, this interaction can be a series of steps, with each succeeding step dependent on the value entered by the user in the previous step. For example, depending on the value input for username and password, the user might need to complete further authentication on their mobile device or enter another PIN already in the user's possession.
For user-selected banks requiring the capture of authentication information prior to redirection to the bank for consent, the TPP is furnished with the initial user credentials in the response to its GET /banks call. A user ID is typically required as the first step in the credentials exchange. Should the bank require additional user verification, the respective fields are made available to the TPP (in the background) so it can capture the additional information from the user. The TPP then sends the captured fields back to the bank (through Token, again in the background). Iterations of this exchange continue to occur until all necessary steps to complete user authentication at the bank are complete; at which point the user is taken to the bank's consent page.
Bank-dependent Field Formatting
The bank's response may include a fieldsFormatInformation object array describing specific formatting constraints imposed by the bank. This typically involves which special characters are allowed, if any, and/or other formats, such as all caps, allowable numerals, etc.
The response syntax for fieldsFormatInformation will look something like this (see sample response for placement), in which name identifies the field and path is its location vis-à-vis object.field) within the requestPayload:
"fieldsFormatInformation"
: [{ // bank-dependent formats indicating allowable characters
"name"
: "description"
, // name of the field
"path"
: "description"
, // field location in token request payload
"constraint"
: "^[A-Za-z0-9?:().\/,\u0027+\-\s]*$"
// regex indicating allowable characters
}],
In the example above, the constraint field limits what can be included in the field specified by name; in this case, description in the token requestPayload for the given bank, which allows A through Z, a through z, 0 through 9, question mark, colon, open parenthesis, close parenthesis, period, forward slash, comma, single quotation mark, plus sign, back slash, and s. All other characters or character codes are disallowed and, if included in the description field of a request submitted to this particular bank, an exception will be thrown.
See https://regexr.com/3cr6f to conveniently translate specific expressions, when necessary. See also the example request in Single Immediate Payment for the placement of description in the token request and/or the swagger definition for the POST /token-requests endpoint.
Call Variants
Variants on the GET /banks call include:
- GET /banks/countries – to get the list of countries in which Token-connected banks are located
- GET /banks/{bankId}/info – to get bank information for a specific Token-connected bank
- GET /banks/{bankId}/token-requests/{tokenRequestId}/url – to get the authorization URL of a specific Token-connected bank. Prerequisite is a successful token request that produces a valid tokenRequestId.
Upon user selection of a bank, the corresponding service flows listed next can be appropriately implemented.