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)
- StepsDescription
- 1. Initiate authorization The response from the initiation resource will contain either a so called autoStartToken (when same device) or a QR code (when different devices).
- 2. Start BankID appAuto/Manual start of BankID app.
- 3. Request Decoupled Grant tokenRetrieve a DG token.
- 4. Access API resources with Decoupled Grant tokenAccess the functional APIs by using the DG token in the authorization header.
- 5. Refresh tokenRefresh a DG token.
- 6. Cancel tokenCancel the ongoing verification.
- 7. DocumentationDocumentation for decoupled flow.
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