NAV
HTTP cURL

New Swagger based API docs available

Introduction

FinTecSystems offers easy to use and easy to integrate client and server-side APIs based on our XS2A platform.

The API provides an interface for connecting and extracting online banking account information to meet your individual business requirements. We like to call it the “access to the account” concept.

API

Authentication

https://api.xs2a.com/

Default API endpoint

You can create and manage API keys from your account. Multiple API keys can be active at the same time. Authentication to the API uses HTTP Basic Auth. Provide api as username and your API key as password.

Endpoints are only available via HTTPS. Plain HTTP requests will not be processed.

Please be aware of the different modes for API keys. An API key in mode Test is not allowed to access Live transactions. Live API keys are not able to access data made from test transactions.

Should the authentication fail, you will received a 401 HTTP error code with a corresponding error message, see also Error messages.

This example uses a GET request to call the URL. The username api is always used for API authentication. Password is your generated API key.

curl -X GET --user api:<your-api-key> https://api.xs2a.com/v1/version
GET /v1/version HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

The above command returns JSON structured like this:

{
    "version": "2015-11-13"
}

We mostly use cURL in our examples but you can also use POST requests with JSON body to communicate with our API. Please make sure to include the HTTP header Content-Type: application/json with your JSON body, if you decide to use JSON for your POST data instead of URL encoded data.

Error Messages

With all error codes >400 you will receive an additional error message in the response body.

{
    "code": "401",
    "message": "Invalid credentials."
}

The HTTP status code 422 returns a special object. The error messages are returned corresponding to the field:

{
    "code": 422,
    "message": "Validation failed",
    "errors": {
        "direction": [
            "The selected direction is invalid."
        ],
        "per_page": [
            "The per page must be an integer."
        ]
    }
}

The API uses HTTP status codes for error messages:

HTTP Status Code Description
200 Request successful processed
401 Authentication failed API key missing or not valid
403 Forbidden Access blocked
404 Not found The requested object does not exist on the server
410* The object has been deleted intentionally
422 Validation failed Something is wrong with the user input
500 An internal server problem occurred

* Please note that to comply with our privacy policy we only keep transaction data for 30 days. The transaction data will not be available after this period.

Pagination

{
    "total": 15,
    "per_page": 15,
    "current_page": 1,
    "last_page": 8,
    "from": 1,
    "to": 15,
    "data": [
        // ... user data ...
    ]
}

Most calls which return a list like data structure allow pagination.

Explanation of response fields:

Key Type Description
total number Total number of results.
per_page number Number of objects per page.
current_page number Current page.
last_page number Last page, usually the total of available pages.
from number Showing results from index element.
to number Showing results to index element.
data array An array of user data with the actual results.

Every call that supports paging is able to use the parameters per_page and page.

curl -X GET -u api:<your-api-key> \
https://api.xs2a.com/v1/events?page=1&per_page=15
GET /v1/events?page=1&per_page=15 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "total": 66,
    "per_page": 15,
    "current_page": 1,
    "last_page": 5,
    "from": 1,
    "to": 15,
    "data": [
        {
            "id": "ev_fhDFdPRtECqwOlys",
            "transaction": "xv_eR08AnBz7CeBKnzp",
            "type": "transaction.created",
            "data": {
                "account_holder": "MUSTERMANN, HARTMUT",
                "iban": "DE62888888880012345678",
                "bic": "TESTDE88XXX",
                "bank_name": "Testbank",
                "country_id": "DE",
                "check_requested": false,
                "check_amount": 0,
                "check_currency_id": "EUR",
                "check_passed": false,
                "metadata": null,
                "merchant_id": "",
                "transaction": "10001-xv-zCTO-xpIT",
                "testmode": "1",
                "id": "xv_eR08AnBz7CeBKnzp",
                "created_at": "2015-05-05 11:47:45",
                "object": "xs2a_verification"
            },
            "testmode": "1",
            "created_at": "2015-05-05 11:47:45",
            "message": "Transaction xv_eR08AnBz7CeBKnzp created.",
            "object": "xs2a_event"
        },
    ]
}

Versioning

curl -X GET \
    --user api:<your-api-key> \
    https://api.xs2a.com/v1/version
GET /v1/version HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "version": "2015-11-13"
}

In case we make an API change, we might release a new version of the API. You can retrieve the current version by calling the version endpoint. This contains the date of the release date of the API. With every change we update the release date.

API compatibility

We consider the following changes as ‘non-breaking’ changes to the API:

However we consider these examples for 'breaking’ changes:

We consider the HTML that is generated by our xs2a.js and possibly styled by your own application as a form of API, and also try to limit changes to the structure and semantics of the generated markup, however we might add certain markup in the future which is the reason why you have to include the xs2a.css file in your HTML.

Blacklist

The Blacklist API allows you to magage a personal blacklist of IBANs. After adding an iban to the blacklist the customer won’t be able to use it in the XS2A Wizard.

The following operations are available.

Add item

POST /v1/blacklist HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json

{
    "data": "EE382200221020145685"
}

Adding a blacklist entry

Use the following endpoint.

POST https://api.xs2a.com/v1/blacklist

The POST request has to include the following parameter:

Parameter Type Required Description
data string Required Valid IBAN

Item details

GET /v1/blacklist/bl_c3nL2MafX8WdfiIM HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Getting the details of a blacklist item

Use the following endpoint.

GET https://api.xs2a.com/v1/blacklist/<id>

The value ist the ID that was given in the response after adding the IBAN. The fields in the response are the same you get after adding an entry.

Removing an item

DELETE /v1/blacklist/bl_c3nL2MafX8WdfiIM HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Removing an item from the blacklist

Use the following endpoint.

DELETE https://api.xs2a.com/v1/blacklist/<id>

The value ist the ID that was given in the response after adding the IBAN. The Response is the entry, that has been successfully deleted. The fields are the same you get after adding an entry.

Response

{
    "id": "bl_c3nL2MafX8WdfiIM",
    "data": "EE382200221020145685",
    "type": "iban"
}

Response of all the requests

The Response of the requests is an object with the following fields.

Parameter Type Description
id string Blacklist item id
type string Type of the entry, in this case ‘iban’
data string IBAN

Errors and validation errors

{
  "code": 422,
  "message": "Validation failed",
  "errors": {
    "data": [
      "Duplicate entry."
    ]
  }
}
{
  "code": 404,
  "message": "The requested resource was not found"
}

Validation Errors

The following errors could occur when adding, removing or selecting an item.

Complete Blacklist

GET /v1/blacklist HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Response

{
  "total": 2,
  "per_page": 15,
  "current_page": 1,
  "last_page": 1,
  "next_page_url": null,
  "prev_page_url": null,
  "from": 1,
  "to": 2,
  "data": [
    {
      "id": "bl_I6oeEWMVltIS2tOt",
      "data": "FR1420041010050500013M02606",
      "type": "iban"
    },
    {
      "id": "bl_4epDHJnxDwkbDKJF",
      "data": "EE382200221020145685",
      "type": "iban"
    },
  ]
}

Getting a list of all blacklist items

Yout can get a list of all the blacklist items by using the following endpoint.

GET https://api.xs2a.com/v1/blacklist

The items will be wrapped in a pagination element. Read the chapter Pagination for more information.

Bankcodes

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/bankcodes?bank_code=88888888&country_id=DE
GET /v1/bankcodes?bank_code=88888888&country_id=DE HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Using BIC instead of bank code

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/bankcodes?bic=TESTDE88XXX
GET /v1/bankcodes?bic=TESTDE88XXX HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

If you are unsure whether the customer has entered a BIC or bank code use the q parameter:

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/bankcodes?q=TESTDE88XXX
curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/bankcodes?q=88888888
GET /v1/bankcodes?q=TESTDE88XXX HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
GET /v1/bankcodes?q=88888888 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "bank_code": "88888888",
    "bic": "TESTDE88XXX",
    "name": "Testbank",
    "short_name": "Testbank",
    "zipcode": 12345,
    "city": "Teststadt",
    "country_id": "DE",
    "xs2a_supported": true,
    "testmode": true
}

XS2A might not support every bank. To help you decide whether or not you should offer a XS2A product to a customer, you can call this API endpoint to determine whether or not XS2A supports the bank code of the customer.

You will receive information about the selected bank. The field xs2a_supported can be used to determine whether or not you should offer XS2A products to your customer.

Parameter Type Required Description
bank_code string Optional bank code of the customers bank, optionally a country_id, otherwise Germany will be assumed
country_id string Optional Two letter country code id, e.g. AT, CH, DE
bic string Optional BIC of the customers bank, no country id is necessary
q string Optional Uses the value to search for customers bank as either BIC or bank code

The call returns a bank object, which has these properties:

Property Type Description
bank_code string bank code of the bank
bic string BIC of the bank
name string Name of the bank
short_name string Abbreviated bank name
zipcode string National ZIP code of the bank
city string City
country_id string Two letter country code id, e.g. AT, CH, DE
xs2a_supported boolean true, if this bank is supported by XS2A
testmode boolean true, if this bank is a testbank

All bankcodes

Get all bank codes (paginated)

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/bankcodes/all
GET /v1/bankcodes/all? HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

For a paginated result of all bank-codes send an empty GET request.

Parameter Type Required Default Description
country_id string Optional DE Two letter country code id, e.g. AT, CH, DE
per_page number Optional 15 Items per page
page number Optional 1 Which page to display

The call returns a paginated list of bank objects, which have these properties:

Property Type Description
bank_code string bank code of the bank
bic string BIC of the bank
name string Name of the bank
short_name string Abbreviated bank name
zipcode string National ZIP code of the bank
city string City
country_id string Two letter country code id, e.g. AT, CH, DE
xs2a_supported boolean true, if this bank is supported by XS2A
testmode boolean true, if this bank is a testbank

Bankcodes autocomplete

For a paginated result of bankcodes based on a query string send a GET to v1/bankcodes/autocomplete

Search for a bank code (paginated)

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/bankcodes/autocomplete?q=<search-query-here>
GET /v1/bankcodes/autocomplete?q=<search-query-here> HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Parameter Type Required Default Description
q string Required Part of a bank_code, bic or bank name.
country_id string Optional DE Two letter country code id, e.g. AT, CH, DE
per_page number Optional 15 Items per page.
page number Optional 1 Which page to display.
product string Optional Limit your search to a specific product. Valid vale

The call returns a paginated list of bank objects, which have these properties:

Property Type Description
bank_code string bank code of the bank
bic string BIC of the bank
name string Name of the bank
short_name string Abbreviated bank name
zipcode string National ZIP code of the bank
city string City
country_id string Two letter country code id, e.g. AT, CH, DE
xs2a_supported boolean true, if this bank is supported by XS2A
testmode boolean true, if this bank is a testbank

XS2A.verify

curl -X POST -u api:<your-api-key> \
    -d bank_code=88888888 \
    -d country_id=DE \
    -d check_amount=100 \
    -d check_currency_id=EUR \
    https://api.xs2a.com/v1/verifications
POST /v1/verifications HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 71

bank_code=88888888&country_id=DE&check_amount=100&check_currency_id=EUR

Request using POST with JSON

curl -X POST -u api:<your-api-key> \
    -H 'Content-Type: application/json'
    -d '{ "bank_code": "88888888", "country_id": "DE", "check_amount": 100, "check_currency_id": "EUR" }' \
    https://api.xs2a.com/v1/verifications
POST /v1/verifications HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 100

{
    "bank_code": "88888888",
    "country_id": "DE",
    "check_amount": 100,
    "check_currency_id": "EUR"
}

Server-Response

{
    "wizard_session_key": "<random-key>",
    "transaction": "<internal-XS2A-ID>"
}

Example request with BIC

curl -X POST -u api:<your-api-key> \
    -d bic=TESTDE88XXX \
    -d check_amount=100 \
    -d check_currency_id=EUR \
    https://api.xs2a.com/v1/verifications
POST /v1/verifications HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 76

{
    "bic": "TESTDE88XXX",
    "check_amount": 100,
    "check_currency_id": "EUR"
}

Example request with metadata

curl -X POST -u api:<your-api-key> \
    -d bic=TESTDE88XXX \
    -d check_amount=100 \
    -d check_currency_id=EUR \
    -d metadata[custid]=4711 \
    -d metadata[orderid]=12345 \
    https://api.xs2a.com/v1/verifications
POST /v1/verifications HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 165

{
    "bic": "TESTDE88XXX",
    "check_amount": "100",
    "check_currency_id": "EUR",
    "metadata": {
        "custid": "4711",
        "orderid": "12345"
    }
}

XS2A.verify allows you to collect and validate a bank connection. Optionally you can check the account balance/coverage against a given amount.

To create an XS2A.verify object and receive a Wizard session key use the endpoint

POST https://api.xs2a.com/v1/verifications

Please make sure to include the HTTP header Content-Type: application/json with your JSON body, if you decide to use JSON for your POST data instead of URL encoded data.

The POST request may include the following parameters:

Parameter Type Required Description
bank_code number Optional bank code of the customers bank, requires also parameter country_id. If supplied the step/page for entering a bank code will be skipped.
country_id string Optional Two letter country code id, e.g. AT, CH, DE
account_number string Optional (national) account number of the customer
iban string Optional IBAN of the customers account
bic string Optional BIC of the customers account
check_amount number Optional Account balance amount to be checked against
check_currency_id string Optional Currency id of check_amount, e.g. EUR
metadata array Optional An array of data which will be passed back to your application
merchant_id string Optional The internal ID of your merchant, if any.
language string Optional The initial language. May be en or de.

Please also note the following restrictions:

Using the wizard_session_key you can now initialize our Wizard which is running on your website. We suggest that you store the internally used XS2A transaction id transaction with your transaction data, because if you later have questions about a transaction, we need this number to be able to quickly assist you.

XS2A.verify response object

{
    "id": "xv_hd84kg9zns53lvh1",
    "transaction": "10001-xv-abcd-abcd",
    "object": "xs2a_verification",
    "account_holder": "Account Holder",
    "iban": "DE62888888880012345678",
    "bic": "TESTDE88XXX",
    "bank_name": "Testbank",
    "country_id": "DE",
    "check_requested": true,
    "check_amount": "100.0",
    "check_currency_id": "EUR",
    "check_passed": true,
    "testmode": true,
    "metadata": {
        "custid": 4711,
        "orderid": 12345
    },
    "merchant_id": "",
    "created_at": "2014-03-23 15:55:54"
}

