Handelsbanken has launched a new version of the Sandbox

Handelsbanken has launched a new version of the Sandbox today the 16th of April. Kindly follow the instructions in the developer portals new Sandbox tab and change your test data accordingly to continue testing.

Decoupled Authorization flow

Here you'll find the steps required to authorize the end user with the decoupled grant, for Handelsbanken's PSD2 APIs.

 

 

General information

This page describes the details of how to implement PSU authorization with the SCA method Decoupled (with Mobile BankID), via Handelsbanken's PSD2 APIs. Please note that this is only available to Swedish customers. When the process is successfully completed, you will receive a Decoupled Grant access token (DG).

An overview of the steps in these guidelines can be found here: SCA Decoupled - Authorization flow chart

These guidelines are valid for the Live environment and Sandbox environment, however, please note that in the Live environment, the endpoints are requested with a TPP certificate (issued by a QTSP).

Sandbox Gateway Host URL

When testing our APIs in our Sandbox environment, please ensure that the below base URL is used in the calls.

Live Data Gateway Host URL

When using our APIs in the Live environment, please ensure that the below base URL is used in the calls.

 

Step-by-step guide (for Decoupled Authorization)

 

Step 1: Initiate authorization

The PSU authorization process starts with an initiation step against Handelsbanken's Decoupled Grant API

Request

curl -X POST https://api.handelsbanken.com/mlurd/decoupled/mbid/initAuthorization/2.0 \
--key <Your private key file> \
--cert <Your public cert file> \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{ \
"client_id":"f31b7318-8f21-4eaf-8817-6b5e4e02d6bc", \
"scope":"AIS:22aa3559-577d-441c-b9e6-664ac3311a3e", \
"psu_client_ip":"<IPv4 or IPv6 address>" \
"psu_id" : "19030303333”, \
"bisa_same_device" : "true” \
}'

The above request is an example against the Live environment.

See below for the type of information that needs to be in your request. Please make sure you replace the example values with the correct ones in your request.

                                                                                                                                                                                                                                                                                                                                                               
Parameter Description Example
client_id Your application's client-id.
            Mandatory.
f31b7318-8f21-4eaf-8817-6b5e4e02d6bc
scope "AIS" for Account / Card information plus consent-id
"PIS" for Payments plus payment-id
"CBPII" for Confirmation of Funds plus consent-id.
 Mandatory.
AIS:22aa3559-577d-441c-b9e6-664ac3311a3e
PIS:58cdfef9-7f6e-476e-a1af-c54c0a9a3135
CBPII:69b50cd4-33d9-47b6-bfe7-98aea7bda22d
psu_client_ip IP address of the PSU's device. Both IPV4 and IPV6 address formats are allowed.
Mandatory.
192.102.28.2
psu_id PSU Personal Id which is the customer's Swedish Personnummer (12 digits).
Optional.
19030303333
bisa_same_device Mandatory. Data type : boolean. Set value to true when the customer BankID app (BISA) run on the same device as the TPP client. An autoStartToken will be returned
in the response. Set value to false when the BISA app run on a different device then the TPP client. A complete QR code will be returned in the response.
true
 

Response

Response when bisa_same_device=true

HTTP/1.1 200 OK
{
 "auto_start_token": "d7c5ea79-a677-44e4-8259-772945ade2f6",
 "sleep_time": 2000,
 "_links": {
  "token": {
   "href": "https://api.handelsbanken.com/mlurd/decoupled/mbid/token/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797",
   "hints": {
    "allow": ["POST"]
   }
  },
  "cancel": {
   "href": "https://api.handelsbanken.com/mlurd/decoupled/mbid/cancel/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797",
   "hints": {
    "allow": ["POST"]
   }
  }
 }
}

Response when bisa_same_device=false

HTTP/1.1 200 OK
{
 "qr_code": "bankid.d7c5ea79-a677-44e4-8259-772945ade2f6.0.77024e4d........",
 "sleep_time": 2000,
 "_links": {
  "token": {
   "href": "https://api.handelsbanken.com/mlurd/decoupled/mbid/token/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797",
   "hints": {
    "allow": ["POST"]
   }
  },
  "cancel": {
   "href": "https://api.handelsbanken.com/mlurd/decoupled/mbid/cancel/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797",
   "hints": {
    "allow": ["POST"]
   }
  }
 }
}

The above response is an example against the Live environment.

                                                                                                                                                                                                                                                                                                      

Description of response parameters.

