Open Banking
Open Banking is a modern approach to providing financial services that offers customers more opportunities to manage their funds conveniently and effectively.
With the user’s consent, Open Banking allows authorized payment service providers to access information about accounts held at various banks or other financial institutions. This enables customers to view account balances and transaction history, monitor fund movements, and initiate payments—all within a single app.
Regulatory APIs
| Version | Description of changes | Date |
|---|---|---|
| v.1.0 | Original version | 30.04.26 |
This section provides a general description of specialized interfaces. A detailed description corresponding to the version used by the NPP is available at https://docs.api.upc.ua/api-services/compliance-apis
The account servicing TPP provides access to the user’s account to a third-party provider (TPP) through the following specialized interfaces:
- PIS (Payment Initiation Service)
Base URL path: /pis/v2/
API version: v2
- AIS (Account Information Service)
Base URL path: /ais/v2/
API version: v2
| Version | Description of changes | Date |
|---|---|---|
| v.1.0 | Original version | 30.04.26 |
| v.1.1 | A clarification has been added to section 2.4 regarding the 31-day period for transaction history | 05.06.26 |
1. PIS (Payment Initiation Service)
The Payment Initiation Service (PIS) enables a third-party payment service provider (TPP) to initiate payments on behalf of a payment service user (PSU). To initiate a payment, the TPP requires authorisation (transaction confirmation) from the PSU. The PSU provides consent within the framework of a Strong Customer Authentication (SCA) session.
Main functions of the PIS interface:
- 1.1. Payment initiation
The TPP sends a payment initiation request using the POST /pis/v2/payments/{payment-product} method. The request includes the payer’s account details (IBAN), the transfer amount and currency, the payee’s details (name, identifier, account IBAN), and the payment purpose details. The platform returns a unique transaction identifier (paymentId) and the initial payment status (RCVD — received).
- 1.2. Authorisation initiation (SCA)
After initiating the payment, the TPP invokes the POST /pis/v2/payments/{payment-product}/{payment-id}/authorisations method to explicitly initiate the authorisation procedure. Two SCA modes are supported:
Decoupled SCA: the platform returns a message for the PSU ($.psuMessage), for example: “Authorise the payment in the bank’s mobile application.” The PSU authorises the payment directly in the bank’s application (for example, via a push notification).
Redirect SCA: the platform returns a redirect URL for the PSU ($.links.scaRedirect.href). The TPP redirects the PSU to the bank’s page for authentication and payment confirmation. After authorisation, the bank redirects the PSU back to the TPP using the specified address (Client-Redirect-URI).
- 1.3. Payment status check
The TPP may check the current payment status using the GET /pis/v2/payments/{payment-product}/{payment-id}/status method. The platform returns the current transaction status ($.transactionStatus), for example, ACCC (successfully completed). Supported payment products: instant-credit-transfers.
2. AIS (Account Information Service) — Account Information Service
The Account Information Service (AIS) enables a third-party payment service provider (TPP) to access account information of a payment service user (PSU). To access such information, the TPP must first obtain authorisation (consent confirmation) from the PSU. Based on the confirmed consent, the TPP may obtain information on the PSU’s accounts, including balances, transaction history, and other relevant data.
Main functions of the AIS interface:
- 2.1. Creation of consent for account access
The TPP sends a consent creation request using the POST /ais/v2/consents/account-access method. The request includes: the account IBAN, access rights ("accountDetails", "balances", "transactions"), the consent type, the recurring access indicator (recurringIndicator), the validity period (validTo), and the maximum request frequency per day (frequencyPerDay, maximum 4 times per day). The platform returns a unique consent identifier (consentId).
- 2.2. Consent authorisation (SCA)
After creating the consent, the TPP initiates authorisation using the POST /ais/v2/consents/account-access/{consent-id}/authorisations method. Two SCA modes are supported (Decoupled and Redirect — аналогічно до PIS). The TPP checks the consent status using the GET /ais/v2/consents/account-access/{consent-id}/status method until the status “valid” or “rejected” is obtained.
- 2.3. Retrieval of the list of accounts
The TPP retrieves the list of the PSU’s accounts using the GET /ais/v2/accounts?withBalance=true method, providing the Consent-ID header with the identifier of the confirmed consent. The platform returns a list of accounts including IBAN, currency, resource identifier, account name, and current balances.
- 2.4. Retrieval of transaction history
The TPP retrieves the transaction history for an account using the GET /ais/v2/accounts/{account-id}/transactions method. The bank provides transaction history for the last 31 days, taking into account the request date. If the bank provides transaction history for a period from 31 to 90 days, the request may be processed without additional SCA authorisation. To obtain transactions older than 90 days, a one-time AIS consent is required (recurringIndicator: false). Pagination is supported using the limit and offset parameters.
| Version | Description of changes | Date |
|---|---|---|
| v.1.0 | Original version | 30.04.26 |
1. General Technical Specifications
- 1.1. Architecture and Standard
Specialized interfaces are built on REST API principles and are based on the XS2A (Access to Account) specification, implemented via the Open Banking Platform (OBP). XS2A is a standard interface for third-party access to payment accounts in accordance with PSD2 requirements.
- 1.2. Transport Protocol
Protocol: HTTPS (HTTP over TLS/SSL). All requests are transmitted exclusively over a secure HTTPS channel. The use of the unsecured HTTP protocol is not permitted.
- 1.3. Data Format
Request and response body format: JSON (JavaScript Object Notation). The Content-Type header: application/json is mandatory for all requests containing a body (POST).
- 1.4. Versioning
Current version of both interfaces: v2. The version is specified in the base URL path: /pis/v2/ and /ais/v2/.
- 1.5. Mandatory HTTP Headers (common to both interfaces)
X-Request-Id — unique request identifier (UUID format), for example: dc7b16a5-4ac8-4fdc-9c4e-9f9d0387dc07. Used for request identification and tracing.
Content-Type — request body content type: application/json (for POST requests).
PSU-ID — Payment Service User (PSU) identifier in the bank’s system.
PSU-IP-Address — IP address of the PSU device.
Consent-ID — identifier of a confirmed AIS consent (for AIS requests after authorization).
Client-Redirect-URI — URL for redirecting the PSU after successful authorization (SCA Redirect).
Client-Redirect-Nok-URI — URL for redirecting the PSU in case of unsuccessful authorization (SCA Redirect).
2. PIS (Payment Initiation Service) Interface Technical Specifications
- 2.1. Base URL Path /pis/v2/
- 2.2. Endpoints
- 2.2.1. Payment Initiation
Method and path: POST /pis/v2/payments/{payment-product}
Path parameter: payment-product — type of payment product (currently supported: instant-credit-transfers).
Request body (JSON):
paymentIdentification.endToEndId — end-to-end payment identifier (string).
debtorAccount.iban — payer account IBAN.
debtorAccount.currency — payer account currency (e.g. "UAH").
instructedAmount.currency — transfer amount currency.
instructedAmount.amount — transfer amount (decimal string, e.g. "12.21").
creditor.name — recipient name.
creditor.creditorId — recipient identifier.
creditor.creditorIdType — recipient identifier type (e.g. "PSPT").
creditorAccount.iban — recipient account IBAN.
creditorAccount.currency — recipient account currency.
remittanceInformationUnstructured — array of strings containing payment purpose.
Response (JSON): paymentId (UUID), transactionStatus ("RCVD"), _links.startAuthorisation.href.
- 2.2.2. Payment Authorization Initiation (SCA)
Method and path: POST /pis/v2/payments/{payment-product}/{payment-id}/authorisations
Path parameters: payment-product, payment-id (obtained from previous step).
Headers: Client-Redirect-URI, Client-Redirect-Nok-URI (mandatory for Redirect SCA).
Response for Decoupled SCA (JSON): scaStatus ("received"), authorisationId (UUID), psuMessage (message text for PSU).
Response for Redirect SCA (JSON): scaStatus ("received"), authorisationId (UUID), _links.scaRedirect.href (URL for redirecting PSU to the bank’s SCA page).
- 2.2.3. Payment Status Check
Method and path: GET /pis/v2/payments/{payment-product}/{payment-id}/status
Path parameters: payment-product, payment-id.
Response (JSON): transactionStatus — transaction status (e.g. "ACCC" — successfully completed).
- 2.3. PIS Interaction Flow
TPP initiates payment (POST /payments/{payment-product}) → receives paymentId.
TPP initiates authorization (POST /payments/{payment-product}/{payment-id}/authorisations) → receives authorisationId and either psuMessage (Decoupled) or scaRedirect URL (Redirect).
PSU authorizes the payment (via bank application or bank web page depending on SCA mode).
TPP checks payment status (GET /payments/{payment-product}/{payment-id}/status) → receives transactionStatus.
TPP informs PSU about payment execution result.
- 2.4. PIS-Specific Error Codes
404 — PRODUCT_UNKNOWN: specified payment product is not supported by the bank.
400 — PAYMENT_FAILED: payment initiation request could not be processed.
403 — SERVICE_BLOCKED: service is unavailable for PSU due to bank-side blocking.
3. AIS (Account Information Service) Interface Technical Specifications
- 3.1. Base URL Path /ais/v2/
- 3.2. Endpoints
- 3.2.1. AIS Consent Creation
Method and path: POST /ais/v2/consents/account-access
Request body (JSON):
access.payments[].account.iban — IBAN of the account to which access is granted.
access.payments[].rights — access rights array: "accountDetails", "balances", "transactions". If "balances" or "transactions" is specified, "accountDetails" is granted implicitly.
consentType — consent type: "detailed".
recurringIndicator — recurring access indicator: true (permanent) or false (one-time).
validTo — consent expiry date (format: YYYY-MM-DD).
frequencyPerDay — maximum number of requests per day without PSU presence (max: 4).
Response (JSON): consentId (UUID), consentStatus ("received"), _links.startAuthorisation.href.
- 3.2.2. Consent Authorization Initiation (SCA)
Method and path: POST /ais/v2/consents/account-access/{consent-id}/authorisations
Path parameter: consent-id (obtained from previous step).
Headers: Client-Redirect-URI, Client-Redirect-Nok-URI.
Response for Decoupled SCA (JSON): scaStatus, authorisationId, psuMessage.
Response for Redirect SCA (JSON): scaStatus, authorisationId, _links.scaRedirect.href.
- 3.2.3. Consent Status Check
Method and path: GET /ais/v2/consents/account-access/{consent-id}/status
Response (JSON): consentStatus — consent status ("received", "valid", "rejected", etc.).
- 3.2.4. Account List Retrieval
Method and path: GET /ais/v2/accounts
Query parameter: withBalance=true (to include balances in response).
Header: Consent-ID — identifier of confirmed AIS consent.
Response (JSON): array of accounts objects with fields: iban, currency, resourceId, name, balances[].balanceAmount, balances[].balanceType, balances[].referenceDate.
- 3.2.5. Transaction History Retrieval
Method and path: GET /ais/v2/accounts/{account-id}/transactions
Query parameters:
dateFrom — start date (without additional SCA access available up to 90 days back; older transactions require one-time AIS consent with recurringIndicator: false and "transactions" right).
limit — maximum number of transaction records in response (pagination).
offset — number of skipped records from start (pagination).
Pagination: TPP increases offset by the number of already received records. Completion is indicated by a response containing fewer records than limit or an empty list. If pagination parameters are not provided, the number of returned transactions is determined by the bank.
- 3.3. AIS Interaction Flow
TPP creates AIS consent (POST /consents/account-access) → receives consentId.
TPP initiates consent authorization (POST /consents/account-access/{consent-id}/authorisations) → receives authorisationId and either psuMessage (Decoupled) or scaRedirect URL (Redirect).
PSU authorizes consent (via bank application or web page).
TPP checks consent status (GET /consents/account-access/{consent-id}/status) until status becomes "valid".
TPP retrieves account and transaction data by passing Consent-ID in request headers.
- 3.4. Restrictions and Limits
Maximum request frequency without PSU presence: 4 times per day (frequencyPerDay ≤ 4).
Available transaction history depth without additional SCA: 90 calendar days.
- 3.5. AIS-Specific Error Codes
401 — CONSENT_INVALID: consent is invalid or does not grant required access rights.
403 — CONSENT_UNKNOWN: consent does not exist.
429 — ACCESS_EXCEEDED: daily limit of 4 GET requests without PSU presence exceeded.
400 — FORMAT_ERROR (transaction pagination): dateFrom exceeds 90 days in the past for recurring AIS consent.
4. Strong Customer Authentication (SCA) Procedures
Both interfaces (PIS and AIS) support two SCA modes:
- 4.1. Decoupled SCA
Procedure: PSU receives a message or push notification from the bank and authorizes the operation directly in the bank application without leaving the TPP interface. TPP receives psuMessage in the response. The bank independently notifies the PSU about the need for authorization.
- 4.2. Redirect SCA
Procedure: TPP redirects PSU to the bank SCA page (scaRedirect.href), where PSU completes authentication and confirms the operation. After completion, the bank redirects PSU back to TPP via Client-Redirect-URI (success) or Client-Redirect-Nok-URI (failure).
5. TPP Tools and Requirements
- 5.1. Registration and Certificates
To connect to specialized interfaces, a third-party TPP must:
Complete registration on the Developer Portal (portal.api.upc.ua).
Obtain and configure digital certificates for mutual TLS authentication (mTLS) in accordance with the “Certificates” section of the portal.
Configure electronic request signatures in accordance with the “Electronic signatures” section of the portal.
Register an application in the “Applications” section and subscribe to the relevant API service.
- 5.2. Technical Requirements
HTTPS/TLS-capable HTTP client with mutual authentication (mTLS).
Support for JSON serialization and deserialization.
Ability to generate unique UUIDs for the X-Request-Id header.
Implementation of polling logic for payment and consent status checking.
Pagination mechanism for large transaction sets (limit and offset parameters).
Publicly accessible URLs for Client-Redirect-URI and Client-Redirect-Nok-URI (for Redirect SCA).
- 5.3. Environments
Sandbox (test environment): available for integration development and testing.
Production (live environment): for real interaction with PSU payment accounts.
| Version | Description of changes | Date |
|---|---|---|
| v.1.0 | Original version | 30.04.26 |
Account Information Service (AIS)
1. Test Scenarios for Creating Account Consent
Test Case #1 Create Consent type "detailed" | POST /consents/account-access
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user is registered in the system
Has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
Execution steps:
Select the provider for which the Consent is being created, record providerId
Select the list of accounts for Consent creation, record IBANs
Make an API call:
POST /providers/{providerId}/ais/v2/consents/account-access
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
TPP-Redirect-URI: "https://google.com"
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
PSU-IP-Address: "1.1.1.1"
TPP-Explicit-Authorisation-Preferred: true
Client-SCA-Approach-Preference: decoupled
// OR: Client-SCA-Approach-Preference: redirect
PSU-ID: "+380971112233" // Not required for Client-SCA-Approach-Preference redirect
PSU-ID-Type: "PHONE" // Not required for Client-SCA-Approach-Preference redirect
BODY:
{ "access": { "payments": [ { "account": { "iban": "UA1234567890123456789012134567" }, "rights": [ "accountDetails", "balances", "transactions" ] } ] }, "consentType": "detailed", "recurringIndicator": true, "validTo": "2026-06-28", "frequencyPerDay": "4" } Expected result:
A Consent with type "detailed" is created
The response contains consentId
Example response:
{ "consentStatus": "received", "consentId": "019c0916-ef4d-7228-babe-e0b2a03d57dd", "_links": { "self": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd" }, "status": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd/status" }, "startAuthorisation": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd/authorisations" } } } Test Case #2 Create Consent type "accountList" | POST /consents/account-access
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user is registered in the system
Has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
Execution steps:
Select the provider for which the Consent is being created, record providerId
Make an API call:
POST /providers/{providerId}/ais/v2/consents/account-access
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
TPP-Redirect-URI: "https://google.com"
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
PSU-IP-Address: "1.1.1.1"
TPP-Explicit-Authorisation-Preferred: true
Client-SCA-Approach-Preference: decoupled
// OR: Client-SCA-Approach-Preference: redirect
PSU-ID: "+380971112233" // Not required for Client-SCA-Approach-Preference redirect
PSU-ID-Type: "PHONE" // Not required for Client-SCA-Approach-Preference redirect
BODY:
{ "access": { "payments": [ { "rights": [ "accountDetails", "balances", "transactions" ] } ] }, "consentType": "accountList", "recurringIndicator": true, "validTo": "2026-06-28", "frequencyPerDay": "4" } Expected result:
A Consent with type "accountList" is created
The response contains consentId
Example response:
{ "consentStatus": "received", "consentId": "019c0916-ef4d-7228-babe-e0b2a03d57dd", "_links": { "self": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd" }, "status": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd/status" }, "startAuthorisation": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd/authorisations" } } } Test Case #3 Create Consent type "aspspManaged" | POST /consents/account-access
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Important:
The type "aspspManaged" is supported only in specification version 2.2.0 (2.0.6)
Prerequisites:
The user is registered in the system
Has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
Execution steps:
Select the provider for which the Consent is being created, record providerId
Make an API call:
POST /providers/{providerId}/ais/v2.0/consents/account-access
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
TPP-Redirect-URI: "https://google.com"
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
PSU-IP-Address: "1.1.1.1"
TPP-Explicit-Authorisation-Preferred: true
Client-SCA-Approach-Preference: decoupled
// OR: Client-SCA-Approach-Preference: redirect
PSU-ID: "+380971112233" // Not required for Client-SCA-Approach-Preference redirect
PSU-ID-Type: "PHONE" // Not required for Client-SCA-Approach-Preference redirect
BODY:
{ "access": { "payments": [ { "rights": [ "accountDetails", "balances", "transactions" ] } ] }, "consentType": "aspspManaged", "recurringIndicator": true, "validTo": "2026-06-28", "frequencyPerDay": "4" } Expected result:
A Consent with type "aspspManaged" is created
The response contains consentId
Example response:
{ "consentStatus": "received", "consentId": "019c0916-ef4d-7228-babe-e0b2a03d57dd", "_links": { "self": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd" }, "status": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd/status" }, "startAuthorisation": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0916-ef4d-7228-babe-e0b2a03d57dd/authorisations" } } } 2. Test Scenarios for Consent Authorization
Test Case #4 Consent Authorization | POST /consents/account-access/{consent-id}/authorisations
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3), consentId is recorded
Execution steps:
Make an API call:
POST /providers/{providerId}/ais/v2/consents/account-access/{consent-id}/authorisations
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
TPP-Redirect-URI: "https://google.com"
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
PSU-IP-Address: "1.1.1.1"
TPP-Explicit-Authorisation-Preferred: true
Client-SCA-Approach-Preference: decoupled
// OR: Client-SCA-Approach-Preference: redirect
PSU-ID: "+380971112233" // Not required for Client-SCA-Approach-Preference redirect
PSU-ID-Type: "PHONE" // Not required for Client-SCA-Approach-Preference redirect
BODY:
{} Consent authorization is created
Response contains scaStatus and authorisationId
Example response:
{ "consentStatus": "received", "consentId": "019c7aab-5419-7046-bcf5-e718134e0adc", "_links": { "self": { "href": "/sandbox/ais/v2.0/consents/account-access/019c7aab-5419-7046-bcf5-e718134e0adc" }, "status": { "href": "/sandbox/ais/v2.0/consents/account-access/019c7aab-5419-7046-bcf5-e718134e0adc/status" }, "startAuthorisation": { "href": "/sandbox/ais/v2.0/consents/account-access/019c7aab-5419-7046-bcf5-e718134e0adc/authorisations" } } } For Client-SCA-Approach-Preference: redirect
Proceed to scaRedirect link (if redirect) or initiate SCA via another channel (if decoupled)
On the Sandbox page, an handler is available to accept or reject the authorization request:
Confirm authorization by clicking "Accept"
For Client-SCA-Approach-Preference: decoupled
Example response:
{ "scaStatus": "finalised", "_links": { "scaStatus": { "href": "/sandbox/ais/v2.0/consents/account-access/019c7b2e-6a91-7644-ae5d-c2617e6931d5/authorisations/019c7b2e-7c47-7d5b-beb5-593ac088df1e" } }, "authorisationId": "019c7b2e-7c47-7d5b-beb5-593ac088df1e", "psuMessage": "Authorize payment in Bank's mobile application" } Sandbox provides an emulator that automatically confirms authorization within 1 second after creation.
Expected result:
Redirect occurs to Google (or another provided TPP-Redirect-URI if not sandbox)
On GET ConsentId status request, the status must be "valid" (see Test Case #5)
3. Test Scenarios for Consent and Consent Authorization Verification
Test Case #5 Get Consent Status | GET /consents/account-access/{consent-id}/status
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3), consentId is recorded
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/consents/account-access/{consent-id}/status
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response contains current Consent status
Example response:
{ "consentStatus": "valid" } Test Case #6 Get all Authorisations for a Consent | GET /consents/account-access/{consent-id}/authorisations
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3), consentId is recorded
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/consents/account-access/{consent-id}/authorisations
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response contains list of authorisation IDs
Example response:
{ "authorisationIds": [ "019c0e6d-1ef7-7f4e-a552-d7cec5ff34d9" ] } Test Case #7 Get specific Consent Authorisation status | GET /consents/account-access/{consent-id}/authorisations/{authorisation-id}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3), consentId is recorded
An authorization exists for the Consent (see Test Case #4), authorisationId is recorded (see Test Case #6)
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/consents/account-access/{consent-id}/authorisations/{authorisation-id}
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response contains current authorization status
Example response:
{ "scaStatus": "finalised", "_links": { "scaStatus": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0e6c-f7cf-70f7-983f-05df521de43d/authorisations/019c0e6d-1ef7-7f4e-a552-d7cec5ff34d9" }, "scaRedirect": { "href": "https://portal.preprod.api.upc.ua/sca-client/mock/upc/bfdb6794-bcb8-4dde-9f3b-07acf73ef202/019c0e6d-1ef7-7f4e-a552-d7cec5ff34d9/consent" } }, "authorisationId": "019c0e6d-1ef7-7f4e-a552-d7cec5ff34d9" } Test Case #8 Get Consent object | GET /consents/account-access/{consent-id}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3), consentId is recorded
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/consents/account-access/{consent-id}
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
{}
Expected result:
Response contains Consent details: current status, access rights, type, validity period, etc.
Example response:
{ "consentStatus": "valid", "_links": { "self": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0e6c-f7cf-70f7-983f-05df521de43d" }, "status": { "href": "/sandbox/ais/v2.0/consents/account-access/019c0e6c-f7cf-70f7-983f-05df521de43d/status" }, "account": { "href": "/sandbox/ais/v2.0/accounts" } }, "access": { "payments": [ { "rights": [ "accountDetails", "balances", "transactions" ] } ] }, "consentType": "accountList", "recurringIndicator": true, "validTo": "2026-06-28", "frequencyPerDay": 4, "combinedServiceIndicator": false } Test Case #9 Revoke Consent | DELETE /consents/account-access/{consent-id}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3), consentId is recorded
Execution steps:
Make an API call:
DELETE /providers/{providerId}/ais/v2/consents/account-access/{consent-id}
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response with status code 204 No Content. On subsequent Consent status request (see Test Case #5), status should be "terminatedByTpp" or "revokedByPsu", depending on who initiated the revocation.
4. Test Scenarios for Account Consent Usage
IMPORTANT: Prerequisite for the following test cases
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A created Consent exists (see Test Case #1, #2 or #3) and it has status "valid" (see Test Case #4)
consentId is recorded
Test Case #10 Get list of accounts | GET /accounts
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/accounts
Query parameters:
withBalance: boolean // ignored if Consent does not provide balance access
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
Consent-ID: "{consentId}"
PSU-IP-Address: "8.8.8.8"
PSU-Corporate-ID: "123456789" // optional
PSU-Corporate-ID-Type: "PHONE" // optional
BODY:
null
Expected result:
List of accounts corresponding to the access rights defined in the Consent. If the Consent includes balance access, balances will also be included in the response for each account.
Example response without balances:
{ "accounts": [ { "iban": "UA1234567890123456789012134567", "currency": "UAH", "resourceId": "e555222c-6304-40aa-9933-7952e2fd9999", "name": "Current account", "cashAccountType": "CACC", "_links": { "balances": { "href": "/sandbox/ais/v2.0/accounts/{resourceId}/balances" }, "transactions": { "href": "/sandbox/ais/v2.0/accounts/{resourceId}/transactions?dateFrom=2017-01-01&bookingStatus=both" } } } ] } Example response with balances:
{ "accounts": [ { "iban": "UA313220000000026007233566001", "currency": "UAH", "resourceId": "e555222c-6304-40aa-9933-7952e2fd9999", "name": "Current account", "cashAccountType": "CACC", "balances": [ { "balanceAmount": { "currency": "UAH", "amount": "500000.00" }, "balanceType": "closingBooked" }, { "balanceAmount": { "currency": "UAH", "amount": "500000.00" }, "balanceType": "expected" } ], "_links": { "balances": { "href": "/sandbox/ais/v2.0/accounts/{resourceId}/balances" }, "transactions": { "href": "/sandbox/ais/v2.0/accounts/{resourceId}/transactions?dateFrom=2017-01-01&bookingStatus=both" } } } ] } Test Case #11 Get account details | GET /accounts/{account-id}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/accounts/{account-id}
Query parameters:
withBalance: boolean // ignored if Consent does not provide balance access
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
Consent-ID: "{consentId}"
PSU-IP-Address: "8.8.8.8"
PSU-Corporate-ID: "123456789" // optional
PSU-Corporate-ID-Type: "PHONE" // optional
BODY:
null
Expected result:
Provides account details if Consent includes access rights. If Consent includes balance access and withBalance=true, balances will also be included.
Example response without balances:
{ "iban": "UA1234567890123456789012134567", "currency": "UAH", "resourceId": "e555222c-6304-40aa-9933-7952e2fd9999", "name": "Current account", "cashAccountType": "CACC", "_links": { "balances": { "href": "/sandbox/ais/v2.0/accounts/{resourceId}/balances" }, "transactions": { "href": "/sandbox/ais/v2.0/accounts/{resourceId}/transactions?dateFrom=2017-01-01&bookingStatus=both" } } } Example response with balances:
{ "account": { "iban": "UA313220000000026007233566001", "currency": "UAH", "resourceId": "e55022cc-6304-40aa-9733-7952e2fd9597", "name": "Current account", "cashAccountType": "CACC", "balances": [ { "balanceAmount": { "currency": "UAH", "amount": "500000.00" }, "balanceType": "closingBooked" } ], "_links": { "balances": { "href": "/sandbox/ais/v2.0/accounts/e55022cc-6304-40aa-9733-7952e2fd9597/balances" }, "transactions": { "href": "/sandbox/ais/v2.0/accounts/e55022cc-6304-40aa-9733-7952e2fd9597/transactions?dateFrom=2017-01-01&bookingStatus=both" } } } } Test Case #12 Get account transactions | GET /accounts/{account-id}/transactions
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/accounts/{account-id}/transactions
Query parameters:
withBalance: boolean // ignored if Consent does not provide balance access
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
Consent-ID: "{consentId}"
PSU-IP-Address: "8.8.8.8"
PSU-Corporate-ID: "123456789" // optional
PSU-Corporate-ID-Type: "PHONE" // optional
BODY:
null
Expected result:
Provides transaction details if Consent includes access rights.
Example response:
{ "account": { "iban": "UA313220000000026007233566001", "currency": "UAH" }, "transactions": { "booked": [ { "transactionId": 123, "debtor": { "name": "Debtor name" }, "debtorAccount": { "iban": "LV80BANK0000435195001", "currency": "EUR" }, "creditor": { "name": "Creditor name" }, "creditorAccount": { "iban": "LV80BANK0000435195321", "currency": "EUR" }, "transactionAmount": { "currency": "EUR", "amount": 123.32 }, "bookingDate": "12.12.2012", "valueDate": "12.12.2012", "remittanceInformationUnstructured": "Some details" } ], "pending": [], "_links": { "account": { "href": "/sandbox/ais/v2.0/accounts/c59ab17b-6a71-4052-aef5-72165783f4bf" } } }, "size": 0, "limit": 20 } Test Case #13 Get transaction details | GET /accounts/{account-id}/transactions/{transactionId}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Execution steps:
Make an API call:
GET /providers/{providerId}/ais/v2/accounts/{account-id}/transactions/{transaction-id}
Query parameters:
dateFrom: date // required, format YYYY-MM-DD
bookingStatus: string // required. Possible values: booked, pending, both
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
Consent-ID: "{consentId}"
PSU-IP-Address: "8.8.8.8"
PSU-Corporate-ID: "123456789" // optional
PSU-Corporate-ID-Type: "PHONE" // optional
BODY:
null
Expected result:
Provides transaction details if Consent includes access rights.
Example response:
{ "account": { "iban": "LV80BANK0000435195001", "currency": "EUR" }, "transactionsDetails": { "transactionId": 123, "debtor": { "name": "Debtor name" }, "debtorAccount": { "iban": "LV80BANK0000435195001", "currency": "EUR" }, "creditor": { "name": "Creditor name" }, "creditorAccount": { "iban": "LV80BANK0000435195321", "currency": "EUR" }, "transactionAmount": { "currency": "EUR", "amount": 123.32 }, "bookingDate": "12.12.2012", "valueDate": "12.12.2012", "remittanceInformationUnstructured": "Some details" } } Payment Initiation Service (PIS)
1. Test Scenarios for Payment Initiation Service
Test Case #1 Create payment initiation | POST /payments/instant-credit-transfers | POST /payments/credit-transfers
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user is registered in the system
Has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
Execution steps:
Select the provider for which the payment is created, record providerId
Select {payment-product} type — instant-credit-transfers or credit-transfers
Make an API call:
POST /providers/{provider-id}/pis/v2/payments/{payment-product}
HEADERS:
X-Request-ID: 123e4567-e89b-12d3-a456-426614174000 // {uuid}
PSU-IP-Address: "1.1.1.1"
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
{ "debtorAccount": { "iban": "UA313220000000026007233566001", "currency": "UAH" }, "instructedAmount": { "currency": "UAH", "amount": "12.21" }, "creditor": { "name": "Coden Postal", "creditorId": "CP122540", "creditorIdType": "PSPT" }, "creditorAccount": { "iban": "UA633220000000029908753443001", "currency": "UAH" }, "remittanceInformationUnstructured": [ "Some details" ] } Expected result:
Payment created with transactionStatus "RCVD"
Response contains paymentId
Example response:
{ "transactionStatus": "RCVD", "paymentId": "019cfaf3-6d52-76a0-9064-969a181c03ee", "_links": { "self": { "href": "/sandbox/pis/v2.0/payments/instant-credit-transfers/019cfaf3-6d52-76a0-9064-969a181c03ee" }, "status": { "href": "/sandbox/pis/v2.0/payments/instant-credit-transfers/019cfaf3-6d52-76a0-9064-969a181c03ee/status" }, "startAuthorisation": { "href": "/sandbox/pis/v2.0/payments/instant-credit-transfers/019cfaf3-6d52-76a0-9064-969a181c03ee/authorisations" } } } Test Case #2 Start payment authorization | POST /payments/{payment-product}/{payment-id}/authorisations
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A payment has been created (see Test Case #1), paymentId is recorded
IMPORTANT: the {payment-product} type in the request must match the type used when creating the payment in Test Case #1
Possible values for {payment-product}: instant-credit-transfers or credit-transfers
Execution steps:
Make an API call:
POST /providers/{provider-id}/pis/v2/payments/{payment-product}/{payment-id}/authorisations
HEADERS:
X-Request-ID: 123e4567-e89b-12d3-a456-426614174000
Client-Redirect-URI: https://google.com
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
PSU-ID: "2353909119" // use this value for sandbox
PSU-ID-Type: "PHONE"
BODY:
{} Expected result:
Payment authorization is created
Response contains scaStatus and authorisationId
Example response:
{ "scaStatus": "received", "_links": { "scaStatus": { "href": "/sandbox/pis/v2.0/payments/instant-credit-transfers/019cfb75-7982-78b5-9a50-b92813afcd7b/authorisations/019cfb75-8e7d-755d-bbc2-e1e5928a3698" }, "scaRedirect": { "href": "https://portal.preprod.api.upc.ua/sca-client/mock/upc/bfdb6794-bcb8-4dde-9f3b-07acf73ef202/019cfb75-8e7d-755d-bbc2-e1e5928a3698/consent" } }, "authorisationId": "019cfb75-8e7d-755d-bbc2-e1e5928a3698" } For Client-SCA-Approach-Preference: redirect
Additional note: sandbox provides emulation of payment confirmation by the user with PSU-ID: "2353909119".
Follow the scaRedirect link (if redirect mode is used) or initiate SCA via another channel (if decoupled mode is used).
On the Sandbox page, there is a handler allowing acceptance or rejection of the authorization request:
Confirm authorization by clicking "Confirm"
2. Payment verification test scenarios
Test Case #3 Get payment details | GET /payments/{payment-product}/{payment-id}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A payment exists (see Test Case #1, #2), payment-id is recorded
Execution steps:
Make an API call:
GET /providers/{provider-id}/pis/{apiGroupVersion}/payments/{payment-product}/{payment-id}
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response body contains current payment status
Example response fragment:
{ "transactionStatus": "RCVD", "_links": { "self": { "href": "/sandbox/pis/v2.0/payments/instant-credit-transfers/019cfbb3-d015-7a47-bd16-76f18e90d58e" } } } Test Case #4 Get payment status | GET /payments/{payment-product}/{payment-id}/status
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A payment exists (payment-id recorded)
Execution steps:
Make an API call:
GET /providers/{provider-id}/pis/{apiGroupVersion}/payments/{payment-product}/{payment-id}/status
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response contains current payment status
Example response:
{ "transactionStatus": "RCVD" } Test Case #5 Get payment authorisations | GET /payments/{payment-product}/{payment-id}/authorisations
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A payment exists (payment-id recorded)
Execution steps:
Make an API call:
GET /providers/{provider-id}/pis/{apiGroupVersion}/payments/{payment-product}/{payment-id}/authorisations
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response contains authorisationIds
Example response:
{ "authorisationIds": [ "019cfbb3-eee5-771a-b877-89a5a17cd505" ] } Test Case #6 Get payment authorisation details | GET /payments/{payment-product}/{payment-id}/authorisations/{authorisation-id}
API Documentation
Requirements for headers and request body are described in the documentation for the relevant version.
Prerequisites:
The user has a valid access token (logged in)
POST https://{portal_url}/auth/realms/participants/protocol/openid-connect/token
A payment exists (payment-id recorded)
authorisation-id is recorded (see Test Case #5)
Execution steps:
Make an API call:
GET /providers/{provider-id}/pis/{apiGroupVersion}/payments/{payment-product}/{payment-id}/authorisations/{authorisation-id}
HEADERS:
X-Request-ID: "72ebf0c7-31d4-43be-8786-261bd4e5d8a3" // {uuid}
Content-Type: application/json
Authorization: "Bearer {openid-connect/token}"
BODY:
null
Expected result:
Response contains authorisation details
Example response:
{ "scaStatus": "finalised", "_links": { "scaStatus": { "href": "/sandbox/pis/v2.0/payments/instant-credit-transfers/019cfbb3-d015-7a47-bd16-76f18e90d58e/authorisations/019cfbb3-eee5-771a-b877-89a5a17cd505" }, "scaRedirect": { "href": "https://portal.preprod.api.upc.ua/sca-client/mock/upc/bfdb6794-bcb8-4dde-9f3b-07acf73ef202/019cfbb3-eee5-771a-b877-89a5a17cd505/consent" } } }