Explanation of XS2A.verify response fields:

Key Type(length) Description
id string(20) Transaction id
transaction string(19) Internal XS2A transaction id. This id will be the same for the whole transaction
object string(17) Object type, in this case a xs2a_verification
account_holder string(255) Account holder name
iban string(40) IBAN
bic string(11) BIC
bank_name string(255) Bank name
country_id string(3) Two letter country code id, e.g. AT, CH, DE
check_requested boolean Indicates whether or not an additional check was requested
check_amount number The amount the account balance will be checked against
check_currency_id string(3) Currency id of check_amount, e.g. EUR
check_passed boolean Indicates whether or not the check was successful
testmode boolean Indicates whether or not it is a test transaction
metadata array Custom data will be returned unchanged. If no data was submitted, this field will be null
merchant_id string(255) Data will be returned unchanged.

Retrieve a list of all the XS2A.verify transactions

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications
GET /v1/verifications HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "total": 26,
    "per_page": 15,
    "current_page": 1,
    "last_page": 2,
    "from": 1,
    "to": 15,
    "data": [
        {
            "id": "xv_eR08AnBz7CeBKnzp",
            "account_holder": "MUSTERMANN, HARTMUT",
            "iban": "DE62888888880012345678",
            "bic": "TESTDE88XXX",
            "bank_name": "Testbank",
            "country_id": "DE",
            "check_requested": "0",
            "check_amount": "0.0",
            "check_currency_id": "EUR",
            "check_passed": "0",
            "testmode": "1",
            "created_at": "2015-05-05 11:47:45",
            "transaction": "10001-xv-zCTO-xpIT",
            "metadata": null,
            "merchant_id": "",
            "object": "xs2a_verification"
        },
    ]
}

To retrieve a list of all the XS2A.verify transactions, you can send a GET request to the API endpoint v1/verifications. Please note that to comply with our privacy policy we only keep transaction data for 30 days. The transaction data will not be available after this period.

This will return a JSON array consisting of XS2A.verify transactions. You can use it to process this data within your application. The array will be wrapped in a pagination element.

You can also use the following GET parameters to filter the results:

Parameter Type Required Description
account_holder string Optional Filter using account holder of the account
iban string Optional Filter using iban
bic string Optional Filter using bic
country_id string Optional Filter using two letter country id
check_requested boolean Optional Filter by check_requested
check_passed boolean Optional Filter by check_passed
merchant_id string Optional Filter by merchant_id
from,to string Optional Filter by date. Pass ISO8861 conform dates (yyyy-mm-ddThh:mm:ss-zzzz). The time and timezone portions are optional and may be omitted (e.g yyyy-mm-dd or yyyy-mm-ddThh:mm:ss)..
since string Optional Filter by date (format yyyy-mm-dd or yyyy-mm-ddThh:mm:ssZ or an ISO8601 conform date. You can also supply date expressions like “-2 weeks” oder “-4 month”). This parameter has been deprectated in favor of from and to.

Retrieve a list of XS2A.verify transactions which included an account balance check, but were not successful

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications?check_requested=true&check_passed=false
GET /v1/verifications?check_requested=true&check_passed=false HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Retrieve all transactions where a check was requested between 23.03.2014 and 25.04.2014:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications?check_requested=true&from=2014-03-23T00:00:00&to=2014-04-25T00:00:00
GET /v1/verifications?check_requested=true&from=2014-03-23T00:00:00&to=2014-04-25T00:00:00 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Example request to retrieve a single transaction as a JSON object, use the transaction id as a parameter like this:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications/xv_hd84kg9zns53lvh1
GET /v1/verifications/xv_hd84kg9zns53lvh1 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

As an alternative to the id you can use the internal XS2A transaction id transaction as parameter:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications/10001-xv-abcd-abcd
GET /v1/verifications/10001-xv-abcd-abcd HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Retrieve all events for a transactions:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications/xv_hd84kg9zns53lvh1/events
GET /v1/verifications/xv_hd84kg9zns53lvh1/events HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

XS2A.risk

curl -X POST -u api:<your-api-key> https://api.xs2a.com/v1/risks
POST /v1/risks HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 0

Session with preselected bank.

curl -X POST -u api:<your-api-key> \
    -d bank_code=88888888 \
    -d country_id=DE \
    https://api.xs2a.com/v1/risks
POST /v1/risks HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 56

{
    "bank_code": "88888888",
    "country_id": "DE"
}

Session with XS2A.balance_check

curl -X POST -u api:<your-api-key> \
    -d bank_code=88888888 \
    -d country_id=DE \
    -d xs2a_balance_check[check_amount]=100 \
    -d xs2a_balance_check[check_currency_id]=EUR \
    https://api.xs2a.com/v1/risks
POST /v1/risks HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 156

{
    "bank_code": "88888888",
    "country_id": "DE",
    "xs2a_balance_check": {
        "check_amount": "100",
        "check_currency_id": "EUR"
    }
}

Request with metadata

curl -X POST -u api:<your-api-key> \
    -d bank_code=88888888 \
    -d country_id=DE \
    -d xs2a_balance_check[check_amount]=100 \
    -d xs2a_balance_check[check_currency_id]=EUR \
    -d metadata[customer_id]=4711 \
    -d metadata[order_id]=abcdefg \
    https://api.xs2a.com/v1/risks
POST /v1/risks HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 241

{
    "bank_code": "88888888",
    "country_id": "DE",
    "xs2a_balance_check": {
        "check_amount": "100",
        "check_currency_id": "EUR"
    },
    "metadata": {
        "customer_id": "4711",
        "order_id": "abcdefg"
    }
}

Response

{
    "wizard_session_key": "<random-key>",
    "transaction": "<internal-XS2A-ID>"
}

XS2A.risk is similar to XS2A.verify. It allows you to collect and validate a bank connection. Additionally a range of predefined checks can be applied using the retrieved account information. For more information about the predefined checks see XS2A.risk.

To create an XS2A.risk object and receive a Wizard session key use the endpoint

POST https://api.xs2a.com/v1/risks

Please make sure to include the HTTP header Content-Type: application/json with your JSON body, if you decide to use JSON for your POST data instead of URL encoded data.

The POST request may include the following parameters:

Parameter Type Required Description
bank_code number Optional bank code of the customers bank, requires also parameter country_id. If supplied the step/page for entering a bank code will be skipped.
country_id string Optional Two letter country code id, e.g. AT, CH, DE
account_number string Optional (national) account number of the customer
iban string Optional IBAN of the customers account
bic string Optional BIC of the customers account
check_amount number Optional Account balance amount to be checked against
check_currency_id string Optional Currency id of check_amount, e.g. EUR
metadata array Optional An array of data which will be passed back to your application
merchant_id string Optional The internal ID of your merchant, if any.
language string Optional The initial language. May be en or de.

Please also note the following restrictions:

Additionally, for the XS2A.risk product one or more additional checks can be requested. You can find more information about the available checks in xs2a-risk-checks. Each check has its own type of parameters. However they are all composed like check_name[parameter_name].

Using the wizard_session_key you can now initialize our Wizard which is running on your website. We suggest that you store the internal used XS2A transaction id transaction with you transaction data, because if you later have questions about a transaction, we need this number to be able to quickly assist you.

XS2A.risk object

{
    "id": "xr_hd84kg9zns53lvh1",
    "transaction": "10001-xr-abcd-abcd",
    "object": "xs2a_risk",
    "account_holder": "Account Holder",
    "iban": "DE62888888880012345678",
    "bic": "TESTDE88XXX",
    "bank_name": "Testbank",
    "country_id": "DE",
    "testmode": true,
    "metadata": null,
    "merchant_id": "",
    "created_at": "2014-03-23 15:55:54"
}

Explanation of XS2A.risk response fields:

Key Type(length) Description
id string(20) Transaction id
transaction string(19) Internal XS2A transaction id. This id will be the same for the whole transaction
object string(9) Object type, in this case a xs2a_risk
account_holder string(255) Account holder name
iban string(40) IBAN
bic string(11) BIC
bank_name string(255) Bank name
country_id string(2) Two letter country code id, e.g. AT, CH, DE
testmode boolean Indicates whether or not it is a test transaction
metadata array Custom data will be returned unchanged. If no data was submitted, this field will be null
merchant_id string(255) Data will be returned unchanged.

Response with one or more additional checks will add be added to the XS2A.risk object as nested element

{
    "id": "xr_hd84kg9zns53lvh1",
    "transaction": "10001-xr-abcd-abcd",
    "object": "xs2a_risk",
    "account_holder": "Account Holder",
    "iban": "DE62888888880012345678",
    "bic": "TESTDE88XXX",
    "bank_name": "Testbank",
    "country_id": "DE",
    "testmode": true,
    "metadata": null,
    "merchant_id": "",
    "created_at": "2014-03-23 15:55:54",
    "xs2a_balance_check": {
        "check_amount": 100,
        "check_currency_id": "EUR",
        "check_passed": true,
        "object": "xs2a_balance_check",
        "created_at": "2014-03-23 15:55:54"
    }
}

A XS2A.risk might have any number of additional checks. Which one will be included, depends on the of checks that have been request during the initialization of the session.

Retrieve a list of all the XS2A.risk transactions

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/risks
GET /v1/risks HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Response

{
    "total": 10,
    "per_page": 15,
    "current_page": 1,
    "last_page": 1,
    "from": 1,
    "to": 10,
    "data": [
        {
            "id": "xr_6NEm0jRpXYhPP5AO",
            "transaction": "10001-xr-UCnK-0K3Q",
            "account_holder": "MUSTERMANN, HARTMUT",
            "iban": "DE62888888880012345678",
            "bic": "TESTDE88XXX",
            "bank_name": "Testbank",
            "country_id": "DE",
            "testmode": "1",
            "created_at": "2015-04-24 14:02:21",
            "metadata": null,
            "merchant_id": "",
            "object": "xs2a_risk",
            "xs2a_account_snapshot": {
                "days": "10",
                "from": "0000-00-00",
                "to": "0000-00-00",
                "filters": [
                ],
                "all_tags": false,
                "object": "xs2a_account_snapshot"
            }
        },
    ]
}

To retrieve a list of all the XS2A.risk transactions, you can send a GET request to the API endpoint v1/risks. Please note that to comply with our privacy policy we only keep transaction data for 30 days. The transaction data will not be available after this period.

This will return a JSON array consisting of XS2A.risk transactions. You can use it to process this data within your application. The array will be wrapped in a pagination element.

You can also use the following GET parameters to filter the results:

Parameter Type Required Description
account_holder string Optional Filter using account holder of the account
iban string Optional Filter using iban
bic string Optional Filter using bic
country_id string Optional Filter using two letter country id
merchant_id string Optional Filter by merchant_id
from,to string Optional Filter by date. Pass ISO8861 conform dates (yyyy-mm-ddThh:mm:ss-zzzz). The time and timezone portions are optional and may be omitted (e.g yyyy-mm-dd or yyyy-mm-ddThh:mm:ss)..
since string Optional Filter by date (format yyyy-mm-dd or yyyy-mm-ddThh:mm:ssZ or an ISO8601 conform date. You can also supply date expressions like “-2 weeks” oder “-4 month”). This parameter has been deprectated in favor of from and to.

Example request to retrieve all transactions where a check was requested between 23.03.2014 and 25.04.2014 (time and timezone omitted):

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks?from=2014-03-23&to=2014-04-25
GET /v1/risks?from=2014-03-23&to=2014-04-25 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Example request to retrieve a single transaction as a JSON object, use the transaction id as a parameter like this:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks/xr_hd84kg9zns53lvh1
GET /v1/risks/xr_hd84kg9zns53lvh1 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

As an alternative to the id you can use the internal XS2A transaction id transaction as parameter:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks/10001-xr-abcd-abcd
GET /v1/risks/10001-xr-abcd-abcd HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Retrieve all events for a transaction:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks/xr_hd84kg9zns53lvh1/events
GET /v1/risks/xr_hd84kg9zns53lvh1/events HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

XS2A.risk-checks

Currently the following risk checks are available

More checks will be added in the future.

XS2A.account_snapshot

A XS2A.account_snapshot is more an additional option than a whole check. A XS2A.account_snapshot offers direct access to the raw account data. The account data reflects the information at the time of the transaction.

If you use XS2A.risk for example for a loan application process, you can use the account snapshot to complete your files of the customer.

A typical workflow for a XS2A.risk check with a XS2A.account_snapshot option enabled works like this:

Example XS2A.account_snapshot

{
    // embedded in a XS2A.risk object
    "xs2a_account_snapshot": {
        "days": 45,
        "filters": []
    }
}

The XS2A.account_snapshot object accepts the following parameters:

Parameter Type Description
days int Range in days which should be used (min value: 10, max value: 365)
from date A date in the format yyyy-mm-dd
to date A date in the format yyyy-mm-dd
filters array Filter account statements, for valid options see below
all_accounts bool True, if you want to receive all accounts including their turnovers
all_tags bool True, if you want full categorization of the turnovers

The range of the returned turnovers in the the account snapshot can be either constrained by a number of days, starting from the current date or optionally by explicitly stating a from and to parameter. Notice however that the complete account snapshot will be restricted to the given date range. That also means that the account balance will be from the last day of the given date range.

Examples for valid filters options are

Filter Description
rent Information about rent payments
living-cost Information about living cost in general
credit Statements for running credit liabilities
income Income statements

For more filters visit the test call page and select “XS2A.risk” from the product dropdown and click the checkbox at “XS2A.account_snapshot”. You will be presented with a full list of filters.

If you want all turnovers with all available filter without specifying any filters in the first place you may supply the all_tags parameter. Keep in mind however that the filter rules we apply internally may change a lot. To keep your set of filters, and therefore your API, from unexpected changes it is advisable to provide a full list of filters when creating the session.

Example with more than one filter

