Skip to content
Last updated

Bank selection

Once you've successfully activated your Token.io user account, you're 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 /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 /banks request.

In the GET /banks request, there are numerous filtering criteria you can add as parameters 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 results for user selection. If no matches are found, you can display that result to the user, as well.

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

APIv1 Sample Response to GET {{BASE_URL}}/banks?ids=iron

{
"banks": [
    {
     "bankGroup": "xyz-bank-group",
     "bic": "HLFXESMMXXX", // bank's BIC code
     "countries": ["FR","DE"],
     "credentialFields": [   // if populated, user credentials 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": "ob-iron", // Token.io bankId
     "name": "Iron Bank",
     "logoUri": "https://s3-us-west-2.amazonaws.com/tokenio-assets/1.0.0/logos/iron/iron_square.png",
     "fullLogoUri": "https://s3-us-west-2.amazonaws.com/tokenio-assets/1.0.0/logos/iron/iron_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
    }
}

in GET /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 /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 unnecessary.

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 /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.

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:

For transfer:

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

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

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

"mandatoryFields": {
    "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"]
       }
    }
}

If mandatoryFields are required for a bank in GET /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 identifiers and required fields depend in 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 (IBAN Accounts) or bban (BBAN or Clearing Accounts)
Elixir in Polandiban (IBAN Accounts) or accountNumber (Polish domestic accounts)
Bankgiro payments in SwedenbankgiroNumber
PlusGiro payments in SwedenplusgiroNumber

In addition to the Token.io platform's bankId and the bank's bic (BIC), the source also contains a customerData object identifying the payer's legalNames and address (see the Token.io API definition for complete object-field specifications).

In accordance with the following rules, Token.io verifies the source in token requests to avoid preventable account identification errors during payment processing:

  1. If a transfer token request has a non-empty source object, it must also have a populated accountIdentifier. Populating customerData.legalNames without identifying the bank account, for example, will throw an InvalidArgument "Missing required field bank_account or account_identifier in source account"error.

  2. If the accountIdentifier object is populated, it must also have a populated identifier type; otherwise, an InvalidArgument "Missing required field<field name>in source account" error will result. Here, field name depends on the identifier type. For most types — bban, iban, msisdn, bankgiro, and plusgiro — only one field is mandatory. However, gbDomestic requires both accountNumber and sortCode.

  3. The bankAccount cases, when supported by the source bank, that cannot be mapped to an accountIdentifier type and are therefore excluded from the source validation check comprise CUSTOM, BANK, GUEST, SWIFT, ACH, TOKEN_AUTHORIZATION, and SECRET.

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, 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 /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 /banks call to retrieve bank information.

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