NAV Navbar
Javascript Java C#

Access Banks

This page is for developers building applications that need to initiate payments and access account information from Token-connected banks. The page is organized in sections of customer experience, integration steps, sample code and access to the SDKs. And don’t forget to review the Security Considerations section!

A key concept of TokenOS is the “Smart Token”, which is a digital authorizations to access an underlying asset (e.g. bank accounts) to initiate a payment or access information.

Smart Tokens are REQUESTED, CREATED and finally REDEEMED (or cancelled). You’ll find more details about Smart Tokens in the section Flow Overview.

If you have questions or feedback about these docs, please contact us https://token.io/contact.

About TokenOS

TokenOS is the operating system for open banking that allows banks, merchants, enterprises and individuals to interact in a global marketplace of financial services.

Token Ecosystem

TokenOS provides third parties with lower cost payments, new payment propositions, richer customer spend data and a better user experience for their customers. TokenOS easily integrates with a third party’s existing infrastructure using SDKs provided in common languages.

Key benefits include:

Third parties connect to banks through an open and secure API. TokenOS connects to banks through various methods, but provides a single, unified interface for developers. Contact us for a list of banks that TokenOS currently connect to.

Customer Experience

Depending on the underlying bank and its authentication and authorization method, the user experience may vary. The following screens are representative of most cases.

Example UX of a merchant requesting a bank direct payment using Token; the user is visiting the merchant website on a mobile device.

Screen 0 Screen 1 Screen 2 Screen 3 Screen 4 Screen 5 Screen 7 Screen 8

Integration Steps

Getting Started

To start making Token API calls, first setup your back-end service. Download the latest Token SDK and set up a client. To start accepting payments or accessing information using TokenOS, you must first create a Token Business Member account. Your back-end service will use this member’s credentials to initiate API calls and request Smart Tokens for payments and information access.

To create a Token Business Member, you’ll need to specify a domain to use as your member’s alias (in the example below, a randomly generated domain is provided). It’s also recommended to specify a display name, which will be shown to the end-user when requesting authorization to initiate a payment or access account information.

domain Domain of your organization. This will need to be verified so that the user knows who he is approving access to.
member Token member. Used to make authenticated API calls to TokenOS.

Example call to create a business-type member.

const domain = Math.random().toString(36).substring(2, 10) + ".com"
const alias = {
    type: DOMAIN,
    value: domain
};
Token.createBusinessMember(alias, Token.UnsecuredFileCryptoEngine).then(function(m) {
    member = m;
    member.setProfile({
        displayNameFirst: 'Merchant 123'
    });
});
String domain = generateNonce() + ".com";
Alias alias = Alias.newBuilder()
        .setType(DOMAIN)
        .setValue(domain)
        .build();
Member member = tokenIO.createBusinessMember(alias);
member.setProfile(Profile.newBuilder()
        .setDisplayNameFirst("Merchant 123")
        .build());
string domain = Util.Nonce() + ".com";
Alias alias = new Alias
{
    Type = Domain,
    Value = domain
};
MemberSync member = tokenIO.CreateBusinessMember(alias);
var profile = new Profile
{
    DisplayNameFirst = "Merchant 123"
};
member.SetProfile(profile);

If you already have a member created, you should load your existing member.

Flow Overview

At the core of TokenOS is the Smart Token. Smart Tokens are digital authorizations to access an underlying asset (e.g. bank accounts). There are two common use cases:

  1. Smart Tokens to access end-user bank account information (access tokens)
  2. Smart Tokens to initiate payments from end-user bank accounts (transfer tokens)

To obtain a Smart Token, you must request it from the user via the Smart Token Request Flow, an OAuth-like flow that can be easily embedded in any third party website or mobile application.

Token Request Flow Sequence Diagram

At a high level, the Smart Token Request Flow consists of three steps. In the remainder of this document, the word token is used interchangeably with Smart Token for brevity.

1. Create a token request.
POST /token-request
- Front-end sends a request for access or payment to the back-end.
- Back-end service creates a tokenRequest and constructs tokenRequestUrl.
- Back-end service responds with HTTP 303 requesting redirect to tokenRequestUrl.
2. Redirect to TokenOS to obtain authorization. - Front-end visits tokenRequestUrl.
- User proceeds through TokenOS steps.
- TokenOS redirects to callback URL hosted by TPP back-end service (specified in the tokenRequest from Step 1).
3. Redeem the token.
GET /accounts/{accountId}/balance
GET /accounts/{accountId}/transactions
PUT /tokens/{tokenId}/redeem
- Back-end service parses callback URL and obtains tokenId.
- Back-end service uses tokenId for payment initiation or access to account information.