{
    // embedded in a XS2A.risk object
    "xs2a_account_snapshot": {
        "days": 45,
        "filters": [
            "rent",
            "income"
        ]
    }
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_account_snapshot": {
        "days": 45,
        "from": "0000-00-00",
        "to": "0000-00-00",
        "filters": [],
        "all_tags": false,
        "object": "xs2a_account_snapshot"
    }
}

Explanation of response fields:

Parameter Type Description
days int Range in days that were used
from date The start date in the format yyyy-mm-dd
to date The end date in the format yyyy-mm-dd
filters array Filter account statements
all_tags bool True, if the turnovers were fully categorized

The account statement can be downloaded via a GET call to the following URL

GET https://api.xs2a.com/v1/risks/<transaction-id>/accountSnapshot?format=pdf

The format parameter is optional. The account snapshot is available in the following formats: pdf, csv, json and json2. This call defaults to pdf if the format parameter is omitted. Please note that you have to use json2 as format if the all_accounts parameter was set to true.

Example Formats

Format Example
pdf download
csv download
json download
json2 download

XS2A.balance_check

The XS2A.balance_check allows the check of the account coverage against a given amount.

Example XS2A.balance_check

{
    // embedded in a XS2A.risk object
    "xs2a_balance_check": {
        "check_amount": 100,
        "check_currency_id": "EUR",
        "check_passed": true,
        "object": "xs2a_balance_check",
        "created_at": "2014-03-23 15:55:54"
    }
}

Explanation of XS2A.risk balance_check response fields:

Key Type Description
object string(18) Object type, in this case a xs2a_balance_check
check_amount number The amount the account balance will be checked against
check_currency_id string(3) Currency id of check_amount, e.g. EUR
check_passed boolean Indicates whether or not the check was successful
created_at string(19) Creation date of the object

Example XS2A.balance_check object

{
    // embedded in a XS2A.risk object
    "xs2a_balance_check": {
        "check_amount": 100,
        "check_currency_id": "EUR"
    }
}

The XS2A.balance_check object accepts the following parameters:

Parameter Type Required Description
check_amount number Optional Account balance amount to be checked against
check_currency_id string Optional Currency id of check_amount, e.g. EUR

For more information about embedding a check into an XS2A.risk object, see XS2A.risk.

XS2a.balance_overview

XS2A.balance_overview returns the current running total of the chosen account.

An XS2A.balance_overview has no additional parameters. Just append an empty object to the XS2A.risk object to indicate you would like this check to be performed.

Example XS2a.balance_overview

{
    // embedded in a XS2A.risk object
    "xs2a_balance_overview": {}
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_balance_overview": {
        "balance": "135.0",
        "available": "1135.0",
        "limit": "1000.0",
        "currency_id": "EUR",
        "created_at": "2016-03-17 14:07:54",
        "object": "xs2a_balance_overview"
    }
}

Explanation of response fields:

Parameter Type Description
balance number Current balance
available number Current available
limit number Current limit (overdraft)
currency_id string(3) Currency id of above values, e.g. EUR

XS2a.cashflow_overview

XS2A.cashflow_overview provides an cashflow overview for the requested risk date range.

An XS2A.cashflow_overview has no additional parameters. Just append an empty object to the XS2A.risk object to indicate you would like this check to be performed.

Example XS2a.cashflow_overview

{
    // embedded in a XS2A.risk object
    "xs2a_cashflow_overview": {}
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_cashflow_overview": {
            "cashflow": [
                {
                    "month": 0,
                    "incoming": 0,
                    "outgoing": 0,
                    "minimum_balance": "135.00",
                    "incoming_transactions": 0,
                    "outgoing_transactions": 0,
                    "currency_id": "EUR"
                },
                {
                    "month": -1,
                    "incoming": 3038.07,
                    "outgoing": -1436.86,
                    "minimum_balance": -1591.44,
                    "incoming_transactions": 3,
                    "outgoing_transactions": 16,
                    "currency_id": "EUR"
                },
                {
                    "month": -2,
                    "incoming": 3038.07,
                    "outgoing": -833.18,
                    "minimum_balance": -3760.13,
                    "incoming_transactions": 3,
                    "outgoing_transactions": 6,
                    "currency_id": "EUR"
                },
                {
                    "month": -3,
                    "incoming": 0,
                    "outgoing": 0,
                    "minimum_balance": -3671.1,
                    "incoming_transactions": 0,
                    "outgoing_transactions": 0,
                    "currency_id": "EUR"
                }
            ],
            "created_at": "2016-03-17 14:20:51",
            "object": "xs2a_cashflow_overview"
        }
    }

Explanation of response fields:

Parameter Type Description
month number Relative month, e.g. current is 0, previous month is -1 and so on
incoming number Amount of this month incoming transactions
outgoing number Amount of this month outgoing transactions
minimum_balance number The minimum (lowest) balance of the account in that month
incoming_transactions number A count of this month incoming transactions
outgoing_transactions number A count of this month outgoing transactions
currency_id string(3) Currency id of above values, e.g. EUR
created_at string(19) The objects creation date.
object string(22) The object name.

XS2a.chargeback_check

XS2A.chargeback_check returns the number of detected chargeback transactions for the account.

An XS2A.chargeback_check has no additional parameters. Just append an empty object to the XS2A.risk object to indicate you would like this check to be performed.

Example XS2a.chargeback_check

{
    // embedded in a XS2A.risk object
    "xs2a_chargeback_check": {}
}

Response

{
    // embedded in a XS2A.risk object
     "xs2a_chargeback_check": {
        "chargebacks_count": "2",
        "chargebacks_coverage": "1",
        "chargebacks_revoked": "1",
        "chargebacks_sum_amount": "43.20",
        "currency_id": "EUR",
        "created_at": "2016-03-17 14:28:54",
        "object": "xs2a_chargeback_check"
    }
}

Explanation of response fields:

Parameter Type Description
chargebacks_count number Total count of detected chargeback transactions
chargebacks_coverage number Count of chargebacks which was triggered due insufficient funds
chargebacks_revoked number Count of chargebacks which was triggered manually
chargebacks_sum_amount number Sum over the amount of all chargebacks
currency_id string(3) Currency of sum amount in ISO 4217 format
created_at string(19) The objects creation date.
object string(21) The object name.

XS2A.children_check

The XS2A.children_check gathers payments from govermential facilities, which indicate how many children the account has.

This risk-check has no configuration.

Example XS2A.children_check

{
    // embedded in a XS2A.risk object
    "xs2a_children_check": {}
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_children_check": {
        "children_at_account_holder": 0
    }
}

Explanation of response fields:

Parameter Type Description
children_at_account_holder number Count of calculated children.

XS2A.credit_check

The XS2A.credit_check gathers various information about a customer. The check was designed for example to be used in a loan application process without the need to resort to some other medium. Currently information on all available categories are available. For further information see our category documentation

Example XS2A.credit_check

{
    // embedded in a XS2A.risk object
    "xs2a_credit_check": {
        "checks": [
            "income",
            "living-cost",
            "credit"
        ],
        "check_days": 30,
        "results": {
            "income": {
                "amount": 0.0,
                "currency": "EUR"
            },
            "living-cost": {
                "amount": 0.0,
                "currency": "EUR"
            },
            "credit": {
                "amount": 0.0,
                "currency": "EUR"
            }
        },
        "created_at": "2014-08-22 09:47:11",
        "object": "xs2a_credit_check"
    }
}

Explanation of XS2A.credit_check response fields:

Key Type Description
checks array Which checks were performed
check_days number Range in days that were used to calculated and gather the desired information
results array List of requested checks with the corresponding calculated value
created_at string(19) Creation date of the object
object string(17) Object type, in this case a xs2a_credit_check

Example XS2A.credit_check

{
    // embedded in a XS2A.risk object
    "xs2a_credit_check": {
        "checks": [
            "income",
            "credit"
        ]
    }
}

For more information about embedding a check into an XS2A.risk object, see XS2A.risk.

XS2A.direct_debit_check

The XS2A.direct_debit_check uses various metrics to determine the best date to execute a direct debit to minimize the risk of a default due to a lack of account coverage.

Example XS2A.direct_debit_check

{
    // embedded in a XS2A.risk object
    "xs2a_direct_debit_check": {
        "check_amount": 100,
        "check_currency_id": "EUR",
        "start_date": "2014-03-23",
        "end_date": "2014-03-31",
        "recommendation": "DATE",
        "recommendation_date": "2014-03-25",
        "created_at": "2014-03-23 15:55:54",
        "object": "xs2a_direct_debit_check"
    }
}

Explanation of XS2A.risk direct_debit_check response fields:

Key Type Description
object string(23) Object type, in this case a xs2a_direct_debit_check
check_amount number Account balance amount to be checked against
check_currency_id string(3) Currency id of check_amount, e.g. EUR
start_date string(10) Date format is “YYYY-mm-dd”
end_date string(10) Date format is “YYYY-mm-dd”
recommendation string(6) Values will either be ANY, DATE or REJECT
recommendation_date string(10) Date format is “YYYY-mm-dd”
created_at string(19) Creation date of the object

Example XS2A.direct_debit_check

{
    // embedded in a XS2A.risk object
    "xs2a_direct_debit_check": {
        "check_amount": 100,
        "check_currency_id": "EUR",
        "start_date": "2014-03-23",
        "end_date": "2014-03-31"
    }
}

The XS2A.direct_debit_check object accepts the following parameters:

Parameter Type Description
check_amount number Account balance amount to be checked against
check_currency_id string Currency id of check_amount, e.g. EUR
start_date string Date format is “YYYY-mm-dd”
end_date string Date format is “YYYY-mm-dd”

By using the start- and end-date option, you can specify a direct debit date range that is suitable to your liking. Our system will try to find the best day to execute a direct debit in your given date range.

For more information about embedding a check into an XS2A.risk object, see XS2A.risk.

XS2A.fact_sheet

The XS2A.fact_sheet generates a printable PDF with the most important facts about the customers account.

Parameter Type Description
limit_turnover_days number (optional) If needed limit the fetched turnovers to create a fact_sheet. Default 365. Valid Range: 10 - 365

Example XS2A.fact_sheet

{
    // embedded in a XS2A.risk object
    "xs2a_fact_sheet": {
        "limit_turnover_days": 365 
    }
}

You are able to Download a generated PDF file.

Download Fact Sheet PDF

GET v1/risks/<risk_id>/factSheet?format=pdf HTTP/1.1
Host: api.xs2a.com

Reponse: 200 OK
PDF-Binary
curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks/<risk_id>/factSheet?format=pdf

Also it is possible to get the calculated data, which is used to generate the factsheet as JSON.

Download Fact Sheet JSON

GET v1/risks/<risk_id>/factSheet?format=json HTTP/1.1
Host: api.xs2a.com
curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks/<risk_id>/factSheet?format=json
Field Content
monthlySums Contains sums of all turnovers within a month
monthlyAverages average balance in last 3, 6 and 12 months
facts A list of facts we gathered from the account
income a list of income and their averages
incomeAverages Average income in last 3, 6 and 12 months
spendings A list of spendings and their averages
spendingAverages Average spendings in last 3, 6 and 12 months
reoccurringTurnovers A list of categories and reoccurring turnovers of the last 6 month
cashFlow A list of daily balances
overdraftLimit Overdraft limit data. See here
standingOrders A list of standing orders
chargebacks A list of all chargebacks on this account

XS2A.name_check

The XS2A.name_check compares a given name and firstname with the extracted account holder.

Example XS2A.name_check

{
    // embedded in a XS2A.risk object
    "xs2a_name_check": {
        "match": true,
        "similarity": 100,
        "object": "xs2a_name_check",
        "created_at": "2015-11-11 15:55:54"
    }
}

Explanation of XS2A.risk name_check response fields:

Key Type Description
object string(15) Object type, in this case a xs2a_name_check
match boolean Indicates whether on not the given name matches with the extracted bank holder
similarity number A value between 0 and 100. A higher value means the values matched better
created_at string(19) Creation date of the object

Example XS2A.name_check object

{
    // embedded in a XS2A.risk object
    "xs2a_name_check": {
        "name": "Mustermann",
        "firstname": "Hartmut"
    }
}

The XS2A.name_check object accepts the following parameters:

Parameter Type Required Description
name string Required Name to compare against. Usually the surname.
firstname string Required Firstname to compare against.

For more information about embedding a check into an XS2A.risk object, see XS2A.risk.

XS2a.overdraft_limit_check

XS2A.overdraft_limit_check returns the number of booking days of the given risk range. The number of days the account used the overdraft limit, the maximum amount of overdraft used, the average and the median used overdraft.

An XS2A.overdraft_limit_check has no additional parameters. Just append an empty object to the XS2A.risk object to indicate you would like this check to be performed.

Example XS2A.overdraft_limit_check

{
    // embedded in a XS2A.risk object
    "XS2A.overdraft_limit_check": {}
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_overdraft_limit_check": {
        "booking_days": "23",
        "overdraft_limit_days": "23",
        "maximum_overdraft_used": "-3760.13",
        "average_overdraft_used": "-2032.85",
        "median_overdraft_used": "-1466.21",
        "currency_id": "EUR",
        "created_at": "2016-03-17 14:39:44",
        "object": "xs2a_overdraft_limit_check"
    }
}

Explanation of response fields:

Parameter Type Description
booking_days number Count of booking days in the date range found
overdraft_limit_days number Count of days the account used the overdraft limit
maximum_overdraft_used number Maximum amount the overdraft was used in that date range
average_overdraft_used number Average amount the overdraft was used in that date range
median_overdraft_used number Median amount the overdraft was used in that date range
currency_id string(3) Currency id of above values, e.g. EUR
created_at string(19) The objects creation date.
object string(26) The object name.

XS2a.seizure_check

XS2a.seizure_check allows you to check for a seizire account.

Example XS2a.seizure_check

{
    // embedded in a XS2A.risk object
    "xs2a_seizure_check": {}
}

Response

{
    "xs2a_seizure_check": {
        "is_seizure": "0",
        "created_at": "2017-03-30 16:14:32",
        "object": "xs2a_seizure_check"
    }
}

Explanation of response fields:

Parameter Type Description
is_seizure number 1 if the customers account is a seizure account

XS2a.standing_orders_check

XS2A.standing_orders_check allows you to retrieve all standing orders from an account. An XS2A.standing_orders_check has no additional parameters. Simply append an empty object to the XS2A.risk object to indicate you would like this check to be performed.

Example XS2a.standing_orders_check

{
    // embedded in a XS2A.risk object
    "xs2a_standing_orders_check": {}
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_standing_orders_check": {
        "standing_orders": [
            {
                "sender_account": {
                    "holder": "Account Holder",
                    "description": "Account description",
                    "iban": "DE1234...",
                    "bic": "BNK123...",
                    "country_id": "DE"
                },
                "recipient_account": {
                    "holder": "Recipient Holder",
                    "description": "",
                    "iban": "DE4321...",
                    "bic": "BNK321...",
                    "country_id": "DE"
                },
                "amount": 500,
                "currency": "EUR",
                "purpose": "Purpose",
                "frequency": "m",
                "frequency_interval": 1,
                "day": 31,
                "start_execution": "2014-11-05",
                "end_execution": null
            }
        ],
        "created_at": "2016-03-23 12:34:56",
        "object": "xs2a_standing_orders_check"
    }
}

The standing_orders-property contains the list of all standing orders objects.

Explanation of response fields:

Key Type Description
object string(26) Object type, in this case a xs2a_standing_orders_check
sender_account object Account object
recipient_account object Account object
amount number Amount to transfer
currency string(3) Currency id of amount, e.g. EUR
purpose string(54) Purpose of the transfer
frequency string(1) Frequency of standing order, d = daily, w = weekly, m = monthly, y = yearly
frequency_interval integer Frequency interval. For monthly execution frequency would be m, interval would be 1. For a bi-weekly execution frequency would be w, interval would be 2. 0 is used in case for a non standardized intervals (e.g. explicit month selection).
day integer Day of the execution. In case of daily or weekly frequency the range is 1-7 (1 = Monday, 7 = Sunday). In case of monthly or yearly frequency it is 1-31. 31 is used if the execution is sheduled for the last day of the month.
start_execution string(10) Date of the first or next execution of the standing order, format YYYY-mm-dd.
end_execution string(10) Date of the last execution of the standing order, format YYYY-mm-dd.
created_at string(19) Creation date of the object

A typical example would be rent payments executed at the end of every month. The frequency is m for monthly, frequency_interval is 1 since it should be executed every month. The key day is 31 because this will represent either the actual 31st of that month or the last day of the month in case the current month does not have a 31st (Ultimo).

In rare cases frequency_interval might be 0. It indicates irregular intervals in a non standardized format.

XS2a.all_accounts_check

XS2A.all_accounts_check is like the XS2a.account_snapshot more of an additional option than an individual check. If this option is selected, all visible accounts are extracted and reported back.

An XS2A.all_all_accounts_check has no additional parameters. Just append an empty object to the XS2A.risk object to indicate you want this check to be performed.

Example XS2a.all_accounts_check

{
    // embedded in a XS2A.risk object
    "xs2a_all_accounts_check": {}
}

Response

{
    // embedded in a XS2A.risk object
    "xs2a_all_accounts_check": {
        "accounts": [
            {
                "holder": "Account Holder",
                "description": "Account description",
                "iban": "DE1234...",
                "bic": "BNK123...",
                "joint_account": false
            },
            {
                "holder": "Account Holder",
                "description": "Account describes No 2",
                "iban": "DE1234...",
                "bic": "BNK123...",
                "joint_account": false
            },
            {
                "holder": "Account Holder",
                "description": "Visa Card",
                "iban": "",
                "bic": "BNK123...",
                "joint_account": false
            }
        ],
        "created_at": "2015-03-23 12:34:56",
        "object": "xs2a_all_accounts_check"
    }
}

The accounts-property contains the list of all account objects.

Please note that the 3rd account in the list has an empty iban property. This is especially common for savings accounts and credit cards.

XS2A.pay

    curl -X POST -u api:<your-api-key> \
        -d recipient_holder=Holder \
        -d recipient_iban=DE04888888880087654321 \
        -d recipient_bic=TESTDE88XXX \
        -d recipient_country_id=DE \
        -d amount=5.00 \
        -d currency_id=EUR \
        -d purpose=Purpose \
        https://api.xs2a.com/v1/payments
POST /v1/payments HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 229

{
    "recipient_holder": "Holder",
    "recipient_iban": "DE04888888880087654321",
    "recipient_bic": "TESTDE88XXX",
    "recipient_country_id": "DE",
    "amount": "5.00",
    "currency_id": "EUR",
    "purpose": "Purpose"
}

Response

{
    "wizard_session_key": "<random-key>",
    "transaction": "<internal-XS2A-ID>"
}

XS2A.pay offers a payment solution. The customer uses his online banking credentials. Optional security checks will be executed to counter fraud and other suspicious activity. After that the transfer of a fixed amount and purpose will be sent to a predefined recipient account. The customer authorizes the transaction with a TAN after which the bank is executing the transfer.

The customer is the sender of the transfer. You as PSP/merchant are the recipient of the payment.

To create an XS2A.pay object and receive a Wizard session key use the endpoint

POST https://api.xs2a.com/v1/payments

Please make sure to include the HTTP header Content-Type: application/json with your JSON body, if you decide to use JSON for your POST data instead of URL encoded data.

The POST request may include the following parameters:

Parameter Type Required Description
amount number Required Amount to be transferred
currency_id string Required Currency id of the amount (currently only EUR)
purpose string Required Purpose of the transfer
metadata array Optional An array of data which will be passed back to your application
language string Optional The initial language. May be en or de.
merchant_id string Optional The internal ID of your merchant, if any.
sender_holder string Optional Holder name of sender account owner
sender_iban string Optional IBAN of the sender account
sender_bic string Optional BIC of the sender account
sender_country_id string Optional Two letter country code id of the sender account, e.g. AT, CH, DE
recipient_holder string Required Account holder of the recipient account
recipient_iban string Required IBAN of the recipient account
recipient_bic string Optional BIC of the recipient account
recipient_street string Optional Street of the recipient account
recipient_zip string Optional Zip-code of the recipient account
recipient_city string Optional City of the recipient account
recipient_country_id string Optional Two letter country code id, e.g. AT, CH, DE
Payment-Parameters
Sender Account (optional, will be determined by XS2A)

Valid test mode data for a recipient account:

Please use these recipient account data in case you don’t have any other recipient at hand. Also please keep in mind that the recipient information is only valid in combination with a TEST-API-key.

Using the wizard_session_key you can now initialize our Wizard which is running on your website. We suggest that you store the internal used XS2A transaction id transaction with you transaction data, because if you later have questions about a transaction, we need this number to be able to quickly assist you.

XS2A.pay response object

{
    "id": "xp_fSdkfjS2R2S5x1pu",
    "transaction": "10001-xp-abcd-abcd",
    "object": "xs2a_payment",
    "sender_holder": "Holder Customer",
    "sender_iban": "DE62888888880012345678",
    "sender_bic": "TESTDE88XXX",
    "sender_bank_name": "Testbank",
    "sender_country_id": "DE",
    "recipient_holder": "Holder",
    "recipient_iban": "DE04888888880087654321",
    "recipient_bic": "TESTDE88XXX",
    "recipient_bank_name": "Testbank",
    "recipient_country_id": "DE",
    "purpose": "Purpose",
    "amount": 5,
    "currency_id": "EUR",
    "testmode": true,
    "payment_status": "RECEIVED",
    "metadata": {
        "name": "value"
    },
    "merchant_id": ""
}

Explanation of XS2A.pay response fields:

Key Type Description
id string(20) Transaction id
transaction string(19) Internal XS2A transaction id. This id will be the same for the whole transaction
sender_holder string(255) Account holder of the sender account
sender_iban string(40) IBAN of the sender account
sender_bic string(11) BIC of the sender account
sender_bank_name string(255) Name of the sender bank
sender_country_id string(2) Two letter country code id of the sender account, e.g. AT, CH, DE
recipient_holder string(255) Account holder of the recipient account
recipient_iban string(40) IBAN of the recipient account
recipient_bic string(11) BIC of the recipient account
recipient_bank_name string(255) Name of the recipient bank
recipient_country_id string(2) Two letter country code id of the recipient account, e.g. AT, CH, DE
purpose string(54) Purpose of transfer
amount number Amount to transfer
currency_id string(3) Currency id of amount, e.g. EUR
testmode boolean Indicates whether or not it is a test transaction
payment_status string(9) Payment status of the transaction, values NONE, RECEIVED, LOSS
metadata array Custom data will be returned unchanged. If no data was submitted, this field will be null
merchant_id string(255) Data will be returned unchanged.
object string(12) Object type, in this case a xs2a_payment

The payment_status field is intended to be used to notify us that the payment has been received or has been lost.

Example use case:

This mechanism helps us to determine reasons why a payment might not did go through even though the bank reported a successful transfer. It really helps us to improve our service and combating fraud.

Retrieve a list of all the XS2A.pay transactions

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/payments
GET /v1/payments HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Response

{
    "total": 35,
    "per_page": 15,
    "current_page": 1,
    "last_page": 3,
    "from": 1,
    "to": 15,
    "data": [
       {
            "id": "xp_irCumJEUY550DLe2",
            "transaction": "10001-xp-ERB6-4cEm",
            "sender_holder": "MUSTERMANN, HARTMUT",
            "sender_iban": "DE62888888880012345678",
            "sender_bic": "TESTDE88XXX",
            "sender_bank_name": "Testbank",
            "sender_country_id": "DE",
            "recipient_holder": "Holger Baumhaus",
            "recipient_iban": "DE08500105175412638463",
            "recipient_bic": "TESTDE88",
            "recipient_bank_name": "Testbank",
            "recipient_country_id": "DE",
            "purpose": "234234",
            "amount": "1.1",
            "currency_id": "EUR",
            "payment_status": "NONE",
            "testmode": "1",
            "metadata": null,
            "merchant_id": "",
            "created_at": "2015-04-24 14:03:00",
            "object": "xs2a_payment"
        }
    ]
}

To retrieve a list of all the XS2A.pay transactions, you can send a GET request to the API endpoint v1/payments. Please note that to comply with our privacy policy we only keep transaction data for 30 days. The transaction data will not be available after this period.

This will return a JSON array consisting of XS2A.verify transactions. You can use it to process this data within your application. The array will be wrapped in a pagination element.

You can also use the following GET parameters to filter the results:

Parameter Type Required Description
sender_holder string Optional Holder of the sender account
sender_iban string Optional IBAN of the sender account
sender_bic string Optional BIC of the sender account
sender_account_number string Optional Account number of the sender account
sender_bank_code string Optional National bank code of the sender account
sender_country_id string Optional Two letter country code id of the sender account, e.g. AT, CH, DE
recipient_holder string Optional Holder of the recipient account
recipient_iban string Optional IBAN of the recipient account
recipient_bic string Optional BIC of the recipient account
recipient_country_id string Optional Two letter country code id of the recipient account, e.g. AT, CH, DE
amount number Optional Amount to transfer
purpose string Optional Purpose of transfer
from,to string Optional Filter by date. Pass ISO8861 conform dates (yyyy-mm-ddThh:mm:ss-zzzz). The time and timezone portions are optional and may be omitted (e.g yyyy-mm-dd or yyyy-mm-ddThh:mm:ss)..
since string Optional Filter by date (format yyyy-mm-dd or yyyy-mm-ddThh:mm:ssZ or an ISO8601 conform date. You can also supply date expressions like “-2 weeks” oder “-4 month”). This parameter has been deprectated in favor of from and to.

Example request to retrieve all transactions where a check was requested between 23.03.2014 and 25.04.2014:

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/payments?from=2014-03-23T00:00:00&to=2014-04-25T00:00:00
GET /v1/payments?from=2014-03-23T00:00:00&to=2014-04-25T00:00:00 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Example request to retrieve a single transaction as a JSON object, use the transaction id as a parameter like this:

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/payments/xp_hd84kg9zns53lvh1
GET /v1/payments/xp_hd84kg9zns53lvh1 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

As an alternative to the id you can use the internal XS2A transaction id transaction as parameter:

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/payments/10001-xp-abcd-abcd
GET /v1/payments/10001-xp-abcd-abcd HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Retrieve all events for a transaction:

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/payments/xp_hd84kg9zns53lvh1/events
GET /v1/payments/xp_hd84kg9zns53lvh1/events HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

To change the payment status of a transaction use the following API calls:

POST v1/payments/<transaction-id>/received POST v1/payments/<transaction-id>/loss

These api calls allow you to mark a transaction as received or loss. If you perform a payment matching in your application, you can use these endpoints to change the payment status on our XS2A platform. A POST call to the endpoint v1/payments/<transaction-id>/received marks the transaction as received. A call to v1/payments/<transaction-id>/loss will mark the transaction as a loss. Both calls will include the full xs2a_payment object in the response.

Marking the payment status of a transaction will also fire an Event with the type transaction.updated. You can use this event to get a notification via a webhook. More information is available in events and webhooks.

Sessions

GET /v1/sessions/{transaction-id}

This will return a wizard_session object, with the following fields:

field type description
id string Internal identifier. Format: ws_xxxxxxxxxxxxxxxx
transaction string Public transaction identifier. Format: 00000-xx-xxxx-xxxx
wizard_session_key string Key to start the wizard
product string xs2a_risk, xs2a_pay or xs2a_verify
parameters object An array which contains the current wizard configuration.
last_error string The last occurred error. This is overwritten, if another error occurs.
testmode boolean true if this session runs in testmode. false otherwise.
finished boolean true if this session was finished successfully. false if not or still running.
current_step string The current wizard step of this session.
created_at string Time of creation
object string String with content wizard_session

To query this, you can use the transaction-id, which is returned, after the session is created.

XS2A.api

The XS2A.api is a set of APIs that make it possible to manage a users bank accounts in an asyncronous way. This makes the suitable for use in for example PFM tools. The API authentication is slightly different from the rest of the APIs, which makes it possible to deploy the API client including the API keys directly to mobile devices.

Structure

