Authorisation

Describes the authorisation process

The Regulatory Technical Standard mandates the use of SCA for the authorisation of online payments and account access by account holders.

The NextGenPSD2 XS2A Framework "OAuth2 SCA Approach with Implicit Start of the Authorisation Process" is the only SCA mechanism that is supported by our API.

Our APIs use the OpenID Connect Authorization Code Flow to implement the OAuth SCA approach.

Consent Models

We are supporting the Detailed Consent and Bank Offered Consent models as specified by the NextGenPSD2 XS2A Framework.

With the Detailed Consent model the TPP must provide the account number(s) of the PSU in the consent or payment request.

With the Bank Offered Consent model the TPP is not required to provide the account number of the PSU up front. The PSU can select their account during the SCA process in our authorization flow. The TPP can obtain the selected account number by reading the corresponding consent or payment object. Bank Offered Consent is limited to selection of a single account by the PSU and it is not available on endpoints where the request format mandates the account number (e.g. bulk payment request).

Refer to Account Information Service and Payment Initiation Service for more details.

Start the Authorisation Process

Wherever the consent of a PSU is required, the Authorization Code Flow is embedded into the enclosing NextGenPSD2 flow.

The examples on this page refer to the Payment Initiation Flow as a concrete example, but the authorisation process is identical for all Open Banking APIs.

1019

For example, to initiate a payment, invoke the initiate payment API with your registered redirect URI in the TPP-Redirect-URI header.

curl 'https://xs2a-sandbox.triodos.com/xs2a-bg/nl/v1/payments/sepa-credit-transfers/' 
-H 'Digest: ...' 
-H 'PSU-IP-Address: ...' 
-H 'Signature: keyId="...",algorithm="rsa-sha256",headers="digest x-request-id",signature="..."' 
-H 'X-Request-ID: ...' 
-H 'TPP-Redirect-URI: ...' 
-H 'Content-Type: application/json' 
-H 'Accept: application/json' 
-H 'TPP-Signature-Certificate: ...' 
--data-binary '
{
  "instructedAmount": {
    "currency": "EUR",
    "amount": "11"
  },
  "debtorAccount": {
    "iban": "...the account holder's IBAN"
  },
  "creditorAccount": {
    "iban": "...the creditor's IBAN"
  },
  "creditorName": "...",
  "requestedExecutionDate": "2019-02-22"
}'

A successful call to the initiate payment API will implicitly commence the authorisation process. An authorisation sub-resource is automatically created and its location is returned in the confirmation link.

Note: The confirmation link was added in Berlin Group v1.3.6. The scaStatus link is a synonym for the confirmation link and is maintained to provide backwards compatibility for older implementations.

{
  "transactionStatus": "RCVD",
  "paymentId": "5e70106a-f520-47f5-80bf-a942e878d7dc",
  "authorisationId": "7d91d61c-1c3d-4a57-8e6f-dee877affcaa",
  "_links": {
    "scaOAuth": "http://xs2a-sandbox.triodos.com/auth/nl/.well-known/openid-configuration",
    "scaRedirect": "http://xs2a-sandbox.triodos.com/auth/nl/v1/auth?response_type=code&scope=openid+PIS%3A5e70106a-f520-47f5-80bf-a942e878d7dc&client_id=...&redirect_uri=...",
    "scaStatus": "/nl/v1/payments/sepa-credit-transfers/5e70106a-f520-47f5-80bf-a942e878d7dc/authorisations/7d91d61c-1c3d-4a57-8e6f-dee877affcaa",
    "confirmation": "/nl/v1/payments/sepa-credit-transfers/5e70106a-f520-47f5-80bf-a942e878d7dc/authorisations/7d91d61c-1c3d-4a57-8e6f-dee877affcaa",
    "self": "/nl/v1/payments/sepa-credit-transfers/5e70106a-f520-47f5-80bf-a942e878d7dc",
    "status": "/nl/v1/payments/sepa-credit-transfers/5e70106a-f520-47f5-80bf-a942e878d7dc/status"
  }
}

OAuth 2.0 Authorization Code Flow

The response includes an scaRedirect link. This is a link that is pre-populated with all parameters except code_challenge and code_challenge_method that are required to initiate the Authorization Code Flow.