1. Create a Token Request

TokenOS handles the creation of the token. It manages user authentication and consent, and is designed to abstract away the complexity of the underlying bank connections. In order to request a token, first create a TokenRequest, which contains all the information that will be in the final token (payment amount, account information permissions, etc.).

The contents of the TokenRequest will differ depending on the type of token being requested. Since the member creating the TokenRequest must match the member that redeems the token later in the flow, you should perform TokenRequest creation server-side.

A TokenRequest expires in a short period of time, so you should use it immediately. A TokenRequest contains the following information:

tokenRequest Request containing requested terms (for either a Transfer Token or an Access Token, details below).
redirectUrl Defines the callback URL where your server will initiate redemption of the token.
bankId Optional. Specify if you would like to display your own bank selection UI. See below for more details.
emailAddress Optional. Specify if you would like to skip user email input in certain cases. See below for more details.

A RequestId will be returned on submission of the TokenRequest, which must be included in the URL when redirecting the user to Token to obtain the authorization. This ID references the stored TokenRequest and is used to verify that the conditions of the request are unchanged.


Transfer Tokens

tokenBuilder Builder to create a transfer token. You can use this to specify the requested token terms.
redeemer Member that will redeem the token and initiate the transfer of funds. This is the member that is requesting the transfer, who was registered during initial setup.

The transfer tokenBuilder is constructed with the following details:

TransferTokenBuilder(Double amount, String currency) Initial constructor that takes an amount and currency.
setDescription(String description) Description of the payment.
addDestination(TransferEndpoint destination) Destination account for the payment. This will typically be an IBAN for SEPA transfer, or Sort Code and Account Number for Faster Payments. Details about the TransferEndpoint object can be found here.
setToAlias(Alias alias) The alias of the member redeeming the token, registered during initial setup of the Token member.
setToMemberId(String memberId) The ID of the member redeeming the token.
setRefId(String referenceId) Optional A reference ID used for reconciliation purposes (max length is 18 characters).
setPurposeOfPayment(PurposeOfPayment purpose) Optional The purpose of payment. See options here.

See our SDK Documentation for more information.

See our SDK Documentation for more information.

See our SDK Documentation for more information.

Though optional, we recommend setting a Reference ID in the tokenBuilder, which will be included in the request to transfer the funds. This allows merchants the ability to easily reconcile transactions against payments received to their account(s). Due to restrictions of particular payment rails, this value cannot exceed 18 characters in length.

An example of creating a TokenRequest for a transfer token

const tokenBuilder = redeemer.createTransferTokenBuilder(100.00, 'EUR')
        .setDescription('Book purchase')
        .addDestination(TransferEndpoint.newBuilder()
            .setAccount(BankAccount.newBuilder()
                  .setSepa(Sepa.newBuilder()
                         .setIban('DE16700222000072880129')))
            .build())
        .setToAlias(redeemer.firstAlias())
        .setToMemberId(redeemer.memberId());

const tokenRequest = Token.TokenRequest.create(tokenBuilder.build())
        // Configure options for the TokenRequest
        .setRedirectUrl(redirectUrl)
        .setBankId(bankId)
        .setEmail(email)

redeemer.storeTokenRequest(tokenRequest).then(function(res) {
        const requestId = res.id;
});
// Create a TransferTokenBuilder
TransferTokenBuilder tokenBuilder =
        new TransferTokenBuilder(100.0, "EUR") // currency and amount
                .setDescription("Book purchase") // optional description
                .addDestination(TransferEndpoint.newBuilder()
                    .setAccount(BankAccount.newBuilder()
                        .setSepa(Sepa.newBuilder()
                             .setIban('DE16700222000072880129')))
                    .build())
                .setToAlias(redeemer.firstAlias())
                .setToMemberId(redeemer.memberId()); // redeemer member id

// Create a TokenRequest to be stored
TokenRequest request = TokenRequest.create(tokenBuilder)
        // Configure options for the TokenRequest
        .setOption(REDIRECT_URL, redirectUrl)
        .setOption(BANK_ID, bankId)
        .setOption(ALIAS, emailAddress);