The entities that can be managed using the XS2A.api are as follows:

Basic Flow and Authentication

The authentication to the API is divided into two parts. The first part or the API is accessed via the standard authentication as described in the authentication chapter. This part of the API can be used to create bank users and manage access tokens. These access tokens enable to access the rest of the API of behalf of a user.

So the basic flow of this API is as follows:

  1. Create a bank user using the global API key.
  2. Create an access token for that bank user, to be able to access the API on behalf of the user. Use the new access token from here on instead of the global API key.
  3. Create a bank connection for the user.
  4. Display a wizard for that bank connection for the user.
  5. The user completes the wizard, by entering her bank login credentials.
  6. Retrieve the account contents like balance and transactions.

Bank Users

Creating a user

curl -X PUT -u api:<your-api-key> \
    -d email=user@example.com \
    -d name=Username \
    https://api.xs2a.com/v1/users
PUT /v1/verifications HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 71

email=user@example.com&name=Username
{
    "id": "bus_Ck7nGg05TK68jd9O",
    "name": "Username",
    "email": "user@example.com",
    "testmode": true,
    "created_at": "2017-11-24T16:07:52Z",
    "object": "bank_user"
}

Retrieve a paginated list of all the users

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/users
GET /v1/api/users HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "total": 1,
    "per_page": 15,
    "current_page": 1,
    "last_page": 1,
    "from": 1,
    "to": 15,
    "data": [
        {
            "id": "bus_Ck7nGg05TK68jd9O",
            "name": "Username",
            "email": "user@example.com",
            "testmode": true,
            "created_at": "2017-11-24T16:07:52Z",
            "object": "bank_user"
        }
    ]
}

Retrieve a single user

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/users/bus_Ck7nGg05TK68jd9O
GET /v1/api/users/bus_Ck7nGg05TK68jd9O HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "bus_Ck7nGg05TK68jd9O",
    "name": "Username",
    "email": "user@example.com",
    "testmode": true,
    "created_at": "2017-11-24T16:07:52Z",
    "object": "bank_user"
}

The endpoint

https://api.xs2a.com/v1/api/users

allows to create and delete bank users. A bank user is basically a person that has one or more logins to an online banking portal, a bank connection. In XS2A.api a bank user is mainly an entity which is used to aggregate bank account information on, therefore it does not have many attributes.

A user has has the following attributes:

Attribute Type Description
id string The ID of the bank user.
name string The name of the user.
email string An email adress (optional).
testmode boolean True, if this user has been created with a testing API key, false otherwise.
created_at string The creation time of the user.
object string The value bank_user.

Creating a user

To create a bank user, issue a PUT request to the URL. The PUT request can have these parameters:

Parameter Type Required Description
name string Required The name of the user.
email string Optional The email of the user.

The response will contain the newly created bank user.

Retrieve a list of users

To retrieve a list of all bank users, issue a GET request on this API endpoint. The list is a standard pagination repsonse as described here.

Get a single user

To get a single user issue a GET request on the resource URL, which is constructed as follows:

https://api.xs2a.com/v1/api/users/{$user-id}

Delete a user

To delete a user, issue a DELETE request on the resource URL.

Access Tokens

Creating an access token

curl --user api:<your-api-key> \
    -X PUT \
    -d valid_until='2018-12-01 10:00:00' \
    http://localhost:8000/v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens
PUT /v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 0

valid_until=2018-12-01 10:00:00
{
    "id": "uat_ELdQ3VHoO0C3IPc3",
    "token": "5Q1JCKqf1ONDw6SHZT4DECyrn28xm1ct",
    "valid_until": "2017-12-18T12:13:27Z",
    "created_at": "2017-12-18T11:13:27Z",
    "object": "bank_user_access_token"
}

Retrieve a paginated list of access tokens

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens
GET /v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "total": 1,
    "per_page": 15,
    "current_page": 1,
    "last_page": 1,
    "from": 1,
    "to": 15,
    "data": [
        {
            "id": "uat_ELdQ3VHoO0C3IPc3",
            "token": "5Q1JCKqf1ONDw6SHZT4DECyrn28xm1ct",
            "valid_until": "2017-12-18T12:13:27Z",
            "created_at": "2017-12-18T11:13:27Z",
            "object": "bank_user_access_token"
        }
    ]
}

Retrieve a single token

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens/uat_ELdQ3VHoO0C3IPc3
GET /v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens/uat_ELdQ3VHoO0C3IPc3 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "uat_ELdQ3VHoO0C3IPc3",
    "token": "5Q1JCKqf1ONDw6SHZT4DECyrn28xm1ct",
    "valid_until": "2017-12-18T12:13:27Z",
    "created_at": "2017-12-18T11:13:27Z",
    "object": "bank_user_access_token"
}

Refreshing an access token

curl -X PATCH -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens/uat_ELdQ3VHoO0C3IPc3
PATCH /v1/api/users/bus_Ck7nGg05TK68jd9O/accesstokens/uat_ELdQ3VHoO0C3IPc3 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "uat_ELdQ3VHoO0C3IPc3",
    "token": "5Q1JCKqf1ONDw6SHZT4DECyrn28xm1ct",
    "valid_until": "2017-12-19T18:13:27Z",
    "created_at": "2017-12-18T11:13:27Z",
    "object": "bank_user_access_token"
}

To be able to access the rest of the API on behalf of the user you just created, you have to create API access tokens. The API endpoint to manage access tokens is:

https://api.xs2a.com/v1/users/{$user-id}/accesstokens

Where {$user-id} must be an ID of a bank user.

An access token has has the following attributes:

Attribute Type Description
id string The ID of the token.
token string The actual access token.
valid_until string The date-time this token expires.
created_at string The creation time.
object string The value bank_user_access_token.

Creating an access token

To create an access token, issue a PUT request to the API endpoint. The generated access token is valid for one hour before it expires by default. It is possible to set a specific expiration-date by the following parameter:

Parameter Type Required Description
valid_until string Optional Expiration-date of access token in date-time string (Format: YYYY-MM-DD hh:mm:ss).

The response will contain the newly created access token.

Retrieving a list of tokens

To retrieve a list of access tokens issue a GET request on the API endpoint. The list is a standard pagination repsonse as described here.

Get a single token

To get a single token issue a GET request on the resource URL, which is constructed as follows:

https://api.xs2a.com/v1/api/users/{$user-id}/accesstokens/{$token-id}

Delete a token

To delete a user, issue a DELETE request on the resource URL.

Refresh a token

To refresh an access token and set a new expiration date for it, issue a PATCH request to the URL https://api.xs2a.com/v1/api/users/{$user-id}/accesstokens/{$token-id}.

Parameter Type Required Description
valid_until string Optional Expiration-date of access token in date-time string (Format: YYYY-MM-DD hh:mm:ss).

The response will contain the refreshed access token.

Using an access token

To use the access token and access the rest of the API on behalf of the user, simply replace the global API key with the generated access token. That means, still use Basic-Authentication with api as the username and the newly generated access token as the password.

Subsequent API calls with then be done on behalf of the user, that owns the access token.

Bank Connections

Bank connection represents a login to a specific bank. The creation of a bank connection always requires user interaction. The user has to select the bank she wants to connect and provide her login credentials to that bank. This process in done in our wizard, that guides the end user through the process.

The wizard itself comes in two flavors, the first on is a complete Javascript implementaion of the wizard. The Javascript implementation is by far the easiest to use, with the use of CSS it’s 100% compatible with most layouts and can be strongly customized. See the chapter on client integration for details on how to embedd the Javascript wizard.

The second option is the Wizard-API, which provides and API that is queried to guide the user throught the bank login process. Whenever embedding the Javascript wizard on a page or an app is not option, the use of the Wizard-API should be considered. For morre information on how to integrate this API see the chapter Wizard-API.

Bank connection can be synced. Syncing a bank connection means that the login to the bank is repeated, the new balance and the new list of turnovers is fetched and the list of accounts associated to the bank user is updated accordingly. Syncing a bank connection can be done in three different modes:

  1. full - If a bank connections sync_mode is set to full, the bank credentials are stored in XS2A and the connection will be synced automatically one a day.
  2. shared - If sync_mode is set to shared, XS2A will collect the credentials, encrypt them, cut the cipher in half and make one half of the credentials available at the end of the session. This way neither XS2A, nor the client has access to the full set of credentials. The sync of a bank connection has then to be done via API, providing the other half of the credential cipher as an argument to the sync call.
  3. none - The connection will not be synced automatically. Everytime a sync is initiated via the API, the user has to provide her bank credentials via the wizard.

A bank connection object consists of these attributes:

Attribute Type Description
id string The ID of the bank connection.
bic string The banks BIC.
bank_name string The banks name.
country_id string The banks country.
sync_mode string The mode in which this bank connection syncs itself.
sync_active boolean If the bank connection is still automatically syncing.
sync_message string The last error message, if a sync failed.
sync_fail_counter integer The sync fail counter. After 3 failed attempts a bank connection is permanently disabled and has to be deleted and recreated.
last_synced string The date of the last sync run.
testmode boolean True, if this is a test connection.
created_at string The creation time.
object string The value bank_connection.

The API endpoint for managing bank connections is

https://api.xs2a.com/v1/connections

This API endpoint is accessed in the user scope. This means that instead of the API key a user specific access token must be used.

Creating a bank connection

Creating a bank connection

curl --user api:{$the-bank-users-access-token} \
    -X PUT \
    -d sync_mode=full \
    -d country_id=DE \
    https://api.xs2a.com/v1/connections
PUT /v1/connections HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 28

sync_mode=full&country_id=DE
{
    "wizard_session_key": "2JB4yVDFzK6UV7vlkTRVgEzYigjTDWnefDs4cKUb",
    "transaction": "10001-bcs-GseB-mcBJ"
}

Retrieving a bank connection

curl --user api:{$the-bank-users-access-token} \
    https://api.xs2a.com/v1/connections/bcn_BnB6mQLsHKZacYvC
PUT v1/connections/bcn_BnB6mQLsHKZacYvC HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "bcn_BnB6mQLsHKZacYvC",
    "bic": "TESTDE88XXX",
    "bank_name": "Testbank",
    "country_id": "DE",
    "sync_mode": "full",
    "sync_active": true,
    "sync_message": "",
    "sync_fail_counter": 0,
    "last_synced": "2017-12-06T13:07:25Z",
    "testmode": true,
    "created_at": "2017-12-06T13:01:01Z",
    "object": "bank_connection"
}

To create a bank connection you issue a PUT request on the API endpoint. The parameters for the creation of a bank connection are

Parameter Type Description
sync_mode string The mode, how to sync the bank connection. full, shared or none.
bic string The BIC of the bank, if known already.
country_id string The country ID of the bank, if known already.

The creation of a bank connection always requires user interaction. Therefore the bank connection can not be created imediately. Instead this call will return a wizard_session_key that must be used to start a wizard.

A wizard is used to guide the user through the login process to her bank. The login proocess is modeled as close to the real bank as possible. A wizard is therefore basically a set of forms that has to be displayed to the user.

The wizard can either be a Javascript widget, that can be embedded on the website or the mobile app or a pure API solution, that does not require Javascript, but is a little harder to implement.

For the Javascript wizard integration, please refer to the chapter on client integration. For the pure API solution, please refer to the chapter on the Wizard-API.

Retrieving the list of bank connections

To retrieve a paginated list of all bank connections for a user issue a GET request on the bank connection endpoint https://api.xs2a.com/v1/connections.

Retrieving a bank connection

To retrieve a bank connection issue a GET request on the bank connection endpoint and append its ID at the end: https://api.xs2a.com/v1/connections/{$connection-id}.

Syncing a bank connection

Syncing a bank connection

curl --user api:{$the-bank-users-access-token} \
    -X POST \
    https://api.xs2a.com/v1/connections/bcn_BnB6mQLsHKZacYvC/sync
POST /v1/connections/bcn_BnB6mQLsHKZacYvC/sync HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Manually syncing a bank connection is only needed when the sync mode is shared or none. If the sync mode for a bank connection is full it will be synced automatically by XS2A once a day.

To sync a bank connection issue a post request on the API endpoint

https://api.xs2a.com/v1/connections/{$connection-id}/sync

The sync call has the following parameters:

Parameter Type Description
credentials string Your part of the shared credentials, if the sync mode is shared.
force boolean If an error occured during syncing, you may force a retry. If the sync_fail_counter goes up to 3 no more syncs are allowed.

Depending on the state of the bank connection there are two possible responses:

Error handling

Any bank connections that are in sync mode full are synced automatically by XS2A. No further steps are needed the turnovers and balance information on the accounts will always be up to date. If a sync process fails for some reason, e.g. the user has changed her password, that the automatic sync will stop. The field sync_message will contain more information about the error. The field sync_fail_counter will have the number of subsequent failures. sync_active will be set to false an the connection will not be synced again.

If the case above the sync can however be forced via the API. See also syncing a bank connection. After 3 failures in a row the bank connection will be disabled and can not be synced again. It will have to be deleted and recreated. The user will have to re-enter her credentials.

Deleting a bank connection

curl --user api:{$the-bank-users-access-token} \
    -X DELETE \
    https://api.xs2a.com/v1/connections/bcn_A0bkAL1h1POZNKMr
DELETE /v1/connections/bcn_A0bkAL1h1POZNKMr HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

To delete a bank connection, issue a DELETE request on the bank connections resource URL. The request will only delete the bank connection, not the bank account. This means that if a bank connection is faulty, you can simply delete and recreate it without affecting the list of account. New turnovers will just synchronize into the existing accounts.

The response to a DELETE request is an 204 status code with an empty response body.

Bank connection events

Payload for bank_accounts.new_account and bank_accounts.new_turnovers

{
    "id": "ev_vJnkqIQ8f3AMszf2",
    "transaction": null,
    "type": "bank_accounts.new_turnovers",
    "message": "User has new turnovers on a bank account",
    "data": {
        "bank_user_id": "bus_UcupnDXT1p6WSpWI",
        "bank_account_id": "bac_1aQL65xB8ASjvbiJ"
    },
    "testmode": "0",
    "created_at": "2017-12-28 13:44:34",
    "object": "xs2a_event"
}

