Skip to content
Last updated

Bank selection

GET /v2/banks is now available for Bank selection.

Token.io continues to support the existing GET /banks endpoint. If you're using Payments v1, please refer to Bank selection using the GET /banks endpoint.

Guidance for GET /v2/banks is presented in this section.

Once you have successfully activated your Token.io user account, you are ready to start integrating our API. Before initiating a request to a Token.io-connected bank you'll need to get the list of banks in the desired country that support the features you need to access — or, more specifically, the features your user is requesting, presuming the user is an authorized account holder with a Token.io-connected bank. The GET /v2/banks call filters the list of Token.io-connected banks based on your selection criteria with respect to bank location and bank-supported features.

See Base URLs and Common Request Headers for more information on structuring the GET /v2/banks request.

In the GET /v2/banks request, there are numerous filters you can add as criteria you can configure to narrow your query. Field descriptions and usage are shown in the API definition. You can request a list of all banks available to users in a specific country or countries supporting particular features. Then, upon identifying the bank(s) meeting your criteria, you can display the result for user selection. If no matches are found, you can display that result to the user as well.

In response to a successful request — for example, GET /v2/banks?ids = ob-iron — the payload returned in the response will take this format:

Sample Response to GET /v2/banks?ids = ob-iron

{
"banks": [
    {
     "id": "ob-iron", // bank's Token identifier
     "bic": "HLFXESMMXXX", // bank's BIC code
     "name": "Iron Bank", // bank's name
     "logoUri": "https://example.com/path/full.png", // URI of bank's avatar icon
     "bankGroup": "xyz-bank-group", // bank's group
     "countries": ["FR","DE"],
     "openBankingStandard": ["UK_Open_Banking_Standard"],
     "credentialFields": [   // if populated, required as part of initial authorization at bank
           {
            "description": "User authentication",
            "displayName": "Client ID",
            "flickerCode": "FLICKERCODE",
            "id": "clientId",
            "image": "YWJAeXoyWhAeXohteQ",
            "options": ["SMS", "Phone Call"],
            "type": "PASSWORD"
     }],
     "mandatory-fields": [ //populated request fields required by this bank
           {
            "products": [ ]
            "fieldPaths": [ ]
            "paymentTypes": [ ]
            "localInstruments": [ ]
         }
     "fieldsFormatInformation": [{ // bank-dependent formats indicating allowable characters
               "constraint": "^[A-Za-z0-9?:().\\/,\\u0027+\\-\\s]*$" // regex indicating allowable characters
               "name": "field name", // name of the field
               "path": "path", // field location in request payload
     }],
     "supportedLocalInstruments": ["SEPA_INSTANT", "FASTER_PAYMENTS", "SEPA"]
     "operationalTime": "MON to FRI, 00:00 to 24:00 GMT+1"
     "transactionHistoryLimit": 65,
     "supportsAccountList": true,
     "supportsAccountDetails": true,
     "supportsAccountBalance": true,
     "supportsTransactionList": true,
     "supportsTransactionDetails": true,
     "supportsStandingOrderList": true,
     "supportsTransactionDateFilter": true,
     "requiresOneStepPayment" : false.
     "supportsSinglePayment": true,
     "supportsScheduledPayment": true,
     "supportsStandingOrder": true,
     "supportsReturnRefundAccount": true,
     "supportsReturnRefundAccountHolderName": true,
     "supportsFundsConfirmation": true,
     "supportsVariableRecurringPayment": true,
     "supportsApptoAppOnIos": true,
     "supportsApptoApponAndroid": false,
   }],
   "paging": {
        "page": 15,
         "pageCount": 80
         "perPage": 32,
         "totalCount": 2500
    }
}

in GET v2/banks, when a bank name has a special character, it requires JSON parsing to display correctly.

For example, in the name "Caja Rural de L'alcudia" the apostrophe should be parsed with "\u0027" as the unicode character ': "Caja Rural de L\u0027alcudia" .

Mandatory fields are bank-dependent and are handled on a bank-by-bank basis, as discussed below.

Search and sort

You can optionally perform additional internal filtering on the result set returned by Token.io before displaying the results to the user for final selection. When retrieving the list of banks for which search text is provided in a GET /v2/banks?field=search-string call, an alphabetical sort, 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.

Mandatory fields

Some banks require the TPP to provide certain fields in the payment initiation request. These are referred to as Mandatory fields. The Mandatory fields are captured in the mandatoryFields object in the banks object within the GET /v2/banks response from Token.io. The mandatoryFields object contains the fields which must be populated by the TPP for the given bank to accept a payment initiation request, or request for 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 that are required for all banks (e.g., refId) or which are always optional (e.g., description) are not part of mandatoryFields.

The mandatoryFields object specifies products (e.g., SIP, FDP, VRP), fieldPaths (e.g., initiation.debtor), paymentTypes (e.g., DOMESTIC or INTERNATIONAL) and localInstruments (e.g., SEPA, FASTER_PAYMENTS, BANKGIRO).

For paymentTypes:

  • DOMESTIC – the payer (debtor) and the payee (creditor) country are the same

  • INTERNATIONAL – the payer (debtor) and the payee (creditor) country are different.

If mandatory fields are required, they must be sent as part of the POST /v2/payments request.

After accepting consent from the user, the TPP can check whether the bank selected by the user requires mandatory fields and request them from the user.

Mandatory field information can be retrieved using the GET /v2/Banks call.

This part of the payment flow is conducted between the TPP and the user.

  1. TPP - The TPP checks whether the selected bank requires mandatory fields from the user.

  2. TPP -> User - The TPP requests mandatory fields from the user.

  3. User -> TPP - The user provides mandatory fields to the TPP.

When added within the bank object, a particular bank's mandatoryFields might be populated like this:

"mandatoryFields": [
    {
        "products": ["SIP"],
        "fieldPaths": ["initiation.debtor"],
        "paymentTypes":["DOMESTIC"]
        "localInstruments":["FASTER_PAYMENTS"]
    },
    {
        "products": ["SIP"],
        "fieldPaths": [
            "initiation.debtor",
            "initiation.creditor.address.country",
            "initiation.creditor.address.town_name",
            "initiation.creditor.address.post_code",
            "initiation.creditor.address.street_name",
            "initiation.creditor.address.building_number"
        ],
        "paymentTypes":["INTERNATIONAL"]
        "localInstruments":["SEPA"]
    }
]

If mandatoryFields are required for a bank in GET /v2/banks, you must provide these fields within the initiation request.
If the field is not provided by the TPP, then either Token.io or the bank may return an error as a result of the missing field.

Debtor account validation

The requirement to specify the debtor account for a transfer is bank-dependent. When required, the TPP needs to include the user’s bank account from which the payment amount is being debited in the initiation.debtor object. The type of account identifier and required fields depend on the payment rail:

Account TypeField name
SEPAiban
SEPA Instantiban
UK DomesticaccountNumber and sortCode
EU Domestic Non Euroiban (IBAN Accounts) or bban (BBAN or Clearing Accounts)
EU Domestic Non Euro Instantiban
Elixir in Polandiban (IBAN Accounts) or accountNumber (Polish domestic accounts)
Bankgiro payments in SwedenbankgiroNumber
PlusGiro payments in SwedenplusgiroNumber

#9## 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, in which name identifies the field and path is its location (in relation to object.field) within the requestPayload:

"fieldsFormatInformation": [{ // bank-dependent formats indicating allowable characters
    "constraint": "^[A-Za-z0-9?:()./,\u0027+\\-\\s]*$"// regex indicating allowable characters
    "name": "description", // name of the field
    "path": "description", // field location in token request payload
}],

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, plus sign, minus sign, and a space. 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.

Authentication: how do I identify the correct model?

Banks support different authentication models:

  • Redirect – the user connects with the TPP but is redirected to the bank's web interface for authentication.

  • Embedded – the payment process is executed entirely through the UI presented by the TPP.

  • Decoupled – the user authenticates using an external form of identification, for example, the bank's dedicated mobile app.

See Authentication for a more detailed description of the authentication models.

Use the GET /v2/banks call to determine which authentication model is required. If the bank supports embedded and decoupled authentication, additional credentials will be available in the credentialFields field.

Maintenance of bank information

We recommend that you maintain bank information regularly, by caching daily at 11pm UTC.

Use the GET /v2/banks call to retrieve bank information.

If you have any feedback about the developer documentation, please contact devdocs@token.io