Get An Authorization Code

Append your RFC7636 compliant code_challenge and code_challenge_method parameters to the scaRedirect link and use HTTP GET to initiate the Authorization Code Flow

curl 'http://xs2a-sandbox.triodos.com/auth/nl/v1/auth'
--data 'response_type=code&scope=openid+PIS%3A5e70106a-f520-47f5-80bf-a942e878d7dc&client_id=...&redirect_uri=...&code_challenge_method=S256&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'

The HTTP response will redirect the PSU's user agent (e.g. web browser) to our authorization screen, where the PSU is requested to give consent via SCA.

HTTP/1.1 302 Found
Location: http://xs2a-sandbox.triodos.com/xs2a-bg/pages/authorisepayment.action?locale=nl_NL&redirect_uri=...&client_id=...&scope=openid+PIS%3A5e70106a-f520-47f5-80bf-a942e878d7dc&request_uuid=5322e96a-ba34-46c6-be94-db7350ea407e

The PSU's consent results in the generation of an authorization code which is returned by means of HTTP redirection to your tppRedirectUri.

The Authorization code has limited validity. To avoid expiry it should be directly exchanged for an access token.

HTTP/1.1 302 Found
Location: https://yourOrg.com/yourTppRedirectURI?code=0866923484

Exchange the Authorization Code for an Access Token

The Authorization code can now be exchanged for an access token.

The Authorization header contains your RFC2617 Basic authentication encoded client id and client_secret that were issued in the registration process.

The code verifier parameter must correspond to the code challenge that was sent in the authorization code request. This is specified by RFC7636.

The redirect_uri should be populated with the ttpRedirectURI value from the payment initiation.

The grant_type should be populated with authorization_code.
For backwards compatibility grant_type=client_credentials is also accepted.

curl "http://xs2a-sandbox.triodos.com/auth/nl/v1/token" 
-H "Content-Type: application/x-www-form-urlencoded" 
-H "Accept: application/json" 
-H "Authorization: Basic UFNETkwtRE5CLVRFU1RYWFg6T05CZnpSdjVJdTl1bUtibTdmTU1zTmJocnNQSWFyT3M1OHRPaGcxYko5bmhHX1NKeExERHdzMUhDdG04Z2JWUzltNWxRZHFnemhRLVQ3QWt6NExCaFE=" 
--data "grant_type=authorization_code&code=0866923484&redirect_uri=...&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

A successful response contains an access token that can subsequently be used to authorise the payment.

{
    "access_token": "DWvJxxH8jDSa_BHWBhSCkgzh7Q5IPeaAs5B6Sa_1xQI",
    "scope": "openid PIS:5e70106a-f520-47f5-80bf-a942e878d7dc",
    ...,
    "token_type": "Bearer",
    "expires_in": 600
}

Refresh Tokens

Access tokens have limited validity and expire after a short period.

If the access token has expired (e.g. for long lived consents such as access to accounts), the refresh token can be exchanged for a new access token.

When requesting the Authorization code, add offline_access to the requested scope.

curl 'http://xs2a-sandbox.triodos.com/auth/nl/v1/auth'
--data 'response_type=code&scope=openid+offline_access+PIS%3A5e70106a-f520-47f5-80bf-a942e878d7dc&client_id=...&redirect_uri=...&code_challenge_method=S256&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'

This will result in issuance of a refresh token together with the access token.

Note: offline_access is automatically included in the scaRedirect link when recurring account access is requested.

The refresh token can be exchanged for a new access token at any time by specifying:

  • grant_type=refresh_token
  • refresh_token=your refresh token
curl "http://xs2a-sandbox.triodos.com/auth/nl/v1/token" 
-H "Content-Type: application/x-www-form-urlencoded" 
-H "Accept: application/json" 
-H "Authorization: Basic UFNETkwtRE5CLVRFU1RYWFg6T05CZnpSdjVJdTl1bUtibTdmTU1zTmJocnNQSWFyT3M1OHRPaGcxYko5bmhHX1NKeExERHdzMUhDdG04Z2JWUzltNWxRZHFnemhRLVQ3QWt6NExCaFE=" 
--data "grant_type=refresh_token&refresh_token=xhOm5yFuk90KHItmGW0KILOnJE06iH4pqyv9OHuZ_mY"

