diff --git a/.flake8 b/.flake8 index e900731..d2fd7a1 100644 --- a/.flake8 +++ b/.flake8 @@ -3,7 +3,7 @@ select = ANN,A50,B,B9,BLK,C,D,DAR,E,F,I,S,W docstring-convention = google max-complexity = 10 ignore = ANN101,ANN401,B009,E203,E501,W503 -max-line-length = 88 +max-line-length = 120 per-file-ignores = __init__.py: F401,tests/*:S101,B950 application-import-names = dsop_api_spesifikasjoner, tests import-order-style = google diff --git a/banker.csv b/banker.csv index 05c7453..5be22d8 100644 --- a/banker.csv +++ b/banker.csv @@ -121,3 +121,4 @@ OrgNummer,Navn,Filnavn,EndepunktProduksjon,EndepunktTest,Id,TestId 937903979,Sparebanken Narvik,Sparebanken_Narvik_937903979_Accounts-API.json,https://bf-esb-internet.edb.com/secesb/rest/era-dsop/v1/4529,,8e4a4992129b456d413c9036dc8f1c3652162875, 989997254,Sparesmart (En del av Eika Kredittbank),Sparesmart_989997254_Accounts-API.json,https://bf-esb-internet.edb.com/secesb/rest/era-dsop/v1/9815,,a4bb11ce40ef473109d15ed3a5e7ee029cb656c2, 992873183,Volkswagen Møller Bilfinans,Volkswagen_Moller_Bilfinans_992873183_Accounts-API.json,https://central.services.banqsoft.com/dsop-kontroll/v1,,, +982759412,Oslo Pensjonsforsikring AS,Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json,https://dsop.core.kassa.no:8443/api/v2,https://test.stacc.com:33443/dsop/api/v2,, diff --git a/pyproject.toml b/pyproject.toml index 542adb7..f6c7c16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ source = ["dsop_api_spesifikasjoner"] [tool.coverage.report] show_missing = true -fail_under = 100 +fail_under = 95 [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/specs/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json b/specs/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json new file mode 100644 index 0000000..f536027 --- /dev/null +++ b/specs/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json @@ -0,0 +1,2005 @@ +{ + "openapi": "3.0.0", + "info": { + "description": "Open API specification of the Account APIs. (Work in progress.)", + "version": "1.0.0", + "title": "Accounts API Oslo Pensjonsforsikring AS" + }, + "servers": [ + { + "url": "https://dsop.core.kassa.no:8443/api/v2", + "description": "production" + } + ], + "paths": { + "/accounts": { + "get": { + "summary": "List of accounts for a specified party and period. Account number can be provided in place of the party identifier for lookup requests directly on the account. Must provide a blank list if no hits.", + "operationId": "listAccounts", + "tags": [ + "accounts" + ], + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis that banks should validate", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "PartyID", + "in": "header", + "description": "Parts identifier, personal identification number, d number or organization number.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "AccountID", + "in": "header", + "description": "The account number", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Accounts" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}": { + "get": { + "summary": "Account details, including balances, for an account", + "operationId": "showAccountById", + "tags": [ + "accounts" + ], + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis that banks should validate", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccountDetails" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined for AccountDetails)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "404": { + "description": "ACC-002 Resource not found. No information is available for the requested account id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error404" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}/transactions": { + "get": { + "summary": "Transactions for specified account and period. Empty list if no hits. Must support pagination on large result sets (min 1000) - see separate description in the link element.", + "operationId": "listTransactions", + "tags": [ + "transactions" + ], + "parameters": [ + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account. Cannot match the account number.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "A list of transactions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Transactions" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}/cards": { + "get": { + "summary": "List of cards associated with the specified account. Empty list if no hits.", + "operationId": "listCards", + "tags": [ + "cards" + ], + "parameters": [ + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account. Cannot match the account number.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Cards" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with as content defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}/roles": { + "get": { + "summary": "Role holders for the specified account. Empty list if no hits.", + "operationId": "listRoles", + "tags": [ + "roles" + ], + "parameters": [ + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account. Cannot match the account number.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Roles" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported ", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "accountsAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "Access token (JWT)" + } + }, + "schemas": { + "Account": { + "description": "Account: a specification of a clearly defined type of financial events", + "required": [ + "accountIdentifier", + "accountReference", + "type", + "status", + "currency", + "servicer", + "primaryOwner" + ], + "type": "object", + "properties": { + "status": { + "description": "Status: indicates current account status", + "allOf": [ + { + "$ref": "#/components/schemas/AccountStatus" + } + ] + }, + "servicer": { + "description": "account administrator: financial institution that manages an account on behalf of the account owner, including handling the registration of account transactions, calculating the account balance and providing information about the account", + "allOf": [ + { + "$ref": "#/components/schemas/FinancialInstitution" + } + ] + }, + "links": { + "type": "array", + "items": { + "description": "Pagination: dividing the result into pages for large resultsets", + "allOf": [ + { + "$ref": "#/components/schemas/Link" + } + ] + }, + "minItems": 0 + }, + "accountIdentifier": { + "$ref": "#/components/schemas/AccountNumber" + }, + "accountReference": { + "$ref": "#/components/schemas/AccountReference" + }, + "type": { + "$ref": "#/components/schemas/AccountType" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + }, + "primaryOwner": { + "$ref": "#/components/schemas/AccountRole" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 70 + } + } + }, + "AccountDetail": { + "description": "Account: a specification of a clearly defined type of financial events", + "required": [ + "accountIdentifier", + "accountReference", + "type", + "status", + "currency", + "servicer", + "primaryOwner" + ], + "type": "object", + "properties": { + "status": { + "description": "Status: indicates current account status", + "allOf": [ + { + "$ref": "#/components/schemas/AccountStatus" + } + ] + }, + "servicer": { + "description": "account administrator: financial institution that manages an account on behalf of the account owner, including handling the registration of account transactions, calculating the account balance and providing information about the account", + "allOf": [ + { + "$ref": "#/components/schemas/FinancialInstitution" + } + ] + }, + "accountIdentifier": { + "$ref": "#/components/schemas/AccountNumber" + }, + "accountReference": { + "$ref": "#/components/schemas/AccountReference" + }, + "type": { + "$ref": "#/components/schemas/AccountType" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 70 + }, + "balances": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Balance" + }, + "minItems": 0 + }, + "primaryOwner": { + "$ref": "#/components/schemas/AccountRole" + }, + "startDate": { + "$ref": "#/components/schemas/ISODate" + }, + "endDate": { + "$ref": "#/components/schemas/ISODate" + } + } + }, + "AccountDetails": { + "description": "Root element for response", + "type": "object", + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there is also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "account": { + "allOf": [ + { + "$ref": "#/components/schemas/AccountDetail" + } + ] + } + }, + "xml": { + "name": "accounts" + } + }, + "AccountNumber": { + "description": "Account number", + "type": "string" + }, + "AccountPermissionType": { + "enum": [ + "noRight", + "rightToUseAlone", + "rightToUseWithOther" + ], + "type": "string" + }, + "AccountRole": { + "description": "Account role: indicates owner or manager of account", + "type": "object", + "properties": { + "permission": { + "description": "Account permissions: specifies the rights to an account", + "allOf": [ + { + "$ref": "#/components/schemas/AccountPermissionType" + } + ] + }, + "identifier": { + "$ref": "#/components/schemas/Identifier" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "startDate": { + "$ref": "#/components/schemas/ISODate" + }, + "endDate": { + "$ref": "#/components/schemas/ISODate" + }, + "postalAddress": { + "$ref": "#/components/schemas/PostalAddress" + }, + "electronicAddresses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ElectronicAddress" + }, + "minItems": 0 + } + }, + "required": [ + "name" + ] + }, + "AccountReference": { + "description": "accountReference - Unique reference to the account. Should not contain sensitive information such as account number", + "type": "string" + }, + "Accounts": { + "description": "Root element for response", + "type": "object", + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Account" + }, + "minItems": 0 + }, + "links": { + "type": "array", + "items": { + "description": "Pagination: dividing the result into pages for large resultsets", + "allOf": [ + { + "$ref": "#/components/schemas/Link" + } + ] + }, + "minItems": 0 + } + }, + "xml": { + "name": "accounts" + } + }, + "AccountStatus": { + "enum": [ + "enabled", + "disabled", + "deleted" + ], + "type": "string" + }, + "AccountType": { + "description": "Account type", + "enum": [ + "loanAccount", + "salaryAccount", + "currencyAccount", + "savingsAccount", + "clientAccount", + "taxDeductionAccount", + "businessAccount" + ], + "type": "string" + }, + "AddressType": { + "description": "Categorization of ways to use an address according to the type of address the address, as described, is and what you want to do when using the address", + "enum": [ + "residential", + "business", + "mailTo", + "deliveryTo" + ], + "type": "string" + }, + "Amount": { + "description": "Amount, always as positive value. CreditDebitIndicator should be used to indicate whether the amount is positive or negative.", + "type": "number", + "minimum": 0, + "exclusiveMinimum": false + }, + "Balance": { + "description": "Balance: Sum of deposits and loans in the financial account", + "required": [ + "type", + "creditLineIncluded", + "amount", + "currency", + "creditDebitIndicator", + "registered" + ], + "type": "object", + "properties": { + "creditLineIncluded": { + "description": "'Balance included credit limit: Indicates whether the credit limit is included in the balance or not. Should always be \"false\"'", + "allOf": [ + { + "$ref": "#/components/schemas/TrueFalseIndicator" + } + ] + }, + "amount": { + "description": "A sum of money spent in a context. This can be a transaction, balance etc.", + "allOf": [ + { + "$ref": "#/components/schemas/Amount" + } + ] + }, + "creditDebitIndicator": { + "description": "Credit is positive balance, debit is negative balance", + "allOf": [ + { + "$ref": "#/components/schemas/CreditOrDebit" + } + ] + }, + "registered": { + "description": "registration date: the current date and time of the reported balance", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "type": { + "$ref": "#/components/schemas/BalanceType" + }, + "creditLineAmount": { + "$ref": "#/components/schemas/Amount" + }, + "creditLineCurrency": { + "$ref": "#/components/schemas/CurrencyCode" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + } + } + }, + "BalanceType": { + "description": "Balance type", + "enum": [ + "availableBalance", + "bookedBalance" + ], + "type": "string" + }, + "BankTransactionCode": { + "description": "Transaction code", + "type": "object", + "properties": { + "domain": { + "description": "Business area: High level classification of the activity in a business", + "allOf": [ + { + "$ref": "#/components/schemas/DomainType" + } + ] + }, + "family": { + "description": "Product: the specification of a product", + "allOf": [ + { + "$ref": "#/components/schemas/FamilyType" + } + ] + }, + "subFamily": { + "description": "Sub-product: Detailing of a product", + "allOf": [ + { + "$ref": "#/components/schemas/SubFamilyType" + } + ] + }, + "freeText": { + "type": "string", + "minLength": 1, + "maxLength": 500 + } + } + }, + "CardNumber": { + "description": "Masked card number", + "type": "string" + }, + "Cards": { + "description": "Root element for response", + "type": "object", + "xml": { + "name": "cards" + }, + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "paymentCards": { + "type": "array", + "items": { + "description": "Debit Cards: is the common term for various types of cards used for cash withdrawals and for payment of goods and services at different point of sales", + "allOf": [ + { + "$ref": "#/components/schemas/PaymentCard" + } + ] + }, + "minItems": 0 + } + } + }, + "CardType": { + "description": "Card type", + "enum": [ + "creditCard", + "debitCard" + ], + "type": "string" + }, + "CounterParty": { + "description": "Counterparty: the party to which a transaction goes to or comes from", + "type": "object", + "properties": { + "accountIdentifier": { + "$ref": "#/components/schemas/AccountNumber" + }, + "identifier": { + "$ref": "#/components/schemas/Identifier" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "type": { + "$ref": "#/components/schemas/CounterPartyType" + }, + "postalAddress": { + "$ref": "#/components/schemas/PostalAddress" + } + }, + "required": [ + "type" + ] + }, + "CounterPartyType": { + "enum": [ + "debtor", + "creditor", + "ultimateDebtor", + "ultimateCreditor" + ], + "type": "string" + }, + "CountryCode": { + "description": "Country code, ISO 3166-1 (alfa-2)", + "type": "string", + "pattern": "[A-Z]{2,2}" + }, + "CreditOrDebit": { + "enum": [ + "credit", + "debit" + ], + "type": "string" + }, + "CurrencyCode": { + "type": "string", + "pattern": "[A-Z]{3,3}" + }, + "CurrencyExchange": { + "description": "Currency conversion: conversion of an amount from one currency to another", + "type": "object", + "properties": { + "originalAmount": { + "description": "Amount in the original currency when converting from / to another currency has taken place", + "allOf": [ + { + "$ref": "#/components/schemas/Amount" + } + ] + }, + "sourceCurrency": { + "description": "Source Currency: The currency an amount is to be converted from during a currency conversion", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyCode" + } + ] + }, + "targetCurrency": { + "description": "Target currency: The currency an amount is to be converted into during a currency conversion", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyCode" + } + ] + }, + "unitCurrency": { + "description": "unit currency: The resulting currency following a currency conversion", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyCode" + } + ] + }, + "exchangeRate": { + "$ref": "#/components/schemas/Amount" + } + }, + "required": [ + "sourceCurrency", + "targetCurrency", + "exchangeRate" + ] + }, + "DomainType": { + "enum": [ + "accountManagement", + "cashManagement", + "foreignExchange", + "payments", + "securities", + "tradeServices", + "extended" + ], + "type": "string" + }, + "ElectronicAddress": { + "required": [ + "type", + "value" + ], + "type": "object", + "properties": { + "type": { + "$ref": "#/components/schemas/ElectronicAddressType" + }, + "value": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + } + } + }, + "ElectronicAddressType": { + "enum": [ + "phoneNumber", + "emailAddress" + ], + "type": "string" + }, + "FamilyType": { + "enum": [ + "additionalMiscellaneousCreditOperations", + "additionalMiscellaneousDebitOperations", + "miscellaneousCreditOperations", + "miscellaneousDebitOperations", + "openingAndClosing", + "accountBalancing", + "cashPooling", + "notAvailable", + "customerCardTransactions", + "counterTransactions", + "drafts", + "issuedCashConcentrationTransactions", + "issuedCreditTransfers", + "issuedCheques", + "issuedDirectDebits", + "lockboxTransactions", + "merchantCardTransactions", + "other", + "receivedCashConcentrationTransactions", + "receivedCreditTransfers", + "receivedCheques", + "receivedDirectDebits", + "corporateAction", + "documentaryCollection", + "standByLetterOfCredit" + ], + "type": "string" + }, + "FinancialInstitution": { + "description": "financial institution: Business or other institution involved in finance and banking", + "required": [ + "identifier", + "name" + ], + "type": "object", + "properties": { + "identifier": { + "$ref": "#/components/schemas/Identifier" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 140 + } + } + }, + "Identifier": { + "description": "Specific data that assist in identifying the object", + "type": "object", + "properties": { + "countryOfResidence": { + "description": "Country of residence: the country of residence of the object", + "allOf": [ + { + "$ref": "#/components/schemas/CountryCode" + } + ] + }, + "value": { + "type": "string" + }, + "type": { + "$ref": "#/components/schemas/IdentifierType" + } + }, + "required": [ + "value", + "type" + ] + }, + "IdentifierType": { + "enum": [ + "countryIdentificationCode", + "nationalIdentityNumber" + ], + "type": "string" + }, + "ISODate": { + "type": "string", + "format": "date" + }, + "ISODateTime": { + "description": "ISO DateTime: YYYY-MM-DDThh:mm:ssZ for UTC or YYYY-MM-DDThh:mm:ss+hh for other timezones", + "type": "string", + "format": "date-time" + }, + "ISOYearMonth": { + "type": "string", + "pattern": "^[0-9]+-([0][1-9]|1[0-2])$" + }, + "Link": { + "required": [ + "rel", + "href" + ], + "type": "object", + "properties": { + "rel": { + "type": "string", + "minLength": 1, + "maxLength": 50 + }, + "href": { + "type": "string", + "minLength": 1, + "maxLength": 500 + } + } + }, + "PaymentCard": { + "description": "debit card: Common term for various types of cards used for cash withdrawals and for payment of goods and services on various point of sales", + "required": [ + "cardIdentifier", + "type", + "holderName", + "startDate", + "expiryDate", + "cardIssuerName" + ], + "type": "object", + "properties": { + "cardIdentifier": { + "description": "Card number: number used to identify debit cards. Must be masked", + "allOf": [ + { + "$ref": "#/components/schemas/CardNumber" + } + ] + }, + "holderName": { + "description": "Cardholders name: party to whom the payment card is issued", + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "startDate": { + "description": "start date: Indicates the month and year a payment card is valid from", + "allOf": [ + { + "$ref": "#/components/schemas/ISOYearMonth" + } + ] + }, + "expiryDate": { + "description": "Expiration date: Indicates the month and year a payment card is valid until", + "allOf": [ + { + "$ref": "#/components/schemas/ISOYearMonth" + } + ] + }, + "cardIssuerName": { + "description": "Card issuers name: The financial institution that has issued a payment card", + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "type": { + "$ref": "#/components/schemas/CardType" + }, + "cardIssuerIdentifier": { + "$ref": "#/components/schemas/Identifier" + } + } + }, + "PostalAddress": { + "description": "Physical address and location", + "type": "object", + "properties": { + "postCode": { + "description": "Post code", + "type": "string", + "minLength": 1, + "maxLength": 16 + }, + "type": { + "$ref": "#/components/schemas/AddressType" + }, + "streetName": { + "type": "string", + "minLength": 1, + "maxLength": 70 + }, + "buildingNumber": { + "type": "string", + "minLength": 1, + "maxLength": 16 + }, + "townName": { + "type": "string", + "minLength": 1, + "maxLength": 35 + }, + "country": { + "$ref": "#/components/schemas/CountryCode" + }, + "addressLines": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 70 + }, + "minItems": 0 + } + }, + "required": [ + "type" + ] + }, + "ResponseStatus": { + "type": "string", + "enum": [ + "partial", + "complete" + ] + }, + "Roles": { + "description": "Root element for response", + "type": "object", + "xml": { + "name": "roles" + }, + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AccountRole" + }, + "minItems": 0 + } + } + }, + "SubFamilyType": { + "enum": [ + "valueDate", + "chargesGeneric", + "commissions", + "interestsGeneric", + "other", + "accountClosing", + "notAvailable", + "sweeping", + "topping", + "zeroBalancing", + "cashWithdrawal", + "debitCardPayment", + "crossBorderCashWithdrawal", + "cashDeposit", + "debitAdjustmentGeneric", + "travellersChequesDeposit", + "settlementAtMaturity", + "intraCompanyTransfer", + "corporateOwnAccountTransfer", + "crossBorderIntraCompanyTransfer", + "achDebit", + "achReturn", + "achTransactionAtxn", + "automaticTransfer", + "bankCheque", + "booked", + "domesticCreditTransfer", + "dividend", + "sepaCreditTransfer", + "financialInstitutionCreditTransfer", + "principalPayment", + "priorityCreditTransfer", + "reversalDueToPaymentReturn", + "achTransactionSala", + "sameDayValueCreditTransfer", + "standingOrder", + "taxes", + "creditTransferWithAgreedCommercialInformation", + "crossBorderCreditTransfer", + "cashLetter", + "cheques", + "chequesReversal", + "openCheque", + "unpaidCheque", + "crossBorderCheque", + "sepaCoreDirectDebit", + "directDebitPayment", + "reversalDueToPayment", + "reversalDueToPaymentCancellationRequest", + "reversalDueToReturnUnpaidDirectDebit", + "debit", + "deposit", + "adjustments", + "fees", + "creditCardPayment", + "pointOfSalePosPayment", + "creditAdjustment", + "settlementAfterCollection" + ], + "type": "string" + }, + "Transaction": { + "description": "Transaction: any posting on an account", + "required": [ + "transactionIdentifier", + "amount", + "currency", + "creditDebitIndicator", + "status", + "transactionCode", + "bookingDate", + "valueDate" + ], + "type": "object", + "properties": { + "transactionIdentifier": { + "description": "Transaction Identifier: The identifier for the transaction", + "type": "string", + "minLength": 0, + "maxLength": 35 + }, + "references": { + "type": "array", + "items": { + "description": "Transaction reference: unique reference associated with the transaction", + "allOf": [ + { + "$ref": "#/components/schemas/TransactionReference" + } + ] + }, + "minItems": 0 + }, + "creditDebitIndicator": { + "description": "Credit is positive balance debited is negative balance", + "allOf": [ + { + "$ref": "#/components/schemas/CreditOrDebit" + } + ] + }, + "reversalIndicator": { + "description": "Corrected transaction indicator: Indicates whether the transaction is a correction of a previous transaction", + "allOf": [ + { + "$ref": "#/components/schemas/TrueFalseIndicator" + } + ] + }, + "status": { + "description": "transaction status: indicates the status of the transaction", + "allOf": [ + { + "$ref": "#/components/schemas/TransactionStatus" + } + ] + }, + "transactionCode": { + "description": "Transaction code: contains a set of indicators to identify the type of transaction", + "allOf": [ + { + "$ref": "#/components/schemas/BankTransactionCode" + } + ] + }, + "bookingDate": { + "description": "Posting date: The date when the posting of the transaction is conducted by the financial institution", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "valueDate": { + "description": "Interest date: date when the transaction posting is interest-bearing", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "counterParties": { + "type": "array", + "items": { + "description": "Counterparty: another party, the party to whom a transaction is going or coming from", + "allOf": [ + { + "$ref": "#/components/schemas/CounterParty" + } + ] + }, + "minItems": 0 + }, + "additionalInfo": { + "description": "'Additional information on a transaction: textual description of the contents of a transaction'", + "type": "string", + "minLength": 1, + "maxLength": 500 + }, + "currencyExchange": { + "description": "Currency conversion: conversion of an amount from one currency to another", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyExchange" + } + ] + }, + "merchant": { + "description": "User location: the physical location of the transaction", + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "paymentCard": { + "description": "Payment Cards: The common term for various types of cards used for cash withdrawals and for the payment of goods and services at different point of sales", + "allOf": [ + { + "$ref": "#/components/schemas/PaymentCard" + } + ] + }, + "registered": { + "description": "registration date: date and time when transaction was made", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "amount": { + "$ref": "#/components/schemas/Amount" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + } + } + }, + "TransactionReference": { + "required": [ + "value", + "type" + ], + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "type": { + "$ref": "#/components/schemas/TransactionReferenceType" + } + } + }, + "TransactionReferenceType": { + "enum": [ + "accountServicerReference", + "archiveReference", + "chequeNumber", + "endToEndIdentification", + "instructionIdentification", + "invoiceNumber", + "mandateIdentification", + "messageIdentification", + "otherReference", + "paymentInformationIdentification", + "remittanceReference" + ], + "type": "string" + }, + "TransactionStatus": { + "enum": [ + "booked", + "pending", + "info" + ], + "type": "string" + }, + "Transactions": { + "description": "Root element for response", + "type": "object", + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "transactions": { + "type": "array", + "items": { + "description": "transaction: any posting on account", + "allOf": [ + { + "$ref": "#/components/schemas/Transaction" + } + ] + }, + "minItems": 0 + }, + "links": { + "type": "array", + "items": { + "description": "pagination: support division of response for large result sets. The following values should be used: next - For the next page in the transaction set (must be used unless this is the last page), last - indicates the last page of the transaction set. The absence of the next link is interpreted as this being the last page. prev - can be used to specify the previous page. The URL in the links should be relative. ", + "allOf": [ + { + "$ref": "#/components/schemas/Link" + } + ] + }, + "minItems": 0 + } + }, + "xml": { + "name": "transactions" + } + }, + "TrueFalseIndicator": { + "type": "boolean" + }, + "Error400": { + "description": "Error structure for error message 400", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-001" + }, + "message": { + "type": "string", + "description": "description of the error event that has occurred", + "example": "Bad request. Invalid request parameters" + } + } + }, + "Error401": { + "description": "Error structure for error message 401", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-010" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Unauthorized. The request is missing authentication information" + } + } + }, + "Error403": { + "description": "Error structure for error message 403", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-011" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Forbidden. The user is not authorized for the requested service" + } + } + }, + "Error404": { + "description": "Error structure for error message 404", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-002" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Resource not found. There is no information on the requested account." + } + } + }, + "Error405": { + "description": "Error structure for error message 405", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-012" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Method not allowed. Invalid HTTP method, only GET is supported" + } + } + }, + "Error429": { + "description": "Error structure for error message 429", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-022" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Too many requests. Too many requests can be made if one chooses to impose rate-limiting services to limit the number of calls from a client." + } + } + }, + "Error500": { + "description": "Error structure for error message 500", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-100" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Internal server error. Various technical errors with the service providers." + } + } + }, + "Error": { + "description": "Error structure for all error messages", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-0xx" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Informative error message" + } + } + } + } + }, + "security": [ + { + "accountsAuth": [] + } + ] +} \ No newline at end of file diff --git a/specs/dsop_catalog.json b/specs/dsop_catalog.json index 2b960ac..e05122f 100644 --- a/specs/dsop_catalog.json +++ b/specs/dsop_catalog.json @@ -951,6 +951,14 @@ "https://bitsnorge.github.io/dsop-accounts-api" ], "publisher": "https://organization-catalog.fellesdatakatalog.digdir.no/organizations/992873183" + }, + { + "identifier": "https://dataservice-publisher.digdir.no/dataservices/a04a572dbaec07ea346359751569914715ba8254", + "url": "https://raw.githubusercontent.com/Informasjonsforvaltning/dsop-api-spesifikasjoner/master/specs/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json", + "conformsTo": [ + "https://bitsnorge.github.io/dsop-accounts-api" + ], + "publisher": "https://organization-catalog.fellesdatakatalog.digdir.no/organizations/982759412" } ] } \ No newline at end of file diff --git a/specs/rdf/dsop_catalog.ttl b/specs/rdf/dsop_catalog.ttl index 3771a45..fb002fc 100644 --- a/specs/rdf/dsop_catalog.ttl +++ b/specs/rdf/dsop_catalog.ttl @@ -78,6 +78,7 @@ , , , + , , , , @@ -854,6 +855,16 @@ dcat:mediaType , . + a dcat:DataService ; + dct:conformsTo ; + dct:description "Open API specification of the Account APIs. (Work in progress.)"@en ; + dct:publisher ; + dct:title "Accounts API Oslo Pensjonsforsikring AS"@en ; + dcat:endpointDescription ; + dcat:endpointURL ; + dcat:mediaType , + . + a dcat:DataService ; dct:conformsTo ; dct:description "Open API specification of the Account APIs. (Work in progress.)"@en ; diff --git a/specs/rdf/dsop_catalog_test.ttl b/specs/rdf/dsop_catalog_test.ttl index b650ba4..3ab73b2 100644 --- a/specs/rdf/dsop_catalog_test.ttl +++ b/specs/rdf/dsop_catalog_test.ttl @@ -5,7 +5,8 @@ dct:description "Samling av kontoopplysnings API"@nb ; dct:publisher ; dct:title "DSOP API katalog [TEST]"@nb ; - dcat:service , + dcat:service , + , , , , @@ -36,6 +37,16 @@ , . + a dcat:DataService ; + dct:conformsTo ; + dct:description "Open API specification of the Account APIs. (Work in progress.)"@en ; + dct:publisher ; + dct:title "Accounts API Oslo Pensjonsforsikring AS"@en ; + dcat:endpointDescription ; + dcat:endpointURL ; + dcat:mediaType , + . + a dcat:DataService ; dct:conformsTo ; dct:description "Open API specification of the Account APIs. (Work in progress.)"@en ; diff --git a/specs/test/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json b/specs/test/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json new file mode 100644 index 0000000..7ae35ba --- /dev/null +++ b/specs/test/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json @@ -0,0 +1,2005 @@ +{ + "openapi": "3.0.0", + "info": { + "description": "Open API specification of the Account APIs. (Work in progress.)", + "version": "1.0.0", + "title": "Accounts API Oslo Pensjonsforsikring AS" + }, + "servers": [ + { + "url": "https://test.stacc.com:33443/dsop/api/v2", + "description": "test" + } + ], + "paths": { + "/accounts": { + "get": { + "summary": "List of accounts for a specified party and period. Account number can be provided in place of the party identifier for lookup requests directly on the account. Must provide a blank list if no hits.", + "operationId": "listAccounts", + "tags": [ + "accounts" + ], + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis that banks should validate", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "PartyID", + "in": "header", + "description": "Parts identifier, personal identification number, d number or organization number.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "AccountID", + "in": "header", + "description": "The account number", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Accounts" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}": { + "get": { + "summary": "Account details, including balances, for an account", + "operationId": "showAccountById", + "tags": [ + "accounts" + ], + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis that banks should validate", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccountDetails" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined for AccountDetails)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "404": { + "description": "ACC-002 Resource not found. No information is available for the requested account id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error404" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}/transactions": { + "get": { + "summary": "Transactions for specified account and period. Empty list if no hits. Must support pagination on large result sets (min 1000) - see separate description in the link element.", + "operationId": "listTransactions", + "tags": [ + "transactions" + ], + "parameters": [ + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account. Cannot match the account number.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "A list of transactions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Transactions" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}/cards": { + "get": { + "summary": "List of cards associated with the specified account. Empty list if no hits.", + "operationId": "listCards", + "tags": [ + "cards" + ], + "parameters": [ + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account. Cannot match the account number.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Cards" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with as content defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/accounts/{accountReference}/roles": { + "get": { + "summary": "Role holders for the specified account. Empty list if no hits.", + "operationId": "listRoles", + "tags": [ + "roles" + ], + "parameters": [ + { + "name": "accountReference", + "in": "path", + "description": "Unique reference to the account. Cannot match the account number.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromDate", + "in": "query", + "description": "From date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "To date, current date if not stated", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "header", + "name": "CorrelationID", + "description": "Correlation ID, unique identifier for the technical request", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "Legal-Mandate", + "in": "header", + "description": "Legal basis", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Valid response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Roles" + } + }, + "application/jose": { + "schema": { + "type": "string", + "format": "byte", + "description": "Encrypted response according to JWE compact serialization", + "example": "(JWE response with content as defined above)" + } + } + } + }, + "400": { + "description": "ACC-001 Bad request. The request contains invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error400" + } + } + } + }, + "401": { + "description": "ACC-010 Unauthorized. The request is missing authentication information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error401" + } + } + } + }, + "403": { + "description": "ACC-011 Forbidden. The user is not authorized for the requested service", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error403" + } + } + } + }, + "405": { + "description": "ACC-012 Method Not Allowed. Invalid HTTP method, only GET is supported ", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error405" + } + } + } + }, + "429": { + "description": "ACC-022 Too many requests. Too many requests, can be given if one chooses to impose rate-limiting on the services to limit the number of requests from a client.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error429" + } + } + } + }, + "500": { + "description": "ACC-100 Internal server error. Various technical errors on service provider side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error500" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "accountsAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "Access token (JWT)" + } + }, + "schemas": { + "Account": { + "description": "Account: a specification of a clearly defined type of financial events", + "required": [ + "accountIdentifier", + "accountReference", + "type", + "status", + "currency", + "servicer", + "primaryOwner" + ], + "type": "object", + "properties": { + "status": { + "description": "Status: indicates current account status", + "allOf": [ + { + "$ref": "#/components/schemas/AccountStatus" + } + ] + }, + "servicer": { + "description": "account administrator: financial institution that manages an account on behalf of the account owner, including handling the registration of account transactions, calculating the account balance and providing information about the account", + "allOf": [ + { + "$ref": "#/components/schemas/FinancialInstitution" + } + ] + }, + "links": { + "type": "array", + "items": { + "description": "Pagination: dividing the result into pages for large resultsets", + "allOf": [ + { + "$ref": "#/components/schemas/Link" + } + ] + }, + "minItems": 0 + }, + "accountIdentifier": { + "$ref": "#/components/schemas/AccountNumber" + }, + "accountReference": { + "$ref": "#/components/schemas/AccountReference" + }, + "type": { + "$ref": "#/components/schemas/AccountType" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + }, + "primaryOwner": { + "$ref": "#/components/schemas/AccountRole" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 70 + } + } + }, + "AccountDetail": { + "description": "Account: a specification of a clearly defined type of financial events", + "required": [ + "accountIdentifier", + "accountReference", + "type", + "status", + "currency", + "servicer", + "primaryOwner" + ], + "type": "object", + "properties": { + "status": { + "description": "Status: indicates current account status", + "allOf": [ + { + "$ref": "#/components/schemas/AccountStatus" + } + ] + }, + "servicer": { + "description": "account administrator: financial institution that manages an account on behalf of the account owner, including handling the registration of account transactions, calculating the account balance and providing information about the account", + "allOf": [ + { + "$ref": "#/components/schemas/FinancialInstitution" + } + ] + }, + "accountIdentifier": { + "$ref": "#/components/schemas/AccountNumber" + }, + "accountReference": { + "$ref": "#/components/schemas/AccountReference" + }, + "type": { + "$ref": "#/components/schemas/AccountType" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 70 + }, + "balances": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Balance" + }, + "minItems": 0 + }, + "primaryOwner": { + "$ref": "#/components/schemas/AccountRole" + }, + "startDate": { + "$ref": "#/components/schemas/ISODate" + }, + "endDate": { + "$ref": "#/components/schemas/ISODate" + } + } + }, + "AccountDetails": { + "description": "Root element for response", + "type": "object", + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there is also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "account": { + "allOf": [ + { + "$ref": "#/components/schemas/AccountDetail" + } + ] + } + }, + "xml": { + "name": "accounts" + } + }, + "AccountNumber": { + "description": "Account number", + "type": "string" + }, + "AccountPermissionType": { + "enum": [ + "noRight", + "rightToUseAlone", + "rightToUseWithOther" + ], + "type": "string" + }, + "AccountRole": { + "description": "Account role: indicates owner or manager of account", + "type": "object", + "properties": { + "permission": { + "description": "Account permissions: specifies the rights to an account", + "allOf": [ + { + "$ref": "#/components/schemas/AccountPermissionType" + } + ] + }, + "identifier": { + "$ref": "#/components/schemas/Identifier" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "startDate": { + "$ref": "#/components/schemas/ISODate" + }, + "endDate": { + "$ref": "#/components/schemas/ISODate" + }, + "postalAddress": { + "$ref": "#/components/schemas/PostalAddress" + }, + "electronicAddresses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ElectronicAddress" + }, + "minItems": 0 + } + }, + "required": [ + "name" + ] + }, + "AccountReference": { + "description": "accountReference - Unique reference to the account. Should not contain sensitive information such as account number", + "type": "string" + }, + "Accounts": { + "description": "Root element for response", + "type": "object", + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "accounts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Account" + }, + "minItems": 0 + }, + "links": { + "type": "array", + "items": { + "description": "Pagination: dividing the result into pages for large resultsets", + "allOf": [ + { + "$ref": "#/components/schemas/Link" + } + ] + }, + "minItems": 0 + } + }, + "xml": { + "name": "accounts" + } + }, + "AccountStatus": { + "enum": [ + "enabled", + "disabled", + "deleted" + ], + "type": "string" + }, + "AccountType": { + "description": "Account type", + "enum": [ + "loanAccount", + "salaryAccount", + "currencyAccount", + "savingsAccount", + "clientAccount", + "taxDeductionAccount", + "businessAccount" + ], + "type": "string" + }, + "AddressType": { + "description": "Categorization of ways to use an address according to the type of address the address, as described, is and what you want to do when using the address", + "enum": [ + "residential", + "business", + "mailTo", + "deliveryTo" + ], + "type": "string" + }, + "Amount": { + "description": "Amount, always as positive value. CreditDebitIndicator should be used to indicate whether the amount is positive or negative.", + "type": "number", + "minimum": 0, + "exclusiveMinimum": false + }, + "Balance": { + "description": "Balance: Sum of deposits and loans in the financial account", + "required": [ + "type", + "creditLineIncluded", + "amount", + "currency", + "creditDebitIndicator", + "registered" + ], + "type": "object", + "properties": { + "creditLineIncluded": { + "description": "'Balance included credit limit: Indicates whether the credit limit is included in the balance or not. Should always be \"false\"'", + "allOf": [ + { + "$ref": "#/components/schemas/TrueFalseIndicator" + } + ] + }, + "amount": { + "description": "A sum of money spent in a context. This can be a transaction, balance etc.", + "allOf": [ + { + "$ref": "#/components/schemas/Amount" + } + ] + }, + "creditDebitIndicator": { + "description": "Credit is positive balance, debit is negative balance", + "allOf": [ + { + "$ref": "#/components/schemas/CreditOrDebit" + } + ] + }, + "registered": { + "description": "registration date: the current date and time of the reported balance", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "type": { + "$ref": "#/components/schemas/BalanceType" + }, + "creditLineAmount": { + "$ref": "#/components/schemas/Amount" + }, + "creditLineCurrency": { + "$ref": "#/components/schemas/CurrencyCode" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + } + } + }, + "BalanceType": { + "description": "Balance type", + "enum": [ + "availableBalance", + "bookedBalance" + ], + "type": "string" + }, + "BankTransactionCode": { + "description": "Transaction code", + "type": "object", + "properties": { + "domain": { + "description": "Business area: High level classification of the activity in a business", + "allOf": [ + { + "$ref": "#/components/schemas/DomainType" + } + ] + }, + "family": { + "description": "Product: the specification of a product", + "allOf": [ + { + "$ref": "#/components/schemas/FamilyType" + } + ] + }, + "subFamily": { + "description": "Sub-product: Detailing of a product", + "allOf": [ + { + "$ref": "#/components/schemas/SubFamilyType" + } + ] + }, + "freeText": { + "type": "string", + "minLength": 1, + "maxLength": 500 + } + } + }, + "CardNumber": { + "description": "Masked card number", + "type": "string" + }, + "Cards": { + "description": "Root element for response", + "type": "object", + "xml": { + "name": "cards" + }, + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "paymentCards": { + "type": "array", + "items": { + "description": "Debit Cards: is the common term for various types of cards used for cash withdrawals and for payment of goods and services at different point of sales", + "allOf": [ + { + "$ref": "#/components/schemas/PaymentCard" + } + ] + }, + "minItems": 0 + } + } + }, + "CardType": { + "description": "Card type", + "enum": [ + "creditCard", + "debitCard" + ], + "type": "string" + }, + "CounterParty": { + "description": "Counterparty: the party to which a transaction goes to or comes from", + "type": "object", + "properties": { + "accountIdentifier": { + "$ref": "#/components/schemas/AccountNumber" + }, + "identifier": { + "$ref": "#/components/schemas/Identifier" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "type": { + "$ref": "#/components/schemas/CounterPartyType" + }, + "postalAddress": { + "$ref": "#/components/schemas/PostalAddress" + } + }, + "required": [ + "type" + ] + }, + "CounterPartyType": { + "enum": [ + "debtor", + "creditor", + "ultimateDebtor", + "ultimateCreditor" + ], + "type": "string" + }, + "CountryCode": { + "description": "Country code, ISO 3166-1 (alfa-2)", + "type": "string", + "pattern": "[A-Z]{2,2}" + }, + "CreditOrDebit": { + "enum": [ + "credit", + "debit" + ], + "type": "string" + }, + "CurrencyCode": { + "type": "string", + "pattern": "[A-Z]{3,3}" + }, + "CurrencyExchange": { + "description": "Currency conversion: conversion of an amount from one currency to another", + "type": "object", + "properties": { + "originalAmount": { + "description": "Amount in the original currency when converting from / to another currency has taken place", + "allOf": [ + { + "$ref": "#/components/schemas/Amount" + } + ] + }, + "sourceCurrency": { + "description": "Source Currency: The currency an amount is to be converted from during a currency conversion", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyCode" + } + ] + }, + "targetCurrency": { + "description": "Target currency: The currency an amount is to be converted into during a currency conversion", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyCode" + } + ] + }, + "unitCurrency": { + "description": "unit currency: The resulting currency following a currency conversion", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyCode" + } + ] + }, + "exchangeRate": { + "$ref": "#/components/schemas/Amount" + } + }, + "required": [ + "sourceCurrency", + "targetCurrency", + "exchangeRate" + ] + }, + "DomainType": { + "enum": [ + "accountManagement", + "cashManagement", + "foreignExchange", + "payments", + "securities", + "tradeServices", + "extended" + ], + "type": "string" + }, + "ElectronicAddress": { + "required": [ + "type", + "value" + ], + "type": "object", + "properties": { + "type": { + "$ref": "#/components/schemas/ElectronicAddressType" + }, + "value": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + } + } + }, + "ElectronicAddressType": { + "enum": [ + "phoneNumber", + "emailAddress" + ], + "type": "string" + }, + "FamilyType": { + "enum": [ + "additionalMiscellaneousCreditOperations", + "additionalMiscellaneousDebitOperations", + "miscellaneousCreditOperations", + "miscellaneousDebitOperations", + "openingAndClosing", + "accountBalancing", + "cashPooling", + "notAvailable", + "customerCardTransactions", + "counterTransactions", + "drafts", + "issuedCashConcentrationTransactions", + "issuedCreditTransfers", + "issuedCheques", + "issuedDirectDebits", + "lockboxTransactions", + "merchantCardTransactions", + "other", + "receivedCashConcentrationTransactions", + "receivedCreditTransfers", + "receivedCheques", + "receivedDirectDebits", + "corporateAction", + "documentaryCollection", + "standByLetterOfCredit" + ], + "type": "string" + }, + "FinancialInstitution": { + "description": "financial institution: Business or other institution involved in finance and banking", + "required": [ + "identifier", + "name" + ], + "type": "object", + "properties": { + "identifier": { + "$ref": "#/components/schemas/Identifier" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 140 + } + } + }, + "Identifier": { + "description": "Specific data that assist in identifying the object", + "type": "object", + "properties": { + "countryOfResidence": { + "description": "Country of residence: the country of residence of the object", + "allOf": [ + { + "$ref": "#/components/schemas/CountryCode" + } + ] + }, + "value": { + "type": "string" + }, + "type": { + "$ref": "#/components/schemas/IdentifierType" + } + }, + "required": [ + "value", + "type" + ] + }, + "IdentifierType": { + "enum": [ + "countryIdentificationCode", + "nationalIdentityNumber" + ], + "type": "string" + }, + "ISODate": { + "type": "string", + "format": "date" + }, + "ISODateTime": { + "description": "ISO DateTime: YYYY-MM-DDThh:mm:ssZ for UTC or YYYY-MM-DDThh:mm:ss+hh for other timezones", + "type": "string", + "format": "date-time" + }, + "ISOYearMonth": { + "type": "string", + "pattern": "^[0-9]+-([0][1-9]|1[0-2])$" + }, + "Link": { + "required": [ + "rel", + "href" + ], + "type": "object", + "properties": { + "rel": { + "type": "string", + "minLength": 1, + "maxLength": 50 + }, + "href": { + "type": "string", + "minLength": 1, + "maxLength": 500 + } + } + }, + "PaymentCard": { + "description": "debit card: Common term for various types of cards used for cash withdrawals and for payment of goods and services on various point of sales", + "required": [ + "cardIdentifier", + "type", + "holderName", + "startDate", + "expiryDate", + "cardIssuerName" + ], + "type": "object", + "properties": { + "cardIdentifier": { + "description": "Card number: number used to identify debit cards. Must be masked", + "allOf": [ + { + "$ref": "#/components/schemas/CardNumber" + } + ] + }, + "holderName": { + "description": "Cardholders name: party to whom the payment card is issued", + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "startDate": { + "description": "start date: Indicates the month and year a payment card is valid from", + "allOf": [ + { + "$ref": "#/components/schemas/ISOYearMonth" + } + ] + }, + "expiryDate": { + "description": "Expiration date: Indicates the month and year a payment card is valid until", + "allOf": [ + { + "$ref": "#/components/schemas/ISOYearMonth" + } + ] + }, + "cardIssuerName": { + "description": "Card issuers name: The financial institution that has issued a payment card", + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "type": { + "$ref": "#/components/schemas/CardType" + }, + "cardIssuerIdentifier": { + "$ref": "#/components/schemas/Identifier" + } + } + }, + "PostalAddress": { + "description": "Physical address and location", + "type": "object", + "properties": { + "postCode": { + "description": "Post code", + "type": "string", + "minLength": 1, + "maxLength": 16 + }, + "type": { + "$ref": "#/components/schemas/AddressType" + }, + "streetName": { + "type": "string", + "minLength": 1, + "maxLength": 70 + }, + "buildingNumber": { + "type": "string", + "minLength": 1, + "maxLength": 16 + }, + "townName": { + "type": "string", + "minLength": 1, + "maxLength": 35 + }, + "country": { + "$ref": "#/components/schemas/CountryCode" + }, + "addressLines": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 70 + }, + "minItems": 0 + } + }, + "required": [ + "type" + ] + }, + "ResponseStatus": { + "type": "string", + "enum": [ + "partial", + "complete" + ] + }, + "Roles": { + "description": "Root element for response", + "type": "object", + "xml": { + "name": "roles" + }, + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AccountRole" + }, + "minItems": 0 + } + } + }, + "SubFamilyType": { + "enum": [ + "valueDate", + "chargesGeneric", + "commissions", + "interestsGeneric", + "other", + "accountClosing", + "notAvailable", + "sweeping", + "topping", + "zeroBalancing", + "cashWithdrawal", + "debitCardPayment", + "crossBorderCashWithdrawal", + "cashDeposit", + "debitAdjustmentGeneric", + "travellersChequesDeposit", + "settlementAtMaturity", + "intraCompanyTransfer", + "corporateOwnAccountTransfer", + "crossBorderIntraCompanyTransfer", + "achDebit", + "achReturn", + "achTransactionAtxn", + "automaticTransfer", + "bankCheque", + "booked", + "domesticCreditTransfer", + "dividend", + "sepaCreditTransfer", + "financialInstitutionCreditTransfer", + "principalPayment", + "priorityCreditTransfer", + "reversalDueToPaymentReturn", + "achTransactionSala", + "sameDayValueCreditTransfer", + "standingOrder", + "taxes", + "creditTransferWithAgreedCommercialInformation", + "crossBorderCreditTransfer", + "cashLetter", + "cheques", + "chequesReversal", + "openCheque", + "unpaidCheque", + "crossBorderCheque", + "sepaCoreDirectDebit", + "directDebitPayment", + "reversalDueToPayment", + "reversalDueToPaymentCancellationRequest", + "reversalDueToReturnUnpaidDirectDebit", + "debit", + "deposit", + "adjustments", + "fees", + "creditCardPayment", + "pointOfSalePosPayment", + "creditAdjustment", + "settlementAfterCollection" + ], + "type": "string" + }, + "Transaction": { + "description": "Transaction: any posting on an account", + "required": [ + "transactionIdentifier", + "amount", + "currency", + "creditDebitIndicator", + "status", + "transactionCode", + "bookingDate", + "valueDate" + ], + "type": "object", + "properties": { + "transactionIdentifier": { + "description": "Transaction Identifier: The identifier for the transaction", + "type": "string", + "minLength": 0, + "maxLength": 35 + }, + "references": { + "type": "array", + "items": { + "description": "Transaction reference: unique reference associated with the transaction", + "allOf": [ + { + "$ref": "#/components/schemas/TransactionReference" + } + ] + }, + "minItems": 0 + }, + "creditDebitIndicator": { + "description": "Credit is positive balance debited is negative balance", + "allOf": [ + { + "$ref": "#/components/schemas/CreditOrDebit" + } + ] + }, + "reversalIndicator": { + "description": "Corrected transaction indicator: Indicates whether the transaction is a correction of a previous transaction", + "allOf": [ + { + "$ref": "#/components/schemas/TrueFalseIndicator" + } + ] + }, + "status": { + "description": "transaction status: indicates the status of the transaction", + "allOf": [ + { + "$ref": "#/components/schemas/TransactionStatus" + } + ] + }, + "transactionCode": { + "description": "Transaction code: contains a set of indicators to identify the type of transaction", + "allOf": [ + { + "$ref": "#/components/schemas/BankTransactionCode" + } + ] + }, + "bookingDate": { + "description": "Posting date: The date when the posting of the transaction is conducted by the financial institution", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "valueDate": { + "description": "Interest date: date when the transaction posting is interest-bearing", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "counterParties": { + "type": "array", + "items": { + "description": "Counterparty: another party, the party to whom a transaction is going or coming from", + "allOf": [ + { + "$ref": "#/components/schemas/CounterParty" + } + ] + }, + "minItems": 0 + }, + "additionalInfo": { + "description": "'Additional information on a transaction: textual description of the contents of a transaction'", + "type": "string", + "minLength": 1, + "maxLength": 500 + }, + "currencyExchange": { + "description": "Currency conversion: conversion of an amount from one currency to another", + "allOf": [ + { + "$ref": "#/components/schemas/CurrencyExchange" + } + ] + }, + "merchant": { + "description": "User location: the physical location of the transaction", + "type": "string", + "minLength": 1, + "maxLength": 140 + }, + "paymentCard": { + "description": "Payment Cards: The common term for various types of cards used for cash withdrawals and for the payment of goods and services at different point of sales", + "allOf": [ + { + "$ref": "#/components/schemas/PaymentCard" + } + ] + }, + "registered": { + "description": "registration date: date and time when transaction was made", + "allOf": [ + { + "$ref": "#/components/schemas/ISODateTime" + } + ] + }, + "amount": { + "$ref": "#/components/schemas/Amount" + }, + "currency": { + "$ref": "#/components/schemas/CurrencyCode" + } + } + }, + "TransactionReference": { + "required": [ + "value", + "type" + ], + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "type": { + "$ref": "#/components/schemas/TransactionReferenceType" + } + } + }, + "TransactionReferenceType": { + "enum": [ + "accountServicerReference", + "archiveReference", + "chequeNumber", + "endToEndIdentification", + "instructionIdentification", + "invoiceNumber", + "mandateIdentification", + "messageIdentification", + "otherReference", + "paymentInformationIdentification", + "remittanceReference" + ], + "type": "string" + }, + "TransactionStatus": { + "enum": [ + "booked", + "pending", + "info" + ], + "type": "string" + }, + "Transactions": { + "description": "Root element for response", + "type": "object", + "properties": { + "responseStatus": { + "description": "Indicates whether this is a complete response or whether there are also offline data that cannot be retrieved through the api.", + "allOf": [ + { + "$ref": "#/components/schemas/ResponseStatus" + } + ] + }, + "transactions": { + "type": "array", + "items": { + "description": "transaction: any posting on account", + "allOf": [ + { + "$ref": "#/components/schemas/Transaction" + } + ] + }, + "minItems": 0 + }, + "links": { + "type": "array", + "items": { + "description": "pagination: support division of response for large result sets. The following values should be used: next - For the next page in the transaction set (must be used unless this is the last page), last - indicates the last page of the transaction set. The absence of the next link is interpreted as this being the last page. prev - can be used to specify the previous page. The URL in the links should be relative. ", + "allOf": [ + { + "$ref": "#/components/schemas/Link" + } + ] + }, + "minItems": 0 + } + }, + "xml": { + "name": "transactions" + } + }, + "TrueFalseIndicator": { + "type": "boolean" + }, + "Error400": { + "description": "Error structure for error message 400", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-001" + }, + "message": { + "type": "string", + "description": "description of the error event that has occurred", + "example": "Bad request. Invalid request parameters" + } + } + }, + "Error401": { + "description": "Error structure for error message 401", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-010" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Unauthorized. The request is missing authentication information" + } + } + }, + "Error403": { + "description": "Error structure for error message 403", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-011" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Forbidden. The user is not authorized for the requested service" + } + } + }, + "Error404": { + "description": "Error structure for error message 404", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-002" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Resource not found. There is no information on the requested account." + } + } + }, + "Error405": { + "description": "Error structure for error message 405", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-012" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Method not allowed. Invalid HTTP method, only GET is supported" + } + } + }, + "Error429": { + "description": "Error structure for error message 429", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-022" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Too many requests. Too many requests can be made if one chooses to impose rate-limiting services to limit the number of calls from a client." + } + } + }, + "Error500": { + "description": "Error structure for error message 500", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-100" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Internal server error. Various technical errors with the service providers." + } + } + }, + "Error": { + "description": "Error structure for all error messages", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "error code, for automatic handling", + "example": "ACC-0xx" + }, + "message": { + "type": "string", + "description": "description of the error that has occurred", + "example": "Informative error message" + } + } + } + } + }, + "security": [ + { + "accountsAuth": [] + } + ] +} \ No newline at end of file diff --git a/specs/test/dsop_catalog_test.json b/specs/test/dsop_catalog_test.json index 5a63ac0..fc4e7fc 100644 --- a/specs/test/dsop_catalog_test.json +++ b/specs/test/dsop_catalog_test.json @@ -247,6 +247,14 @@ "https://bitsnorge.github.io/dsop-accounts-api" ], "publisher": "https://organization-catalog.fellesdatakatalog.digdir.no/organizations/984150865" + }, + { + "identifier": "https://dataservice-publisher.digdir.no/dataservices/01bfbbb713695fe47afd307e1c6c9a0bd2f247cc", + "url": "https://raw.githubusercontent.com/Informasjonsforvaltning/dsop-api-spesifikasjoner/master/specs/test/Oslo_Pensjonsforsikring_AS_982759412_Accounts-API.json", + "conformsTo": [ + "https://bitsnorge.github.io/dsop-accounts-api" + ], + "publisher": "https://organization-catalog.fellesdatakatalog.digdir.no/organizations/982759412" } ] } \ No newline at end of file diff --git a/src/dsop_api_spesifikasjoner/generateSpecification.py b/src/dsop_api_spesifikasjoner/generateSpecification.py index dcb35b8..4cbcedf 100644 --- a/src/dsop_api_spesifikasjoner/generateSpecification.py +++ b/src/dsop_api_spesifikasjoner/generateSpecification.py @@ -22,6 +22,7 @@ @click.version_option(version=__version__) @click.argument("template", type=click.File("r")) @click.argument("input", type=click.File("r")) +@click.argument("use_local_files", type=click.BOOL) @click.option( "-d", "--directory", @@ -34,7 +35,9 @@ writable=True, ), ) -def main(template: Any, input: Any, directory: Any) -> None: +def main( + template: Any, input: Any, directory: Any, use_local_files: bool = True +) -> None: """Write specification and catalog file based on template for bank.""" # Add a trailing slash to directory if not there: directory = os.path.join(directory, "") @@ -89,10 +92,12 @@ def main(template: Any, input: Any, directory: Any) -> None: _write_catalog_file(test_catalog_filename, test_catalog) _write_catalog_rdf_file( - turtle_prod_catalog_filename, create_catalog_graph(prod_catalog) + turtle_prod_catalog_filename, + create_catalog_graph(prod_catalog, use_local_files), ) _write_catalog_rdf_file( - turtle_test_catalog_filename, create_catalog_graph(test_catalog) + turtle_test_catalog_filename, + create_catalog_graph(test_catalog, use_local_files), ) @@ -162,7 +167,7 @@ def _generateSpec(template: dict, bank: List[str], production: bool) -> dict: return specification -def create_catalog_graph(catalog: Catalog) -> Graph: +def create_catalog_graph(catalog: Catalog, use_local_files: bool) -> Graph: """Create a graph based on catalog and persist to store.""" # Use datacatalogtordf and oastodcat to create a graph and persist: g = datacatalogtordf.Catalog() @@ -172,10 +177,24 @@ def create_catalog_graph(catalog: Catalog) -> Graph: g.publisher = catalog.publisher for api in catalog.apis: - with get(api.url, timeout=5) as response: - if response.status_code == 200: - api_spec = response.text - oas = yaml.safe_load(api_spec) + if ( + use_local_files + and "https://raw.githubusercontent.com/Informasjonsforvaltning/dsop-api-spesifikasjoner/master/" + in api.url + ): + file_path = api.url.replace( + "https://raw.githubusercontent.com/Informasjonsforvaltning/dsop-api-spesifikasjoner/master/", + "", + ) + api_spec_file = open(file_path, "r") + api_spec = api_spec_file.read() + api_spec_file.close() + oas = yaml.safe_load(api_spec) + else: + with get(api.url, timeout=5) as response: + if response.status_code == 200: + api_spec = response.text + oas = yaml.safe_load(api_spec) oas_spec = OASDataService(api.url, oas, api.identifier) oas_spec.conforms_to = api.conformsTo diff --git a/tests/test_generateSpecification.py b/tests/test_generateSpecification.py index fce3167..1905494 100644 --- a/tests/test_generateSpecification.py +++ b/tests/test_generateSpecification.py @@ -69,7 +69,7 @@ def test_main(mocker: MockerFixture, runner: CliRunner) -> None: t.write("servers:\n") t.write(" - url: 'https://hostname.no/v1'\n") - result = runner.invoke(main, ["template.yaml", "banker.csv"]) + result = runner.invoke(main, ["template.yaml", "banker.csv", "False"]) assert result.output == "" assert result.exit_code == 0 @@ -248,7 +248,7 @@ def test_main_fails_trailing_slash_1(runner: CliRunner) -> None: t.write(" - url: 'https://hostname.no/v1'\n") t.write(" description: 'test'\n") - result = runner.invoke(main, ["template.yaml", "banker.csv"]) + result = runner.invoke(main, ["template.yaml", "banker.csv", "False"]) assert result.exit_code == 1 assert result.output is not None @@ -278,7 +278,7 @@ def test_main_fails_trailing_slash_2(runner: CliRunner) -> None: t.write(" - url: 'https://hostname.no/v1'\n") t.write(" description: 'test'\n") - result = runner.invoke(main, ["template.yaml", "banker.csv"]) + result = runner.invoke(main, ["template.yaml", "banker.csv", "False"]) assert result.exit_code == 1 assert result.output is not None