Parameter Description Example
auto_start_token Optional, will only be returned when bisa_same_device=true. Token to use when starting BankID app. d7c5ea79-a677-44e4-8259-772945ade2f6
qr_code Optional, will only be returned when bisa_same_device=false. A complete QR-code with limited lifetime. d7c5ea79-a677-44e4-8259-772945ade2f6
sleep_time The minimum number of milliseconds to wait before invoking the token endpoint (Step 3) and between each call to that endpoint. 1000
links.token.href Link to the token endpoint, with your unique session-id, to use in Step 3. https://api.handelsbanken.com/mlurd/decoupled/mbid/token/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797
links.cancel.href Link to the cancel endpoint, to cancel the ongoing authorization process. https://api.handelsbanken.com/mlurd/decoupled/mbid/cancel/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797

 

Step 2: Start BankID app

This step is out of scope when it comes to the responsibility and support from Handelsbanken. Instead, please refer to the "Integrationsguide" found here: BankID's technical support page

The BankID app can be started in different ways, but in our case, the autostart token from the previous step must be used either by launching the BankID app on the same device (see chapter 3 in BankID's guidelines) or by using a QR code when the BankID app is launched on another device (see chapter 4 in Bank ID's guidelines).

 

Step 3: Request Decoupled Grant token

The final step in the DG authorization process is to retrieve an access token, by calling the Decoupled Grant API

Request