This results in a new access token and refresh token. The old access token and refresh token can no longer be used.

{
    "access_token": "bu85iKrNDlF6dqfkiC8Z5aftIXG6vm7pcaheNQB-e7c",
    "refresh_token": "lux7MKv57aevmGY3Tsu1xVuP8gwbB1HfFK6nYCiMflk",
    "scope": "openid offline_access",
    "id_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJXb09rcmdhZ2xheWN5d1pmMVcxR3lnNHNpY0RYcDhXcmcxdWdaMjF1ejY0PSIsImF1ZCI6IlBTRE5MLVBYT0tGVi1OQ0FBVVRITlVNQkVSIiwiYXV0aF90aW1lIjoiMTU1MTEwMDM3NCIsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9hdXRoXC9ubCIsImNuZiI6eyJ4NXQjUzI1NiI6IjYyMDJFOEE4QzU2NjE2NzlBMzFCQ0IxNkQwMDJGQjg0OTQ0NThCMUE0QjRCRUVDNzBFRjA4NjUwMDJBMzgzQ0MifSwiZXhwIjoxNTUxMTAwOTc2LCJpYXQiOjE1NTExMDAzNzZ9.x7vdOfZB1NPZ97uoRmP0e9T8F7N0BNNb0Rzt4SpR4As",
    "token_type": "Bearer",
    "expires_in": 600
}

Authorise the authorisation sub-resource

Use HTTP PUT on the confirmation link received in the payment initiation or consent request response to update the authorisation sub-resource with the access token to complete the authorisation process.

curl 'http://xs2a-sandbox.triodos.com/xs2a-bg/nl/v1/payments/sepa-credit-transfers/f27145bf-38e3-48db-8859-c23920da8620/authorisations/e317d847-090c-4874-bd62-57e2923a640f' 
-X PUT 
-H 'PSU-IP-Address: 192.18.13.22' 
-H 'Digest: ...' 
-H 'authorization: Bearer DWvJxxH8jDSa_BHWBhSCkgzh7Q5IPeaAs5B6Sa_1xQI' 
-H 'Signature: keyId="...",algorithm="SHA256withRSA",headers="digest x-request-id",signature="..."' 
-H 'X-Request-ID: 11111111-2222-3333-4444-48b81396a01' 
-H 'Content-type: application/json' 
-H 'Accept: application/json' 
-H 'TPP-Signature-Certificate: ...'

If the authorisation sub-resource has been successfully authorised, the response will contain scaStatus: finalised.

{
  "scaStatus": "finalised",
  "authorisationId": "e317d847-090c-4874-bd62-57e2923a640f",
  "_links": {
    "scaStatus": "/nl/v1/payments/sepa-credit-transfers/f27145bf-38e3-48db-8859-c23920da8620/authorisations/e317d847-090c-4874-bd62-57e2923a640f",
    "confirmation": "/nl/v1/payments/sepa-credit-transfers/f27145bf-38e3-48db-8859-c23920da8620/authorisations/e317d847-090c-4874-bd62-57e2923a640f"
  }
}

Multiple authorisations

Some actions (e.g. payments from some joint or company accounts) require multiple authorisations.

Multiple authorisations can be acquired in the manner specified by the NextGenPSD2 Framework.

1153

After the first authorisation sub-resource has been authorised, get the status of the payment resource to determine if the payment is fully authorised.

curl 'https://xs2a-sandbox.triodos.com/xs2a-bg/nl/v1/payments/sepa-credit-transfers/e7a0e481-48f6-45a6-91ae-bd5001bd2d05/status' 
-H 'Digest: ...' 
-H 'Signature: keyId="...",algorithm="rsa-sha256",headers="digest x-request-id",signature=..."' 
-H 'X-Request-ID: 11111111-2222-3333-4444-10489aa19491' 
-H 'Content-type: application/json' 
-H 'Accept: application/json' 
-H 'TPP-Signature-Certificate: ...'

A response containing transactionStatus: PATC (Partially Accepted Technically Correct) indicates that the payment requires additional authorisation.

{
  "transactionStatus": "PATC"
}

In this case an additional authorisation sub-resource on the payment resource must be created and authorised. This is implemented as specified by the NextGenPSD2 Framework.