Payments (PIS)
Specification of the API provided by Alior Bank
What is it?
How to make it work?
How is my app performing?
What do all acronyms mean?
Is this secure?
Refresh token
Consent rules
Exchange Token
API request rules
What is it?
Payment Initiation Services is a set of services that offers the possibility to initiate, complete and check the status of transfers from a customer's payment account. These APIs are mostly directed to merchants and payment service providers.
How to make it work?
You have to follow a few easy steps to register, create and build an app using our available APIs:
1. You need to create a new app by going to My APPS and clicking on "Create New APP".
2. Then you will need to register your app by filling in the form with:
- the name of the app
- the selection of services that it will use
- a short description
- OAuth redirect URL
Please remember: all services must be secured by OAuth service first, so always select the Authorisation (AS) services and then the business services that you need.
OAuth redirect URL is the site that the client will be directed to after the authorisation process ends. It can be something like: https://tppapp:8080/callback
3. Once the registration is completed, you will receive a Client ID and Secret.
The Client ID and Secret will be used with all the APIs that you use and they are provided for each app.
Please remember: the secret will be presented to you only once, so please make note of it.
If you forget the Secret you can always use the "secret reset" service.
If you have a secret and you don't know which app it is for, you can use the "verify secret" service.
Both services can be accessed from an app's profile page (go to My APPS and then click on an app profile tile).
How is my app performing?
Our sandbox offers the analytics functionality which you can use in order to get stats on success rate, latency, data usage and a few more.
You can see the statistics for a single app or all of your applications.
The analytics functionality is accessed from My APPS and then after clicking on a particular application's profile. It is on the top right secondary menu list.
What do all acronyms mean?
AIS - Account Information Services - a set of APIs that under the PSD2 regulation give TPPs access to basic information on the account and transaction history that goes three months back
AISP - Account Information Services Provider - an entity that works alongside customer and bank and offers tools that allow companies and consumers to have a consolidated view of their financial situation
AS - Authorisation Services - APIs that allow secure operations of business APIs. As standard, these include OAuth authorisation service
ASP (ASPSP) - Account Service Provider or Account Servicing Payment Service Provider - Financial institutions that offer payment accounts (e.g. current accounts, credit cards) with online access to those accounts through APIs
CAF or COF - Confirmation of Available Funds or Confirmation of Funds - a set of APIs that allow for verification if a transaction will exceed currently available funds on the payment account
PSP (PISP) -Payment Service Provider or Payment Initiation Service Provider - an organisation that offers companies, retailers, merchants etc. an online solution for accepting electronic payments
PIS - Payment Initiation Services or Payment Information Services - a set of APIs that allow initiation, completion and checking the status of transfers from payment accounts
TPP (TPPSP) - Third Party Provider or Third Party Payment Service Providers - companies that are providing services as AISPs or PISPs
XSTA (XS2A) - Access to Accounts - allows TPPs access to the bank accounts of EU consumers
Is this secure?
Yes, we use a few levels of security:
1. Basic Authentication
By registering an application in our portal you will be provided with Client ID and Secret. You should attach this to every API request in corresponding properties in the Request Header e.g:
X-IBM-Client-Secret: pC2vH1hG3qX6sE6eG0lC2pA4xW5oU4hQ0jP5dJ6dH7rR2cG0lC X-IBM-Client-Id: 52d781f6-54e6-43e8-a93e-456943e89fa5
2. OAUTH 2.0
We use the OAuth standard to allow clients to grant permission to account and payment resources for other websites. To call the desired API you will have to make a few steps:
Step 1 - authorize request - POST to our API endpoint:
POST https: //gateway.developer.aliorbank.pl/openapipl/sb/v3_0.1/auth/v3_0.1/authorize --header 'X-JWS-SIGNATURE: ' \ --header 'X-REQUEST-ID: UUID format (Variant 1, Version 1)' \ --header 'X-IBM-Client-Id: pC2vH1hG3qX6sE6eG0lC2pA4xW5oU4hQ0jP5dJ6dH7rR2cG0lC' \ --header 'X-IBM-Client-Secret: 52d781f6-54e6-43e8-a93e-456943e89fa5 \ --header 'contentType: application/json' \ --data '{ { "requestHeader": { "requestId": UUID format (Variant 1, Version 1) the same value as in X-REQUEST-ID, "userAgent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0", "ipAddress": "000.000.0.0", "sendDate": "2017-11-24T14:13:05.424Z", "tppId": "myId", "isCompanyContext": false, "psuIdentifierType": "string", "psuIdentifierValue": "string" }, "response_type": "code", "client_id": "1b3456d3-bc33-4190-80c8-623bb9a0b12d", "scope": "ais-accounts", "scope_details": { "privilegeList":[ {"accountNumber":"", "ais-accounts:getAccounts":{"scopeUsageLimit":"multiple"} } ], "scopeGroupType":"ais-accounts", "consentId":"MYTPP-b3ae3d34", "scopeTimeLimit":"2019-09-01T04:45:48", "throttlingPolicy":"psd2Regulatory" }, "redirect_uri": "http://tppapp:3000/auth/oauth2/callback", "state": "your state" } }'
*The meaning of these parameters can be found in the API definition.
In response, the API will send the AuthorizeResponse object (HTTP_CODE 200). In this object you will find the aspspRedirectUri parameter with address to our Internet Banking Application Simulator, where the PSU can review and authenticate grants for your application. You have to redirect the PSU to this URL address.
The redirection call will send the PSU browser on the following form:
The username and password are as follows:
username | password | account number(s) | brand | |
1 | 22058375 | 12345678 | PL63249000050000400030900682 PL50249000050000400076134538 | Alior Bank - Individual Customer |
2 | 60370698 | 12345678 | PL47249000050000453075450686 | Alior Bank - Business Customer |
3 | 39732163 | 12345678 | PL50249010570000990039732163 | Alior Bank Exchange Currency Poland |
We will send the result of PSU authentication via the PSU browser. You can go to the next step after you receive access_code
access_code=AAJSLgy-OMo9DlDpYINxTB-Njawqz0bfmuoPRUG5yJea0zkgcURr_W3sCADKH3oWzLum-jiRuwGpn0AS9_SJcJGBa7Nkf_evHUm7zz119yyqw3DxdZIrUc6lHI0g-fjCV8hTP7zt....
Step 2 - get access Token - POST to our API gateway with basic authentication and your access code from step 1:
curl --request POST \ --url https: //gateway.developer.aliorbank.pl/openapipl/sb/v3_0.1/auth/v3_0.1/token \ --header 'X-JWS-SIGNATURE: ' \ --header 'X-REQUEST-ID: UUID format (Variant 1, Version 1)' \ --header 'X-IBM-Client-Id: pC2vH1hG3qX6sE6eG0lC2pA4xW5oU4hQ0jP5dJ6dH7rR2cG0lC' \ --header 'X-IBM-Client-Secret: 52d781f6-54e6-43e8-a93e-456943e89fa5 \ --header 'contentType: application/json' \ --data '{ { "requestHeader": { "requestId": UUID format (Variant 1, Version 1) the same value as in X-REQUEST-ID , "userAgent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0", "ipAddress": "000.000.0.0", "sendDate": "2017-11-24T14:13:05.424Z", "tppId": "your id", "isDirectPsu": false }, "Code": "7rXMHbKUVIf…..", "grant_type": "authorization_code", "redirect_uri": "http://tppapp:3000/auth/oauth2/callback", "client_id": "52d781f6-54e6-43e8-a93e-456943e89fa5", "client_secret": "pC2vH1hG3qX6sE6eG0lC2pA4xW5oU4hQ0jP5dJ6dH7rR2cG0lC" } }'
Please take note that the field with name "Code" where you put the access code from step 1 starts with a capital letter.
In response, you will get your access Token with the basic information about the user accepted scope, token valid time and so on:
{ "token_type": "bearer", "access_token": "kYzZlNTFiN2UtMj……", "expires_in": 1560241352000, "scope": "ais-accounts", "scopeDetails": { "consentId": "MYTPP-b3ae3d34", "scopeTimeLimit": "2019-09-01T04:45:48", "throttlingPolicy": "psd2Regulatory", "scopeGroupType": "ais-accounts", "privilegeList": [ { "ais-accounts:getAccounts": {"scopeUsageLimit": "multiple"}, "accountNumber": "" }] }, "responseHeader": { "requestId": "UUID format (Variant 1, Version 1)", "sendDate": "2019-03-13T08:22:32.522Z", "isCallback": false } }
This token will give you access to the information about the PSU accounts.
STEP 3 - API call - now you can use your accessToken to call API like for example:
curl --request POST \ --url https: //gateway.developer.aliorbank.pl/openapipl/sb/v3_0.1/accounts/v3_0.1/getAccounts \ --header 'AUTHORIZATION: Bearer kYzZlNTFiN2UtMj……' \ --header 'X-JWS-SIGNATURE: ' \ --header 'X-REQUEST-ID: UUID format (Variant 1, Version 1)' \ --header 'X-IBM-Client-Id: pC2vH1hG3qX6sE6eG0lC2pA4xW5oU4hQ0jP5dJ6dH7rR2cG0lC' \ --header 'X-IBM-Client-Secret: 52d781f6-54e6-43e8-a93e-456943e89fa5 \ --header 'contentType: application/json' \ --data '{ {"requestHeader": {"requestId":"d2da0db0-4570-11e9-81cb-53957d7bb4d1", "userAgent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0", "ipAddress":"000.000.0.0", "sendDate":"2019-03-13T09:17:13Z" ,"tppId":"your id", "token":"Bearer kYzZlNTFiN2UtMj……", "isDirectPsu":false, "directPsu":false } } }'
In response, you will get the PSU data. In this example data are as follows:
{ "accounts": [ { "accountNumber": "PL46249……..", "accountType": { "code": "4000", "description": "Rachunek oszczednosciowo - rozliczeniowy" }, "accountTypeName": "Konto Wyższej Jakości" }, { "accountNumber": "PL07249……..", "accountType": { "code": "4000", "description": "Rachunek oszczednosciowo - rozliczeniowy" }, "accountTypeName": "Konto Walutowe" }, { "accountNumber": "PL22249……..", "accountType": { "code": "4000", "description": "Rachunek oszczednosciowo - rozliczeniowy" }, "accountTypeName": "Konto Jakże Osobiste" }, { "accountNumber": "PL85249……..", "accountType": { "code": "4000", "description": "Rachunek oszczednosciowo - rozliczeniowy" }, "accountTypeName": "Konto Jakże Osobiste" } ], "responseHeader": { "requestId": "UUID format (Variant 1, Version 1)", "sendDate": "2019-03-13T09:17:30.553Z", "isCallback": false } }
Please take note that the field AUTHORIZATION in request header and the requestHeader : Object.token have the same value.
3. Certificates
In a production environment every TPP should have a pair of eIDAS certificates:
- QWAC (Qualified certificate for website authentication)
- QCert for ESeal (Qualified certificate for electronic seal)
Certificates should be signed by one of the qualified Certificate Authority, according to list on https://webgate.ec.europa.eu/tl-browser .
In a sandbox environment you can access our API:
- without any certificates
- with test certificate from KIR (CA http://www.elektronicznypodpis.pl/certyfikaty/mkw2017test.crt )
- with another trust CA (after contact with the Bank and agree on details - by contact form)
In case your certificates are about to expire or you want to configure a new set of certificates for your application, please provide us with a new set of certificates in advance (at least 2-3 working days). Please make sure to specify the clientId and the kid of your new certificate.
4. Communication protocol
As the communication protocol, HTTP / 2 or HTTP 1.1 will be used, secured with TLS 1.2+ protocol with mutual authentication of the client and the server using X.509v3 (Mutual authentication) certificates - eIDAS QWAC (Qualified certificate for website authentication) certificate. Due to the requirement to ensure non-repudiation (signing requests and responses), only the POST method will be used in http communication.
5. JWS
At the message level, to ensure non-repudiation, a JSON Web Signature should be used, according to the RFC 7515 standard (https://tools.ietf.org/html/rfc7515). For JWS we use QCert for ESeal certificate type. The signature must be placed in every request in the header named X-JWS-SIGNATURE. Signature is in detached form and contents sign for the whole body. Responses from ASPSP are also signed with Bank certificate.
The header X-JWS-Signature response field is enriched with data in kid, x5u and x5t#S256 fields.
Example:
eyJhbGciOiJSUzI1NiIsImtpZCI6IkFMSU9SLVBMLVNCLVBTRDItSldTLVBVQkxJQy0yMDIwLTAxIiwieDV1IjoiaHR0cHM6Ly9BZGRyZXNzV2l0aFB1YmxpY0tleSIsIng1dCNTMjU2IjoiNDdERVFwajhIQlNhLV9USW1XKzVKQ2V1UWVSa201Tk1wSldaRzNoU3VGVSJ9..
Content:
{"alg":"RS256","kid":"ALIOR-PL-SB-PSD2-JWS-PUBLIC-2020-01","x5u":"https://AddressWithPublicKey","x5t#S256":"47DEQpj8HBSa-_TImW+5JCeuQeRkm5NMpJWZG3hSuFU"}..
The TPP can use certificate which was registered during onbording process.
The new is that the TPP can register more than one certificate and manage it by kid which is introducing in X-JWS-Signature.
This option is allowed by sending email form to our Administrators.
This functionality can be used when you want to change the certificate dynamically, for example if you know that your certificate will be expired in near future and do you want to use new one.
6. IP address control
IP address of PSU's terminal device is required when isDirectPsu=true and for every PIS service except for getPayment, getBundle, getRecurring.
Refresh Token
TPP can take new access token using refresh token (if bank issued it).
The Alior Bank support this functionality for AIS and PIS services.
This process is mandatory in situations when the date of original token had expired.
The refresh token can be issue for the same priviliges as in original token, except for situation when the TPP use PIS services.
For the PIS services TPP have to change refresh token for new token with priviliges for getPayment, getRecurringPayment and getBundle services.
This process allows to take status of PIS transactions and replace exchange token process from version v2.1.1.1 and v2.1.1.2.
Example for PIS:
1. Get original token
When you receive an authorization code you should put it into code field in the request, like below and send it (this step doesn't change in proportion to previous versions).
POST https://....................../v3_0.1/auth/v3_0.1/token HTTP/1.1
Accept-Language: PL
Accept-Charset: UTF-8
X-JWS-SIGNATURE: xxxxxxxxxxxxxxxxxxxxxxx
X-REQUEST-ID: c63673bb-3ed7-11eb-b74b-e990904ae302
X-IBM-Client-Id: xxxxxxxxxxxxxxxxxxxxxxx
X-IBM-Client-Secret: xxxxxxxxxxxxxxxxxxxxxxx
Accept-Encoding: gzip
Content-Type: application/json
REQUEST:
{"requestHeader":
{"requestId":"c63673bb-3ed7-11eb-b74b-e990904ae302",
"sendDate":"2020-12-15T14:16:42.928Z",
"tppId":"2756940759302144"},
"grant_type":"authorization_code",
"redirect_uri":"http://tppapp:3000/auth/oauth2/callback",
"client_id":"f3257438-537d-4fb2-af69-0bb2a6672a34",
"Code":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
RESPONSE:
{
"token_type": "Bearer",
"access_token": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"refresh_token": "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"expires_in": 298,
"scope": "pis",
"scope_details": {
"consentId": "xxxxxxxxxxxxxxxxx",
"scopeTimeLimit": "2021-01-10T10:37:39.087Z",
"throttlingPolicy": "psd2Regulatory",
"privilegeList": [{"pis:domestic": {
"transferData": {
"amount": "195.27",
"description": "domestic Elixir",
"currency": "PLN"
},
"system": "Elixir",
"sender": {"accountNumber": "PL50249000050000400076134538"},
"deliveryMode": "StandardD1",
"scopeUsageLimit": "single",
"recipient": {
"nameAddress": {"value": [
"Recipient Name1",
"Recipient Name2",
"Recipient Address 1",
"Recipient Address 2"
]},
"accountNumber": "PL15101015280020332220000000"
},
"executionMode": "Immediate"
}}]
},
"responseHeader": {
"requestId": "c63673bb-3ed7-11eb-b74b-e990904ae302",
"sendDate": "2020-12-15T13:16:44.541Z",
"isCallback": false
}
}
The access_token for PIS transfer can be used only one time.
After that you have to change scope details as described below.
2. Exchange refresh token content
REQUEST:
POST https://...................................../v3_0.1/auth/v3_0.1/token
Accept-Language: PL
Accept-Charset: UTF-8
X-JWS-SIGNATURE: xxxxxxxxxxxxxxxxxxxxxxxxxx
X-REQUEST-ID: 2d65cf3a-3ebd-11eb-b74b-27448d1e8c3f
X-IBM-Client-Id: xxxxxxxxxxxxxxxxxxxxxxx
X-IBM-Client-Secret: xxxxxxxxxxxxxxxxxxxxxxxxx
Accept-Encoding: gzip
Content-Type: application/json
{"requestHeader":{
"requestId":"2d65cf3a-3ebd-11eb-b74b-27448d1e8c3f",
"sendDate":"2020-12-15T10:06:19.632Z",
"tppId":"PSDES-BDE-3DFD21"},
"grant_type":"refresh_token",
"refresh_token":"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"scope":"pis",
"scope_details":{
"privilegeList":[
{
"pis:getPayment":{"scopeUsageLimit":"multiple",
"paymentId":"OA-ij10SzjRTdyJLy9rp9006Q",
"tppTransactionId":"12345678"}}],
"scopeGroupType":"pis",
"consentId":"xxxxxxxxxxxxxxxxxxxx",
"scopeTimeLimit":"2021-01-10T10:37:39.087Z",
"throttlingPolicy":"psd2Regulatory"}
}
RESPONSE:
{
"token_type": "Bearer",
"access_token": "zzzzzzzzzzzzzzzzzzzzzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"refresh_token": "yyyyyyyyyyyyyyyyyyyyyyyyyyybbbbbbbbbbbbbbbbbbbbbbbb",
"expires_in": 600,
"scope": "pis",
"scope_details": {
"consentId": "xxxxxxxxxxxxxxxx",
"scopeTimeLimit": "2021-01-10T10:37:39.087Z",
"throttlingPolicy": "psd2Regulatory",
"privilegeList": [{"pis:getPayment": {
"tppTransactionId": "12345678",
"paymentId": "OA-ij10SzjRTdyJLy9rp9006Q",
"scopeUsageLimit": "multiple"
}}]
},
"responseHeader": {
"requestId": "2d65cf3a-3ebd-11eb-b74b-27448d1e8c3f",
"sendDate": "2020-12-15T10:06:21.294Z",
"isCallback": false
}
}
Please note, that if you wants to exchange content of token, you have to add scope_details field.
If you did that than next refresh procedure can be done without this field as desribed below.
3. Next refresh PIS token
REQUEST:
POST https://........................../v3_0.1/auth/v3_0.1/token
Accept-Language: PL
Accept-Charset: UTF-8
X-JWS-SIGNATURE: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-REQUEST-ID: 6556622c-3ed8-11eb-b74b-9dab7983d9b7
X-IBM-Client-Id: xxxxxxxxxxxxxxxxxxx
X-IBM-Client-Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept-Encoding: gzip
Content-Type: application/json
{"requestHeader":{
"requestId":"6556622c-3ed8-11eb-b74b-9dab7983d9b7",
"sendDate":"2020-12-15T01:21:09.895Z",
"tppId":"xxxxxxxxxxxxxxxxxxx"
},
"grant_type":"refresh_token",
"redirect_uri":"xxxxxxxxxxxxx",
"client_id":"xxxxxxxxxxxxxxxx",
"refresh_token":"yyyyyyyyyyyyyyyyyyyyyyyyyyybbbbbbbbbbbbbbbbbbbbbbbb",
RESPONSE:
{
"token_type": "Bearer",
"access_token": "cccccccccccccccxxxxxxxxxxxxxxxxxxxxxxx",
"refresh_token": "wwwwwwwwwwwwwwwwwfffffffffffffffffffffffffff",
"expires_in": 600,
"scope_details": {
"consentId": "xxxxxxxxxxxxxx",
"scopeTimeLimit": "2021-01-10T10:37:39.087Z",
"throttlingPolicy": "psd2Regulatory",
"privilegeList": [{"pis:getPayment": {
"tppTransactionId": "12345678",
"paymentId": "OA-ij10SzjRTdyJLy9rp9006Q",
"scopeUsageLimit": "multiple"
}}]
},
"responseHeader": {
"requestId": "6556622c-3ed8-11eb-b74b-9dab7983d9b7",
"sendDate": "2020-12-15T13:21:11.700Z",
"isCallback": false
}
}
This refresh token proces can be repeated as long as you need but take a note that should be connected with real needs.
The best solution is to call refresh token before next call but no often then 10 minutes.
Additional rules:
The fields redirect_uri and client_id and scope_details are optional for refresh token proces.
The fields scope, refresh_token, grant_type are mandatory.
If the redirect_uri field is set than value should be consistent with original token.
If the client_id field is set than value should be consistent with original token and client id header value.
The scope_details field have to be set if you want to exchange content of PIS refresh token for getPayment, getRecurringPayment, getBundle services. In other cases the scope_details will be ignored.
It is not possible to refresh token from version v2_1_1.1 or v2_1_1.2 but it is possible to use this token on version v3_0.1.
Be advised that depending on the e-banking system in which the account is held and also on executionMode and deliveryMode, some payment systems may not be available.
Consent rules
You should take careful note of what you are setting in authorize request. We set a few rules to this step, which allow us to present your consent in our confirmation form. These rules are:
- We present a homogeneous, consistent scope of consents for all privileges received from TPP.
- The PSU gives the uniform consent, so you have to set the same consent privileges for all accounts listed in scope_details
Please take into account the following logic:
- scopeTimeLimit value in /authorize service should not be greater than 180 days (starting from May 28, 2023 in Sandbox and from July 25, 2023 on Production)
- scopeUsageLimit attribute can be set to single mode only
- the fields scopeGroupType have to be set with value pis
- you can not set privileges from other scopes
- the only one privilige is allowed
Exchange Token
At this point API does not support Exchange Token.
API request rules
Having the consent for PIS the TPP can send payment initialisation request. This request has to fulfil the rules as follows:
- the field tppTransactionId has to be set by TPP
- the TPP has to copy sender account number from token response
- all of the request data have to be compliance with consent
- please be aware that for split payment transactions, the description field will not be presented to the user and transferred to the tax office (despite it being obligatory on production environment). That is the value of the spDescription field, which will be transferred to the tax office and visible in the transaction history.
- in services related to tax transfer (authorize, tax, bundle, recurring), the obligationId field is mandatory even if it is empty.
- after the 15th of January 2025 in the recipient's data, provided in requests for EEA and nonEEA transfer services, it is mandatory to complete at least the first line with the recipient's name and the third line with the recipient's address.