String requestId = redeemer.storeTokenRequest(request);
TransferTokenBuilder tokenBuilder = redeemer.CreateTransferToken(100.0, "EUR") // currency and amount
    .SetDescription("Book purchase") // optional description
    .AddDestination(new TransferEndpoint
    {
        Account = new BankAccount
        {
            Sepa = new Sepa
            {
                Iban = "DE16700222000072880129"
            }
        }
    })
    .SetToAlias(redeemer.FirstAlias())
    .SetToMemberId(redeemer.MemberId()); // redeemer member id

// Create a TokenRequest to be stored
TokenRequest request = new TokenRequest
{
    Payload = tokenBuilder.BuildPayload(),
    // Configure options for the TokenRequest
    Options =
    {
        {TokenRequestOptions.redirectUrl.ToString(), redirectUrl},
        {TokenRequestOptions.bankId.ToString(), bankId},
        {TokenRequestOptions.alias.ToString(), emailAddress}
    }
};

string requestId = redeemer.StoreTokenRequest(request);

Access Tokens

tokenBuilder Builder to create an access token. You can use this to specify the requested token terms.
grantee Member that is allowed to redeem the token for information.

The access tokenBuilder can be constructed with the following options:

AccessTokenBuilder() Initial constructor for an access token.
forAll() To request all account, balance, and transaction information for accounts authorized by the end-user.
forAccountBalances(String accountId) To request balance information for one account (must have already obtained access to account information from end-user).
forAccountTransactions(String accountId) To request transaction history for one account (must have already obtained access to account information from end-user).

For the full set of options, see our SDK Documentation.

For the full set of options, see our SDK Documentation.

An example of creating a TokenRequest for an access token

const tokenBuilder = grantee.createAccessTokenBuilder()
        .forAll()
        .setToAlias(grantee.alias())
        .setToMemberId(grantee.memberId());

const tokenRequest = Token.TokenRequest.create(tokenBuilder.build())
        // Configure options for the TokenRequest
        .setRedirectUrl(redirectUrl)
        .setBankId(bankId)
        .setEmail(email)


grantee.storeTokenRequest(tokenRequest).then(function(res) {
        const requestId = res.id;
});
// Create an AccessTokenBuilder
AccessTokenBuilder tokenBuilder = AccessTokenBuilder.create(grantee.firstAlias()).forAll();

// Create a TokenRequest to be stored
TokenRequest request = TokenRequest.create(tokenBuilder)
        // Configure options for the TokenRequest
        .setOption(REDIRECT_URL, redirectUrl)
        .setOption(BANK_ID, bankId)
        .setOption(ALIAS, emailAddress)

String requestId = grantee.storeTokenRequest(request);
AccessTokenBuilder tokenBuilder = AccessTokenBuilder.Create(grantee.FirstAlias()).ForAll();

// Create a TokenRequest to be stored
TokenRequest request = new TokenRequest
{
    Payload = tokenBuilder.BuildPayload(),
    // Configure options for the TokenRequest
    Options =
    {
        {TokenRequestOptions.redirectUrl.ToString(), redirectUrl},
        {TokenRequestOptions.bankId.ToString(), bankId},
        {TokenRequestOptions.alias.ToString(), emailAddress}
    }
};

string requestId = grantee.StoreTokenRequest(request);

2. Redirect to TokenOS to obtain authorization

After creating a TokenRequest, construct a URL to direct your user to Token. The Token SDK provides an easy way to do this.

tokenRequestUrl URL to TokenOS that guides your user through the necessary steps to create a token.
requestId ID that references a previously created TokenRequest stored in TokenOS.

An example of constructing a Token Request URL

const tokenRequestUrl = Token.generateTokenRequestUrl(requestId);
String tokenRequestUrl = tokenIO.generateTokenRequestUrl(requestId);
string tokenRequestUrl = tokenIO.GenerateTokenRequestUrl(requestId);

After constructing the Token Request URL from above, direct your front-end to visit this URL.

If you are integrating into a website, we suggest that you send an HTTP POST to your back-end to initiate the Token Request creation in Step 1 and redirect using an HTTP 302.
If you are integrating with a mobile app, we suggest that you initiate Token Request creation in a WebView in Step 1 so that the redirect is also in the form of an HTTP 302.

