Requesting Confirmation of Funds (CBPII)

In Open Banking, the "Card-Based Payment Instrument" service allows TPPs to initiate payments from a payment account held with another payment service provider. A CAFClosedConfirmation of Available Funds – A CBPII begins the Confirmation of Funds journey by registering a request to confirm funds of a PSU. The CBPII must then obtain consent from the PSU in order to authorise the request, enabling it to request the information. Once the request is authorised, the CBPII will be able to invoke Confirmation of Funds API to the confirm availability of funds in the PSU account. request is made by the CBPIIClosedCard Based Payment Instrument Issuer – a payment services provider that issues card-based payment instruments and allows its customers to pay from bank accounts. to confirm with the ASPSPClosedAccount Servicing Payment Services Provider – any financial institution that offers a payment account with online access. This includes banks and building societies. PSD2 requires ASPSPs to provide access to trusted third parties for initiating payments and accessing account information. that the necessary funds are currently available in a PSUClosedPayment Services User – an individual person or legal business entity making use of an Open Banking service as a payee, payer or both.'s bank account. To initiate such a request, the CBPII must have the PSU's consent and specify a valid consentId included in the request payload.

In the context of the account information queries discussed here, CBPII and TPPClosedThird-Party Provider – an authorised online service provider introduced as part of Open Banking. TPPs exist outside of the account holder’s relationship with their bank but may be involved in transactions carried out by the user. are one and the same.

To access Account Details, the value of supportsInformation must be true for each bank displayed to the user for selection from the GET /banks payload.

Token's REST API support for responding to these funds confirmation requests implements a communications workflow that ensures all Open BankingClosedProvides third-party financial service providers open access to consumer banking, transaction, and other financial data from banks and non-bank financial institutions through the use of application programming interfaces (APIs). Open banking will allow the networking of accounts and data across institutions for use by consumers, financial institutions, and third-party service providers. regulations and specifications for PSU consent and authorisation are met, as seen in the following diagram (hover to enlarge):

Guidance for making the appropriate POST and GET calls, as well as handling Token's responses to these requests is covered next.

Detailed API request-reply code samples supporting each use case are available in the API's Postman profiles. Download the PostmanClosedA tool for performing integration testing with your API. It allows for repeatable, reliable tests that can be automated and used in a variety of environments and includes useful tools for persisting data and simulating how a user might actually be interacting with the system. app from https://www.postman.com/downloads/.

Correlated in the following table, the {{BASE_URL}} for calls and redirects depends on the environment in which you're operating.

Environment BASE_URL
API calls
Production https://api.token.io
Sandbox https://api.sandbox.token.io
Web App Redirect (for consent)
Production https://web-app.token.io
Sandbox https://web-app.sandbox.token.io

Be sure to include the BASE_URL for the appropriate environment and purpose in each call.

Making the Token Request

To initiate standing order request with the bank, you'll need to be able to identify yourself as the calling TPP using one of two ways; either your Member ID or your Alias, defined as follows:

  • Member ID – unique value generated by the Developer Dashboard when you signed up.
  • Alias – unique email or domain generated when you signed up.

For purposes of an AIS request — to avoid a mismatch caused by a typo — use both.

You can obtain the values from the dashboard by following these steps:

    (1)   If the dashboard isn't already open in a browser tab, sign in.

    (2)   Click Member Information in navigation panel on the left.

    (3)  Click the "eye" icon to the right of each value to reveal it.

    (4)   Copy the value you need.

Once the PSU gives consent for you to initiate PIS on the PSU's behalf, here's the call for POSTing /token-requests:

{

    "requestPayload": {

        "to": {

            "alias": { // include only one type and its corresponding value

                "realmId": "value available from dashboard",

                "type": "EIDAS",

                "type": "EMAIL",

                "value": "noverify@token.io" // example value

                "value": "value available from dashboard"

            }

            "id": "m:nP4w3u5y8ddrxDJkjimgSX9e4fZ:5zKtXEAq"// TPP member ID

        },

        "authorizationMetadata": {   // map from response to GET /banks call

            "additionalProp1": "string",

            "additionalProp2": "string",

            "additionalProp3": "string"

        },

        "accessBody": {

               "accountResourceList": {

                    "resources": [{

                         "type": "ACCOUNT_FUNDS_CONFIRMATION",

                         "bankAccount": {

                              "domestic": {

                                   "bankCode": "700001",

                                   "accountNumber": "70000006",

                                   "country": "GB"

                },

                "amount": {

                    "currency": "string",

                    "value": "string"

                }

        },

        "description": "test",

        "redirectUrl": "https://sample-merchant-domain.com"

    },

    "requestOptions": {

        "bankId": "ob-modelo",

        "from": {

        }

    }

}

The most important request fields and their corresponding descriptions are listed in the following table.

Key Fields in the Transfer Token Request for Funds Confirmation
Field Required/Optional Description
alias Required A human-readable proxy for your member identifier that contains your alias type (DOMAIN, EMAIL, other) and a value string. Find your alias in the sandbox after logging in by clicking the Payload Constructor button in the Payload Builder card.
authorizationMetadata Required Maps the key-value pairs from the GET /banks response, where key is the name of the field and value is the value of the field. 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.
id Required, unless Alias is included Member ID of the TPP, a constant value in all requests; find yours in the sandbox after logging in by clicking the Construct Payload button in the Payload Builder card.
redirectUrl Required Defines the callback URL where your server initiates token redemption
bankAccount Required Currency for the card-based payment
amount Required Amount of the payment
callbackState Optional Developer-specified string allowing state to be persisted between the request and callback phases of the flow
refiD Optional TPP-generated reference identifier
requestOptions Optional • Bank ID where payment is to be initiated
• Receipt Requested – to specify that an email
  receipt is to be sent to the PSU by Token

Here's an example of the response you'll receive:

"tokenRequest": {

    "id": "rq:3g5RVV7Z4oU9P5rtzX2YhnssuPC5:5zKtXEAq", // request-id; add to BASE_URL for consent

    "requestPayload": {

        "redirectUrl": "https://sample-merchant-domain.com/pis"

        "to": {

            "id": "m:ifnUakCEJAot1XSXsmrMZHHd19A:5zKtXEAq" // TPP member ID

        },

         "transferBody": {

            "currency": "EUR",

            "lifetimeAmount": "10",

            "instructions": {

                "transferDestinations": [

                    {

                         "sepa": {

                             "iban": "testIBAN",

                             "bic": "testBIC"

                         }

                    }

                ]

            }

        },

        "description": "test",

        "redirectUrl": "https://sample-merchant-domain.com"/transfer

    }

}

Create the redirect URL by appending the request id in the response (shown above in red) to the redirect base URL, then send it to the user to provide explicit consent to bank.

https://{{BASE_URL}}/app/request-token/app/request-token/{{Insert request-id here}}

// example = https://web-app.sandbox.token.io/app/request-token/rq:3RKfCA7KQEEZERLoFsAt3MoAnoP5:5zKtXEAq

Upon user consent, Token will redirect the user back to the TPP with a tokenId as a query parameter.

"redirectUrl": "https://sample-merchant-domain.com"/ais?tokenId=sample_token_id

To derive the complete redirect URL, you'll need to URL decodeClosedURL encoding makes sure that the characters in the URL that are not allowed to be put into the URL directly can still be used. For example a space or : is not allowed, but replacing it with %20 or %3A encodes a space or : (and most browsers will display a space in the browser bar). For encoded URLs, use Java's URLDecoder (java.net.URLDecoder) unless you have a different preference. the tokenId value provided.

Using the tokenId sent by the bank, which confirms PSU consent, you can now initiate funds confirmation with a PUT /accounts/{account_id}/funds-confirmation call to the redirect URL.

{   

    "amount": {

         "currency": "EUR"

         "value": "10"

    }

}

The response will be boolean-affirmative or empty:

{

     fundsAvailable: true // empty if not true

}

If sufficient funds are not available, the fundsAvailable tag will be empty.