Redeeming an Access Token

The account information access permissions you specify in your access token request are reflected in the access token generated. Consequently, if you don't ask for access to a resource type in your access token request, it won't be granted in the access token.

Keeping that in mind, the server-side call forAccessToken() is used to get the object — called a representing your customer-user. You can then make getResource calls on the Representable object— getAccounts(), getBalances(), getTransactions(), getStandingOrders() and/or getTransferDestinations() — depending on the resource permissions granted in the access token.

A getAccounts() call retrieves a list of accounts the customer holds in the selected bank. Similarly, getBalances() fetches the current balance of each listed account. getTransactions() for a specified account returns a of transactions made to/from that account, which can be filtered by booking date — startDate and/or endDate. A getTransferDestinations() call fetches the beneficiary accounts associated with each transaction.

Fields in a Access Token Redemption
Field Description Required/ Optional
balance This is the access object; contains the account information requested Required
customerInitiated Boolean value. Set it to true if the customer initiates the access to bypass the cache. Optional
grantee TPP that has been granted information access by grantor Required
grantor The customer-user granting access consent to the TPP (grantee) Required
refId Reference identifier for the token; not to be confused with requestId. This field is typically used by the TPP to de-duplicate requests. If not provided, Token.io generates a random string as the refId. Required
tokenId Identifies the access token to be redeemed Required

Get Balances

For an account balance query, here's the quick form:

public static Money redeemBalanceAccessToken(Member grantee, String tokenId) {

 

    // specifies whether the request originated from a customer

    boolean customerInitiated = true;

 

    // access grantor's account list by applying

    // access token to the grantee client

    Representable grantor = grantee.forAccessToken(tokenId, customerInitiated);

    List<Account> accounts = grantor.getAccountsBlocking();

 

    // get the data we want — here, STANDARD is the key-pair level for the grantor

    Money balance = accounts.get(0).getBalanceBlocking(STANDARD).getCurrent();

 

    return balance;

}

Tip: Because the forAccessToken method lets you specify which access token to apply to access account information, you should establish your own server-side mechanism to correlate access tokens with users. For more on member key pairs, see the onboarding topic on managing keys.

Get Transactions

To get a paged list of transactions for one or more customer-user accounts:

public static List<Transaction> redeemTransactionsAccessToken(Member grantee, String tokenId) {

 

    // Specifies whether the request originated from a customer

    boolean customerInitiated = true;

 

    // access grantor's account list by applying

    // access token to the grantee client

    Representable grantor = grantee.forAccessToken(tokenId, customerInitiated);

    List<Account> accounts = grantor.getAccountsBlocking();

 

    // get the 10 most recent transactions —

    // here, STANDARD is the key-pair level for the grantor

    PagedList<Transaction, String> transactions = accounts.get(0)

        .getTransactionsBlocking(null, 10, STANDARD);

 

    // get the 10 most recent transactions in the specified start-end date range

    PagedList<Transaction, String> transactionsByDate = accounts.get(0)

        .getTransactionsBlocking(null, 10, STANDARD, "2019-01-15", "2022-01-15");

 

    // pass this offset to the next getTransactions

    // call to fetch the next page of transactions

    String nextOffset = transactions.getOffset();

 

    return transactions.getList();

}

Certain banks do not encode the transaction id returned in their response; in which case, it falls to the TPP itself to encode the transaction id in order to retrieve an individual transaction record in a subsequent access request. Token.io does not manipulate or alter data returned by the bank.

For all calls, field values in the response are populated based on data returned by the bank. Field values that are not populated in a response were not provided by the bank.

Payee Information

Submission and return of payee information is not supported by all banks. When supported, and based on the standard adopted by the bank, creditor account (payee) information (legal name and/or address) is included in customerData within providerTransactionDetails for single transactions. When included in the request, payee/creditor account information is available in the response, regardless of the API standard adopted by the bank; typically, however, the following guidelines apply:

  • STET requires creditor account information.

  • CMA9, NextGenPSD2, and PolishAPI have the creditor name and account identifiers, as well as the creditor agent BIC. However, these are optional fields, so the presence of creditor account information is bank-dependent.

  • CMA9 needs the creditor agent address, whilst PolishAPI requires the creditor's address.

Return of payee information is not supported by all banks. When available from the bank, the response payload includes creditor account (payee) information (legal name and/or address) in customerData within providerTransactionDetails based on the API standard adopted by the bank, outlined as follows:

  • does not require creditor account information.
  • , , and have the creditor name and account identifiers, as well as the . However, these are optional fields, so the presence of creditor account information is bank-dependent.
  • CMA9 needs the creditor agent address, whilst PolishAPI has the creditor address.

Get Standing Orders

Accessing a customer's list of standing orders works in much the same way as one-time transactions. Here's the quick form:

public static List<StandingOrder> redeemStandingOrdersAccessToken(

    Member grantee,

    String tokenId) {

 

    // Specifies whether the request originated from a customer

    boolean customerInitiated = true;

 

    // access grantor's account list by applying

    // access token to the grantee client

    Representable grantor = grantee.forAccessToken(tokenId, customerInitiated);

    List<Account> accounts = grantor.getAccountsBlocking();

 

    // get the first 5 standing orders — here, STANDARD is the key-pair level

    //  for the grantor

    PagedList<StandingOrder, String> standingOrders = accounts.get(0)

        .getStandingOrdersBlocking(null, 5, STANDARD);

 

    // pass this offset to the next getStandingOrders

    // call to fetch the next page of standing orders

    String nextOffset = standingOrders.getOffset();

 

    return standingOrders.getList();

}

As with providerTransactionDetails, the response payload for standing orders includes creditor account (payee) information (legal name and/or address) in customerData within providerStandingOrderDetails outlined as follows:

  • does not require creditor account information
  • , , and have the creditor name and account identifiers, as well as the
  • CMA9 needs the creditor agent address, whilst PolishAPI has the creditor address.

Tip: You can add a CustomerTrackingMetadata object to furnish the bank with customer tracking fields — token-customer-ip-address and token-customer-device-id — for getBalances(), getTransactions(), and getStandingOrders() to let the bank know a particular API call was initiated by the . When you do, the SDK sets the customer-initiated header as true automatically.

This may be useful in circumnavigating bank restrictions that impose a 4-times-a-day (i.e., within the same 24-hour period) access limit on the same in accordance with .

For example:

token-customer-ip-address: "127.0.0.1"

token-customer-device-id: "mozilla/5.0 (Windows NT 6.1; Win64; rv47.0) Gecko/20100101 Firefox/47.0:"

Hence, when an access request is explicitly initiated by the customer, the bank may waive the standard TPP access limit. However, this is bank-dependent and can vary from bank to bank.

* * * *

Using its tokenId, you can fetch any unredeemed (active), redeemed (endorsed), or canceled (canceled) token at any time after the token is generated to review its parameters or to cancel the token altogether, as covered next.