Example anatomy of Token Request URL

https://web-app.token.io/request-token/rq:42w7yzgwJtN9fQVx78McJzEKiyU9:5zKtXEAq?lang=en

When your end-user visits this URL, TokenOS will take her through the necessary steps to authenticate and consent to the requested token terms. Once the token has been created, it will redirect to the callback URL you specified in the TokenRequest with an HTTP 302.

Example anatomy of TokenRequest Callback URL

https://merchant-site.com/callback?tokenId=tt:3PFXqSnRX7LCXo7MenmW26VVgMnHi44Br4WCM5MgEq4f:5zKxyCKM

TokenOS will include the necessary parameters for your server-side code to redeem the token in the callback URL.

3. Redeem the Token

After obtaining user authorization, TokenOS will redirect to the callback URL specified in the TokenRequest with an HTTP 302. When your server-side code receives an HTTP GET request at the callback URL, it should use the Token SDK parseTokenRequestCallbackUrl method to extract the tokenId.

callbackUrl URL of HTTP request sent to the server callback endpoint.
tokenId ID that refers to a Token stored in TokenOS.

Example of parsing callback url

Token.parseTokenRequestCallbackUrl(callbackUrl).then(function(res) {
        const tokenId = res.tokenId;
})
String tokenId = tokenIO.parseTokenRequestCallbackUrl(callbackUrl).getTokenId();
string tokenId = tokenIO.ParseTokenRequestCallbackUrl(callbackUrl).TokenId;

The Smart Token is an authorization. It must be redeemed to create a payment or access account information. If your token is a transfer token for a single payment, it only lasts a short period of time and should be redeemed immediately.


Redeem Transfer Tokens for Payment

Using the server-side Token member, call the redeemToken method to create a Transfer. This initiates a payment (via one of Token’s supported rails: e.g. SEPA) from the user’s bank.

tokenId ID that refers to a Token stored in TokenOS.
refID Optional. Client-supplied reference ID used for deduplicating requests.
transferToken A Token retrieved from TokenOS using a tokenId.
transfer Represents a payment. The status of the transaction can be retrieved using this object.

Example of transfer token redemption

//retrieve the token
payee.getToken(tokenId).then(function (transferToken){
        // Payee redeems a transfer token.
        // Money is transferred to a payee bank account.
        payee.redeemToken(transferToken, amount, currency, description, [], refId).then(function(transfer) {
                // Do something with transfer
        })
});
Token transferToken = payee.getToken(tokenId); // retrieve the token

// Payee redeems a transfer token.
// Money is transferred to a payee bank account.
Transfer transfer = payee.redeemToken(
            transferToken,
            refId);
Token transferToken = payee.GetToken(tokenId); // retrieve the token

// Payee redeems a transfer token.
// Money is transferred to a payee bank account.
Transfer transfer = payee.RedeemToken(
    transferToken,
    refId);

The transfer object (or its ID) returned can be used to retrieve the status of the transaction.

transferId ID that refers to a Transfer stored in TokenOS.
transfer A Transfer retrieved from TokenOS using a transferId or created with redeemToken.
status Represents a transaction status (processing, success, or failed).

Example of retrieving status of transfer

payee.getTransfer(transferId).then(function(transfer) {
        const status = transfer.status;
});
Transfer transfer = payee.getTransfer(transferId);
TransactionStatus status = transfer.getStatus()
Transfer transfer = payee.GetTransfer(transferId);
TransactionStatus status = transfer.Status;


Redeem Access Token for Account Information

Using your server member, call forAccessToken to get a Representable object that represents the user. You can then call getBalance, getTransactions, on the Representable object to retrieve account information. The methods will only succeed if the specified access token has sufficient permissions.

Due to certain bank connection limitations, TokenOS will sometimes cache data on schedule and return cached information unless otherwise specified.

grantee Member to whom the access token was granted.
tokenId ID that refers to an access token stored in TokenOS.
customerInitiated Optional. Flag to set if access is customer-initiated. This bypasses the TokenOS cache.
balance Balance of the account.

Example of access token redemption

const grantor = grantee.forAccessToken(tokenId);
const accounts = await grantor.getAccounts();
Representable grantor = grantee.forAccessToken(tokenId, false);
List<Account> grantorAccounts = grantor.getAccounts();

