Working with PSD2 XS2A API

Prerequisites

Create customer and fill SCA methods using Admin-Console (https://jrholding.atlassian.net/wiki/spaces/MPD/pages/679149583 ) or API (https://jrholding.atlassian.net/wiki/spaces/MPD/pages/685899802)

Embedded authentication

Request example:

1 2 3 4 5 6 7 8 9 10 11 12 curl --location --request POST 'https://api.mockbank.io/v1/consents' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 3d1afce9-f7fe-4b3a-89cb-cd03b7820b63' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --data-raw '{ "access": { "allPsd2": "allAccounts" }, "frequencyPerDay": 0, "recurringIndicator": false, "validUntil": "2030-10-10" }'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { "consentStatus": "received", "consentId": "{CREATED_CONSENT_ID}", "_links": { "self": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}" }, "status": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/status" }, "startAuthorisation": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations" } } }

Start authorisation

Request example:

1 2 3 4 5 6 7 8 9 curl --location --request POST 'https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --header 'X-Request-ID: e5b654ab-c95e-4014-be4f-1e043e714bca' \ --header 'Content-Type: application/json' \ --data-raw '{ "psuData": { "password": "{YOUR_CUSTOMER_PASSWORD}" } }'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 { "scaStatus": "psuAuthenticated", "authorisationId": "{CREATED_AUTHORISATION_ID}", "scaMethods": [ { "authenticationType": "SMS", "authenticationMethodId": "smstaniphonex", "authenticationVersion": "0", "name": "Verify by Phone", "explanation": "Send SMS to +489********34", "decoupled": false }, { "authenticationType": "APP", "authenticationMethodId": "vaultappcheck", "authenticationVersion": "0", "name": "Verify by App", "explanation": "Please check your app", "decoupled": true } ], "_links": { "updatePsuAuthentication": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}" }, "scaStatus": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}" } } }

Choose SCA method

Request example:

1 2 3 4 5 6 7 8 curl --location --request PUT 'https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --header 'X-Request-ID: 652d39c2-f0e4-4d24-bf05-25bcc11e064a' \ --header 'Content-Type: application/json' \ --data-raw ' { "authenticationMethodId": "smstaniphonex" }'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 { "scaMethods": [ { "authenticationType": "SMS", "authenticationMethodId": "smstaniphonex", "authenticationVersion": "0", "name": "Verify by Phone", "explanation": "Send SMS to +489********34", "decoupled": false }, { "authenticationType": "APP", "authenticationMethodId": "vaultappcheck", "authenticationVersion": "0", "name": "Verify by App", "explanation": "Please check your app", "decoupled": true } ], "_links": { "scaStatus": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}" }, "authoriseTransaction": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}" } }, "scaStatus": "scaMethodSelected", "authorisationId": "{CREATED_AUTHORISATION_ID}" }

 

Finish SCA

Request example:

1 2 3 4 5 6 7 8 9 curl --location --request PUT 'https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --header 'X-Request-ID: 59339c1d-f7f1-4112-bc18-8419a34c66f7' \ --header 'Content-Type: application/json' \ --data-raw '{ "scaAuthenticationData": "123321" }'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 { "scaMethods": [ { "authenticationType": "SMS", "authenticationMethodId": "smstaniphonex", "authenticationVersion": "0", "name": "Verify by Phone", "explanation": "Send SMS to +489********34", "decoupled": false }, { "authenticationType": "APP", "authenticationMethodId": "vaultappcheck", "authenticationVersion": "0", "name": "Verify by App", "explanation": "Please check your app", "decoupled": true } ], "_links": { "scaStatus": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}" } }, "scaStatus": "finalised", "authorisationId": "{CREATED_AUTHORISATION_ID}" }

Redirect approach

Create consent

Request example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 curl --location --request POST 'https://api.mockbank.io/v1/consents' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: b1c7e088-180c-49fc-8f45-889ad8b9381e' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --header 'TPP-Redirect-Preferred: true' \ --header 'TPP-Redirect-URI: {YOUR_REDIRECT_URL_ON_SUCCESS}' \ --header 'TPP-Nok-Redirect-URI: {YOUR_REDIRECT_URL_ON_FAIL}' \ --data-raw '{ "access": { "allPsd2": "allAccounts" }, "frequencyPerDay": 0, "recurringIndicator": false, "validUntil": "2030-10-10" }'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { "consentStatus": "received", "consentId": "{CREATED_CONSENT_ID}", "_links": { "scaRedirect": { "href": "https://https://app.mockbank.io/sca/login?redirectId={REDIRECT_ID}&consentId={CREATED_CONSENT_ID}&internalRequestId={INTERNAL_REQUEST_ID}" }, "self": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}" }, "status": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/status" } } }

 

Follow the “scaRedirect” link and use {YOUR_CUSTOMER_USERNAME} and {YOUR_CUSTOMER_PASSWORD} to log in:

Request example:

1 2 3 4 curl --location --request GET 'https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/status' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 860892f8-e91e-417e-8a7b-ca0ef9e1f7ee' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}'

Response example:

1 2 3 { "consentStatus": "received" }

 

Decoupled approach

It is similar to embedded approach. The only difference is when SCA method is being selected you need to use Admin-Console to approve or reject authorisation. No more authorisation updates required.

Create consent

1 2 3 4 5 6 7 8 9 10 11 12 curl --location --request POST 'https://api.mockbank.io/v1/consents' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 3d1afce9-f7fe-4b3a-89cb-cd03b7820b63' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --data-raw '{ "access": { "allPsd2": "allAccounts" }, "frequencyPerDay": 0, "recurringIndicator": false, "validUntil": "2030-10-10" }'

Start authorisation

1 2 3 4 5 6 7 8 9 curl --location --request POST 'https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --header 'X-Request-ID: e5b654ab-c95e-4014-be4f-1e043e714bca' \ --header 'Content-Type: application/json' \ --data-raw '{ "psuData": { "password": "{YOUR_CUSTOMER_PASSWORD}" } }'

Choose decoupled method

1 2 3 4 5 6 7 8 9 { "_links": { "scaStatus": { "href": "https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}" } }, "scaStatus": "scaMethodSelected", "authorisationId": "{CREATED_AUTHORISATION_ID}" }

Approve authorisation in Admin-Console

Verify SCA status

Request example:

1 2 3 curl --location --request GET 'https://api.mockbank.io/v1/consents/{CREATED_CONSENT_ID}/authorisations/{CREATED_AUTHORISATION_ID}' \ --header 'PSU-ID: {YOUR_CUSTOMER_USERNAME}' \ --header 'X-Request-ID: 6c4a8bef-4d5e-43e4-9889-3e01ae57158c'

Response example:

1 2 3 { "scaStatus": "finalised" }

 

OAUTH 2.0 approach

Prerequisites

Set up Client id, Client secret, Redirect urls for your organisation using Admin-Console

Example:

 

Get authorisation code

Go to link

1 https://oauth.mockbank.io/oauth/authorize?client_id={YOUR_CLIENT_ID}&response_type=code&redirect_uri={YOUR_REDIRECT_URL}

Authorise with {YOUR_CUSTOMER_USERNAME} and {YOUR_CUSTOMER_PASSWORD}

 

Confirm existing scopes

 

After that you will receive redirect to {YOUR_REDIRECT_URL}?code={AUTHORISATION_CODE}

Get Access Token

Example request:

1 2 3 4 5 curl --location --request POST 'https://oauth.mockbank.io/oauth/token' \ --header 'Authorization: Basic {YOUR_CLIENTID_CLIENT_SECRET}' \ --form 'redirect_uri={YOUR_REDIRECT_URL}' \ --form 'code={AUTHORISATION_CODE}' \ --form 'grant_type=authorization_code'

Please note that YOUR_CLIENTID_CLIENT_SECRET is effectively base64(clientid+":"+clientsecret)

Example response:

1 2 3 4 5 6 7 { "access_token": "{ACCESS_TOKEN}", "token_type": "bearer", "refresh_token": "{REFRESH_TOKEN}", "expires_in": 3649, "scope": "balances accounts transactions" }

Get Accounts

Request example using Consent-ID:

1 2 3 4 curl --location --request GET 'https://api.mockbank.io/v1/accounts' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 92b5abce-5aac-4187-b69e-8017a75bb21f' \ --header 'Consent-ID: {CREATED_CONSENT_ID}'

Request example using access token:

1 2 3 4 curl --location --request GET 'https://oauth-api.mockbank.io/v1/accounts' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 7db9a17e-b451-4126-afc7-6c78b49edb84' \ --header 'Authorization: Bearer {ACCESS_TOKEN}'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 { "accounts": [ { "externalId": "{ACCOUNT_ID}", "resourceId": "fe1184f6-4b04-4887-b227-1e3b78e827fe", "iban": "DE89370400440532013002", "bban": "370400440532013001", "pan": "120000003", "maskedPan": "12******3", "currency": "EUR", "name": "Current", "cashAccountType": "CASH", "accountStatus": "ENABLED", "bic": "MOCKDEXXXXX", "ownerName": "AlexforDel" } ] }

 

Get Transactions

Request example using Consent-ID

1 2 3 4 curl --location --request GET 'https://api.mockbank.io/v1/accounts/{ACCOUNT_ID}/transactions?bookingStatus=both' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 1ee4bd47-2f34-4a4e-9fc9-853166da2194' \ --header 'Consent-ID: {CREATED_CONSENT_ID}'

Request example using access token:

1 2 3 4 curl --location --request GET 'https://oauth-api.mockbank.io/v1/accounts/{ACCOUNT_ID}/transactions?bookingStatus=both' \ --header 'Content-Type: application/json' \ --header 'X-Request-ID: 7db9a17e-b451-4126-afc7-6c78b49edb84' \ --header 'Authorization: Bearer {ACCESS_TOKEN}'

Response example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 { "account": { "iban": "DE89370400440532013002", "bban": "370400440532013001", "pan": "120000003", "maskedPan": "12******3", "currency": "EUR" }, "transactions": { "booked": [ { "transactionId": "5dffbe98-2263-40de-b4a6-36a1a3e27d6a", "entryReference": "ref-xxx", "endToEndId": "id-xxx", "checkId": "check-xxx", "creditorId": "creditorId", "bookingDate": "2020-01-26", "valueDate": "2020-01-25", "creditorName": "creditorName", "creditorAccount": { "iban": "iban", "bban": "bban", "pan": "pan", "maskedPan": "maskedPan", "msisdn": "msisdn", "currency": "EUR" }, "ultimateCreditor": "ultimateCreditor", "debtorName": "debtorName", "debtorAccount": { "iban": "iban", "bban": "bban", "pan": "pan", "maskedPan": "maskedPan", "msisdn": "msisdn", "currency": "EUR" }, "ultimateDebtor": "ultimateDebtor", "remittanceInformationUnstructured": "remittanceInformationUnstructured", "remittanceInformationStructured": "remittanceInformationStructured", "additionalInformation": "additionalInformation", "purposeCode": "BKDF", "proprietaryBankTransactionCode": "proprietaryBankTransactionCode", "transactionAmount": { "currency": "EUR", "amount": -434.00 }, "bankTransactionCode": "bankTransactionCode" } ] } }