Here is the nominal flow in Account Information to get the access to accounts.

Notes

  • We consider that the User registration has been done.
  • For simplicity, Docker and Gateway have been merged. In Private mode, there is not Gateway, the Docker is calling directly the bank and in Gateway mode, the Docker is forwarding the request to the Gateway.
  • Another difference between the two modes is the roundtrip to the bank that is going directly from the client to the bank and back. In Gateway mode, since banks are checking the callback URL against the ones that have been registered in their system upon onboarding, the callback must be among one of ours. Else, if it's not found, they won't process the request.
  • No UI/UX considerations here, bank selection efficiency is up to you :).
  • For efficiency and flexibility, you should have a cache/copy of the banks list in your system.

Tips & tricks

Cache/copy of the list of banks in your system

Having a cache/copy of the list of banks can substantially improve the response time of your UI. It can also allow you to decide which banks you want to work with. E.g. you may not want to work with the banks that are not offering the instant payment. To do this without cache on your side, you would have to call the Docker to get the list of banks of the selected country, then, for each bank, you'll have to call again to get the connector's options and introspect the options to see if they support instant payment... You'd better to do it in a background job and cache it in your system!

Be ready to face the options

Options are describing the differences between the banks. E.g. one is requiring IBAN(s) to work, another not. If your application can respond to the options, you'll be able to use any bank. In your code, you don't have - and you shouldn't have - to switch on the connector id to decide how to behave. Should I provide the IBAN(s) or not when requesting account access? Are they mandatory or optional?

That's the kind of questions the options are answering. Your code is capable of prompting the user to enter the IBANs or display a message that he will select the accounts on the bank side. That's all. Then you just have to check the options of the selected connector to switch your display.

Explanations

Bank selection

The key between you and us is to know which bank to use is the connector id. It is a property of a bank record. they are grouped by countries. Without any UI/UX considerations, you can grab the list of banks ask the user to select the country, then ask him to select one bank in the list the banks in that country.

You'll find also an extra parameter bankGroup which contains, when necessary, a group name for multiple connectors. E.g., in France, you'll find Banque Populaire Alsace Lorraine Champagne, Banque Populaire Aquitaine Centre Atlantique / CMM Littoral du Sud Ouest, Banque Populaire Auvergne et Rhône-Alpes... all Banque Populaire. The bankGroup for those is "Banque Populaire". You can then adapt you UI to prevent very long list of connectors. If you want of course...

Build your UI

Now that you have the connector id, you can ask the options for AIS. Based on those options, you can build your interface and logic. Don't build them on the bank/connector id but on those options. You'll have less case and your code is not sensible to bank changes.

Check the accessOption to see if you cannot ask or may ask or must ask the PSU to enter account identifier (IBAN, BBAN...).

Check the linkingOption to see if the bank can only have one consent for all the accounts or multiple.

Check the accountSchemes to see what kind of account identifier scheme is supported. IBAN goes into iban field and other are going to genericAAccountIdentifier structure.

Create the account access request

Create the model and call the access Docker endpoint. In return you'll get a resultStatus with the value REDIRECT and in dataString the URL where to redirect the PSU.

You should save the necessary data for this request in your storage associated with the unique flowId of that request; you'll use it when you're back from the bank: linked PSU to get the user context, connector id, response's flowContext.

You do the redirect the PSU to that URL which leads to the bank Strong Customer Authentication (SCA). The PSU identifies and validate the consent request on bank side. The bank redirect to our Gateway which redirects to the callback URL you defined in redirectUrl field of the request.

Finalize the request

Back to your app, you can call the Docker to get the flow id you set in the flowId field of the request, providing the query string verbatim. With this flow id, you can restore the context of this call from your storage and prepare the call to the finalize endpoint.

You call the finalize endpoint by passing it the flow context you restored from your storage and the user context of the linked PSU.

Getting the accounts

If the response resultStatus is DONE, this means that the access request is... done, you can now ask for the connected accounts. You call this endpoint regularly and pay attention to the transactionConsent and/or balanceConsent structures. First, the validUntil date which is the natural end of the consent. You should ask the PSU to renew it when reaching this date. Second, the status field. If the bank dropped the consent prior to the natural ending date, we set this field to the value of 100 and the date of the first notice of that lost in statusAt.

Multiple bank roundtrips

It may happen that the bank requires multiple roundtrip. E.g. the first is for the login of the user, the second is for the validation of the consent. In that case, you get a REDIRECT from the account access request initiation (POST access), you get a REDIRECT from the first call to finalize (PUT access), you should redirect again to the new URL (dataString) and call a second time the finalize (PUT access) as you did the first time.

Asynchronous bank (RETRY case)

Some banks may need some time to complete their internal process, they are working asynchronously. In that case, you'll get RETRY from the finalize (PUT access).

📘

You will never need to call twice the init (POST access)! So you'll never have a RETRY out of it.

So, in that case, initiation return REDIRECT > bank roundtrip > finalize call returns RETRY > wait some hundreds milliseconds > call again finalize > loop until not RETRY or your internal timeout.

DECOUPLED action

Some bank requires an action to be done on another device/application. They will certainly firstly do a REDIRECT to identify the PSU and then, they require an action to be done on this device/application. In this case, you get a DECOUPLED and you have to display a message to the user. If the bank provided a message, you'll find it in the field dataString of the response. If not provided, dataString is null, you can put your own message. You have to invite the user to press a button when the action has been done.

Programming principle

The programming principle could look to this:

  • call initiation
    • case REDIRECT
      • do bank roundtrip
    • case DECOUPLED
      • display (received message || default message) && button
    • case DONE
      • Nothing to do, call finalize directly
  • do
    • call finalize
      • case REDIRECT
        • do bank roundtrip
      • case DECOUPLED
        • display (received message || default message) && button
      • case RETRY
        • wait some hundreds of milliseconds
  • while not DONE || ERROR
  • get accounts
  • for each account
    • get balances
    • get transactions

Going further

You can find in the following page AIS - Account Information Service more information about the calls or you can navigate to the API definition for AIS .