// Get the data we want
Money balance = grantorAccounts.get(0).getCurrentBalance(STANDARD);
IRepresentable grantor = grantee.ForAccessToken(tokenId, false);
IList<AccountSync> grantorAccounts = grantor.GetAccounts();

// Get the data we want 
Money balance = grantorAccounts[0].GetCurrentBalance(Standard);

The forAccessToken method allows you to specify which access token to use to access information. You should keep track of the association between your access tokens and your users.

Download Sample Code

If you’d like to see a working implementation of the Smart Token Request Flow, check out our samples below:

Clone or download the appropriate sample. The README.md tells how to build and run the sample. Each sample contains a reference back-end service implementation as well as a reference front-end website.

Extensions

Optional: Display Your Own Bank Selection UI

The first screen your user will see when he is redirected to TokenOS is a bank selection screen, prompting him to choose the bank that he would like to use.

Banks Selection Screen

If you would like to filter the banks that are available to the user or control this bank selection UI in your own application, you can do so by specifying the bankId of the user-selected bank when creating the Token Request.

To retrieve the list of banks to display, use the getBanks method in the Token SDK.

Example of using getBanks

Token.getBanks().then(function(banks) {
        String bankId = banks[0].id;
})
List<Bank> banks = TokenIO.getBanks();
String bankId = banks.get(0).getId; // take the first bank id
PagedBanks banks = tokenIO.GetBanks();
string bankId = banks.Banks[0].Id;

Each bank also specifies additional properties described below. These properties can be used to filter the banks list displayed to the user.

supports_information Allows for retrieval of account information
supports_send_payment Allows for payment initiation
supports_receive_payment Allows for receiving payments
provider Underlying connectivity type; e.g. Yodlee FinAPI Token (direct integration)
country ISO 3166-1 alpha-2 two letter country code in uppercase.

After obtaining the user-selected bankId, provide it in the TokenRequest

Example of specifying bankId in tokenRequest creation

const tokenRequest = Token.TokenRequest.create(builder.build())
        .setRedirectUrl(redirectUrl)
        .setBankId(bankId)
// Create a TokenRequest to be stored
TokenRequest request = TokenRequest.create(tokenBuilder)
        // Configure options for the TokenRequest
        .setOption(REDIRECT_URL, redirectUrl)
        .setOption(BANK_ID, bankId)
TokenRequest request = new TokenRequest
{
    Payload = tokenBuilder.BuildPayload(),
    // Configure options for the TokenRequest
    Options =
    {
        {TokenRequestOptions.redirectUrl.ToString(), redirectUrl},
        {TokenRequestOptions.bankId.ToString(), bankId}
    }
};

When TokenOS displays this TokenRequest, it will see that a bankId has been specified and default to that bank instead of displaying the bank selection screen.

Optional: Provide User Email Address For Better UX

In the case of a Token Integrated bank , your user may be prompted to type in his email address in order to enable a customer experience that does not involve entering bank credentials.

Email Input Screen App Approval Screen

To provide an even more seamless experience, you have the option of specifying the user’s email address when creating the Token Request.

Example of specifying the user email address in tokenRequest creation

const tokenRequest = Token.TokenRequest.create(builder.build())
        .setRedirectUrl(redirectUrl)
        .setEmail(email)
// Create a TokenRequest to be stored
TokenRequest request = TokenRequest.create(tokenBuilder)
      // Configure options for the TokenRequest
      .setOption(REDIRECT_URL, redirectUrl)
      .setOption(ALIAS, emailAddress)
TokenRequest request = new TokenRequest
{
    Payload = tokenBuilder.BuildPayload(),
    // Configure options for the TokenRequest
    Options =
    {
        {TokenRequestOptions.redirectUrl.ToString(), redirectUrl},
        {TokenRequestOptions.alias.ToString(), emailAddress}
    }
};

By providing the email, TokenOS will skip the email input screen and ask the user to approve on his app directly, further reducing friction in the UX.

Optional: View Token Terms

Upon receiving a token, if you would like to check the terms of the token you can retrieve it with the getToken method and inspect the Token object returned.

Example of retrieving the token

payee.getToken(tokenId).then(function (token) {
        // Verify terms of the token
});
Token transferToken = payee.getToken(tokenId);
Token transferToken = payee.GetToken(tokenId);

Optional: Create a token on behalf of another party

