Creating an Access Token Request

Submitting an access token request is pivotal to successfully querying a customer's account information.

The scope of analysis and service supported by the Token.io SDK includes comparing a customer's () accounts and transaction history to a range of financial service options, aggregating data across participating financial institutions and customers to create marketing profiles, and making new transactions and account changes on the PSU's behalf.

Remember, to access Account Details, the value of supports_account_details_api must be true in the Bank object for each bank displayed to the user for selection from the GET /banks payload.

API support for accessing a PSU's account information institutes a communications workflow that ensures all PSD2 mandates for PSU consent and authorization are met. Pictured next (click to enlarge) is the general flow.

First, however, you have to build the token request and store it. At a minimum, it must contain the relevant details for the account you wish to access — bank, grantor (the account holder), your memberId, and the type of information (resources) you want to receive about the account — account list, balances, transactions, and/or transfer destinations — along with a description of why you are requesting the information and your callback URL, so you can redeem the token once it's issued. There are also a number of other, optional, data items you can include for your own tracking and control.

A request-id is generated and returned with the token payload in response to your token request submission. This identifier references the stored TokenRequest and is used to validate the conditions of the request and to verify that these conditions remain unchanged. You must include the request-id in the URL that redirects the customer to Token.io to obtain user authentication and authorization.

Each token request submission has a time limit of 20 minutes. If you do not receive a response within the allotted timeframe, your token request expires and a new request will have to be created and submitted.

Tip: If you know the request-id, you can retrieve the result of any token request — even requests that have expired — with a call to getTokenRequestResult(tokenRequestId). An unauthenticated call can be made within the 20-minute expiration period. It looks like this:

// Get the token request result based on a token's tokenRequestId

TokenRequestResult requestResult = tokenClient.getTokenRequestResultBlocking(tokenRequestId);

You can make an authenticated call to fetch the request result at any time if you are the TPP that created the original token request. The authenticated version of the call looks like this:

// Get the token request result based on a token's tokenRequestId

TokenRequestResult requestResult = member.getTokenRequestResultBlocking(tokenRequestId);

Most importantly, the TPP member creating the TokenRequest must match the TPP member redeeming the token or token redemption will fail and access will be denied.

Building and Storing the Request

All access token requests are created with the selected-language variant of the accessTokenRequestBuilder() method. Once the token request is created, you store it, awaiting a corresponding request-id, which is returned by Token.io in a response payload. In addition to the request-id, the response payload reflects all the information you included in your original request. Equipped with the request-id, you can redeem the token, thereby receiving the requested information regarding the customer's bank account(s).

Even though it's really quite simple and incredibly secure, accuracy remains paramount vis-à-vis making the right calls with the right information at the right time.

So, let's examine the key field definitions for an access token request call.

Tip: Classes, methods and parameters are initially presented in their default Java syntax. Select the corresponding tab — Java, JavaScript or C# in the navigation bar of the first code example in the sequence — to display the correct syntax and field names for the SDK language chosen.

Here's the basic structure of the request.

/**

* Stores an access token request.

*

* @param grantee – Token.io member requesting the access token be created

* @return – a token request-id

*/

public static String storeAccessTokenRequest(Member grantee) {

    // Create token request to be stored

    TokenRequest request = TokenRequest.accessTokenRequestBuilder(ACCOUNTS, BALANCES)

        .setToMemberId(grantee.memberId()) // TPP's member ID

        .setRedirectUrl("https://mytpp.com/callback") // callback URL

        .setFromAlias(Alias.newBuilder()

            .setValue("grantor-alias@token.io") // customer-user alias

            .setType(Alias.Type.EMAIL)

            .build())

        .setBankId("iron") // bank ID

        .setCsrfToken(generateNonce()) // nonce for CSRF check

        // use keys in bank authorization metadata from getBanks() response

        .putAllAuthorizationMetadata(newHashMap<>())

        .build();

 

    return grantee.storeTokenRequestBlocking(request);

}

The key fields comprising an access token request are defined in the following table.

Fields in an Access Token Request
Field Description Required/ Optional
actingAs Party or entity for which the to member is acting as a proxy. See Creating a Token on Behalf of another Party for details on setting the properties for this field. Optional
accountId Account number from which the amount is being debited; set using the AccountIdentifier object, which allows four types of account identifiers:
  • Token, for linked accounts
  • Iban
  • Bban
  • GbDomestic – 8-digit bank account number in the UK

Although setting source with the BankAccount object has been deprecated, it is still supported

Required
accountDetails
accountHolderName Name of the individual listed as owner of the account
accountIdentifiers One of four supported categories of bank and account identification – , , , or
String value representing the bank identification code
providerAccountDetails Specific information regarding the required by the respective Open Banking API standard adopted by the bank:. These include additional ASPSP business identifiers and contact information (address, phone, email, etc.) for:

See the protobuf reference or Swagger spec (under the Model tab) for object and field details.