Payload for bank_accounts.sync_failed

{
    "id": "ev_vJnkqIQ8f3AMszf2",
    "transaction": null,
    "type": "bank_accounts.sync_failed",
    "message": "Bank connection synchronization failed.",
    "data": {
        "id": "bcn_A0bkAL1h1POZNKMr",
        "bic": "TESTDE88XXX",
        "bank_name": "Testbank",
        "country_id": "DE",
        "sync_mode": "full",
        "sync_active": false,
        "sync_message": " Der Login zu Ihrer Bank ist fehlgeschlagen.",
        "sync_fail_counter": 2,
        "last_synced": "2017-12-27T14:57:59Z",
        "testmode": false,
        "created_at": "2017-12-27T14:57:59Z",
        "object": "bank_connection"
    },
    "testmode": "0",
    "created_at": "2017-12-28 13:44:34",
    "object": "xs2a_event"
}

Every event that occurs when syncronizing bank connections is sent out to a webhook URL, that can be configured in the customer cockpit. The following events will be automatically sent to the webhook URLs as they occur:

The URLs will be called using the POST method. Unless a successful response code of 200 is seen the URL will be called again up to 30 times in growing time frames. The events are accompanied by a payload that contains information a about what changed.

Bank Accounts

Retrieve a paginated list of all the users bank accounts

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/accounts
GET /v1/api/accounts HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "total": 1,
    "per_page": 15,
    "current_page": 1,
    "last_page": 1,
    "next_page_url": null,
    "prev_page_url": null,
    "from": 1,
    "to": 1,
    "data": [
        {
            "id": "bac_c8KYwjexO2iO5AE9",
            "holder": "MUSTERMANN, HARTMUT",
            "iban": "DE62888888880012345678",
            "bic": "TESTDE88XXX",
            "bank_name": "Testbank",
            "country_id": "DE",
            "joint_account": false,
            "transaction_possible": true,
            "created_at": "2017-12-06T13:01:01Z",
            "object": "bank_account"
        }
    ]
}

Retrieve a bank account

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/accounts/bac_c8KYwjexO2iO5AE9
GET /v1/api/accounts/bac_c8KYwjexO2iO5AE9 HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "bac_c8KYwjexO2iO5AE9",
    "holder": "MUSTERMANN, HARTMUT",
    "iban": "DE62888888880012345678",
    "bic": "TESTDE88XXX",
    "bank_name": "Testbank",
    "country_id": "DE",
    "joint_account": false,
    "transaction_possible": true,
    "created_at": "2017-12-06T13:01:01Z",
    "object": "bank_account"
}

The endpoint

https://api.xs2a.com/v1/accounts

allows to fetch the list of bank accounts for a user. This endpoint is accessed in the scope a user with a user specific accesst token. Bank accounts are automatically read from bank connections.

A bank account has the following attributes:

Attribute Type Description
id string The ID of the bank account.
holder string The name of the account holder as reported by the bank.
iban string The IBAN of the bank account.
bic string The BIC of the bank account.
bank_name string The name of the bank.
country_id string The country for the bank.
joint_account boolean True, if this account has more that one owner.
transaction_possible boolean True, if this account place payments.
created_at string The creation time of the bank account.
object string The value bank_account.

Account Balance

Retrieve a bank accounts balance

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/accounts/bac_c8KYwjexO2iO5AE9/balance
GET /v1/api/accounts/bac_c8KYwjexO2iO5AE9/balance HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "bac_c8KYwjexO2iO5AE9",
    "available": 3123,
    "limit": 1000,
    "balance": 2123,
    "currency": "EUR",
    "date": "2017-12-06T00:00:00Z",
    "created_at": "2017-12-06T13:01:01Z",
    "object": "bank_account_balance"
}

To retrieve the current balance for an account use the endpoint

https://api.xs2a.com/v1/accounts/{$bank-account-id}/balance

A bank account balance has the following attributes:

Attribute Type Description
id string The ID of the bank account.
available number The available amount. This can be null, if the available amount is not known.
limit number The limit of the account. This can be null, if the limit is not known.
balance number The current account balance.
currency string The bank accounts currency code (3-digit, e.g. EUR).
date string The date the balance was seen on.
created_at string The creation time of the bank account balance object.
object string The value bank_account_balance.

Account Turnovers

Retrieve a bank accounts turnovers

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/api/accounts/bac_c8KYwjexO2iO5AE9/turnovers
GET /v1/api/accounts/bac_c8KYwjexO2iO5AE9/turnovers HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
{
    "id": "bac_c8KYwjexO2iO5AE9",
    "turnovers": [
         {
            "booking_date": "2017-10-08T00:00:00Z",
            "amount": -962,
            "currency_id": "EUR",
            "purpose": [
                "SEPA-DAUERAUFTRAG EMPFAENGER HAUSVERWALTUNG",
                "MUELLER IBAN DE18701693100100029394 BIC GENODEF1ALX",
                "Order-Nr. 00022688654 VERWENDUNGSZWECK MIETE"
            ],
            "counter_iban": "DE18701693100100029394",
            "counter_bic": "GENODEF1ALX",
            "prebooked": false,
            "canceled": false,
            "tags": [
                "expenditure",
                "rent"
            ]
        }
    ],
    "days": 59,
    "date": "2017-12-06T00:00:00Z",
    "created_at": "2017-12-06T13:01:01Z",
    "object": "bank_account_turnovers"
}

To retrieve the list of turnovers for an account use the endpoint

https://api.xs2a.com/v1/accounts/{$bank-account-id}/turnovers

You can use the following GET parameters to filter the turnovers:

Parameter Type Required Description
from, to string Optional Filter by date. Pass ISO8861 conform dates (yyyy-mm-dd). If you use from without to attribute, it is set to the current date. You will get all turnovers since from

A turnover list object has the following attributes:

Attribute Type Description
id string The ID of the bank account.
turnovers array The list of turnovers.
days number The number of days requested.
date string The date the turnovers were seen on.
created_at string The creation time of the turnovers object.
object string The value bank_account_turnovers.

A turnover object inside the list has these attributes:

Attribute Type Description
booking_date string The booking date.
amount number The turnover amount. Negative for expenditures.
currency_id string The currency.
purpose array A string array of purpose lines. The contents vary from bank to bank.
counter_iban string The counter IBAN of the booking. This is not always present.
counter_bic string The counter BIC of the booking. This is not always present.
counter_holder string The counter holder of the booking. This is not always present.
prebooked boolean True, if the turnover has not been booked yet
canceled boolean True, if the turnover has been canceled.
tags array A string array of tags for this turnover.

Events

curl -X GET -u api:<your-api-key> https://api.xs2a.com/v1/events
GET /v1/events HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Response

{
    "total": 66,
    "per_page": 15,
    "current_page": 1,
    "last_page": 5,
    "from": 1,
    "to": 15,
    "data": [
        {
            "id": "ev_fhDFdPRtECqwOlys",
            "transaction": "xv_eR08AnBz7CeBKnzp",
            "type": "transaction.created",
            "data": {
                "account_holder": "MUSTERMANN, HARTMUT",
                "iban": "DE62888888880012345678",
                "bic": "TESTDE88XXX",
                "bank_name": "Testbank",
                "country_id": "DE",
                "check_requested": false,
                "check_amount": 0,
                "check_currency_id": "EUR",
                "check_passed": false,
                "metadata": null,
                "merchant_id": "",
                "transaction": "10001-xv-zCTO-xpIT",
                "testmode": "1",
                "id": "xv_eR08AnBz7CeBKnzp",
                "created_at": "2015-05-05 11:47:45",
                "object": "xs2a_verification"
            },
            "testmode": "1",
            "created_at": "2015-05-05 11:47:45",
            "message": "Transaction xv_eR08AnBz7CeBKnzp created.",
            "object": "xs2a_event"
        }
    ]
}

Downloading a single event

curl -X GET -u api:<your-api-key> \
    https://api.xs2a.com/v1/events/ev_fhDFdPRtECqwOlys
GET /v1/events/ev_fhDFdPRtECqwOlys HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Response

{
    "id": "ev_fhDFdPRtECqwOlys",
    "transaction": "xv_eR08AnBz7CeBKnzp",
    "type": "transaction.created",
    "data": {
        "account_holder": "MUSTERMANN, HARTMUT",
        "iban": "DE62888888880012345678",
        "bic": "TESTDE88XXX",
        "bank_name": "Testbank",
        "country_id": "DE",
        "check_requested": false,
        "check_amount": 0,
        "check_currency_id": "EUR",
        "check_passed": false,
        "metadata": null,
        "merchant_id": "",
        "transaction": "10001-xv-zCTO-xpIT",
        "testmode": "1",
        "id": "xv_eR08AnBz7CeBKnzp",
        "created_at": "2015-05-05 11:47:45",
        "object": "xs2a_verification"
    },
    "testmode": "1",
    "message": "Transaction xv_eR08AnBz7CeBKnzp created.",
    "created_at": "2015-05-05 11:47:45",
    "object": "xs2a_event"
}

An event is basically the API representation of a webhook. Every webhook you receive fires an event, that you can process further. You can retrieve a list of all events via the API endpoint v1/events.

You can also use the following GET parameters to filter the results:

Parameter Type Required Description
transaction string Optional List all events for single transaction
type string Optional The type of event e.g. ‘transaction.created’ or 'transaction.updated’ etc.
from,to string Optional Filter by date. Pass ISO8861 conform dates (yyyy-mm-ddThh:mm:ss-zzzz). The time and timezone portions are optional and may be omitted (e.g yyyy-mm-dd or yyyy-mm-ddThh:mm:ss)..
since string Optional Filter by date (format yyyy-mm-dd or yyyy-mm-ddThh:mm:ssZ or an ISO8601 conform date. You can also supply date expressions like “-2 weeks” oder “-4 month”). This parameter has been deprecated in favor of from and to.

The event object is made up of the following fields:

Fieldname Type Description
id string(20) The internal ID of this object.
transaction string(19) The transaction ID this object belongs to. May be null for some events.
type string(64) The type of event. 'transaction.created’ or 'transaction.updated’.
data object The object, that this event relates to. This is usually a transaction object.
testmode boolean 1 for events that belong to test transactions.
message string(255) A human readable message that describes this event.
created_at string(19) The date the event was fired.
object string(10) “xs2a_event” for event objects.

Deleting Data

All transaction data will get deleted 30 days after they were created.

Transaction data also can be deleted manually by sending a DELETE request for that transaction.

Delete XS2A.Verify request

curl -X DELETE -u api:<your-api-key> \
    https://api.xs2a.com/v1/verifications/<transaction-id>
DELETE /v1/verifications/<transaction-id> HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Delete XS2A.Risk request

curl -X DELETE -u api:<your-api-key> \
    https://api.xs2a.com/v1/risks/<transaction-id>
DELETE /v1/risks/<transaction-id> HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=

Delete XS2A.Payment request

curl -X DELETE -u api:<your-api-key> \
    https://api.xs2a.com/v1/payments/<transaction-id>
DELETE /v1/payments/<transaction-id> HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Product Method uri
XS2A.verify DELETE /v1/verifications/{transaction-id}
XS2A.pay DELETE /v1/payments/{transaction-id}
XS2A.risk DELETE /v1/risks/{transaction-id}

Wizard-API

The wizard API allows to avoid the usage of the javascript library xs2a.js.

Please note that the Wizard API is a feature that needs to be activated for your account in order to use it.

Request

The API endpoint is:

POST https://api.xs2a.com/v1/wizard

There might be different parameters for each POST request for each bank. Therefore there is no explicit listing of all parameters available. However, the following parameters are possible or respectively needed for every request:

Parameter Type Required Description
wizard_session_key string Required The wizard session key
action string Optional Valid values are: back (go back one step), switch-login-tabs (switch to another transport), poll (status polling) and change-language (change the language)

Response

The wizard API is using http status codes to indicate whether the request was successful. If the http status code is not equal to 200, the response will only contain the following parameters:

Key Type Description
code number status code to indicate whether the request was successful
message string Descriptive message for the status code
error array Contains the validation errors (only set in case there are any)

Response to an erroneous request

{
    "code": 401,
    "message": "Invalid credentials."
}

“Validation failed” response

{
    "code": 422,
    "message": "Validation failed",
    "errors": {
        "key": [
            "The key field is required."
        ]
    }
}

In all other cases the API will reply with the http status code 200. The following fields will be set:

Key Type Description
code number The http status code
message string The error message
error array Will be set if an error occurs during the processing of the current step (e.g. the session has expired). If the recoverable flag equals false a new session has to be started.
polling object Indicates if the transaction status needs to be polled (see Polling).
form array Contains the form elements (see Form Elements)

Response

{
    "code": 200,
    "message": "ok",
    "error": [],
    "polling": {},
    "form": {
        "name": "bank",
        "elements": [
            {
                "type": "select",
                "name": "country_id",
                "selected": "",
                "options": {
                    "DE": "Deutschland",
                },
                "validation": "",
                "invalid": false,
                "failed_validation_rules": "",
                "validation_error": ""
            },
            {
                "type": "text",
                "name": "bank_code",
                "value": "",
                "validation": "required",
                "invalid": false,
                "failed_validation_rules": "",
                "validation_error": ""
            }
        ]
    }
}

Form Elements

The following elements are possible within each step:

Captcha

Key Type Description
type string The type of the form element (here: captcha)
name string The name of the form element
data string The Base64 encoded image
value string The set value of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Checkbox

Key Type Description
type string The type of the form element (here: checkbox)
name string The name of the form element
checked boolean Indicates whether the checkbox is checked
label string The label of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Flicker

Key Type Description
type string The type of the form element (here: flicker)
name string The name of the form element
value string The set value of the form element
code array The actual flicker image as an array representation (0 = black bar, 1 = white bar)
label string The label of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Help Text

Key Type Description
type string The type of the form element (here: help_text)
title string The title of the form element
text string The text of the form element

Image

Key Type Description
type string The type of the form element (here: image)
data string The Base64 encoded image
label string The label of the form element

Multi

Key Type Description
type string The type of the form element (here: multi)
name string The name of the form element
selected string Name of the selected element (value of one of the nested elements)
elements array Array containing the nested elements