If you are a business member and have been verified by Token to do so, you can create a token on behalf of another party. To do that you need to set the ActingAs field on the token payload with the following properties describing the intended recipient.

display_name Name of recipient, to be shown to user.
ref_id Optional. Your reference ID of the recipient. Opaque to Token.
logo_url URL pointing to recipient’s logo.
secondary_name Optional. Domain or email of the recipient, to be shown to user along with display_name.

Example of setting acting_as

// Transfer Token Builder
const tokenBuilder = payee.createTransferTokenBuilder(100.00, 'EUR')
        .setDescription('Book purchase')
        .setActingAs({
            displayName,
            refId,
            logoUrl,
            secondaryName
        })
        .setToAlias(payee.firstAlias())
        .setToMemberId(payee.memberId());

// Access Token Builder
const tokenBuilder = grantee.createAccessTokenBuilder()
        .forAll()
        .setActingAs({
            displayName,
            refId,
            logoUrl,
            secondaryName
        })
        .setToMemberId(grantee.memberId());
// Transfer Token Builder
TransferTokenBuilder tokenBuilder = new TransferTokenBuilder(100.0, "EUR")
        .setDescription("Book purchase")
        .setActingAs(ActingAs.newBuilder()
                .setDisplayName(displayName)
                .setRefId(refId)
                .setLogoUrl(logoUrl)
                .setSecondaryName(secondaryName))
        .setToAlias(payee.firstAlias())
        .setToMemberId(payee.memberId());

// Access Token Builder
AccessTokenBuilder tokenBuilder = AccessTokenBuilder.create(grantee.memberId())
        .actingAs(ActingAs.newBuilder()
                .setDisplayName(displayName)
                .setRefId(refId)
                .setLogoUrl(logoUrl)
                .setSecondaryName(secondaryName))
        .forAll();
// Transfer Token Builder
TransferTokenBuilder tokenBuilders = payee.CreateTransferToken(100.0, "EUR") // currency and amount
    .SetDescription("Book purchase") // optional description
    .AddDestination(new TransferEndpoint
    {
        Account = new BankAccount
        {
            Sepa = new Sepa
            {
                Iban = "DE16700222000072880129"
            }
        }
    })
    .SetToAlias(payee.FirstAlias())
    .SetToMemberId(payee.MemberId()); // redeemer member id

// Access Token Builder
AccessTokenBuilder tokenBuilder = AccessTokenBuilder.Create(grantee.MemberId())
    .ActingAs(new ActingAs
    {
        DisplayName = displayName,
        RefId = refId,
        LogoUrl = logoUrl,
        SecondaryName = secondaryName
    })
    .ForAll();

Security Considerations

Flow Overview

Since the Smart Token Request Flow is based on OAuth 2.0, we strongly recommended that you implement protection against CSRF and “OAuth Cut and Paste” (slides). TokenOS helps you mitigate both threats by providing a way to cryptographically bind CSRF tokens to the token ID.

This modifies the above outlined flow by introducing a step before the beginning of the process.

Token Request Flow Secure Sequence Diagram

0. Authenticate the Browser - Front-end authenticates with back-end service and creates a session.
1. Create a Token Request - Back-end service generates csrfToken as hash of session cookie, creates a tokenRequest, and constructs tokenRequestUrl
- Back-end service responds with HTTP 303 requesting redirect to tokenRequestUrl.
2. Redirect to TokenOS to obtain authorization - Front-end visits tokenRequestUrl.
- User proceeds through TokenOS steps.
- TokenOS redirects to callback URL hosted by your back-end service
3. Redeem the Token - Back-end service parses callback URL, validates csrfToken, and obtains tokenId and optional state.
- Back-end service uses tokenId to redeem to access account information or create a payment.

The Smart Token Request Flow is a web-based flow. In order to mitigate the above attacks, the first step is to authenticate your user in a web-based environment. In a typical application, the user is already logged in, so this may mean something different depending on if you are working with a website or a mobile application.

A web application does not need to implement anything additional if the user is already authenticated.

A mobile application will need to authenticate the user in the WebView. In order to avoid authenticating user on a separate web page you may want to share sessions between the mobile application and the WebView or use the existing mobile app session to create a new session in the WebView.

SDK Methods

There are two methods in the Token SDK to help with improving your application security.

String TokenIO.generateTokenRequestUrl(requestId, state, csrfToken)
Generates a Token Request URL that can be used to initiate the token request process. The state and csrfToken will be encoded in the URL.