status Provider-dependent string (ex. "Active", "Inactive", etc.)
type Type of provider account; i.e., CHECKING, SAVINGS, LOAN, CARD, OTHER
Required*
authorizationMetadata Needed to capture additional information from the user for initial authorization by the bank, thereby allowing the user to proceed with providing consent for the initiation request. Maps the key-value pairs from the getBanks() response, where key is the name of the field and value is the value of the field. Required
bankId When specified, indicates you wish to bypass the Token bank selection UI and use your own bank selection UI for the request. See Using the getbanks Method Optional
callBackState TPP-specified string that persists state between request and callback Optional, but recommended
description Description of the payment with the following qualifiers:
  • description in a subsequent call must match description in originating request
  • description omitted in originating request must also be omitted in subsequent calls
  • description omitted in subsequent call will be replaced with refId

This description field maps to description in the bank's consentRequest presented to the user.

Warning: If description in a subsequent token request for lookups/changes/updates (retrieve, redeem, or cancel) doesn't match the description in the originating token request, an exception will be thrown.

Optional
grantee "To" TPP member placing the access request, which will receive the information upon successful token redemption Required
grantor "From" Alias (DOMAIN orEMAIL) of the user member granting access to the specified bank account(s). To review the methods for finding an alias see Fetching an Alias. Required
providerAccountDetails Specific information regarding the required by the respective Open Banking API standard adopted by the bank:. These include additional ASPSP business identifiers and contact information (address, phone, email, etc.) for:

See the protobuf reference or Swagger spec (under the Model tab) for object and field details.

Required
receiptRequested Boolean; requests a receipt be sent to the grantor member's default email address Optional
redirectUrl Specifies the callback URL where your server will initiate token redemption Required
refId

Reference identifier for the token; not to be confused with requestId. RefId maps to tppRefId in the bank's consentRequest. It is needed to match/verify the originating token request with the bank's consent request.

Warning: A description mismatch between the originating token request and subsequent token lookups/changes/updates (retrieve, redeem, or cancel) will throw an exception.

Required
resourceType Specifies the type of information for which access permission is requested:

  • ACCOUNTS – list of accounts with associated names

  • BALANCES – current balance of each requested account

  • TRANSACTIONS – recorded account activity in terms of debits and credits

  • TRANSFER_DESTINATIONS – account number and sort code/BIC, where applicable

  • FUNDS_CONFIRMATIONS – confirmation of available funds in the specified account

  • STANDING_ORDERS – scheduled recurring payments, frequency and duration

Required
token_expiration

Sets the consent expiration in number of days for access requests (default is 90 days per regulation); override of the default value is not supported by all banks. This is a particularly important parameter to pass to banks to ensure an adequate custom consent expiry period is set for the access token upon successful authorization.

JSON in a successful response payload will look something like this:

{"Data:["Permissions":["ReadAccountsDetails","ReadBalances"], "ExpirationsDateTime":"2020-10-21T18:03:07.371+01:00"}, "Risk":{}}

Optional
traceID TPP-provided unique value captured by Token.io and sent across to the bank to be stored with the request throughout its lifecycle as an audit-trail aid. Optional
* Required if supported by the responding bank

Caution: A is disallowed in the token request payload within the refId and description fields. In accordance with the security standard, is used for pattern matching of numeric strings that intentionally or inadvertently reveal or resemble a PAN in the refId or description of a token request. Potential PAN patterns found will now throw an exception.

Nonce generation to protect account information ensures that the specified transfer destination account cannot be reused in a replay attack. As desired, you can add to or replace the resource types in the example (in yellow) with TRANSACTIONS and/or TRANSFER_DESTINATIONS.

Important Update: In the access token response payload, account_identifiers are now specified in AccountDetails, which include bic and account_holder_name, along with account_number and/or sort_code. In general, four types of account identifiers are supported:

  • Token, for linked accounts
  • Iban
  • Bban
  • GbDomestic – 8-digit bank account number in the UK

Only fields supported by the responding bank will be populated.

These fields were recently added pursuant to deprecating the resolveTransferDestinations call by TPPs. Previously, TPPs could obtain these data — account identifiers, , and customer name — after a getAccount or getAccountDetails call with a subsequent resolveTransferDestinations call, wherein the debit-side bank returned its preferred transfer method(s) — , , , etc. — along with the bic and CustomerData.

However, to optimise API utilisation and eliminate the additional call to resolveTransferDestinations, banks are now required to populate account_identifiers, bic and account_holder_name in the accountDetails object returned by the getAccount and getAccountDetails calls. TPPs are therefore encouraged to discontinue relying on the resolveTranserDestinations method.

After storing the transfer token request, you're ready to construct the redirect URL for authorization so the customer can authenticate, provide consent, and authorize account information access as previously outlined in the AIS communication workflow.

Tip: When integrating the Token.io SDK with a mobile app, you can initiate the token request in so that the redirect is also in the form of an . However, in terms of activity layout, WebView lacks many features found in a fully developed web browser.

Nevertheless, WebView provides increased control over the UI and advanced configuration options that allow you to embed web pages in a specially-designed environment for your app, but you will forfeit an array of features supported by Chrome, Firefox, and other browsers.