Multi elements

Key Type Description
label string The label of the element
value string The value of the form element
elements array Array containing the nested elements

Password

Key Type Description
type string The type of the form element (here: password)
name string The name of the form element
value string The set value of the form element
label string The label of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Radio

Key Type Description
type string The type of the form element (here: radio)
name string The name of the form element
checked string Index of the checked element
options array An array of possible options
label string The label of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Select

Key Type Description
type string The type of the form element (here: select)
name string The name of the form element
selected string Index of the selected element
options array An array of possible options
label string The label of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Tabs

Key Type Description
type string The type of the form element (here: tabs)
name string The name of the form element
tabs array An array of possible transports
label string The label of the form element
selected string The selected transport

Currently tabs will only be used within the login screen if the same bank code is used by different banks (e.g. Frankfurter Sparkasse and 1822direkt).

On the bank transport selection step the transport-ID (e.g.: tab=tra_abcdef3h8J7200aa) as well as the action (switch-login-tabs ) need to be provided in the request. Further parameters are not required.

Text

Key Type Description
type string The type of the form element (here: text)
name string The name of the form element
value string The set value of the form element
label string The label of the form element
validation string List of validation rules, concatenated with a pipe character
invalid boolean Indicates whether the validation of the element failed
failed_validation_rules string A list of failed validation rules (concatenated with a pipe character)
validation_error string The validation error (human readable)

Validation rules

Rule Description
alpha_num Only alpha-numeric characters are allowed
between:min,max The field must have a size between min and max
digits:value The field must be numeric and must have an exact length of value
in:value1,value2, The field must be included in the given list of values
min:value The field must have a minimum value
max:value The field must have a maximum value
required The field must be present and not empty
size:value The field must have a size matching the value

Polling

Example response

{
    "code": 200,
    "message": "ok",
    "error": [],
    "polling": {
        "interval": 1000
    },
    "form": {
        "name": "tan",
        "elements": [
            {
                "type": "help_text",
                "title": "",
                "text": "Bitte geben Sie den Auftrag in Ihrer Banking-App frei."
            }
        ]
    }
}
Key Type Description
interval integer The interval in milliseconds

The polling attribute indicates whether the transaction status needs to be polled. This is usually the case when your customer has to approve a payment via the bank’s mobile app.

If polling is an empty object no action is required. If interval is set you need to POST a request every interval milliseconds to the wizard API endpoint providing the wizard session key as well as the parameter action=poll until you receive the finish response.

Action

As mentioned above you can provide the action parameter within your request (e.g. for polling the transaction status). Here is a list of all possible action values as well as their description.

Action value Description
back Go back one step
switch-login-tabs Switch to another transport. Also the parameter tab with the value of the chosen transport ID needs to be present
poll Poll the transaction status
change-language Change the language. The actual language can be set with the language parameter (de, en and es are supported at the moment)

“Shared Credentials”

With the Shared Credentials feature you can receive and store the user’s encrypted login credentials in a secure way.

After having logged in successfully the user’s login credentials are encrypted using OpenSSL and the AES-256-CBC cipher. The resulting string is splitted in two parts. The first part will be added to the API’s response, the second part will be stored by us. Please be aware that the credentials will only be included in the response if

Example response

{
    "code": 200,
    "message": "ok",
    "error": [],
    "polling": {},
    "form": {
        "name": "finish",
        "elements": []
    },
    "additional_data": {
        "login_credentials": "crp_T09bO6ba2nSaIsYI|||eyJpdiI6Im...k1M1RXM2xU"
    }
}

Whenever your user should be logged in automatically in his bank account without typing in his login credentials, you just need to provide the received credentials part in your POST request for the login form.

    curl -X POST -u api:<your-api-key> \
        -d credentials=crp_T09bO6ba2nSaIsYI|||eyJpdiI6Im...k1M1RXM2xU
        https://api.xs2a.com/v1/wizard
POST /v1/wizard HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Type: application/json
Content-Length: 71

{
    "credentials": "crp_T09bO6ba2nSaIsYI|||eyJpdiI6Im...k1M1RXM2xU"
}

Please note that the Shared Credentials feature needs to be activated for your account.

Flow

Initializing the Session

A valid session and a wizard session key are required for the wizard API. Further information on how to create a session is available at XS2A.risk, XS2A.risk-checks as well as XS2A.pay and XS2A.verify.

Initial Request

The initial request requires the key parameter only.

Initial Request

curl -X POST -u api:<your-api-key> \
    -d key=<wizard-session-key>
    https://api.xs2a.com/v1/wizard
POST /v1/wizard HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 44

key=<wizard-session-key>

Response

{
    "code": 200,
    "message": "ok",
    "error": [],
    "polling": {},
    "form": {
        "name": "bank",
        "elements": [
            {
                "type": "select",
                "name": "country_id",
                "selected": "",
                "options": {
                    "DE": "Deutschland",
                },
                "validation": "",
                "invalid": false,
                "failed_validation_rules": "",
                "validation_error": ""
            },
            {
                "type": "text",
                "name": "bank_code",
                "value": "",
                "validation": "required",
                "invalid": false,
                "failed_validation_rules": "",
                "validation_error": ""
            }
        ]
    }
}

Further Steps

Any following requests need to contain at least all required parameters mentioned in the last response (e.g. on the bank selection page those parameters would be country_id and bank_code).

As soon as the wizard has been processed successfully, the last response contains a form element with the name finish. The elements array remains empty. There are no further requests needed and possible.

Finish Response

{
    "code": 200,
    "message": "ok",
    "error": [],
    "polling": {},
    "form": {
        "name": "finish",
        "elements": []
    }
}

Autocompletion

Autocomplete request

curl -X POST -u api:<your-api-key> \
    -d key=<wizard-session-key>
    -d action=complete-bankcodes
    -d bank_code=<user-input-here>
    -d country_id=DE
    https://api.xs2a.com/v1/wizard
POST /v1/wizard HTTP/1.1
Host: api.xs2a.com
Authorization: Basic ZzZIWTUyY2VvQ2lselNBYUNzTldoNjdMSG8=
Content-Length: 44

key=<wizard-session-key>
action=complete-bankcodes
bank_code=<user-input-here>
country_id=DE

Bankcodes can be autocompleted.

An autocomplete request needs to be authenticated with a valid wizard_session_id. With that context, we can only display banks, which are suitable for your current use case.

Autocomplete request

Key Type Description
key string current session identifier
action string Needs to be complete-bankcodes
bank_code string Current value of bank_codes input field to autocomplete
country_id string Identifier of current selected country

Autocomplete response

Autocomplete Response

{
    "code": 200,
    "message": "ok",
    "error": [],
    "polling": {},
    "form": {
        "name": "bank",
        "elements": []
    },
    "autocomplete": {
        "name": "bank_code",
        "data": [
            {
                "value": "88888888",
                "label": "88888888 [TESTDE88XXX] - Testbank (Teststadt)"
            }
        ]
    }
}

A resonse for autocompletion will contain up to 5 suggestions. The data to display will be returned as array in autocomplete.data.

Client Integration

XS2A offers the possibility of building entire product families based on our “access to the account” concept. It is possible to seamlessly integrate XS2A functionality into your own software or processes. To achieve this flexibility our API is composed of two major components:

Client side integration aims towards seamlessly embedding the wizard into your web pages. We offer two methods of integration:

  1. Direct integration using a Javascript library and a set of CSS themes. Both will be embedded directly into your web interface. The GUI elements are created with DOM-Operations an allow easy styling via CSS.
  2. The integration by Iframe using another Javascript library. The Iframe will be running on your site and styling is done through the Javascript library. This method of integration is very robust when it comes to layout changes on the XS2A side.

On the server side we offer a REST-API and webhooks for easy integration of your server components.

The following describes the basic steps for a transaction:

Javascript and CSS

Embed both JavaScript and CSS libraries

<script src="https://api.xs2a.com/xs2a.js"></script>
<link rel="stylesheet" href="https://api.xs2a.com/xs2a.css">

You will have to embed both of our JavaScript and CSS libraries into your website.

Both libraries can be embedded into the <head> section of your website. We suggest to hotlink both files directly from our XS2A server. This will ensure you will always use the latest build of both files.

The xs2a.js will register a new global JavaScript object xs2a. Use this global object to interact with XS2A forms. You will also have to include a container element into your website.

Container element

<div id="XS2A-Form" data-xs2a="<your-wizard-session-key-here>"></div>

The XS2A Wizard will be rendered within the container element. We strongly recommend to leave the id attribute XS2A-Form unchanged. Our CSS rules depend on it. Please see also CSS Styleguide.

If you do include our container element within a form-tag, pressing the enter key might accidentally submit data to your server. There is also the possibility that wrongfully entered login information will be prefilled by the browser.

Initializing JavaScript

xs2a.init();

Initialize our JavaScript by calling the init()-method. The javascript will then connect to our servers and start the XS2A-Wizard inside of the container element.

If you followed our instructions for including our JavaScript file the global xs2a object will be available after the <script> tag. The xs2a object implements the following methods:

xs2a.init()

xs2a.init()

initializes the XS2A object on the current page. It will look for an HTML element with a data-xs2a attribute, e.g.:

<div class="XS2A-Form" data-xs2a="<wizard-session-key>"></div>

The XS2A Wizard will be rendered in the described element. It is considered the “Wizard Element”.

xs2a.finish(function)

xs2a.finish()

Is used to register a callback function which will be called after the transaction has finished.

You must provide a xs2a-finish() callback, because after a finished transaction the customer needs to be redirect.

Redirect example

xs2a.finish(function() {
    window.location.href = 'http://<your-success-link>';
});

xs2a.abort(function)

xs2a.abort()

The callback will be executed in case the customer decides to abort the current transaction. We suggest to redirect the customer accordingly. The abort() callback must be provided.

Abort example

xs2a.abort(function() {
    // Will be executed in case the customer aborts the transaction
});

xs2a.error(function)

xs2a.error(function(errorCode, messages, recoverable))

The callback will be executed in case an error occurs during the transaction.

Error example

xs2a.error(function(errorCode, messages, recoverable) {
    // Will be executed in case an error occurs during transaction
});
Code Description
login_failed Login to bank failed (e.g. invalid login credentials)
session_timeout The customer’s session has timed out.
tan_failed User entered invalid TAN
tech_error An unknown or unspecified error occurred
testmode_error An error occurred using testmode settings
trans_not_possible A transaction is not possible for various reasons
validation_failed Validation error (e.g. entered letters instead of numbers)

recoverable indicates whether the error results in an abortion of the transaction. If recoverable equals false the transaction is aborted.

xs2a.bank(function)

xs2a.bank()

Allows you to register a function which will be executed before a bank selection page will be shown. For example, you can use this callback to provide some custom information on this page.

Blank example

xs2a.bank(function() {
    document.getElementById('your-text').style.display = 'block';
});

xs2a.login(function)

xs2a.login()

Callback can be registered which will be executed before the bank login page will be displayed. See also xs2a.bank(function).

xs2a.account(function)

xs2a.account()

Callback which will be executed before the bank account selection page will be displayed. See also xs2a.bank(function).

xs2a.tan(function)

xs2a.tan()

Callback can be registered which will be executed before the bank enter tan page will be displayed. See also xs2a.bank(function).

xs2a.render(function)

xs2a.render()

Callback can be registered which will be executed every time a new form is displayed. So basically it will be executed before every step. See also xs2a.bank(function).

xs2a.abortTransaction()

Abort transaction example

    <a href="#" id="abort">Abort transaction</a>
    <script>
        document.getElementById('abort').onclick = function() {
            xs2a.abortTransaction();
        };
    </script>

xs2a.abortTransaction() makes it possible to abort the current transaction manually.

If it fits your use case you may simply add an Abort-Link or Button to your Form and register an event listener, that calls xs2a.abortTransaction(). This can be done like that:

The callback that you registered in xs2a.abort() will also be executed within this call. There is no need to trigger it yourself.

xs2a.lang()

Set language example

<select id="lang">
    <option>de</option>
    <option>en</option>
</select>

<script>
$('#lang').change(function() {
    var language = $('#lang').val();
    // set the language for the xs2a wizard
    xs2a.lang(language);
    // set the language for your app
    document.location.href = "..."
});
</script>

xs2a.lang() allows to get or set the language during a transaction. If no parameter is passed xs2a.lang() simple returns the current language which may be de or en. If a parameter is passed, the form will be redisplayed with the new language set. The method will again return the language that was actually set.

Please note that setting the language is only allowed if the user is not yet logged in to his or her bank. If the user is already logged in the language will not be changeable.

Please also note that bank messages will not always be translated. For example banks, used via HBCI or banks that do not allow to switch the language will be served in German or in the default language provided by the bank.

xs2a.configure()

It is possible to set some configuration options, to alter the default behavior of the wizard.

This method needs to be called before init().

disable login credentials validation “`javascript xs2a.configure({ ‘validate-login-credentials’: false, 'autocomplete-suggestions’: 10 });

xs2a.init(); ”`

name default description
validate-login-credentials true A warning will be displayed, if the user enters a password which is 4 characters or less.
autocomplete-suggestions 5 Set the amont of autocomplete suggestions. (1-20)

CSS

We strongly suggest to include our base CSS directly from our servers:

<link rel="stylesheet" href="https://api.xs2a.com/xs2a.css">

The XS2A form embeds itself seamlessly into your website using DOM operations. This enables you to define your own custom CSS rules and customize the look and feel to fit your needs. You can even define your own themes. We would like to give you some basic guidelines for creating your own themes.

The CSS rules define the positioning of elements within the XS2A container. For other formatting needs you can use themes. You can also defined custom themes in combination with xs2a.css.

We currently offer the following themes:

<link rel="stylesheet" href="https://api.xs2a.com/xs2a-green-gray.css">
<link rel="stylesheet" href="https://api.xs2a.com/xs2a-dark-flat.css">
<link rel="stylesheet" href="https://api.xs2a.com/xs2a-light-blue.css">

Custom Themes

When creating your own themes, the easiest way is to use the base CSS xs2a.css theme as a basis for your own design.