TokenRequestCallback TokenIO.parseTokenRequestCallbackUrl(callbackUrl, csrfToken)
Parses a Token Request callback URL, validates the cryptographic signature binding the csrfToken, state, and tokenId, and returns the state.

csrfToken Unique string bound to the session of the user (e.g. the hash of a session cookie or associated with server-side user session). The csrfToken should be passed into both generateTokenRequestUrl and parseTokenRequestCallbackUrl to validate that the same user session initiated and completed the request.

TokenOS suggests that you follow the IETF-recommended mitigation method of binding the CSRF token to the user’s authenticated state (using, for example, a the hash of a session cookie).

Note: Sensitive strings (such as sessionCookie) can be used directly as the csrfToken in the Token SDK since it hashes the token before using it. For more details on CSRF attacks against OAuth 2.0 and mitigation techniques, refer to this rfc.

If your application does not have user authentication, you can use Util.generateNonce to generate a secure random string to use as a CSRF token.
state Developer-specified string that allows state to be persisted between the the request and callback phases of the flow.

Important Note: The state parameter can contain additional application-specific information, but should not be used to authenticate a user. The authentication must be performed prior to the initiation of the Smart Token Request Flow, and the callback should use the same authenticated session.


Pass the state and csrfToken parameters into the generateTokenRequestUrl method in Step 2.

requestId ID of the TokenRequest to be used for this request. Refer here for how to create a TokenRequest.

Example of using generateTokenRequestUrl with a CSRF token

const tokenRequestUrl = Token.generateTokenRequestUrl(requestId, state, csrfToken);
String tokenRequestUrl = tokenIO.generateTokenRequestUrl(
        requestId,
        state,
        csrfToken);
string tokenRequestUrl = tokenIO.GenerateTokenRequestUrl(
        requestId,
        state,
        csrfToken);


Retrieve the state when parsing the callback url in Step 3 by passing in the same csrfToken.

callbackUrl The callback URL of your backend-service, along with query parameters
tokenId ID of requested token. Can be redeemed for information or payment initiation.

Example of using parseTokenRequestCallbackUrl with a CSRF token

parseTokenRequestCallbackUrl(callbackUrl, csrfToken).then(function(res) {
        const tokenId = res.tokenId;
        const state = res.innerState;
})
TokenRequestCallback callbackParams = tokenIO.parseTokenRequestCallbackUrl(
        callbackUrl,
        csrfToken);

String tokenId = callbackParams.getTokenId();
String state = callbackParams.getState();
TokenRequestCallback callbackParams = tokenIO.ParseTokenRequestCallbackUrl(
        callbackUrl,
        csrfToken);

string tokenId = callbackParams.TokenId;
string state = callbackParams.State;

Frequently Asked Questions

Do I need to have an AISP or PISP license to use your service?
No, Token has obtained AISP and PISP approval by the FCA in the UK and can act as the regulated entity on your behalf.

Do you have a sandbox that I can test with?
Yes, Token has a full sandbox with model banks for you to test your integration against. In the initial setup steps, point your SDK client to connect to our SANDBOX environment. We recommend you start out with Wood bank, contact us to learn more about the other model banks we have available.

Can I test against sandboxes hosted by real banks in your network?
According to the RTS, European banks are not required to host their own sandbox until March 2019. When you have completed your integration and have successfully tested against Token’s model banks, contact us to start the next steps of testing against the live banks in our network (this requires live bank accounts to use for testing).

Can I set up a standing order or recurring payment using your Smart Token technology?
While our technology is capable of this, the banks in our network currently only support single immediate payments. Standing orders, future dated payments, and additional payment options are expected to be supported by 2019. Stay tuned for more.

Does Token offer categorization options for retrieving transaction history?
Token does not currently offer categorization, we expect to offer this service in the future.

Can I make cross-border payments?
The banks in our network currently only offer domestic payments; banks in select regions in our network are expected to support this in 2019. As such, UK banks only support GBP payments, and EU banks only support EUR payments. Token uses underlying bank rails to initiate payments, the initiating bank determines the most suitable rail to use given the payment details.

How do I notify Token of questions or issues I’m encountering?
Contact Us at our help desk, and we’ll get back to you as soon as we can.

Copyright © 2018 Token, Inc. All Rights Reserved