This is the request where the URL was given by the response in Step 1. It should be called by polling repeatedly (in the sleep-time interval given by the response in Step 1, until the response contains a "COMPLETE" result.

curl -X POST https://api.handelsbanken.com/mlurd/decoupled/mbid/token/2.0?sessionId=458f3d8f-c013-4ca0-b1f9-d15850341797",
--key <Your private key file> \
--cert <Your public cert file> \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{}'

The above request is an example against the Live environment.

Response - in progress or cancelled by PSU

This is what the response looks like when authorization has not yet been completed by the end user (PSU).

HTTP/1.1 200 OK
{
"result" : "userSing"
}

                                                                                                                           

Parameter Description Example
result Information about which "status" the token request is in:
outstandingTransaction - The PSU has not yet verified in BankID app
noClient - The PSU has cancelled the verification in BankID app
started - The PSU has cancelled the verification in BankID app
userSign - The PSU has cancelled the verification in BankID app
userSing
 

If the end user (PSU) cancels the authorization, the session towards Mobile BankID will be cancelled. To complete the authorization, a new session towards Mobile BankID needs to be initiated.

Response - completed

This is what the response looks like when the authorization has been successfully completed by the end user (PSU).

HTTP/1.1 200 OK
{
"result" : "COMPLETE”,
"access_token" : "QVQ6YTM2ZmYyMmIyYjFkMS00M2VlLTk5MWMt",
"token_type" : "Bearer",
"expires_in" : 123456,
"refresh_token" : "VlQ6ZjNkY2FkMTUyOThhNC00OGMwLTkzNDct"
}

The above response is an example.

                                                                                                                                                                                                                                                                                                                                                               

Parameter Description Example
result Information about which "status" the token request is in:
COMPLETE - the PSU has verified and the response includes token info.
COMPLETE
access_token The access token to be used in Authorization header in the coming requests against the endpoints of the functional APIs (see Step 4 below).
Note! This token can only be used for the particular scope+PSU consent, that was given at initiation of the authorization in Step 1.
QVQ6YTM2ZmYyMmIyYjFkMS00M2VlLTk5MWMt
token_type Always the value "Bearer". Bearer
expires_in Number of seconds the access_token is valid.
Always use this value rather than hardcoding a set time value (e.g. 24h).
e.g. 123456 (please check what you receive in the response.)
refresh_token A token that can be used when the access_token has expired, but the consent is still valid. This way, you don't need the PSU to grant a new consent. See Step 5 how to do this. VlQ6ZjNkY2FkMTUyOThhNC00OGMwLTkzNDct

Response - error handling

HTTP status 400, 500 or 503 can be returned. Error handling is SHB specific but inspired by the Oauth2 specification. Status 500 Internal Server Error and 503 Service Not Available is returned with an empty body: "{}".

HTTP/1.1 200 OK
{
"error" : "mbid_user_cancelled"
}

The table below describes the error situations when status code 400 is returned.

error Description
invalid_request Normally occuring when a TPP invokes the resource after the transaction has been terminated, either because it was complete or an error occured.
mbid_invalid_polling Resource invoked to often. Check that frequency is greater then the time returned in the initAuthorization call (1 second).
mbid_transaction_expired Maximum time has been reached, longers than 2 minutes since order was created. The order is cancelled in BankID systems before response is returned.
mbid_cancelled BankID has cancelled the transaction, ex the PSU started a new transaction
mbid_user_cancelled The PSU has cancelled the transaction in BISA.
mbid_start_failed When autostartToken was used it could be caused by no BISA app installed on the PSU device. If QR code was used, it could be that the QR code scanned was to old or that the PSU didn’t scan at all.
mbid_error Other BankID related errors, error situations that is none of the above.
mbid_not_shb_activated PSU uses an external issued MBID that has not been confirmed by the PSU in either our mobile apps or internet service during login.
not_shb_approved PSU does not have the correct agreement to confirm TPP usage.

 

Step 4: Access API resources with Decoupled Grant token

The authorization process is finished and you can now call our APIs!

Using the DG access token, the endpoints of the functional APIs can be called and you can retrieve balances and transactions (using the Account Information API) or initiate and execute a payment (using the Payment Initiation API).

Please note: the access token from the previous step (Step 3: Request Decoupled Grant token) is sent in the “Authorize” HTTP-header.

See more details about this step in the links below:

Accounts & Cards - Step 4: Call the Account / Card Account Information APIs

Payments - Step 4: Request payment execution

Confirmation of Funds - Step 4: Validate consent (using ACG/DG token)

 

Step 5: Refresh token

**Refresh tokens are only issued in the Authorization flow for the Account/Card-Account Information requests.**

If the Decoupled Grant access token (DG) expires, a new DG can be requested using the refresh token that was issued together with the DG (Step 3: Request Decoupled Grant token). Typically, this should be made when a DG token has expired (after 24 hours), but the consent is still valid. This way, you don't need the PSU to grant a new consent.

Request

curl -X POST https://api.handelsbanken.com/mlurd/oauth2/token/1.0 \
--key <Your private key file> \
--cert <Your public cert file> \
-H 'Accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token&refresh_token=VlQ6ZjNkY2FkMTUyOThhNC00OGMwLTkzNDct&client_id=bb089f8c-8a28-4455-88ad-a572c9f794b0'

The above request is an example against the Live environment.

See below for the type of information that needs to be in your request. Please also refer to the API documentation for the full definitions, descriptions and codes Refresh Token Grant (OAuth 2.0)

Please make sure you replace the example values with the correct ones in your request.

                                                                                                                                                                                                                                                               

Parameter Description Example
grant_type The type of token call. Should be "refresh_token".
Mandatory.
refresh_token
refresh_token The refresh token from Step 3.
Mandatory.
VlQ6ZjNkY2FkMTUyOThhNC00OGMwLTkzNDct
client_id Your application's client-id.
Mandatory.
bb089f8c-8a28-4455-88ad-a572c9f794b0

Response

This is what the response looks like when an access token has been successfully retrieved from the authorization server.

HTTP/1.1 200 OK
{
"access_token":"QWVX8BGW2YxYtBmZjOC30Yzg3LzYyOGU0NTg5YmB4",
"expires_in":123456,
"token_type":"Bearer"
}

The above response is an example.

                                                                                                                                                                                                                                             

Parameter Description Example
access_token The access token to be used in Authorization header in coming requests against the endpoints of the functional APIs (see Step 4 above).
Note! This token can only be used for the particular scope+PSU consent, that was given at initiation of the authorization in Step 1.
QWVX8BGW2YxYtBmZjOC30Yzg3LzYyOGU0NTg5YmB4
expires_in Number of seconds the access_token is valid.
Always use this value rather than hardcoding a set time value (e.g. 90 days).
e.g. 123456 (please check what you receive in the response.)
token_type Always the value ”Bearer”. Bearer

Step 6: Cancel token

Cancel an ongoing verification. A TPP that provides a possibility for a PSU to cancel the verification in its user interface, can use this resource to cancel the transaction in the BankID enviroment. If the PSU decides to confirm again it may fail because the PSU already has an ongoing transaction, this situation will be prevented if cancel is implemented. The resource must only be invoked for transactions that are still alive (a initAuthorization must have been successful and no previous error from Authorization Server from token call).

Request

curl -X POST https://api.handelsbanken.com/mlurd/decoupled/mbid/cancel/2.0 \
--key <Your private key file> \
--cert <Your public cert file> \
-H 'Accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d '{}'

Response

Response will always try to return 200 OK, regardless if the cancellation was successful or not. The response body will always be a empty json object.

7. Documentation

Documentation for the decoupled authorization flow, describes the techincal details for the this authorization flow.

Link to document Decoupled implementation document