If you create your own theme, we recommend to follow these guidelines:

Please keep in mind that we can not provide support for themes which do not use our base CSS as a basis or are not based on one of our standard themes.

Extending the xs2a forms

Extending the bank code entry form by appending an email text input

xs2a.extend('bank', function(form) {
    form.text('email', 'E-Mail', '', '', ['required', 'email'], form.APPEND);
    form.description('To proceed you need to enter a valid email address.', form.APPEND);
});

xs2a.init();

Extending the login form by appending a required checkbox

xs2a.extend('login', function(form) {
    form.paragraph('Custom title', 'Custom text', form.PREPEND);
    form.checkbox('my_policy', 'I accept this policy.', true, form.APPEND);
    form.description('To proceed you need accept this policy.', form.APPEND);
});

xs2a.init();

Extending both forms with a custom message

xs2a.extend('bank', function(form) {
    form.paragraph('Hallo', 'This is a custom message', form.PREPEND);
});

xs2a.extend('login', function(form) {
    form.paragraph('Hallo', 'This is a custom message', form.PREPEND);
});

xs2a.init();

The XS2A platform also offers the ability to extend its forms with your own custom fields. That might be useful if you want to ask for some additional information during the transaction. Additional information may be things like email addresses or asking the user to confirm additional checkboxes.

The two forms that can be extended are the bank code entry form and the login form. You may add custom form elements by appending or prepending them to the existing form. The custom form elements that you can add via the API are:

To extend the forms the global xs2a object provides the method xs2a.extend. This method receives a callback as its first argument. This callback is used to work with a FormBuilder that is passed to the callback. The xs2a.extend method should be called before xs2a.init.

The form builder passed to the callback has the following methods:

form.paragraph()

form.paragraph(title, text, where)

Adds a paragraph to the form.

Parameter Type Description
title string The title of the paragraph (optional).
text string The text of the paragraph (optional).
where string Where to put the paragraph. One of form.APPEND or form.PREPEND. (optional)

form.description()

form.description(text, where)

Adds a description text to the form.

Parameter Type Description
text string The text of the paragraph.
where string Where to put the paragraph. One of form.APPEND or form.PREPEND. (optional)

form.checkbox()

form.checkbox(name, label, required, where)

Adds a checkbox input to the form.

Parameter Type Description
name string The name of the checkbox input.
label string The label of the checkbox input.
required boolean True, if the user has to check this box.
where string Where to put the paragraph. One of form.APPEND or form.PREPEND. (optional)

form.text()

form.text(name, label, value, placeholder, validation, where)

Adds a text input to the form.

Parameter Type Description
name string The name of the input.
label string The label of the input.
value string Prefill this input. (optional)
placeholder string The placeholder text for this input. (optional)
validation array An array of validation rules. Allowed validation rules are required, email, numeric and alpha_num. (optional)
where string Where to put the paragraph. One of form.APPEND or form.PREPEND. (optional)

The values entered will be in the metadata attribute

{
    "id": "xv_hd84kg9zns53lvh1",
    "transaction": "10001-xv-abcd-abcd",
    "object": "xs2a_verification",
    "account_holder": "Account Holder",
    "iban": "DE62888888880012345678",
    "bic": "TESTDE88XXX",
    "bank_name": "Testbank",
    "country_id": "DE",
    "check_requested": true,
    "check_amount": "100.0",
    "check_currency_id": "EUR",
    "check_passed": true,
    "testmode": true,
    "metadata": {
        "email": "mail@customer.com",
        "my_policy": "on"
    },
    "merchant_id": "",
    "created_at": "2014-03-23 15:55:54"
}

You receive the values, that the XS2A platform collected for you in the metadata attribute of your transaction object, when you finally fetch it via the JSON API.

See the API description for the product you are using for more details on how to get the transaction object after a transaction is finished.

Links, modal dialogs and tooltips

You may also include links, modal dialogs and/or tooltips in the provided text.
To include a link use the following syntax:

Text with a link [<name>|link::<url>]

A modal dialog can be included with:

Text with a modal dialog [<name>|dialog::<text>]

You can include a tooltip using the following syntax:

Text with a tooltip [tooltip|<text>]

Iframe

Embed JavaScript library into your page

<script type="text/javascript" src="https://api.xs2a.com/xs2aframe.js">
</script>

Container element

<div id="XS2A-Form" data-xs2a="<wizard-session-key>"></div>

The JavaScript library can either be added to the <head> or the <body> region of you website. It is strongly recommended to hotlink this file so that you always use the latest available version.

The script registers the global object xs2aframe, that can be used to further interact with the wizard. You will also have to include a container element into your website.

xs2a.init();

Initialize our JavaScript by calling the init()-method. The javascript will then connect to our servers and start the XS2A-Wizard inside of the container element.

Example integration

<!DOCTYPE html>
<html>
    <head lang="en">
        <title>xs2a</title>
    </head>
    <body>
        <div id="xs2a-form" data-xs2a="KoA6ZwdTYeqSIvv6QpBf0VU9bWVnf8zmguNdGRpK">
        </div>

        <script src="https://api.xs2a.com/xs2aframe.js" type="text/javascript">
        </script>
        <script type="text/javascript">
            xs2aframe.init();
        </script>
    </body>
</html>

xs2aframe.init()

xs2aframe.init()

Initializes the xs2aframe-object and the iframe is inserted into the container element (e.g. the div-element).

xs2aframe.finish()

xs2aframe.finish()

Register a callback function that will be executed, once the transaction was executed successfully. This callback function must be provided, so that the user is properly redirected after the transaction is completed.

Redirect example

xs2aframe.finish(function() {
    window.location.href = "https://<success_url>";
});

xs2aframe.abort()

xs2aframe.abort()

Register a callback function that is executed when a transaction is canceled by the user, e.g. clicking the abort button. Just like the finish() callback this callback must be defined.

xs2aframe.render()

xs2aframe.render()

Callback which will be executed every time a new form is rendered inside the wizard.

xs2aframe.bank()

xs2aframe.bank()

Callback function that will be executed when the bank selection page is shown. Providers may implement this callback to display some information they might consider helpful for the user.

xs2aframe.login()

xs2aframe.login()

Callback function that will be executed when the login to the bank is displayed.

xs2aframe.account()

xs2aframe.account()

Callback which will be executed when the account selection is displayed to the user. Note that this step only occurs if the user has more than one account.

xs2aframe.tan()

xs2aframe.tan()

Callback which is executed when the TAN input page is displayed.

Customization

The xs2aframe object makes it possible to change the looks of the XS2A wizard according to your requirements.

The CSS ruleset that is loaded by default only defines the positioning of the elements in the wizard. By using one of the predefined themes you can manipulate the coloring of the forms or by using custom style rules using the styling API.

Themes

Changing default theme

xs2aframe.theme("xs2a-green-gray");

Currently there are three predefined themes, that you can build upon:

By calling the theme() method you can use one of the mentioned themes.

Customized Themes

To make individual customizations of the forms possible, you have the style method in place. Currently you can make customizations in the following groups:

Group description
global global settings (e.g. background or font colors)
textInput all <input> elements
buttonForward the button that lead to the next step
buttonBack the back button
buttonAbort the abort button
buttonDisabled a disabled button
warning a box with warning texts
info a box with an info text
error a box that contains an error message

You can set the following attributes:

Name Possible values
backgroundColor #ff0000, transparent, initial, inherit
color #ff0000, transparent, initial, inherit
margin 1px 5px, 0.5em, -5pt, 10%, auto, inherit
padding 1px 5px, 0.5em, -5pt, 10%, auto, inherit
border 5px dotted
borderRadius 2px 1px 4px / 0.5em 30%;
textAlign left, right, center, justify, initial, inherit
textDecoration none, underline, overline, line-through, initial, inherit
fontFamily “Times New Roman”, Times, serif; Arial, sans-serif;

Custom styling based on one of the themes:

xs2aframe.theme("xs2a-green-gray");
xs2aframe.style({
    global: {
        color: "#000",
        backgroundColor: "#cacaca"
    },
    buttonForward: {
        color: "fff",
        backgroundColor: "#00ff00",
        border: "1px solid #00ff44",
        borderRadius: "4px"
    },
    warning: {
        margin: 4px 2px 4px 2px,
        padding: 8px,
        backgroundColor: "ffa500"
    }
});

Events and Webhook

Example system call to your URL

{
    "id": "ev_kdhwWdkshflL237SdkDQ",
    "object": "xs2a_event",
    "type": "transaction.created",
    "testmode": true,
    "data": {
    },
    "created_at": "2014-03-23 14:00:03"
}

An event is basically anything that can happen with your XS2A account, e.g. creating a transaction, matching of a transaction and the like. Also includes things like changing your account password.

A webhook ist just a URL which will be called whenever an event has happened.

You can view events within our admin application or via API. Webhook URLs can be added, edited or deleted. You can enter up to three URLs. All URLs will be called via POST. Using HTTPs is required for all webhooks, yet the certificate may be a self signed one.

The field data will have event dependent information. Currently we support the following events:

Event Description
transaction.created A XS2A transaction has been created. Transaction data will be within the data.
transaction.updated Transactions might get an updated notification. The updated transaction data will be within the data.
account.password_changed Account password has been changed. The field data will be empty.

A connection error or a HTTP status code > 400 will be interpreted by the XS2A platform as a failed webhook. In this case the webhook will keep retrying to call your URL again (with an increasing time span between multiple tries).

The first five tries will be made within the first minute. All other tries will be within an increased time span. After a total of 40 tries the webhook will be killed.

Webhook Signature

Example signed weebhook call to your URL

POST /your-webhook-url HTTP/1.1
Host: yourserver.com
X-Payload-Signature: v1=6754b105f95c0cd9c544701451df7ffeebcb4ff7f17b64f75239502b27b1d8ab
Content-Type: application/json
Content-Length: 56

{
    "id": "ev_kdhwWdkshflL237SdkDQ",
    "object": "xs2a_event",
    "type": "transaction.created",
    "testmode": true,
    "data": {
    },
    "created_at": "2014-03-23 14:00:03"
}

Our webhooks are singed. Its recommended to check signature for validity.

The signature will be sent in HTTP-Header X-Payload-Signature.

You can find your shared secret on your webhook configuration page.

Versioning

To maintain a backward compatibility, we maintain a versioned signature in our HTTP-Header. The format for multiple versions is as followed: v1=hashv1; v2=hashv2

Checking Signatures for validity

To check a signature for validity you need to calculate and compare the hash for your corresponding version.

v1

In this version, you need to create a hash over the entire content of the webhook and create a Hash Message Authentication Code (HMAC) with the following settings:

Algorithm: SHA256

Payload: Entire payload (including whitespaces)

Secret: Shared secret. This can be found on your webhook configuration page.

Example

Message Secret Signature
Hello World! secret_password v1=faeffaa195ee7b044d20f034b5cf7ed1309c9e1f043836a65227d55be6452af2

Testbank

For testing and integration purposes we offer a Testbank. While using the Testbank, no real transactions will be made.

The Testbank allows you to try out various ways the Wizard and other components can or will behave.

Please use 88888888 as bank code or use BIC TESTDE88XXX for a German Testbank. Use 88888 as bank code or use BIC TESTAT88XXX for an Austrian Testbank.

Display of wizard tabs can be forced by using the bank code 88888889 in combination with a test API key.

In case the chosen product requires recipient information, entering almost any data is fine as long it conforms to the basic validation rules set by the chosen product.

You can use the following options with both banks as PIN in the login step to force certain behaviors:

PIN Description
accounts Displays the account selection step with more than one account available.
autosubmit Display a form that simulates waiting for authorization from an external source, e.g. customer uses a token device.
business Returns business accounts instead of private accounts by returning business accounts and turnovers.
config Allows you to configure some custom settings for testing various settings, e.g. turnover types, holder names etc.
forms Allows you to choose from some prepared forms with various UI elements of the Wizard.
next Displays a login next step
no-account A transaction without a valid account type.
no-standing-orders The chosen account has no standing orders.
no-turnovers No turnovers.
negative-balance A transaction with a negative account balance.
slow Slows down the transaction considerably.
with-chargeback Generates a turnover that indicates a chargeback.
with-credit-card Adds a credit card to the list of accounts
with-seizure Generates an account under seizure.
wrong Provokes a login error.
iban: Add a custom account, with an specific iban to the list of available accounts.

To simulate a wrong TAN attempt, please enter WRONG as TAN.

If you provide an account number or IBAN in the initial call, the customer will not be able to choose a different account, even if there are more accounts available to chose from. If the given IBAN is not in the customer list of accounts, the transaction will be aborted.

In case you want to test pinned account numbers or IBANs, the German Testbank will return the following accounts:

IBAN Account Number Bank Code Description Transaction possible
DE62888888880012345678 12345678 88888888 Girokonto Yes
DE04888888880087654321 87654321 88888888 Extra-Konto No

If you use the login PIN accounts the German Testbank will return additional accounts:

IBAN Account Number Bank Code Description Transaction possible
DE35888888880012345679 12345679 88888888 Girokonto Plus Yes
DE93888888880043218765 43218765 88888888 Kontokorrent Yes

In case you want to test pinned account numbers or IBANs, the Austrian Testbank will return the following accounts:

IBAN Account Number Bank Code Description Transaction possible
AT248888800012345678 12345678 88888 Girokonto Yes
AT638888800087654321 87654321 88888 Sparkonto No

If you use the login PIN accounts the Austrian Testbank will return additional accounts:

IBAN Account Number Bank Code Description Transaction possible
AT948888800012345679 12345679 88888 Girokonto Plus Yes
AT558888800043218765 43218765 88888 Kontokorrent Yes

Diagrams

This chapter shows a couple of sequence diagrams for common scenarios. The diagrams are quite detailed and designed to further your understanding of how the involved parties interact.

XS2A.pay with JS widget

This diagram shows a standard integration of the JS widget for a payment initiation service.

Open in new Window

XS2A.risk with wizard API

This diagram shows a standard integration of the XS2A.risk API using the wizard API.

Open in new Window

XS2A.risk with JS widget

This diagram shows a standard integration of the XS2A.risk API using the Javascript widget.

Open in new Window