---
language: "en"
---
# Verification of Payee Public Documentation

## Welcome to finAPI's Verification of Payee - Security made simple

---
language: "en"
---
# FAQs

## **FAQs on Verification of Payee and Instant Payment Regulation**

1. **What is "Verification of Payee"(VoP)?**

Verification of Payee arose as a requirement from the [++EU regulation on Instant Payments (IPR)++](https://www.google.com/search?q=EU+Instant+Payments+Regulation+%28IPR%29&rlz=1C1YTUH_deES1066ES1066&oq=VOP+applies+to+all+Sepa&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigATIHCAMQIRigAdIBCDQ2NzJqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8&mstk=AUtExfDdg7TihXwpk7ZhkF6N7Rsz1r1ezY2-TI0Q4svL-SFHpPSsC-SQmwAJpWN5su5xvMBVqXqh1cHS5icwDs_Fm2wDgBEEiLG4eHYdO60hVyeLtDWRdhp7HizdvoyFy48iGHAuTDjniVKQ5UoJ0mAjYzgOUJeZ9aLeVTaapTQ9uH5OOMY&csui=3&ved=2ahUKEwjRgvWEh-KPAxXIVaQEHXl5MH0QgK4QegQIBRAG). The IPR mandates payee verification prior to executing any payments from payment accounts, aimed at enhancing fraud prevention and increasing trust in real-time transfers. It is, however, applicable to all SEPA payments, not just instant payments.

2. **Does Verification of Payee only apply to instant payments?**

No, the Verification of Payee (VoP) requirements apply to all SEPA credit transfers, not just instant payments.

3. **What does Verification of Payee mean for Open Banking payments?**

The IP Regulation mandates that verification of payee must take place regardless of the payment initiation channel used by the consumer. This means that Open Banking payments must comply with the verification of payee requirements.

4. **Who is responsible for performing the Verification of Payee?**

Verifying the validity of the payee data and presenting it to the consumer is primarily the responsibility of the payer's PSP (Payment Service Provider, i.e, Bank).

For Open Banking payments, the initiating PISP (Payment Initiation Service Provider) will be responsible for performing a VoP and informing the consumer of its result, according to the [++EU Commission clarification in their Q\&A on the interpretation of IPR++](https://finance.ec.europa.eu/document/download/f597b1a5-2a7b-481d-882c-80fb1c5cc3d5_en?filename=instant-payments-implementation-questions-answers_en.pdf).

4. **What is the deadline for these regulatory changes to take effect?**

   The Regulation takes effect on October 9th, after which Verification of Payees (VoP) becomes mandatory, meaning payees must be verified for each transaction.

## I'm an unlicensed customer using finAPI's webform.

5. **What changes in the finAPI products in response to the Verification of Payee requirements?**

finAPI will introduce a new flag called `verifyPayees`, which can be set for each transaction individually, when creating a payment with the create a money transfer endpoint.

The `verifyPayees` flag will be available on Sandbox and on Production with the release on October 1st, 2025. Initially, the flag will be set to false as a default, and can be set to true for testing.

6. **What is the verifyPayees flag, and why is it important?**

   It is a new boolean parameter that can be set to true or false for each individual transaction. This indicates to finAPI whether the payee's identity should be verified. It helps you manage compliance and risk.

7. **When will the verifyPayees flag be available, and how does it work initially?**

   It will be introduced on October 1st, 2025, with the system release. By default, it will be set to false, but you can change it to true for testing purposes. Starting on October 9th, 2025, the default will change to true for all transactions, unless the opt-out is invoked.

8. **Will banks be ready to meet the regulation deadlines?**

   Most banks are not expected to go live before October 9th, 2025, so valid verification of payee responses from PSPs is unlikely before this date.

9. **What happens if I do nothing?**

   If you do nothing, VoP will automatically be performed for all transactions starting October 9th, and you will be compliant with the new regulation without taking additional action.

10. **Who is allowed to opt-out of VoP?**

    Only businesses or companies can opt out. Consumers are not allowed to opt out.

11. **How can I opt out if I am eligible?**

    You need to sign a contract amendment with finAPI. If you have not already received the amendment, you may contact [++support@finapi.io++](mailto:support@finapi.io) to request it. Once signed, the API will accept the `verifyPayees `flag to be set to false.

12. **Can I opt out for individual payments?**

    BaFin accepts bulk payments even if they contain only a single payment to be eligible for an opt-out.

13. **What results can I expect, and what do they mean?**

    ![image-20251001-110341.png](/__attachments/a_f0d70a2152c83bfed4e722e8953ab199f9844096d580e6f7d31d9d9318cb270d/image-20251001-110341.png?cb=717117d842c2725f98d282b30de324f7)

    * **Error:** The payee's bank does not (yet) support VoP checks. The user can still proceed, but must acknowledge the risk before continuing.

      ![image-20251002-094337.png](/__attachments/a_6022d2ecd9c30fc1572aa453bfb6772b2d8a81148bb1656c45a47161d628b8d6/image-20251002-094337.png?cb=0d9d8ecbfed7c515b831fe463510db37)

    * **Mismatch:** The name given by the payer does not match the name of the payee. The user can still proceed, but must acknowledge the risk before continuing. Hovering or touching (on mobile devices) the red icon shows more details.

      ![image-20251001-111530.png](/__attachments/a_b37d6e9b4c2b114bff7bc41be54a6372d19ff249af5a2dacb3835ee244a02a7d/image-20251001-111530.png?cb=a186d613490cf35e63c23dee9d09382e)
    * **Close match:** The name given by the payer does not fully match the name of the payee. The user will see an information icon; hovering or touching (on mobile devices) the icon shows details about the correct recipient. The user can either proceed and acknowledge the risk or cancel the payment and reinitiate with corrected payee details.

      ![image-20251001-111727.png](/__attachments/a_04b87165c8c53b766cf628736f1cd5ee9bf2552cbf9664b1d9e5124ca0ba4527/image-20251001-111727.png?cb=15e1a06cab257eda25fb9dcbaab37376)
    * **Full match:** The name given by the payer matches the name of the payee. The user can proceed with the payment as usual.

      ![image-20251001-111850.png](/__attachments/a_bb3c0085e95daa69ac92effcf6d0282db0b20e6fe1db52d3211f611d4e249f09/image-20251001-111850.png?cb=89c1c17ef7afdcb58f120a0495b5093c)
14. **Will payments still be possible, even if the result was a close match, no match, or an error?**

    The user will be informed that verification was not successful or not possible, but they can still proceed, acknowledging the risks involved.

    ![image-20250930-161435.png](/__attachments/a_b2e578b0575be87ad7f97de04d09cc6f4e88ebcc9e9daff6d81bdf416f6f1006/6d67ea26-50b1-46a2-adcb-87507d4e28de%23media-blob-url=true&id=bd135466-cb13-44ff-bbdd-9be91a182169&contextId=84919&collection=?cb=c33b6d00b31af801a6b07307e599ca7e)
15. **Can I change the recipient's details after creating a payment?**

    No, once a payment is created, it cannot be altered. To change the recipient's name or details, cancel the existing payment and create a new one.

## I'm a licensed customer with my own QWAC

16. **What if I am a licensed customer, not relying on finAPI's Webform/license?**

    If you are operating under a PSD2 license and possess your own QWAC certificate, you are liable for complying with the Verification of Payee requirements.

If you do not have a mechanism in place, finAPI offers a fully compliant solution, relying on the EPC VoP Scheme. #provide link to EPC. More details on it here <https://documentation.finapi.io/vopservice>

Alternatively, a licensed customer may still choose to rely on finAPI's license and webform and automatically become VoP compliant.

## I'm a finAPI end user

17. **Will I see the VoP feedback for every payment?**

    Every payment initiated by a consumer (not on behalf of a business) is, in principle, subject to the VoP check. There are cases where this check is not mandatory, and the payment will go through without displaying a VoP result.

For example, when the payment is in fact "payee-initiated" (by a merchant) or when the business executing the payment has decided to opt out of VoP. If you are a business user and in your application, there is no way of opting out of VoP, you may contact the relevant support team.

18. **What does it mean if the recipient match result is full, close, or no match?**

    ![image-20251001-110341.png](/__attachments/a_f0d70a2152c83bfed4e722e8953ab199f9844096d580e6f7d31d9d9318cb270d/image-20251001-110341.png?cb=717117d842c2725f98d282b30de324f7)

    * **Error:** The bank of the payment recipient does not (yet) support VoP checks. You can still proceed, but must acknowledge the risk before continuing.

      ![image-20251002-094315.png](/__attachments/a_704e6fe3bab2594dd91f92f005c25f266e4e85bd50697cd29fd8a2440ea6dac5/image-20251002-094315.png?cb=0d9d8ecbfed7c515b831fe463510db37)

    * **Mismatch:** The name of the payment recipient provided by you does not match the name of the actual account holder belonging to the provided IBAN. You can still proceed, but must acknowledge the risk before continuing. Hovering over or touching (on mobile devices) the red icon shows more details.

      ![image-20251001-111530.png](/__attachments/a_b37d6e9b4c2b114bff7bc41be54a6372d19ff249af5a2dacb3835ee244a02a7d/image-20251001-111530.png?cb=a186d613490cf35e63c23dee9d09382e)
    * **Close match:** The name of the payment recipient provided by you does not fully match the name of the actual account holder belonging to the provided IBAN. You can hover over or touch (on mobile devices) the icon to see details about the correct recipient.

      You can either proceed and acknowledge the risk or cancel the payment and reinitiate with corrected recipient details.

      ![image-20251001-111727.png](/__attachments/a_04b87165c8c53b766cf628736f1cd5ee9bf2552cbf9664b1d9e5124ca0ba4527/image-20251001-111727.png?cb=15e1a06cab257eda25fb9dcbaab37376)
    * **Full match:** The name of the payment recipient provided by you fully matches the name of the actual account holder belonging to the provided IBAN. You can proceed with the payment as usual.

      ![image-20251001-111850.png](/__attachments/a_bb3c0085e95daa69ac92effcf6d0282db0b20e6fe1db52d3211f611d4e249f09/image-20251001-111850.png?cb=89c1c17ef7afdcb58f120a0495b5093c)
19. **Is a payment still possible, even if the result was no match or an error?**

    You will be informed that verification was not successful or not possible, but you can still proceed, acknowledging the risks involved.

20. **Can I change the recipient's details after creating a payment?**

    No, once a payment is created, it cannot be altered. To change the recipient's name or details, cancel the existing payment and create a new one.

---
language: "en"
---
# Functionality

## Flow of the Verification of Payee

1. The PSU (Payment Service User) initiates a payment.

2. The customer application calls the finAPI VoP API.

3. finAPI forwards the request to the EPC VoP Scheme.

4. The receiving bank validates the provided name against the IBAN.

5. The result is returned to the customer application via finAPI.

![VOP_Overview_Flow_Diagram.drawio.png](https://documentation.finapi.io/__attachments/a_64ce2648354121bc1cbbf7881d0df45fc7eadde46e149bb6637d2a6ecf2a48b2/VOP_Overview_Flow_Diagram.drawio.png?cb=b95fbafc7025a5c1b91a3d29e1fafb13)

## Possible Results

* Match (`MTCH`): The provided name exactly matches the account holder's name at the receiving bank.

* No Match (`NMTC`): The provided name does not match the account holder's name at the receiving bank.

* Close Match (`CMTC`): The provided name slightly differs from the account holder's name; the actual account holder name is returned in the response.

* Verification Not Possible (`NOAP`): The verification could not be performed (e.g., receiving bank not reachable or not part of the scheme).

Note: Regardless of the result, the PSU must always have the option to proceed with or cancel the payment.

---
language: "en"
---
# Getting Started

## Requirements for using finAPI VoP

To use the finAPI VoP Service, the following requirements must be met:

* A QWAC certificate and BIC for registration with the EPC VoP Scheme

* Provision of the private part of the QWAC certificate to finAPI in order to perform the verification

finAPI recommends using a dedicated QWAC certificate. While this is not technically mandatory, it increases security and simplifies administration.

## Fees

Participation in the EPC VoP Scheme involves recurring fees, which must be paid directly to the EPC.

## Support from finAPI

If required, finAPI can handle the EPC VoP Scheme registration as part of the paid VoP Registration Service.

Please note: The EPC Scheme participation fee is not included and must still be paid by the customer directly.

---
language: "en"
---
# Technical integration

## **About the Service**

VOP is an interface that allows your application to communicate with payment and account services of various banks under PSD2 regulations.

This documentation is about a so-called Sandbox service that provides the possibility to test the access to bank data via the VOP interface using test data.

The OpenAPI Definition with examples and additional hints is available under <https://docs.finapi.io/?product=vop>

## **How to Register**

For VOP Sandbox, no client registration is required.

## **VOP API Access**

In order to access VOP API, several prerequisites must be met first, which are provided and authorised by third parties.

1. You must be registered as a PSP at NCA of your country (Bafin in Germany, FMA in Austria)

2. You must obtain a valid PSD2-compliant client certificate to authenticate your application to the VOP API (see for example here <https://www.bundesdruckerei.de/en/Service-Support/Service/Certificates-PSD2> on how to obtain a valid certificate)

## VOP Bulk Processing

VOP offers various options for bulk payments.

Smaller bulk payments can be processed directly, as with single payments.

Larger bulk payments can use asynchronous mode.

### Asynchonous Bulk Processing

In asynchronous mode, transactions are processed in the background and the calling client does not have to wait actively, which can lead to timeouts.

To activate this, set the header `TPP-Asynchronous-Process-Preferred` to `true` at the endpoint `POST /api/v1/vop/bulk-payee-verifications`.

The result is a `vopBulkId`, which allows you to retrieve the status of the bulk processing. If this is not `pending` or `received`, the results can be retrieved.

The flow of asynchronous processing is as follows:  
![VOP_Async_ProcessFlow.drawio.png](https://documentation.finapi.io/__attachments/a_1d27bb6d7fb8fdfaccf026b1cd4fae86e1c60d207308b6e4bbf3b3f4d571b44e/VOP_Async_ProcessFlow.drawio.png?cb=3e5013c358b06a6515ac3ac5e3e38755)

---
language: "en"
---
# Verification of Payee

## Overview

The finAPI VoP service enables the verification of payees required by the Instant Payments Regulation (IPR) via the EPC VoP Scheme.

This allows financial institutions and regulated third-party providers (TPPs) to ensure that payments within the SEPA area are executed to the correct recipient account.

## Who can benefit from VoP?

This documentation is intended for:

* Financial institutions and TPPs that want to integrate VoP into their services

If you would like to learn more about our **Verification of Payee Service** , please visit our [website](https://www.finapi.io/produkte/vop-service/)or reach out to us at [**support@finapi.io**](mailto:support@finapi.io).

---
language: "en"
---
# finAPI Web Form 2.0 Public Documentation Home

The purpose of "**Web Form 2.0 Public Documentation** " is to provide a better understanding of what services the Web Form 2.0 will provide. Customer-side developers could use this along with the [openAPI documentation](https://docs.finapi.io/?product=web_form_2.0) to ensure the quickest integration with finAPI.

## Welcome!

With finAPI's Web Form 2.0 REST Services, we aim to provide the best possible version of the Web Form which customers can present to end-users to implement their use case.

## When to use the Web Form?

As a customer of finAPI services, regulatory requirements of the European PSD2 regulation (ZAG law in Germany) may apply to you (please consult your lawyer or national Regulator for Financial Services for advice).

If you do not have the permission/license of your national Financial Services Regulator to provide PSD2-relevant services, according to the German Regulator you must fulfill the minimum requirements to not process bank credentials or access banks directly. **To allow finAPI customers without a Regulator PSD2 license to fulfill this minimum requirement, we have created the finAPI PSD2 Web Form.**Please note, that additional regulatory requirements may apply to your business and that finAPI cannot provide legal advice. Here is an overview of the different regulatory permissions and their implications on the usage of the finAPI Web Form:  

|   **Customer's Regulatory permission**   |                                                                    **Web Form required for**                                                                     |
|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| No regulatory permission                 | * import/update bank connection * edit bank connection (editing end-user bank credentials) * execute SEPA Money Transfer (SCT) * execute SEPA Direct Debit (SDD) |
| Payments (PIS/ZAD)                       | * import/update bank connection (batch updates) * edit bank connection (editing end-user bank credentials)                                                       |
| Account Information (AIS/KID)            | * execute SEPA Money Transfer (SCT) * execute SEPA Instant Money Transfer (SCT-Inst) * execute SEPA Direct Debit (SDD)                                           |
| Fully regulated (both AIS/KID + PIS/ZAD) | * optional (no Web Form required for any finAPI service)                                                                                                         |

Do you hold a PSD2 license but still want to use finAPI's Web Form? It is possible and we recommend it. It will help you minimize your integration effort considerably. We can set you up to use your own certificate with our Web Form. Please contact our support at [support@finapi.io](mailto:support@finapi.io) in case you need more details.

---
language: "en"
---
# About Web Form 2.0

finAPI offers clients the Web Form for a while now. However, we have now bettered our offering, called Web Form**2.0**. This documentation points to and explains how to take advantage of the improved version of the Web Form. Here is why Web Form 2.0 is better for customers:

* **Simpler Integration**:

  * Compared to the current customer integration process, with Web Form 2.0 customers have fewer API calls to integrate with.

    * Bank Search is now integrated within the Web Form workflows. This means, as a customer, you do not need to figure out the bank with the "[get a bank](https://docs.finapi.io/?product=access#get-/api/v1/banks)" end-point. End-users will get a chance to choose their bank on the Web Form, and the Web Form backend will pick the correct bank and continue with the workflow.

  * Unlike before, customers don't need to understand what "interface" means OR build any logic around it. Customers can focus on their business case while we focus on ours!

  * What is Multi-step Authentication(MSA) you ask? Yes, we would be happy to give you an overview of MSA but unlike in the past, you don't have to worry about integrating with various MSA procedures. Web Form 2.0 will take care of this.

* **UX driven**:

  * We have gone back to the drawing board to bring to customers and their users the best UX possible.

* **White labeling capabilities**:

  * We bring to customers the possibility to white label our solution in an automated way. Use your logo, colors, and font styles to enhance user experience

* Web Form 2.0 is compatible with most standard browsers and their latest versions!

* Web Form 2.0 is also embeddable in customers' web applications and/or mobile applications!

* finAPI manages the display of the PSD2 Web Form. You could use both the existing Web Form and Web Form 2.0 for different business workflows. Please contact our support team at [support@finapi.io](mailto:support@finapi.io), and we will gladly set it up for you.

In case you are looking for the older Web Form implementation, [here](https://finapi.zendesk.com/hc/en-us/articles/360002596391)is the link to more details about it. Reach out to our support team([support@finapi.io](mailto:support@finapi.io)) in case of questions.

---
language: "en"
---
# Embedded Web Form 2.0

## Prerequisites

### CORS configuration

Since the embedded Web Form works as a part of your web page, but still has to communicate with `*.finapi.io` domains, all modern web browsers will apply Cross-Origin Resource Sharing (CORS) policies to all requests triggered by the Web Form scripts. finAPI Web Form 2.0 backend takes care of it and makes sure to only process requests from domains you allow. By default, no domains are allowed for customers, and they must be explicitly configured.  
If you try to use the embedded Web Form, but it apparently fails, and you see "CORS error" in the Network tab of DevTools in the browser, it means CORS configuration is missing for your mandator.

To eliminate this issue, you need to provide us with all domains where you are going to use the embedded Web Form. For that, please raise a request to our support team, and they will take care of the rest.

Please note that due to security requirements, it is not allowed to use any local domains (e.g. `localhost` or `127.0.0.1`) in the CORS configuration. If you want to test your application running on a local machine, consider using public services that can route your local traffic to a domain available on the Internet.

## Web Form Loader

Web Form is bundled as a Web Component.

*Web Components is a suite of different technologies allowing you to create reusable custom elements --- with their functionality encapsulated away from the rest of your code --- and utilize them in your web apps. (* [*source*](https://developer.mozilla.org/en-US/docs/Web/Web_Components)*)*

This means you can attach a Web Form as a custom DOM element to your web page. Web Form is rendered under Shadow root which prevents conflicts with your host application (e.g. CSS styling issues). To make things even easier, we provide you with a Web Form Loader.

Web Form Loader is a small JavaScript library that takes care of loading and unloading Web Form to and from your page.  
Type definitions as well as all options supported by the Web Form Loader can always be found here: <https://webform-dist.finapi.io/latest/docs/modules.html>

### Usage

#### Usage via script

To use Web Form in simple HTML code, one could do it like this:
HTML

    <div id="webFormContainer"></div>
    <script src="https://webform-dist.finapi.io/latest/dist/web-form.min.js"></script>

    <script>
        const createWebForm = async function () {
            // Replace the following line with a real HTTP request to one of the services that create a web form
            // ("Import a bank connection", "Update a bank connection", and others). 
            // Use the `id` field's value of the created web form as the value for the `token` then.
            const token = await Promise.resolve("<token>");
            FinApiWebForm.load(
                document.querySelector("#webFormContainer"),
                { 
                  token: token,
                  // these are examples of how optional properties can be set:
                  targetUrl: "https://webform-live.finapi.io",
                  layoutConfig: "xs",
                  backToAppUrl: "https://customer.app",
                  customerSupportUrl: "https://finapi.io",
                  language: "de"
                },
                {
                  onLoaded: function() {
                    // handle "onLoaded" event
                  },
                  onComplete: function() {
                    // handle "onComplete" event
                  },
                  onFail: function() {
                    // handle "onFail" event
                  },
                  onAbort: function() {
                    // handle "onAbort" event
                  },
                  onLoadError: function() {
                    // handle "onLoadError" event
                  }
                }
            );
        };

        document.addEventListener("DOMContentLoaded", function() {
           createWebForm();
        });
    </script>

Before you can load a web form, you will need to first obtain a valid token - more info in [Web Form Basics](https://documentation.finapi.io/webform/web-form-2-0-basics.md#How-it-all-starts). For each next load, a new token should be provided.

`web-form.min.js` contains an IIFE - immediately invoked function expression, which will create a globally-scoped variable `FinApiWebForm`. This variable name is therefore reserved.

It is possible to "freeze" the version by replacing the latest tag with the desired version: <https://webform-dist.finapi.io/2.6.0/dist/web-form.min.js>

A list of all the available versions can be found in the [NPM version history](https://www.npmjs.com/package/@finapi/web-form?activeTab=versions).

#### Usage as a module

Web Form Loader can also be installed as an NPM package:
Bash

    npm install @finapi/web-form

This package exports functions `load()` and `unload()`. It also provides TypeScript type declarations.

An example of usage in React framework could look like this:
TypeScript

    import React, { useCallback } from "react";
    import { load } from "@finapi/web-form";

    function App() {
      return <FinApiWebForm />;
    }

    function FinApiWebForm() {
      const createWebForm = useCallback(async (target: HTMLElement) => {
        // Replace the following line with a real HTTP request to one of the services that create a web form
        // ("Import a bank connection", "Update a bank connection", and others). 
        // Use the `id` field's value of the created web form as the value for the `token` then.
        const token = await Promise.resolve("<token>");
        load(
          target,
          { 
            token: token,
            // these are examples of how optional properties can be set:
            targetUrl: "https://webform-live.finapi.io",
            layoutConfig: "xs",
            backToAppUrl: "https://customer.app",
            customerSupportUrl: "https://finapi.io",
            language: "de"
          },
          {
            onLoaded: function() {
              // handle "onLoaded" event
            },
            onComplete: function() {
              // handle "onComplete" event
            },
            onFail: function() {
              // handle "onFail" event
            },
            onAbort: function() {
              // handle "onAbort" event
            },
            onLoadError: function() {
              // handle "onLoadError" event
            }
          }
        );
      }, []);

      const containerRef = (container: HTMLDivElement) => {
        if (container) {
          createWebForm(container);
        }
      };

      return <div ref={containerRef}></div>;
    }

    export default App;

Web Form Loader module requires minimum ES5 support.

##### Versions and tags

A list of all the available versions can be found in the [NPM version history](https://www.npmjs.com/package/@finapi/web-form?activeTab=versions).

* `latest` - stable release version that is tested and synced with the live production environment.

* `alpha` - an unstable pre-release version that might be out of sync with the live production environment.

### Configuring the Web Form Loader

#### Docs

Web Form Loader typedoc can be found here: <https://webform-dist.finapi.io/latest/docs/modules.html>.

#### Working with custom environments

The loader works by default with the [Live environment](https://documentation.finapi.io/webform/web-form-2-0-environments.md#Live) (`https://webform-live.finapi.io`), but it might happen that you have a custom environment working on another subdomain, e.g. `https://custom-webform.finapi.io`. In such cases, please use the [targetUrl](https://webform-dist.finapi.io/latest/docs/interfaces/webformprops.html#targeturl) parameter provided by the loader in order to overwrite the default behavior. You can always clarify with our Customer Support team if it applies to your setup.

#### Adjusting the layout of the web form

By default, the embedded web form will choose its layout config based on the current viewport size. Due to technical limitations, only the size of the "main" viewport is taken into consideration and the size of the actual web form component is ignored. That sometimes might lead to an undesired "look and feel" of the web page. In such cases, the default layout config can be overridden via the Loader property `layoutConfig`, where you can either use one of the predefined values (`xs`, `sm`, `md,` and `lg`) or provide your custom breakpoints. For the type definition of the property, check the [typedoc](https://webform-dist.finapi.io/latest/docs/modules.html#layoutconfig).

#### Frontend callbacks

When embedding a web form in either way described above, callback functions can be passed directly to the web form loader during the initialization phase. These functions, if provided, will be triggered when the corresponding event occurs, e.g., when the web form is completed. In that way, you can either avoid using our "server" callbacks (listed in [this section](https://documentation.finapi.io/webform/for-best-results#Forbestresults!-Enhanceyourexperience!)) or combine both approaches in order to provide the best user experience.

Find the full list of supported callbacks, as well as more details about how they function in the [typedoc](https://webform-dist.finapi.io/latest/docs/interfaces/webformhandlers.html).

## Demo

We have prepared mini-DEMO(s) on how standalone and embeddable Web Forms could look. Please feel free to take a look.  
<https://www.youtube.com/watch?v=U80Ol0eNkkA>

**00:00** General Introduction

**01:45** Explanation of how standalone Web Form works

**05:14** Demo

**12:05** Explanation on how to embed the Web Form into a customer web page

**15:00** Demo

**19:42** Explanation on how to integrate the Web Form into an Android app

**21:51** Demo

---
language: "en"
---
# Example workflows

Are you a new customer and would like some help with understanding how to integrate? Here are some example use cases! Please note you might need to integrate with endpoints from 2 products (and hence 2 openAPI locations) in order to execute your use case. Hence, for each step, we clearly point out the product where you can find the endpoint.  
Assumptions:

1. You are new to finAPI and currently reached as far as having client ID and client secret.

2. You have also requested our Customer Success Management Team to set up Web Form 2.0 on your mandator ID!

## I want to allow end-users to make payments without having to import their accounts

We have detailed the steps [here](https://documentation.finapi.io/payments/initiate-a-standalone-payment-with-web-form-recomm.md). Feel free to look around the documentation, it describes various possible payment workflows.

## I want to set up a Dashboard for payments

We have detailed the steps [here](https://documentation.finapi.io/payments/how-to-build-payments-dashboard-with-web-form-2-0.md). Feel free to contact our Customer Success Team ([support@finapi.io](mailto:support@finapi.io)) in case you have further questions.

---
language: "en"
---
# For best results

## Enhance your experience!

All "Payment Initiation Services" and "Account Information Services" endpoints provide server-side callback parameters to enhance your integration and avoid polling.

The callbacks are meant to only notify you that the flow was finalised on our side. As such, the callbacks contain only minimal information. Use the "Get a web form"/"Get a task" call to fetch additional information about the executed flow. The payload will contain:

* a `bankConnectionId`, `paymentId` or `standingOrderId` - if the Web Form is completed successfully. These ids can be used in Access to get more data on the bank connection or payment.

* (optionally) an `errorCode` - when the Web Form is completed with the status "`COMPLETED_WITH_ERROR`". Use the data in this field to determine how you would like to navigate the end-user within your application for the next steps.

In case you don't use callback URLs, you will need to poll the "Get a web form" and/or "Get a task" service at regular intervals to detect by yourself if the workflow has reached the end. We recommend polling the status every couple of seconds (at most, once a second)

### Payment Initiation Services (PIS)

To register for a callback for any of the PIS endpoints, you should pass the URL you want to receive the POST callback as value for the `callbacks.finalised` parameter. If a callback is registered, once a web form is finalised (successfully or not), a POST request will be sent with the body:
JSON

    {
      "webFormId": "31c508d8-51da-11eb-ae93-0242ac130002",
      "status": "COMPLETED"
    }

The possible values for the `status` are:

* **COMPLETED** -the web form has been successfully completed (final status);

* **COMPLETED_WITH_ERROR -**the web form has been completed with an error (final status);

* **EXPIRED** - the web form has expired (final status); This status means that either the `expiresAt`has passed, or the end-user closed the web form and we finalized the flow in the background;

* **ABORTED** - the web form has been cancelled by the end-user (final status).

### Account Information Services (AIS)

There are only 2 AIS endpoints: "Import a bank connection" and "Update a bank connection". The "Import a bank connection" endpoint has the same logic and behaviour as any of the PIS endpoints, providing the `callbacks.finalised` parameter.

#### Update a bank connection

For the "Update a bank connection" endpoint, we provide **2 callback** options, which are triggered based on the bank connection status, stored consent, and whether any end-user interaction is required to finalise the operation. The 2 callback parameters are `callbacks.finalised`, which has the same meaning as for "Import a bank connection" endpoint, and `callbacks.webFormRequired`, which is triggered when a bank connection update task requires end-user interaction and a web form is created to guide the end-user through said interaction.

Furthermore, in the case of "Update a bank connection", the callbacks POST request body is different:

    {
      "taskId": "31c508d8-51da-11eb-ae93-0242ac130002",
      "status": "COMPLETED",
      "webForm": {
        "id": "946db09e-5bfc-11eb-ae93-0242ac130002",
        "url": "https://webform.finapi.io/wf/946db09e-5bfc-11eb-ae93-0242ac130002",
        "status": "COMPLETED"
      }
    }

##### Web Form Required

In the case of `callbacks.webFormRequired`, the body will always contain `status: WEB_FORM_REQUIRED`, with the sub-object `webForm` providing the URL to which you need to redirect the user, and `status: NOT_YET_OPENED`.

    {
      "taskId": "31c508d8-51da-11eb-ae93-0242ac130002",
      "status": "WEB_FORM_REQUIRED",
      "webForm": {
        "id": "946db09e-5bfc-11eb-ae93-0242ac130002",
        "url": "https://webform.finapi.io/wf/946db09e-5bfc-11eb-ae93-0242ac130002",
        "status": "NOT_YET_OPENED"
      }
    }

##### Finalised

Will be called when the task can be finalised in the background, without any end-user interaction (status **COMPLETED** or **COMPLETED_WITH_ERROR**), or when the associated web form is finalised.

The task `status` can have the values:

* **COMPLETED**- the task has been successfully completed (final status);

* **COMPLETED_WITH_ERROR**- the task has been completed with an error (final status).

* **WEB_FORM_REQUIRED** - the task requires a web form to continue the flow with end-user involvement (final status). In this case, the web form details will also be included in the callback, and the `webForm.status` can have one of the values:

  * **COMPLETED** -the web form has been successfully completed (final status);

  * **COMPLETED_WITH_ERROR -**the web form has been completed with an error (final status);

  * **EXPIRED** - the web form has expired (final status); This status means that either the `expiresAt`has passed, or the end-user closed the web form and we finalized the flow in the background;

  * **ABORTED** - the web form has been cancelled by the end-user (final status).

### Enhance end-user experience!

You can forward the web form URL to the user as it is. Or, you can optionally append the following parameters that serve as client-side callbacks to redirect the user back to your application:

* `redirectUrl`, to which the Web Form will redirect the user after the Web Form flow is completed successfully. You can include encoded query parameters in the `redirectUrl` as well, they will be contained in the redirect. If you don't pass a `redirectUrl`, the Web Form page will try to close itself on completion (if the Web Form is unable to close by itself, the user will be shown a message that he can close the page manually and return to your application).

* `errorRedirectUrl`, same philosophy as `redirectUrl` except this URL will redirect the user when the Web Form runs into an unexpected error. Please remember! Users are NOT automatically redirected, unlike `redirectUrl`. This was done intentionally to give the user enough time to read the error message, decide and gather data they want to report, etc. Nevertheless, you can build a workflow for error conditions when the user comes back to this URL. If you don't pass an `errorRedirectUrl`, the Web Form will simply attempt to close the page.

* `abortRedirectUrl`, same philosophy as `redirectUrl` except this URL will redirect the user when the Web Form is aborted by the user.

* `customerSupportUrl`, to which the Web Form will display a link in case you want to offer the possibility for end-users to reach your customer support. We will display the URL in case the user cancels the workflow OR if there is an unexpected error. You can include encoded query parameters in the `customerSupportUrl` as well, they will be contained in the redirect. If you don't pass a `customerSupportUrl`, the user will be shown a message that he can close the page manually and return to your application.

* `colorMode`, allows you to define whether the Web Form should initially be displayed in light or dark mode. Supported values are `light` and `dark`.

* `language`, allows you to define the initial display language of the Web Form. Supported values are `cs`, `de`, `en`, `es`, `fr`, `it`, `nl`, `pl`, `ro`, `sk`, and `tr`.

If you intend to use this feature, we recommend keeping the total URL length under 2048 characters. Although there's no restriction on our side, longer URLs may cause issues with certain browsers or systems.

For the above example, the complete URL to open in your user's browser (with an added `redirectUrl` and `customerSupportUrl`) would be:
> [*https://live.finapi.io/webForm/nEvozFaPhCXw8ZnnRBb2KJGANW6y9RjZgQtX6YRAhB_Li7TzO19jTh0wtBg9AbvblAMnJFp7DS1C0zzj746U4B7GUj4LUIyt9ZR9Sn2UoLzg5SYaEx9Ps6ax_6ImXTOB*](https://live.finapi.io/webForm/nEvozFaPhCXw8ZnnRBb2KJGANW6y9RjZgQtX6YRAhB_Li7TzO19jTh0wtBg9AbvblAMnJFp7DS1C0zzj746U4B7GUj4LUIyt9ZR9Sn2UoLzg5SYaEx9Ps6ax_6ImXTOB)
>
>
***?redirectUrl*** *=https%3A%2F%* [*2Fyourapp.net*](http://2fyourapp.net/)*%2Fweb-form-redirect%3FredirectParam%3Dfoobar* ***\&customerSupportUrl=*** *https%3A%2F%* [*2Fyourapp.net*](http://2fyourapp.net/)*%2Fweb-form-redirect%3FsupportParam%3Dfoobar* ***\&colorMode*** *=dark* ***\&language*** *=de*  
Make sure you include the HTTP protocol in the URLs you append, otherwise the redirect to your domain will fail.

E.g.: `?redirectUrl=https://yourapp.net`

---
language: "en"
---
# Getting started (prerequisites)

The following section describes the technical steps to get started with the integration. It is an additional resource that completes our openAPI description of the REST API.

Web Form 2.0 services use [Access](https://docs.finapi.io/?product=access) in order to implement various workflows. The below steps are the prerequisites to use Web Form 2.0' REST services.

finAPI follows the OAuth 2.0 Standard for authorizing applications and users within them. OAuth uses the terminology of clients and users. A client represents an application that calls finAPI services. A service call might be in the context of a user of the client (e.g: getting a user's bank connections), or outside any user context (e.g.: editing your client's configuration, or creating a new user for your client). In any case, every service call must be authorized by an `access_token`. The documentation below describes how to set up client's users, or for the client itself.
![](https://documentation.finapi.io/__attachments/a_ef9351da82f8682b6a3443b0b9c9a58f209d2437ccb79a9a777d265bd21303e7/1615793336045-Web%20form.drawio.png?cb=73b42d97fee8db7659d588071b8438a6)

## Step 1: Get authorized as a client in Access

The major prerequisite for getting authorized as a client (i.e. application) is having a valid set of client credentials: `client_id` and `client_secret`.

To get authorized as a client, make a call to Access [**POST /oauth/token**](https://docs.finapi.io/#post-/oauth/token) and pass the following request parameters:

* `grant_type=client_credentials`

* `client_id`

* `client_secret`

The client authorization request response:
JSON

    {
      "access_token": "fnsXpguIBkChhCsN8bVty9Y68AsUvJYyXUILcsFBvWABF03k8Ov68Ev2BTyANuBjyX8r9XuuTajNM2zZnhZMDjKWHN4lbRSRcVhg9_PcE7eeXHm0t28ZjzM4TJlrupZD",
      "token_type": "bearer",
      "expires_in": 3599,
      "scope": "all"
    }

To get authorized **as a Client** , use the obtained `access_token` as input for ++Access QUICK AUTH++.

## Step 2: Create an Access user

The major prerequisite for creating a user is getting authorized as a client with the help of the obtained `access_token` in **Step 1**.

To create a user, make a call to Access [**POST /users**](https://docs.finapi.io/#post-/api/v1/users) and pass the following request body:
JSON

    {
      "id": "username",
      "password": "password",
      "email": "email@localhost.de",
      "phone": "+49 99 999999-999",
      "isAutoUpdateEnabled": false
    }

The user creation request response:
JSON

    {
      "id": "username",
      "password": "password",
      "email": "email@localhost.de",
      "phone": "+49 99 999999-999",
      "isAutoUpdateEnabled": false
    }

## Step 3: Get authorized as a user

The major prerequisite for creating a user is getting the user's data, such as `password` and id (`username`) from **Step 2**.

To get authorized as a user, make a call to Access [**POST /oauth/token**](https://docs.finapi.io/#post-/oauth/token) and pass the following request parameters:

* `grant_type=password`

* `client_id`

* `username`

* `password`

The user authorization request response:
JSON

    {
      "access_token": "nnsXpguIBkChhCsN8bVty9Y68AsUvJYyXUILcsFBvWABF03k8Ov68Ev2BTyANuBjyX8r9XuuTajNM2zZnhZMDjKWHN4lbRSRcVhg9_PcE7eeXHm0t28ZjzM4TJlrupZD",
      "token_type": "bearer",
      "expires_in": 3599,
      "scope": "all"
    }

To get authorized **as a User** , use the obtained `access_token` as an input for ++**Web Form QUICK AUTH**++

Once the above steps are completed, any of the workflows related to AIS(Account Information Services) or PIS (Payment Initiation Services) can be triggered successfully either standalone (on a browser) or as an embedded Web Form.

If you experience any problems during the integration or have any questions, please contact our support, [support@finapi.io](mailto:support@finapi.io) at any time. Our customer success team is looking forward to supporting you during your integration journey.

---
language: "en"
---
# Licensed customers using the Web Form

Web Form 2.0 supports customers who have their PSD2 license (and/or finTS registration number) So if you plan to use your license but with our Web Form, please make sure to go over the below checklist carefully.

## 1. Make sure to use our white labeling offering

Since it will be your PSD2 license that will be used during the communication with the bank, the Web Form will carry no references to finAPI. This means your end-users won't see the finAPI Logo in the header or footer of the Web Form. They might find the Web Form header "bare" and unusual without any logos on it. Hence, we strongly urge you to provide your logo via the "[Create a profile](https://docs.finapi.io/?product=web_form_2.0#post-/api/profiles)" endpoint. This will ensure the Web Form has a standard header (with a logo) on each view.

## 2. Upload your licensing documentation

Please see the page [Licensed customers](https://documentation.finapi.io/access/licensed-customers.md) for more details.

## 3. Make sure end-users don't run into hiccups with redirect banks

To avoid end-users running into errors with banks using the redirect approach, please make sure to provide the correct `redirectURL` parameter in the API calls which communicate with the banks (both for AIS and PIS). Which redirect URL, you ask? Kindly look up the URLs you provided while registering at the bank with your certificates OR the URLs which are on your QWAC/QSEAL certificates for the answer.

That redirect endpoint needs to be implemented on your side. And the only function of that endpoint is to redirect any incoming `GET` request to the `<web form host>/callback` endpoint on the Web Form 2.0 side (e.g. `https://webform-live.finapi.io/callback`). Make sure to preserve any given query string of the original request.

The following sequence diagram should provide you with more context.  
![image-20250722-141739.png](https://documentation.finapi.io/__attachments/a_ab1300148962f935e27b302989ae9030c72a81aafd6f3f6522ff788b33227ac9/image-20250722-141739.png?cb=d63bbc285e185dbe0daa4e4e66aeeb3d)

## 4. Make sure your end-users are well informed

As mentioned above, there will be no references to finAPI on the Web Form including finAPI's Terms \& Conditions, Data Protection Policies, Site Notice, or Logo. Hence, please make sure to inform your end-users about being navigated to your service provider(i.e. finAPI) before they land on our Web Form.

---
language: "en"
---
# Migration from Web Form V1

## Overview

Migrating from **Web Form V1** to **Web Form V2** is straightforward. The overall flow remains familiar, but **Web Form V2** introduces several enhancements not available in V1 --- including bank selection, automatic interface management, improved callback handling (see [For best results](https://documentation.finapi.io/webform/for-best-results.md)), and advanced customization options for branding and user experience (see [White labeling](https://documentation.finapi.io/webform/white-labeling.md)).

**Web Form V2** is an extension of the core **finAPI Access API**, using the same user authentication process. The request structures are very similar, with most parameters retaining their names, while response handling has been streamlined. A successfully created web form in V2 will return an HTTP 201 status code, including the web form URL in the response body --- replacing the V1 behavior, which used a custom HTTP 451 code with the URL provided in the response headers.

## Examples

### Example bank connection import

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  **Web form V1**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                                                                                                                      **Web Form V2**                                                                                                                                                                                                                                                                                                                                                                                                      |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Request URL:** `POST https://live.finapi.io/api/v1/bankConnections/import` **Request body** JSON { "bankId": 280001, "name": "Bank connection", "interface": "XS2A", "skipBalancesDownload": false, "skipPositionsDownload": false, "loadOwnerData": false, "maxDaysForDownload": 365, "accountTypes": [ "Checking", "Savings", "CreditCard", "Security", "Loan", "Membership", "Bausparen" ] } **Response headers** .. location: https://live.finapi.io/webForm/g1u4I_310CkZHEHp9ICI5SUeDJVGYWJD33MfWohdniZ0xzNGj1PefcVe7_33Eqal5zcEQHWVNv7Iz6rjpWL5ByouwArK2HVW_fRuoldE9eGS0RPaNIDhnbwBdIK5KnEB ... **Response body** JSON { "errors": [ { "message": "23894699", "code": "WEB_FORM_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": null } ], "date": "2025-05-13 13:30:32.512", "requestId": "selfgen-363b8655-63e2-4c95-97d0-d9ef84699802", "endpoint": "POST /api/v1/bankConnections/import", "authContext": "2063/1959409", "bank": "DEMO0001 - finAPI Test Bank (id: 280001, location: none)" } | **Request URL:** `POST https://webform-live.finapi.io/api/webForms/bankConnectionImport` **Request body** JSON { "bank": { "id": 280001 }, "bankConnectionName": "Bank connection", "allowedInterfaces": [ "XS2A", "FINTS_SERVER", "WEB_SCRAPER" ], "skipBalancesDownload": false, "skipPositionsDownload": false, "loadOwnerData": false, "maxDaysForDownload": 365, "accountTypes": [ "CHECKING", "SAVINGS", "CREDIT_CARD", "SECURITY", "MEMBERSHIP", "LOAN", "BAUSPAREN" ] } **Response headers** N/A **Response body** JSON { "id": "b03e606f-6ae5-4c96-9aad-c4c60a371065", "url": "https://webform-live.finapi.io/wf/b03e606f-6ae5-4c96-9aad-c4c60a371065", "createdAt": "2025-05-13T11:31:59.374+0000", "expiresAt": "2025-05-13T11:51:59.374+0000", "type": "BANK_CONNECTION_IMPORT", "status": "NOT_YET_OPENED" } |

### Example money transfer

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          **Web form V1**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 **Web Form V2**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| For web form V1, creating a money transfer is split into 2 calls: creation and submission **Creation Request URL:** `POST https://live.finapi.io/api/v1/payments/moneyTransfers` **Creation Request body** JSON { "iban": "DE77533700080111111100", "executionDate": "2026-01-01", "moneyTransfers": [ { "counterpartName": "Max Mustermann", "counterpartIban": "DE13700800000061110500", "counterpartBic": "DRESDEFF700", "counterpartAddress": { "street": "Pariser Platz", "houseNumber": "1", "city": "Berlin", "postCode": "10117", "country": "DE" }, "amount": 99.99, "purpose": "Test Payment", "sepaPurposeCode": "OTHR", "endToEndId": "001100550526", "structuredRemittanceInformation": [ "VS:501", "KS:9", "SS:1005" ] } ], "instantPayment": false } **Creation response body** JSON { "id": 7335698, "accountId": null, "iban": "DE77533700080111111100", "bankId": 280001, "type": "MONEY_TRANSFER", "amount": 99.99, "orderCount": 1, "status": "OPEN", "instructedExecutionDate": "2026-01-01", "instantPayment": false, "statusV2": "OPEN" } **Submission URL:** `POST https://live.finapi.io/api/v1/payments/submit` **Submission Request Body** JSON { "paymentId": 7335698, "interface": "XS2A" } **Response headers** .. location: https://live.finapi.io/webForm/qNuxRocY1kew5OSzEzfHYtoFQP0G9usklxC8S8kmSYY6D_EP_vNuV62d0JUrqMWVTIDSTYFjHOtKYP0v2ZIyJAOjmiXYG0C9yu77wClVgf8PwlQpbhuk5GcJK7qqFHyO ... **Response body** JSON { "errors": [ { "message": "23894883", "code": "WEB_FORM_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": null } ], "date": "2025-05-13 13:51:57.051", "requestId": "selfgen-8bca4bab-ff68-4ccc-911c-e552bc74bcb7", "endpoint": "POST /api/v1/payments/submit", "authContext": "2063/1959409", "bank": "DEMO0001 - finAPI Test Bank (id: 280001, location: none)" } | **Request URL:** `POST https://webform-live.finapi.io/api/webForms/standalonePayment` **Request body** JSON { "sender": { "iban": "DE77533700080111111100" }, "executionDate": "2026-01-01", "orders": [ { "recipient": { "name": "Max Mustermann", "iban": "DE13700800000061110500", "bic": "DRESDEFF700", "address": { "street": "Pariser Platz", "houseNumber": "1", "city": "Berlin", "postCode": "10117", "country": "DE" } }, "amount": { "value": 99.99, "currency": "EUR" }, "purpose": "Test Payment", "sepaPurposeCode": "OTHR", "endToEndId": "001100550526", "structuredRemittanceInformation": [ "VS:501", "KS:9", "SS:1005" ] } ], "instantPayment": false } **Response headers** N/A **Response body** JSON { "id": "2541d998-a3a5-4e59-b904-4b654f3a8c19", "url": "https://webform-live.finapi.io/wf/2541d998-a3a5-4e59-b904-4b654f3a8c19", "createdAt": "2025-05-13T11:59:17.453+0000", "expiresAt": "2025-05-13T12:19:17.453+0000", "type": "STANDALONE_PAYMENT", "status": "NOT_YET_OPENED" } |

---
language: "en"
---
# Themes

## What is a Theme?

For customers who are interested in further customization, we have carefully picked specific styling parameters and grouped them together under the umbrella called "Theme". Each of the themes will focus on a specific style. We will offer a set of themes from our side that customers can pick from that blends well with the rest of the customer application. We are focussed on the below styling parameters amongst others.

* (web) elements styling - button, check boxes, text fields

* Text spacing

* Text sizing

## How to set it?

Look out for the API parameter, `profile.aspect.theme` in the section "Customisation / Profiles" in the openAPI documentation. Setting this parameter to one of the available values from the enumeration will ensure all web forms generated will go with the selected styling(theme).

## Things to remember

* Always test what the Web Form will finally look like, with all the customizations. This includes profiles and translations. There is a chance that the customer will need to adjust what they provide in the profile and translation to have the best possible results from all the customization.

## Mockups

Below are some mockups of one of our workflows which clearly show you how the Web Form will be rendered with (on the left) and without (on the right) applying the theme. The theme used in this case is `MOBILE_MINIMALISTIC`.  
![image-20220602-020843.png](https://documentation.finapi.io/__attachments/a_a0c16f22664f8c0e0db60a60a08943ccec8c03b1490c948b1f577e859a8e8bcf/image-20220602-020843.png?cb=1e3a568900b35198bd462d2672fa9d92)  
![image-20220602-021731.png](https://documentation.finapi.io/__attachments/a_772163e0392c397d356d5cd10080fa843a102086b3652c23f17ffc3bc8e63efb/image-20220602-021731.png?cb=4f06ebda19e8aa4c34b703c31ab10ac8)  
![image-20220602-021808.png](https://documentation.finapi.io/__attachments/a_d2947098d0eed91838b68dc298db06297354d2a4e74d582fe29834e2bd543078/image-20220602-021808.png?cb=f95e195ba63befabc72d242196536a13)  
![image-20220602-021838.png](https://documentation.finapi.io/__attachments/a_456ceefc90028b10632f892abbf1e3298bcd6fa297fb2788bdaec4155a9a4e67/image-20220602-021838.png?cb=41797b3ab74bc25c2b338020603faf0c)  
![image-20220602-134507.png](https://documentation.finapi.io/__attachments/a_098ae8a1cf2d017f23f0ef8d3a27c1a7d42a064d378f185ee84dd23827002270/image-20220602-134507.png?cb=6cc45c8de6861fda6fee91abacf1030c)  
![image-20220602-021906.png](https://documentation.finapi.io/__attachments/a_537b54f513dd34612cded12d7bcce7a0242a9c76db8396ecd5e7406c0f73154b/image-20220602-021906.png?cb=b8343875efcd378f7fd35836309e536a)  
![image-20220602-021938.png](https://documentation.finapi.io/__attachments/a_ac1f6c04eca1f3d01601e3706603eaf4f6c6809ffedfbf86f0e14ea25ff15ee9/image-20220602-021938.png?cb=28c56bee90d549b29b3e911d1f174978)

---
language: "en"
---
# Translation

## What is a translation?

For clients who want to customize the text on the main titles and subtitles rendered on the Web Form, we urge you to look up our Translation services. This is one of the many features built to improve the customizations of the Web Form to seamlessly integrate into the customer product.

## How to set it?

Explore our new endpoint ["Create a translation"](https://webform-live.finapi.io/api-docs/index.html#post-/api/translations) in the OpenAPI documentation. For all the languages supported on the Web Form, for each of the views that the Web Form could render, customers will have the possibility to provide customized titles and subtitles. When customers do not want the title or the subtitle, setting it to an empty string `""` will remove the title/subtitle completely from the view.  
Translations end point has been built to work complimentarily to the ["Create a profile"](https://webform-live.finapi.io/api-docs/index.html#post-/api/profiles) endpoint. In totality, both endpoints will apply all the possible customizations to provide the best outcome to customers.

## Things to remember

Below is the list of mockups and the corresponding names of the API parameters you can find in the "Create a translation" endpoint. Customers are welcome to use this as a reference while integrating with the endpoint.  
Most of the views below are steps common to both Account Information Services and Payment Initiation Services. In these cases, when the customization is provided, the same API will apply to Web For views of both AIS and PIS workflows.

`bankSearchView`  
![image-20240705-152846.png](https://documentation.finapi.io/__attachments/a_9f3569205fcbb582d7f1003bc0df2ccce627851943ffbadeddba9eecb4fce881/image-20240705-152846.png?cb=3bcc98e3bd75dad3da8deb81f6772141)

`bankSelectionView`  
![image-20240705-161418.png](https://documentation.finapi.io/__attachments/a_6bf99bcdf0bc3870edbf1e3f11ece024d62a31586d7bb8b4322df5de4349aa9a/image-20240705-161418.png?cb=19538c19c2ac017c0154196e67edccb0)

`bankLoginView`  
![image-20240705-152939.png](https://documentation.finapi.io/__attachments/a_0116cef2a5c9e2c59b05cb9252ba30db80754d94f23a8f035aac616e988cdfa3/image-20240705-152939.png?cb=0af5795db856387d16baf42c0cabfd73)

`redirectBankLoginView`  
![image-20240705-155258.png](https://documentation.finapi.io/__attachments/a_b5f1fc4f8fa3aa7d55f2bdbf51c8588a00f1eed85267ab36568e74b7591c2f26/image-20240705-155258.png?cb=73fa74060cdd3548d1eab733c7747332)

`scaMethodSelectionView`  
![image-20240705-153005.png](https://documentation.finapi.io/__attachments/a_8b1ef1d28ad7cd380d822dca2ecb4424ffbf19e25e4c07b947078b7aa1ac57b6/image-20240705-153005.png?cb=8f0d1818c7c15390388a934752179dce)

`scaChallengeView`  
![image-20240705-153028.png](https://documentation.finapi.io/__attachments/a_ad6225a52ca45ca2eec7957b48910bbda496ac6890c505af15370b7a09421393/image-20240705-153028.png?cb=b119a0ab42bfe457c403eec119bd54f6)

`accountSelectionViewAis`  
![image-20240705-155658.png](https://documentation.finapi.io/__attachments/a_31f60d023833cc607d1e07bfd8c2202c420c47621fb747ed42a9412f4720c577/image-20240705-155658.png?cb=07a2e69607217311974cd1ca7dd711d2)

`accountSelectionViewPis`  
![image-20240705-160029.png](https://documentation.finapi.io/__attachments/a_4e62317813ea948bc67f3dedf693e5e7c7bfd5098825a6b82e94fe169f8ff13e/image-20240705-160029.png?cb=07758a7724c170a3bf05441d3a14b5f7)

`dataDownloadViewAis`  
![image-20240705-153059.png](https://documentation.finapi.io/__attachments/a_69f9939765c83572611e3dcedaed2daafb6bc14819ba4595d54ef7212d0a95ef/image-20240705-153059.png?cb=e2aeabec6dfa8bd3b4ee02e3967ba48a)

`partialConfirmationView`  
![image-20240705-153128.png](https://documentation.finapi.io/__attachments/a_dbaf4bac11e352493bce5adf7624ef6fee7126a0500298365b7563fae96c959d/image-20240705-153128.png?cb=29e14c37ed7f4821c9bb8aec5f1ecd40)

`partialConfirmationWithErrorView`  
![image-20240705-160539.png](https://documentation.finapi.io/__attachments/a_a779c7a79217ac97903b782019869872473de58fc3373aae0bbdfbb643855748/image-20240705-160539.png?cb=c679811d2e8b9b7eb4b662a6474799d0)

`updateSummaryView`  
![image-20240705-161741.png](https://documentation.finapi.io/__attachments/a_90d4970fe6acefe17a3bcc4e130b18dab0db5bcc82b0dfcd1c6c0d255a64a216/image-20240705-161741.png?cb=e61d844fa6bcf15ed6802f0f080cd5bd)

`confirmationView`  
![image-20240705-153155.png](https://documentation.finapi.io/__attachments/a_7e68ff3de996bc2cfe7ed59d08700bdbb30ef4dd92fbaf367cf031d639d90345/image-20240705-153155.png?cb=cd2e30e731a0a685cc842d9ed65dc318)

`errorView`  
![image-20240705-160305.png](https://documentation.finapi.io/__attachments/a_bad523476b5311a50c4b8ed9867389944290be3a40a40469bcd1db834763be04/image-20240705-160305.png?cb=d36eefddd77aff1b52332e34b4aabfbc)

### Default titles and subtitles

Here is the table where default titles and subtitles are listed for all supported languages.  

|------------------------------------------|-------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| **Resource key**                         | **Supported languages**                                                                                           |                                                                                                                                                                                 |                                                                                                                                                      |                                                                                                                                                             |                                                                                                                                                                          |                                                                                                                                                         |                                                                                                                        |                                                                                                                           |
| **Resource key**                         | **CS**                                                                                                            | **DE**                                                                                                                                                                          | **EN**                                                                                                                                               | **FR**                                                                                                                                                      | **NL**                                                                                                                                                                   | **PL**                                                                                                                                                  | **SK**                                                                                                                 | **TR**                                                                                                                    |
| `bankSearchView.title`                   | `Výběr banky`                                                                                                     | `Bank auswählen`                                                                                                                                                                | `Bank Selection`                                                                                                                                     | `Sélectionner une banque`                                                                                                                                   | `Bank selecteren`                                                                                                                                                        | `Wybierz bank`                                                                                                                                          | `Výber banky`                                                                                                          | `Banka seçin`                                                                                                             |
| `bankSelectionView.title`                | `Výběr banky`                                                                                                     | `Bank auswählen`                                                                                                                                                                | `Bank Selection`                                                                                                                                     | `Sélectionner une banque`                                                                                                                                   | `Bank selecteren`                                                                                                                                                        | `Wybierz bank`                                                                                                                                          | `Výber banky`                                                                                                          | `Banka seçin`                                                                                                             |
| `bankLoginView.title`                    | `Přihlášení do banky`                                                                                             | `Bank Login`                                                                                                                                                                    | `Bank Login`                                                                                                                                         | `Connexion à la banque`                                                                                                                                     | `Inloggen bank`                                                                                                                                                          | `Logowanie do banku`                                                                                                                                    | `Prihlásenie do banky`                                                                                                 | `Banka girişi`                                                                                                            |
| `bankLoginView.subtitle`                 | `Zadejte přihlašovací údaje`                                                                                      | `Login Daten eingeben`                                                                                                                                                          | `Enter login data`                                                                                                                                   | `Saisir les données de connexion`                                                                                                                           | `Inloggegevens invoeren`                                                                                                                                                 | `Wprowadź dane logowania`                                                                                                                               | `Zadajte prihlasovacie údaje`                                                                                          | `Oturum açma bilgilerini girin`                                                                                           |
| `redirectBankLoginView.title`            | `Přihlášení do banky`                                                                                             | `Bank Login`                                                                                                                                                                    | `Bank Login`                                                                                                                                         | `Connexion à la banque`                                                                                                                                     | `Inloggen bank`                                                                                                                                                          | `Logowanie do banku`                                                                                                                                    | `Prihlásenie do banky`                                                                                                 | `Banka girişi`                                                                                                            |
| `redirectBankLoginView.subtitle`         | `Zadejte přihlašovací údaje`                                                                                      | `Login Daten eingeben`                                                                                                                                                          | `Enter login data`                                                                                                                                   | `Saisir les données de connexion`                                                                                                                           | `Inloggegevens invoeren`                                                                                                                                                 | `Wprowadź dane logowania`                                                                                                                               | `Zadajte prihlasovacie údaje`                                                                                          | `Oturum açma bilgilerini girin`                                                                                           |
| `scaMethodSelectionView.title`           | `Výběr TAN metody`                                                                                                | `TAN-Methode auswählen`                                                                                                                                                         | `Select TAN Method`                                                                                                                                  | `Sélectionner la méthode TAN`                                                                                                                               | `TAN-methode selecteren`                                                                                                                                                 | `Wybierz metodę TAN`                                                                                                                                    | `Výber TAN metódy`                                                                                                     | `TAN yöntemini seçin`                                                                                                     |
| `scaChallengeView.title`                 | `Ověření TAN`                                                                                                     | `TAN bestätigen`                                                                                                                                                                | `Confirm TAN`                                                                                                                                        | `Confirmer le TAN`                                                                                                                                          | `TAN bevestigen`                                                                                                                                                         | `Potwierdź TAN`                                                                                                                                         | `Overenie TAN`                                                                                                         | `TAN'ı onaylayın`                                                                                                         |
| `accountSelectionViewAis.title`          | `Výběr účtu`                                                                                                      | `Konto auswählen`                                                                                                                                                               | `Account Selection`                                                                                                                                  | `Sélectionner un compte`                                                                                                                                    | `Rekening selecteren`                                                                                                                                                    | `Wybierz konto`                                                                                                                                         | `Výber účtu`                                                                                                           | `Hesabı seçin`                                                                                                            |
| `accountSelectionViewAis.subtitle`       | `Spojení s vaší bankou bylo navázáno a data se stahují na pozadí. Vyberte účty, které chcete uložit do aplikace.` | `Die Verbindung zu Ihrer Bank wurde hergestellt und Ihre Daten bereitgestellt. Nachfolgend können Sie die Konten auswählen, welche in die Anwendung eingebunden werden sollen.` | `Connection with your bank has been established and data is being downloaded in the background. Select the accounts to be saved in the application.` | `La connexion avec votre banque a été établie et vos données ont été fournies. Vous pouvez ensuite sélectionner les comptes à intégrer dans l'application.` | `De verbinding met uw bank is tot stand gebracht en er is toegang tot uw gegevens. Hierna kunt u de rekeningen selecteren, die in de toepassing moeten worden opgenomen` | `Połączenie z Twoim bankiem zostało nawiązane i Twoje dane zostały udostępnione. Poniżej możesz wybrać konta, które mają zostać powiązane z aplikacją.` | `Spojenie s vašou bankou bolo nadviazané a dáta sa sťahujú na pozadí. Vyberte účty, ktoré sa majú uložiť v aplikácii.` | `Bankanızla bağlantı kuruldu ve verileriniz sağlandı. Şimdi ise uygulamaya dahil edilecek olan hesapları seçebilirsiniz.` |
| `accountSelectionViewPis.title`          | `Výběr účtu`                                                                                                      | `Konto auswählen`                                                                                                                                                               | `Account Selection`                                                                                                                                  | `Sélectionner un compte`                                                                                                                                    | `Rekening selecteren`                                                                                                                                                    | `Wybierz konto`                                                                                                                                         | `Výber účtu`                                                                                                           | `Hesabı seçin`                                                                                                            |
| `accountSelectionViewPis.subtitle`       | `(Pro zadání trvalého příkazu)` (for standing orders) `(Pro zadání platebního příkazu)` (for other payments)      | `(Für Dauerauftrag)` (for standing orders) `(Für Zahlungsauslösung)` (for other payments)                                                                                       | `(For Standing Order Initiation)` (for standing orders) `(For Payment Initiation)` (for other payments)                                              | `(Pour les virements automatiques)` (for standing orders) `(Pour le déclenchement de paiement)` (for other payments)                                        | `(Voor doorlopende betalingsopdracht)` (for standing orders) `(Voor betalingsinitiatie)` (for other payments)                                                            | `(dla zlecenia stałego)` (for standing orders) `(dla zlecenia płatności)` (for other payments)                                                          | `(Pre zadanie trvalého príkazu)` (for standing orders) `(Pre zadanie platobného príkazu)` (for other payments)         | `(Sürekli ödeme talimatı için)` (for standing orders) `(Ödeme talimatı için)` (for other payments)                        |
| `dataDownloadViewAis.title`              | `Načíst bankovní údaje`                                                                                           | `Bankdaten abrufen`                                                                                                                                                             | `Retrieve Bank Details`                                                                                                                              | `Récupérer les données bancaires`                                                                                                                           | `Bankgegevens ophalen`                                                                                                                                                   | `Pobierz dane bankowe`                                                                                                                                  | `Načítajte bankové údaje`                                                                                              | `Banka bilgilerini talep et`                                                                                              |
| `partialConfirmationView.title`          | `Potvrzení`                                                                                                       | `Bestätigung`                                                                                                                                                                   | `Confirmation`                                                                                                                                       | `Confirmation`                                                                                                                                              | `Bevestiging`                                                                                                                                                            | `Potwierdzenie`                                                                                                                                         | `Potvrdenie`                                                                                                           | `Onay`                                                                                                                    |
| `partialConfirmationWithErrorView.title` | `Proces byl částečně úspěšný`                                                                                     | `Der Prozess war teilweise erfolgreich`                                                                                                                                         | `The process was partially successful`                                                                                                               | `Le processus a été partiellement couronné de succès`                                                                                                       | `Het proces was gedeeltelijk succesvol`                                                                                                                                  | `Proces ten zakończył się częściowym sukcesem`                                                                                                          | `Tento proces bol čiastočne úspešný`                                                                                   | `Süreç kısmen başarılı oldu`                                                                                              |
| `updateSummaryView.title`                | `Aktualizujte své účty`                                                                                           | `Aktualisierung Ihrer Konten`                                                                                                                                                   | `Updating your bank accounts`                                                                                                                        | `Mise à jour de vos comptes`                                                                                                                                | `Bijwerken van uw rekeningen`                                                                                                                                            | `Aktualizacja Twoich kont`                                                                                                                              | `Aktualizujte svoje účty`                                                                                              | `Hesaplarınızın güncellenmesi`                                                                                            |
| `confirmationView.title`                 | `Potvrzení`                                                                                                       | `Bestätigung`                                                                                                                                                                   | `Confirmation`                                                                                                                                       | `Confirmation`                                                                                                                                              | `Bevestiging`                                                                                                                                                            | `Potwierdzenie`                                                                                                                                         | `Potvrdenie`                                                                                                           | `Onay`                                                                                                                    |
| `errorView.title`                        | `Chybové hlášení`                                                                                                 | `Fehlermeldung`                                                                                                                                                                 | `Error Message`                                                                                                                                      | `Message d'erreur`                                                                                                                                          | `Foutmelding`                                                                                                                                                            | `Komunikat o błędzie`                                                                                                                                   | `Chybová správa`                                                                                                       | `Hata mesajı`                                                                                                             |

---
language: "en"
---
# Using a generated SDK

For quick and easy integration of the Web Form 2.0 API, we offer the SDK download feature. It provides a client SDK that can easily be integrated into your application. Currently, about 60 programming languages and frameworks are supported.

## Generate and download the SDK

The <https://documentation.finapi.io/access/finapi-sdk> page describes how to download a generated SDK. Please follow the steps documented there and select "finAPI Web Form 2.0" as the product.

**Note:** Additionally, you need to integrate an Access SDK, as the Authorization API you need for Web Form 2.0 is part of Access. Detailed information can be found here: [Using a generated Access SDK](https://documentation.finapi.io/access/using-a-generated-sdk.md).

## Integrate the SDK into your application

The downloaded SDK is contained in a ZIP file. Please unpack it into an empty directory.

Usually, a README file and additional docs are provided. Please check them out to get an overview of how to use the SDK and how to integrate it into your application.

For the following languages, we provide detailed SDK usage information:

* Java → see [Web Form 2.0 Java SDK usage](https://documentation.finapi.io/webform/web-form-2-0-java-sdk-usage.md)

---
language: "en"
---
# Web Form 2.0 Basics

## How it all starts

Determine your business case - would you like to use our Account Information Services or Payment Initiation Services? Based on the answer, check our openAPI documentation to understand which endpoint to use.

When the customer application is calling a finAPI Web Form 2.0 service defined [here](https://docs.finapi.io/?product=web_form_2.0)(either for Account Information Services or Payment Initiation Services) the API will respond with **HTTP code 201** , and the **API response**could look like below (example):
JSON

    {
      "id": "c512b6b7-259d-451e-8eec-0ae4ed993c6f",
      "url": "https://webform-sandbox.finapi.io/wf/c512b6b7-259d-451e-8eec-0ae4ed993c6f",
      "createdAt": "2021-03-02T13:51:08.973+0000",
      "expiresAt": "2021-03-02T14:11:08.973+0000",
      "type": "STANDALONE_PAYMENT",
      "status": "NOT_YET_OPENED",
      "payload": {
        "paymentId": null
      }
    }

The `id` field depicts the Web Form instance that has been created by finAPI in the context of this service call. You will need this ID to query the result of the Web Form flow (more details here)

The API response will contain a `URL` to the Web Form to which you must direct your end-user. The general format is:

***"url": https://\<Web Form domain\>/wf/\<Web Form Id\>***

Example: `https://webform-sandbox.finapi.io/wf/c512b6b7-259d-451e-8eec-0ae4ed993c6f `

The rest of the interaction happens directly between the end-user and our Web Form. At the end of the workflow, depending on whether the customer application has set up a `callbackUrl`, we can explicitly notify the customer application of the end state.

Use this notification to come back to us and ask for more details (paymentId in case of PIS and bankConnectionId in case of AIS)

Schematically, the workflow is summarized below (The below workflow also applies to AIS)
![](https://documentation.finapi.io/__attachments/a_cf8c3480ccb8510fdaf5d9bd7ae86ea40377bfe4ca049c8ab876668197533565/Schema%20Standalone%20Payments%20v2.drawio.png?cb=685a9d67cc025528abea3f51a12d17c8)

## Remember!

1. Web Form token is a **one-time token**. You will be able to open the URL just once. Further attempts will result in an error page.

2. Web Form URLs are valid for just 20 minutes. If a Web Form is not consumed for its purpose within 20 minutes of initiation, it will expire.

3. The Web Form will consider the default language (supported languages: DE, EN, CZ and SK) of your browser and render accordingly. However, if your end-user prefers a different language than the browser, they are free to use the language picker in the header to select a different one. If they do, we will store their new language preference for all future Web Forms rendered to the user.

   1. ⚠ User's language preference won't be stored (along with all other user data) in use cases where customers delete users after one time use

   2. ⚠ As a customer, if you prefer all Web Forms to be rendered in only 1 language of your choice, please use our white labeling endpoint to set this up.

## Want to know Web Form status?

The endpoint to the "Get a web form" service is: `GET /api/webForms/{id}`

`GET .../api/webForms/<webFormId that was contained in the message field of the initial service response> `

(For this example: `GET .../api/v1/webForms/e0337037-1228-4db7-bcdb-32b0c5f64af4`*)*

Querying a Web Form will give you the following result:
JSON

    {
      "id": "e0337037-1228-4db7-bcdb-32b0c5f64af4",
      "url": "https://webform-sandbox.finapi.io/wf/e0337037-1228-4db7-bcdb-32b0c5f64af4",
      "createdAt": "2021-03-09T08:36:15.000+0000",
      "expiresAt": "2021-03-09T08:56:15.000+0000",
      "type": "STANDALONE_PAYMENT",
      "status": "COMPLETED",
      "payload": {
        "paymentId": 22718
      }
    }

The `id` is the generated Web Form ID. It is also contained in the URL and used as an access token.

The `status` can be one of:

* **"NOT_YET_OPENED"** - when the Web Form URL has not been accessed yet.

* **"IN_PROGRESS"** - when the Web Form page has been opened and the flow is in progress.

* **"COMPLETED"** - when the Web Form has successfully executed the service.

* **"COMPLETED_WITH_ERROR"** - when the Web Form has been executed but something unexpected happened. Unsuccessful end state.

* **"ABORTED"** - when the user has aborted the Web Form flow (by clicking the CANCEL button at some step during the process)

* "**EXPIRED** " - this is an internally forced state when there are abandoned Web Forms in non-final states (`COMPLETED`, `COMPLETED_WITH_ERROR` or `ABORTED` are the only possible final states) for longer than 20 minutes.

Note that the **"Get a web form"** service is a user-related service, meaning that you have to pass an `Authorization` header with the user's access token, just as with any other of finAPI's user-related REST services. You might want to think about adding some user identifier to the `callbacks.finalised` or `redirectUrl` to be able to resolve the user context in your application in order to get hold of an appropriate access token (For security reasons, you should never include an access token itself in the Web Form URL)

## How to test the Web Form Flow using openAPI?

As of now, openAPI will not automatically open the Web Form for you. You'll have to enter the Web Form URL into a separate tab of your browser yourself, and also have to call the "Get a web form" service for yourself once the Web Form has triggered the callback and/or redirect.

---
language: "en"
---
# Web Form 2.0 Environments

We offer two environments to our customers: **Sandbox** and **Live**.

## Sandbox

**Purpose**: Evaluation \& testing. The sandbox environment always contains the latest version of the web form services.

**URL** : [https://webform-sandbox.finapi.io](https://webform-sandbox.finapi.io/)

The following applies for the use of the Sandbox environment:

* Testing/evaluation of the services.

* Please do not perform load tests on the Sandbox.

* In the background, web form communicates with Access' sandbox environment ([Sandbox](http://sandbox.finapi.io/))

* When customers decide to switch to the Live/Production environment, the data generated in Sandbox will not be migrated.

* All data in the Sandbox environment must be deleted by the users themselves after use.

* No SLA and availability guarantees are offered for Sandbox.

## Live

**Purpose**: Production usage.

**URL** : [https://webform-live.finapi.io](https://webform-live.finapi.io/)

The following applies for the use of the Live environment:

* You may use the Live instance only if you have a valid license agreement for using finAPI.

* Users created on the live instance count towards your license agreement.

* Please do not use the Live instance for load or performance tests.

* Access to the Live environment can be IP restricted for security reasons.

* In the background, web form communicates with Access' Live environment ([Live](http://live.finapi.io/))

* The SLA as per the license agreement is applied.

If customers need to perform load and/or performance tests on any of our environments, please contact us at [support@finapi.io](mailto:support@finapi.io).  
If customers plan on having their own dedicated environments at finAPI, Web Form can be setup on the customer's dedicated environment as well! Check [this section](https://documentation.finapi.io/webform/embedded-web-form-2-0.md#Working-with-custom-environments) for more details.

---
language: "en"
---
# Web Form 2.0 Java SDK usage

## Installation

Please first download a Web Form 2.0 Java SDK by following the instructions as described in [Using a generated SDK](https://documentation.finapi.io/access/using-a-generated-sdk.md) and choosing "java" as the target language.

A standalone Java project is generated that can be built with either Gradle or Maven. You can either build the project and include the created jar file as a dependency in your application or directly copy the generated code into your application.  
The code examples in this chapter assume that you used the "Download SDK" button to generate the SDK and chose the V2 API version. By doing so, the generator runs with the default options, using OkHttp as the HTTP client library and GSON as the serialization library.

If you used the [finAPI SDK Generator](https://openapitools-server-finapi-common-live.finapi.io/) instead to customize SDK generation, you may end up with a different SDK structure and divergent Java code, especially if you change the `library` parameter. The code examples should still be helpful for you, even though you may need to adjust them.

## Overview

The `src/main/java` folder contains the SDK classes. The `app` subpackage contains API classes to call API service methods. For each section of the Web Form 2.0 API (see the left sidebar of the [Web Form 2.0 API documentation](https://docs.finapi.io/?product=web_form_2.0)), a distinct API class is available. The `model` package contains the API request and response model classes.

The `src/test/java` folder is not required to run the SDK, but the pre-generated tests are helpful to check the API usage, as they contain example calls for all API services.

The easiest way to run a service is to just instantiate the API class and execute the desired service method, e.g.:

    new AccountInformationServicesApi().createForBankConnectionImport(<parameters>);

In this case, the API class uses the default global configuration. You can change the configuration settings globally by calling the setter methods of `Configuration.getDefaultApiClient()`. This configuration will by default use [https://webform-sandbox.finapi.io](https://webform-sandbox.finapi.io/) as the API base path, so you'll need your sandbox client credentials to run the following examples.

To find out which parameters you have to provide for a service call, just navigate to the method implementation in your IDE, e.g., to `AccountInformationServicesApi.createForBankConnectionImport`. Each method contains an extensive Javadoc comment with the same information as on our API documentation page. The same applies to all model classes.

## Usage Examples

The following examples are reduced to the necessary minimum to help you get easily started with the SDK. However, for a production application, more topics need to be considered. Please refer to the [Web Form 2.0 Java SDK usage \| Advanced topics](https://documentation.finapi.io/webform/web-form-2-0-java-sdk-usage.md#Advanced-topics) section for this.

### Authorization and Creation of a User Identity

The Web Form 2.0 API services require a user access token to be provided. Authorization and user creation are not part of the Web Form 2.0 API but require the Access API. So, you need to download the Access SDK as described in [Using a generated Access SDK](https://documentation.finapi.io/access/using-a-generated-sdk.md) and additionally integrate it into your application.

The [Access Java SDK usage \| Authorization and Creation of a User Identity](https://documentation.finapi.io/access/access-java-sdk-usage.md#Authorization-and-Creation-of-a-User-Identity) section described the necessary Java calls to create a user and retrieve a user token.

**Note:**The following usage examples assume that you retrieved a user token via the Access API first and registered it globally within the Web Form 2.0 SDK:

    // Call Access API to retrieve user token
    AccessToken userToken = authorizationApi.getToken(...);

    Configuration.getDefaultApiClient().setAccessToken(userToken.getAccessToken());

### Import a new Bank Connection

This section shows how the API calls described in [Import a new Bank Connection - with Web Form 2.0 (Recommended option)](https://documentation.finapi.io/access/import-a-new-bank-connection-with-web-form-2-0-rec.md) can be executed via the Java SDK.

#### Step 1 - Request to generate a web form to import a bank connection

In the easiest case, the service can be called without any arguments. The created web form will then ask the user to first select the bank to be imported. The service returns a web form resource containing the web form URL to be opened.

    AccountInformationServicesApi accountInformationServicesApi = new AccountInformationServicesApi();
    WebForm webForm = accountInformationServicesApi.createForBankConnectionImport(new BankConnectionImportDetails());

The `BankConnectionImportDetails` class supports many parameters to control the web form flow behavior.

E.g., if the bank to be imported is already known, you can provide it as a service parameter, either the bank ID or a search string, so the created web form won't ask the user to select a bank.

The following example provides the ID of the finAPI demo bank:

    AccountInformationServicesApi accountInformationServicesApi = new AccountInformationServicesApi();
    BankConnectionImportDetails bankConnectionImportDetails =
        new BankConnectionImportDetails().bank(new ImportBankDetails().id(280001L));
    WebForm webForm = accountInformationServicesApi.createForBankConnectionImport(bankConnectionImportDetails);

#### Step 2 - Ask the user to log in at the bank and authorize access

As a result of step 1, a web form is generated. Use `webForm.getUrl()` to present the web form to the user to authorize access (login at the bank and complete the second-factor authentication procedure).

No Web Form 2.0 API call is required in this step.

#### Step 3 - Check the status of the Web Form

As no callback was registered during step 1 (which would have directly informed you about web form completion, including the status), you need to poll the "Get a web form" service unless it returns a final status. The ID of the web form created in step 1 must be given as a parameter:

    AccountInformationServicesApi accountInformationServicesApi = new AccountInformationServicesApi();
    WebForm updatedWebForm = new WebFormsApi().getWebForm(webForm.getId());

    // TODO react on updatedWebForm.getStatus()

#### Step 4 - Check the status of the bank connection

If the web form is completed successfully, the bank connection may still be in the process of categorizing transactions in the background (please check [Post Processing of Bank Account Import/Update](https://documentation.finapi.io/access/post-processing-of-bank-account-import-update.md) for details). This means that if you try to access transactions of the imported bank connection, they will likely have no category assigned. Based on your use case, you can either ignore that fact or wait until the categorization is finished. Use the `getBankConnection` service for this and provide the `bankConnectionId` returned in step 3 as the parameter:

    if (updatedWebForm.getStatus() == COMPLETED) {
        BankConnectionsApi bankConnectionsApi = new BankConnectionsApi();
        BankConnection bankConnection = bankConnectionsApi.getBankConnection(
            updatedWebForm.getPayload().getBankConnectionId(), null);

        // TODO check bankConnection.getUpdateStatus() until 'READY'
    }

#### Step 5 - Get Accounts and Transactions

Accounts and transactions are available through the Access API. Please refer to [Access Java SDK usage \| Get Accounts and Transactions](https://documentation.finapi.io/access/access-java-sdk-usage.md#Get-Accounts-and-Transactions) for SDK usage examples.

## Advanced topics

Please also refer to [Access Java SDK usage \| Advanced topics](https://documentation.finapi.io/access/access-java-sdk-usage.md#Advanced-topics) for further topics that also partially apply to the Web Form 2.0 API.

### Configure the API basepath

If you instantiate an API class with the default constructor as shown in the examples, the call will be executed against the finAPI Web Form 2.0 Sandbox ([https://webform-sandbox.finapi.io](https://webform-sandbox.finapi.io/)). This is correct when you start adopting the API, but to switch to our production environment, you need to override the URL to [https://webform-live.finapi.io](https://webform-live.finapi.io/)[.](https://live.finapi.io./)

The simplest option is to override the URL in the default API client:

    Configuration.getDefaultApiClient().setBasePath("https://webform-live.finapi.io");

### Provide a request ID

For each Web Form 2.0 API request, you should provide a unique `X-Request-Id` header on each request, as described in the [General information](http://docs.finapi.io/?product=web_form_2.0#general-information) section of the API documentation.

As the request ID cannot be provided as a parameter to the SDK methods, it must be added at a central place. One approach could be to intercept request handling on the `OkHttpClient` level:

    OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(chain ->
        chain.proceed(chain.request().newBuilder()
            .addHeader("X-Request-Id", requestId())
            .build())).build();
    Configuration.getDefaultApiClient().setHttpClient(httpClient);

A simple approach to always having a unique request ID is to use the UUID:

    private String requestId() {
        return UUID.randomUUID().toString();
    }

---
language: "en"
---
# Web Form Layout Configuration

The Web Form has a responsive layout that adjusts to different screen sizes. For example, when the user opens the Web Form on a phone, a single-column layout is used with adjusted typography. When the Web Form is opened on a computer screen with a high resolution, a different layout is chosen that utilizes a multi-column design, wider margins, and more pronounced typography.

This responsiveness is achieved through the browser's support for media queries. Media queries allow different CSS styles to be applied based on the available space. The available space is measured by the overall width and height of the page, but the Web Form only considers the width.

There are defined "breakpoints" in the Web Form 2.0:  
![grafik-20241217-122231.png](https://documentation.finapi.io/__attachments/a_c5a4c7065fe2f79497ee2f738b34f3d9ca2b8ce55ae8e543e96199d43f2ad1e1/grafik-20241217-122231.png?cb=a9d2ba71c7cd3f10402e5a0251108774)

The breakpoints define different layouts:

* 'xs' -- extra small

* 'sm' -- small

* 'md' -- medium

* 'lg' -- large

* 'xl' -- extra large

The number value represents the page width in pixels at which the corresponding layout becomes active. For example, when the page width is 1000px, the medium layout is activated (it's already over 960px for medium, but not yet 1280px for large).

This works fine when the Web Form's width matches the page's width. However, the Web Form is a web component widget, which you may embed in a container with a width smaller than the full page width.  
![webform-layoutconfig.drawio.png](https://documentation.finapi.io/__attachments/a_ee4a5a6229420e4544e6f7018653d939565aee0b97afcbc4c5840ac4ff1723fe/webform-layoutconfig.drawio.png?cb=aa31cb820b14cde0a53bb16b59f2a510)

In this case, based on the original breakpoint values, the Web Form would still choose the medium layout, since it measures the entire page width as 1000px. However, the actual container is only 500px wide, so the correct layout should be extra-small.

We need to adjust the breakpoints:

    {
      xs: 0,
      sm: 1200, // 600*2
      md: 1920, // 960*2
      lg: 2560, // 1280*2
      xl: 3840, // 1920*2
    }

Now, with the page width at 1000px and the container width at 500px, the Web Form will correctly select the extra-small layout. If the page is resized, for example, to 1920px, the Web Form will switch to the medium layout (since the container size is now 960px, which corresponds to the original medium breakpoint).

You can pass this new layout config as a property when loading the Web Form:  
![grafik-20241217-125429.png](https://documentation.finapi.io/__attachments/a_4f24ec35a658d9d4904dd87516a43c99d88599eb7006ca2e260524dfbeef0cfd/grafik-20241217-125429.png?cb=d6022e1b0c9cdb6496a1e7203777ed02)
<https://webform-dist.finapi.io/latest/docs/interfaces/webformprops.html#layoutconfig>

`LayoutConfig` type also accepts fixed values 'xs', 'sm', 'md', and 'lg'.  
![grafik-20241217-125659.png](https://documentation.finapi.io/__attachments/a_e6b0e2507d824cddc28b3db8a4ce9ecb3de2d5aaceff9695319f68b391691162/grafik-20241217-125659.png?cb=e6bc0af5bd03e38214c5dfa2d29c4c4a)  
'xl' is missing because currently, 'lg' is the largest layout defined in the Web Form. However, we've kept the breakpoint value in place in case we need to use it in the future.

The fixed values will force the Web Form to always render with the corresponding layout. This is useful when the container has a static size that doesn't change as the page is resized.

With this configuration, the Web Form should render with the appropriate layout.

Finally, we should mention container queries. Container queries are a relatively new browser API that functions like media queries, but they are based on the container size instead of the page size. This is exactly what we're aiming to achieve with the method described above, and they will significantly simplify Web Form usage. Container queries are already on our roadmap as part of our ongoing efforts to upgrade the Web Form framework.

---
language: "en"
---
# White labeling

## Overview

In case you are interested in customizing the Web Form based on your branding, this section will assist you in making it happen.

We are pleased to offer a dedicated API to customers for styling the Web Form as per the branding needs and the business case.

* Remember to use the Admin Client credentials to manage the profiles service.

* Use the endpoint to create a `profile` with a profile ID.

* A profile is a style template that will be applied to the Web Forms generated for your end-users.

  * You can set up a default profile. Unless otherwise overridden, this profile will be applied to all your Web Forms.

  * Create multiple profiles, if needed. You can apply a specific `profileId` explicitly on each API call. This will override any default profile if any exists.

* White labeling is now available to customers who plan to use either standalone Web Forms or embedded Web Forms.

## Usage

Think about your branding before triggering the endpoint.

* Which color in the large palette represents your brand?

* Which colors should the text appear in? There are 2 possible placeholders for 2 colors!

  It is important to think about these prior to triggering the endpoint.

### Defaults

By default, the finAPI profile will be applied. The below snippet shows the values finAPI will apply in case no profile is defined.

In case you do not define all values (incomplete values), when rendering the Web Form, your profile will be merged with the finAPI default values to generate a complete profile.
JSON

    {
      "label": "Mobile application label",
      "default": true,
      "brand": {
        "logo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAH4SURBVDhPjZNNSxtRFIazcFHBZuMmUFCqILh358Jl6bJ/QJNAm05UlGKwdNHqSgpdtQs33WltKXSh6E9wpfhBoe6sM5M4McFMEp3YmsS351yPDHXujD4wMOfMvQ/v/ZgY7kH9so1Gsy1VNHcK3T8t9K1YGPhm4+zySrrhRAorJOv9YmFh18X8dgX9JK7/jU4aKuRkPSzbqUoHeLdVwWOSntEWhKEV8oRHyybJXOn4vCUpp75o6ZcfELq0JJ7wfs9Pdps5Wn7fio1zTdKAcGTtGMOrBanCGfqRx5ONolQ+AeGx11QJP/2sSQcwTROO40gFfNivqoTli5Z0fLR7WPRaSCyZWDxs49QpIBaLqade+I2PBw21v6d0aDq0QqZMz+T6LyWaez2DWSONrmfTGN6kQ4u4jqFCJ28r2dPnr/CdDvuzDQyuuuiId1PqvIwKohValqVkb2ZzOKe6l+5e/1cbTXqfMjLqW6lUUmNvExCaR0dqQi6Xk871np40/D0bn5hQY4rFe5zyw3gcDzo7pQqHhYlEQiqfgLBMS+HB2WxWOkFS6bQaU6v5V+sG7R5WXFdNeJHJSMdndGxMffM8Tzr/oxUyJ5L0pWFIB0gmk9fJquG/ZaiQ4U1ngUHLT6ZS6t2l9FFEChm+HizipxqR7IY7hQyn0h1AEOAfAearr/m9PjoAAAAASUVORK5CYII=",
        "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAH4SURBVDhPjZNNSxtRFIazcFHBZuMmUFCqILh358Jl6bJ/QJNAm05UlGKwdNHqSgpdtQs33WltKXSh6E9wpfhBoe6sM5M4McFMEp3YmsS351yPDHXujD4wMOfMvQ/v/ZgY7kH9so1Gsy1VNHcK3T8t9K1YGPhm4+zySrrhRAorJOv9YmFh18X8dgX9JK7/jU4aKuRkPSzbqUoHeLdVwWOSntEWhKEV8oRHyybJXOn4vCUpp75o6ZcfELq0JJ7wfs9Pdps5Wn7fio1zTdKAcGTtGMOrBanCGfqRx5ONolQ+AeGx11QJP/2sSQcwTROO40gFfNivqoTli5Z0fLR7WPRaSCyZWDxs49QpIBaLqade+I2PBw21v6d0aDq0QqZMz+T6LyWaez2DWSONrmfTGN6kQ4u4jqFCJ28r2dPnr/CdDvuzDQyuuuiId1PqvIwKohValqVkb2ZzOKe6l+5e/1cbTXqfMjLqW6lUUmNvExCaR0dqQi6Xk871np40/D0bn5hQY4rFe5zyw3gcDzo7pQqHhYlEQiqfgLBMS+HB2WxWOkFS6bQaU6v5V+sG7R5WXFdNeJHJSMdndGxMffM8Tzr/oxUyJ5L0pWFIB0gmk9fJquG/ZaiQ4U1ngUHLT6ZS6t2l9FFEChm+HizipxqR7IY7hQyn0h1AEOAfAearr/m9PjoAAAAASUVORK5CYII=",
        "icon": {
          "info": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjE4cHgiIGhlaWdodD0iMThweCIgdmlld0JveD0iMCAwIDE4IDE4IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgIDxnIGlkPSJpY29uSW5mbyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGwtcnVsZT0iZXZlbm9kZCI+DQogICAgICAgIDxnIGlkPSJEZXNrdG9wL1tQSVNdLVNpZGViYXItVmlldyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzMTcuMDAwMDAwLCAtNjIwLjAwMDAwMCkiIGZpbGwtcnVsZT0ibm9uemVybyI+DQogICAgICAgICAgICA8ZyBpZD0iaWNfaW5mb18iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEzMTcuMDAwMDAwLCA2MjAuMDAwMDAwKSI+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTksMC4zNDYxNTM4NDYgQzQuMjE4NzUsMC4zNDYxNTM4NDYgMC4zNDYxNTM4NDYsNC4yMTg3NSAwLjM0NjE1Mzg0Niw5IEMwLjM0NjE1Mzg0NiwxMy43ODEyNSA0LjIxODc1LDE3LjY1Mzg0NjIgOSwxNy42NTM4NDYyIEMxMy43ODEyNSwxNy42NTM4NDYyIDE3LjY1Mzg0NjIsMTMuNzgxMjUgMTcuNjUzODQ2Miw5IEMxNy42NTM4NDYyLDQuMjE4NzUgMTMuNzgxMjUsMC4zNDYxNTM4NDYgOSwwLjM0NjE1Mzg0NiBaIE05Ljg2NTM4NDYyLDEzLjMyNjkyMzEgTDguMTM0NjE1MzgsMTMuMzI2OTIzMSBMOC4xMzQ2MTUzOCw4LjEzNDYxNTM4IEw5Ljg2NTM4NDYyLDguMTM0NjE1MzggTDkuODY1Mzg0NjIsMTMuMzI2OTIzMSBaIE05Ljg2NTM4NDYyLDYuNDAzODQ2MTUgTDguMTM0NjE1MzgsNi40MDM4NDYxNSBMOC4xMzQ2MTUzOCw0LjY3MzA3NjkyIEw5Ljg2NTM4NDYyLDQuNjczMDc2OTIgTDkuODY1Mzg0NjIsNi40MDM4NDYxNSBaIiBpZD0iU2hhcGUiPjwvcGF0aD4NCiAgICAgICAgICAgIDwvZz4NCiAgICAgICAgPC9nPg0KICAgIDwvZz4NCjwvc3ZnPg0K",
          "loading": "data:image/gif;base64,R0lGODlhKAAeAPcAAAAAABY3QzqRsTqSsjuTtD2Vtj+VtUCVtEGWtUSYtkKYt0KZuUKavEWbu0eauEucuUueu0+fu0yevUiev0ifwUyhwUyiw02iw1GjwlOiwVGiwFSiv1WhvVeivVqivlikwFmlwl6mwWGnwWSowmKpw1ypx1eox1OnyE6lyFCmyVOoylapylury1+sylytzVutz1yu0V6w02Cw0WKx1GSy1WWy02ewzWevy2qvyWmtxmmsxGutxW2uxW+ux26vyG2xy3CxynGwyHOwyHWxyHezyXq0yn23zXm3z3W1znK1z2u002q21mq22Wy32W632G+523G523K63XS73Xe823m82Hq+3n6+2YK/2IS+1YS904G60H+5z4G6zoS70IW7z4a80Im80Iq+0Yu+0oi+04rA1IvB14zC147C14/A05DB05LD1pTE1ZjF1pnH15vH2J/J2Z/J2pzJ3JbJ3pLI3pHH3I3F24vE3IfD34XD3YLC33/B4X/B4oHC4oPD4YXE4obE44jG5IvH5Y3I45DI5I/J5pHK5pPL55XL55bM5pfM6JnN6JvN5JzP6p7Q557Q6qDR6qHR6qPS66TS7KTT6qbT56nT5aTR5qPP4aTO3qbO3qnP3avQ3q/S37LU4bTV4rbW4rnY47zZ5LrZ5bjZ5rXZ57LZ6qvW66jU7arV7azX7q7X7rDY7rHZ7rLZ7rTa77ba8Lfb7bjc8Lrd8Lve8b3f8r7f777e7bze7Lzc6r/d6L/b5sLd58Le6sXf6cfg6cng6svi6s/j7Mzk7cni7MTi78Lh7cHh8MHg8sLg8sTi88bi88fj8sjj88rk9Mzm9M7m9M7n9NDn9dHm79Pm7dXn7tfo79Xp8tPp9NLp9tTq9tbr9tjr9Njs9trs99vr8dzt9Nzt997u+N/v+ODu8+Lv9OHw9+Hw+eTx+Obx9eby+ejy+Ojz+un0+uv0+ez0+Oz1+u71+e72++/2+/H2+vH4/PL4+/T5+/X6/Pf6/Pj7/Pr8/fv9/v3+/v7+/v///+HA+yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAwD/ACwAAAAAKAAeAAAI9gD9CRxI0F+/gv0OHkS4sKDAhg8dSkwoEWHFiRAvRlQYsWLGjiAtahxJ0mBIjwMTqjxZ0iRHhiZHfmQZc6PImBBnZmxIUabBng5npkRJMKfHhUh1Dr1ZMF8nL6GWtpQa1N+4DQh4gKJZ9KFQhvlA4Gj3cqXXiVVxCiRlwV3Xo1KVEpxDZefOmiy/LsIT9KtGv8Si0MPJjyrIj0YH6isU6Z5Bfvf2GSa6NGM8VKeaaQtHryfSyX9/Ctxnrpu5ejxD+sX7Nm7rxK1dFn35NvHXzyT9pvb5WS5Qyjanoq0svHhX2mlFG4fpO+Vq2LKH08R90Wx10KwDAgAh+QQFAwD/ACwAAAAAKAAeAAAI/gD/CfzXbyDBf/4KDvTnD6FBgQwfGmw4UaFAixYj9rN48SJFiSAdHuQ4UCHFjCERkhQJUSJHjAZXdiRYUCbLmCs/MmzYsF/ClTZb8oRJ8WNNiR9H2kzacuLMmyedhox48KFJhFSt9tyYEulIlj5LZmSadeNGnV2PCvT0xQuwpi9fVgX7sCE5EAt88IDjkCvIokznLvSXr8UPd0131swK0m/RprhOwJMaEyLapnUVFlyEhyzZmzcLJuU4aRDShCVxWg06EJofeyJRYz4oOypEtUf3SWKFTyU/zYH/Yhw9kJ6sWdrSydtH9fHstA6p8mNn7l2+y0Z7pgweFqXguiW1TS90KhsrWNGYw4L+m/q7SL8X1accHlu+U5/B749337V90qLwfVVTUKyNd5JmNNWVX39zMRaTc+jZZJ94TA2X0YCVLXiWg/G1hN53TAUEACH5BAUDAP8ALAAAAAAoAB4AAAj+AP8J/OdvIMF//QoiNMiw4cB+DiEeHKhw4kKLFwUqlOjQYEV/CRFyTCgxYcWLHCkahJjSYUGFJz12hPlS5MyH/iqOfBjyYM6FEk+2ZPixX8+FNVe6JFjy4cWYTn9GnGi0IVSMRmMaHUpRqsyOPoniLNgSpNKcXnk2DKkQHhwhQt7MY8jxZ9WkTTcatIYhQ5ctDtJATOt0Kth/9lxcwVcwn76MFllaFSqwJKwa95RmhNqSK8x/kRBVHl25s2aNVg2yinTYJdnUYLkpqidycFWgTKmiVvkSZEF+sWhlrr17beqyFvM9c2aOnj7TkKMft4mwHr18/Fp/pisd5eitafVMqszd/fDgqxhbe6bu8aTXnlzhj48unytSoujNX60acmvK3twVh1tTT0nl234rQSfWgiWJJyCBus1n0UcH3XVWaZCdx11QerkX4EABAQAh+QQFAwD/ACwAAAAAKAAeAAAI/gD/CRxI8J+/gQcLDuynUGBCggwhFmQY8eFDhwUTRlz4rx9Fggn9afS3MSRCjA0R9ruYUiLKjgI3clQo8mPKgx5fWnwok6TGmAZnwpQocqjLk0NNmsSI0yjMlUAhMsQ5lWVUmSCtBqXZUiZWoF9jWuz48SJPoVuhbiWLz9MYMJ7yAS1KFunCkCU3hmtxAUkQBB3QOQV5s6XAfE6szGOoLoivizkN24Sq9p+xKPUans04WGpUVZOm6tQoGqZWhTlnuUK9FjLGqpHRdkulz+HYtWtXbrRJ+N++ZM/22SY58alVjweJC72nLVw9ffwWIi9tFy3TmPzu4eMXsftRimVxXCNMntwgXYm6Nb/m+nQ3R++7P35t+v58VOskqatV/lPs09biVXcfa0eJVxFKIiUYk1cHetQTUngNyJ+D1KEXoGEXmuYfca7lxxpWWDVV01LlqXRVUCxRZl1QGwUEACH5BAUDAP8ALAAAAAAoAB4AAAj+AP8J/NdvoMGDCAX6S0iwYEGFCwdGlPhv4kODEwketFixn7+FGQ9e/MgwYb+HF0uKTBlSoUuWGlNWnBlz4EmPLQ3KFPhw4UmfHCeGjFjQ30+eRHkeNelQZFKXQhEahahzI8GWJxmCbFjTZMaQRWmK5Kk0ok+yGBvmBFvRqLRMmaY59DnXrNORIwe+o4KiBIYCQuqJRXiT8OCm+/pUIScwWAQeGkEa9YjW4lCN/6DtiWewGo99eLtSxmyTJE1ZqyZnxdzz7GGbUhcmOyaVa22Jra0OBEeLX0eKGJsq9NjT5EB9zsxlvTmV4tbaPfMKrGcuHujRIEenXI0Udlp//PBn7YtKM+xwklNR2uS+fuzM54Z3XqRsmuRP7JW3fu3++/VM6SNdBhx7NMGnFFruFbeTWAuShlVGRZn2kkQSFpfQVM0V1ZSEZKH3n3HzkWXee6uRJ91H7G0lnU6u6ZbiS0S9KNZT/P0TEAAh+QQFAwD/ACwAAAAAKAAeAAAI/gD/9fv3zx9BgQcTChw4UKHDggYNHmyYsB/FihIrEhyYEeFBfxwfOuwo0iNDiAJJgvSosJ8/kgtZUpQ4s+THgggj2myJsyfBjB1hblS48iXLnz87XnSpMyHQmBdH4oy68yHJkzcLujSZtaTSoUh7vtyK1GVUpjGvdvX3jdQock2NCr05N6E9QTBWXFjQBd9SjEaJSjXIT1Gfbf325XpQROvEqT1PPs3KrVC8hL8GTAt6k+xPhg2jKpuVlCCRX2GzXpwc+uAzaA/RcpVKtaW5Zw1XOgx5NaPnzwT1gZNHNrDN2pOh5qOX7zfO5Km15o7dj5/F2pBlIjXo+aXvpK1XUWJ32tWnb6zGndbV7tEoRbPlo1fEPnb96ujTfT4WqfO9UO48gSXYfCnNFtNU54GUXnkzUdXUVlt9lZJ4LekmlVUWVYggfEe5N1FuM0m4U1QBAQAh+QQFAwD/ACwAAAAAKAAeAAAI/gD/+ftHkGC/gf0KFvQ30F9ChQ8VSlw4kWHBfg8H/sNIUSDEiR4lPoyoUGPEkQcJNiwJsiFJlQZjClwJc2PGiwJfbtxp0GFOnCBF2jwZVGdNmyFhIjR482hSoD1VuuQ5MWFKiRohZsWIcWtCmlF/aswaVKhKnWRrjgR7lKHRoOZs5UpXdSTVu2YV3nvEZMYJCmTykR2806jdiPxSGeLWb18uCUY4LvTpdmPDtDIFmosUT+EwAnkXWvW4EvM/bMtiDuTgpmxXvKq/GuzWbSKYTRHHUs099KPAd+GymvZZkerwhPve4dNtGeldk2GLE9ynj59s3y2dzywM1O1B6ExrWDpkC5PjS+jMyYO8jn1t+fVFWVqemtHq+NDwLZZdul54UNNYlXURgBURt91TzWl1X04k8RfSV1M5dRJhmQ0ooG4pQZfhXVdBdWBVpKXUIVPC+fcTiPEBFRAAIfkEBQMA/wAsAAAAACgAHgAACP4A+/37J3CgQX8GEw7shzBhQ4UFFxosGPHgQ4EI+2mEOBDhxYoFG2ZUeLDkP38PJ1YkaZJlS4EwNWJsGFMkRI8lbXZkyZCgv54of7YkiJHgwpUMU5IUmRKmy5AOWf5UanQn0qVOgypE6TIl1ZVGV448Sdbl1qIkkV6syjIdsWLqltocu9YoV4X5WO2BIgOFGXw8o1ItO3UiLUnh/u3jhWGL1qg7lYqduO4VvbDCChDtiDEizrMnNxIMh42zwA5tEk4mO5lix3Tp2P4bkeYpZLt3dw60B48kj1Cqm1qUyBZqv3z7lnbUWbVnYLuhNQ4ePDF3zpc9Q25EuZrj8rLKiU8TBRte/G3wI39KV7lwbeecMKc6D+xat/mJurvLJi81bf/2/nn23EGr0XSSdbkJaFJr4KnW4HpoOQgZVF4peN5/bDHXnlBPoeVUg/BxlVFAACH5BAUDAP8ALAAAAAAoAB4AAAj+AP39+yew38CBBg0ePOhPYT+FBxMSRDhxoMCJDx8utGjQn8eI//oVDElx5MOLG1FqDLly48KODRFqhOiSJkaWEy96jEmy4UeXFkFSpGjToUqeQUUO/VnxZseIECVGJZmT6NCaNkOijChw5NabC7uGBSr0ZdamDCu2REqWqMKvVE2iTfoyJDtnzNptdJjS5ci6CfXRMtTnCYw5+mpulQr05NBmrswZLLYCS9G2Y8n6i7fsHsNhDKoxbXjWLMGTOtmZyynwA5ySmC9K/Si73jybI9bA7ViaKtB9+TbKQ/ApLs6mEHWmJdmPH81qIuxRbZn86vKtYq9KHNrbt+agFlFZkt7bt7H3zARVXvZL9in79NhjykYOV2z26cvBe5cLPqPKsjVhZtVxsQHV1XbvwVYXet5Vh1ZGSlml3koxJScffm25t+BpBJomVFQfOZRVQbvR9RRTAM7lT0AAIfkEBQMA/wAsAAAAACgAHgAACP4A+/0b2M9fwYH+/iUcyLCfQIYEHyZcCLHiP4EF/WnE+NCiQYUdJwpcqFFhwo4VR5IsafEiQo8lKUYc2XKiTIUEGX48GbHlRYoLD8o8CBKhwZs4EaJsWHRiRZZJiepcivMkRZRIcTrMKTOoR5c+U37FqBNsS6omIfJcGjIsQZ5VydJM+1bhu2zQ4l2U+BIiW6Nqq+ZTJimRniaW9j3k+/WqS6gJ+WFbFs/fvmIv5Nz8aNat34H0uukjiosCupQag1ItmdFvPXp++VXw9JJs0oY0nbocqU8f1H8bMtXMynVxSn4VyRHwhRpuX59Yt+7d0WFfUpatA1M1/rzfF29qMWOSfB7+LPTPRcF23P5StUWyK/1+NC69a07c7x0yfi6Sqef4jLX1VHo6/RaUVWAd5R9q1/1230wPkrfeWGYNJV9g6EmkW25PpTbVZmXd5phUTNnnIGCMAQUTSvs1BBRx6xEHVkAAIfkEBQMA/wAsAAAAACgAHgAACP4A/f0b6K+fwIH9BipU6E9gwob/IC5ceHCiwIMPI2KsSJAgx4gTLS5M2PEfSYUnTZZEGbJlw4ItVbYkKREkwYcVU8JkmVPlR4Q2J/YbuhKhwaIjSRI1yPEgRpk+bT4NypNhTKpAs7KcmRKk05JdR6oM+zDhybA1RQr1Knbs0X/82HHjZk+jVp46x16998zVKUJ7YEksqNTk27xX94Xjdu+fvls0SoU8+VOs2ZL42r39V2kFPrUI02bduVCfPpn+3lEQRhEr0YZhIx7tx68rPga9rmK1O9ks0YW+CqADGTs21NlOYfpT12FIZYOXKZIu2dPkAw/wqG++StNlUGqfm1eGvFiR9G+j3c92/B39InGnKQuTTouz8tqg9u++Hj1ZrEP2W1G3UlNo6YaadFbJlNFsAYp0XkyFjbfeUBtB1ZZaxnVFmVbdZRWdgSBWl2BbleWUEVJqBQQAIfkEBQMA/wAsAAAAACgAHgAACP4A/wkc+K+fQH8EDSrs5w+hwYQPExacKDAiQ4n//PV7aLFgRIoDOVYciDBhyYcODxIk2HAkyJcrKWqMSZNmSpIKVZIMyfAiyJIlQ7K8GdFhx4ooUQp1ydJnRow6P+o8WXOl0qAsrQJdCrXqVoRYCwLF2lJqTqtcbapsOTGeOHP5VlI1uNUl2JgP83VLFutRImY0N860KjJsRX7v1ukTaCwKMaRigx7dqTLiPnxYKS3ZV/WpVLl4+a0sl+IbTKFsM35UCLRnxHYUqk3+XNMn2NQFRzWYh3PmRcOVnwpX+m9chC9QT1LdKZKpwzAIRtSTODcw8MBeNi3Ge9drTrYMw1MGbYjyq9CzqlGLJQyaONSeTDsPDh9y8ET38DOyHSy5ttnrp+mEkX2ejbeWcFkdZJ9T+h20UVe/UUZggCNdR+CFBqqXlHwv0UYSgGh5GFWHHT0UEAAh+QQFAwD/ACwAAAAAKAAeAAAI/gD79ftH0N8/gwQTJkSIMOHAhQofRixIsF9DihgPQvTn76HFigMZCryo0KHGgR//eVQpUCBEjRVLdlTYkGTGkiVTVjRoUybPnThVOqw5ceZIjgslIvx4kahElSSfBrUptSfLh0tf4sR682LImDCFTlzp0ipNmRafMtXo1ajagv3qrVu37+1BnVJRBoW5j502Zq1OZZP4ledSi0j3Js1Xbx9BZYCgcQUbtufShv3qKjRVhV9OnFm/xlQqtGG5GOXCig3rkvVPlIaFqkuxzaBomIRl3lUN1t8oC/bOZjWZ0ytFj+MylBnqU6pYhkkdauKiIEfwyWerfg6qb8SOTau1W4YXWjgq2Ly2WzsMyXQm7o63Fw6HujVjR+iKld4urHfv/f5YaadeQSSZV994ZxEHUW4Thaeee+Zh1dRzvImHkXaK8YaZc6XtNNN8oFGYYX7H/aTge7sRuNFAAQEAIfkEBQMA/wAsAAAAACgAHgAACP4A/wnsN/AfwX4H//kzKLChwocCFzJ8uLCiRIIFMTokKNGhQ4kLOYbE6M8fQo8NK3rsmFKhRZQfWXpM2PDkxokHNUI8KbMgzI81dbaEWTLmTKAQJ5rESBKpUoY9GTJ9KPSoy5UGEdIcenNiSqY9TRasyPGq1Ig/sUYVqtUkSI0X/eWLF29fx34dWYaMSDYtQnzquCWTFW5vUb1oP+qc+o+fPn7/9kVjxE0lRZtd2bI8qTEWIchOfeJNWnbzRYHnopwb2BRlUaw6ZS5sF+Nb2sSkfyakiWuFPa9QEWtNTNJmR3Im6gxdLDaqT4/60rjp0gDH76hxaxI9KzAfEQ87Nlvt/Cl2pUaaIA9j5bueKm60Jc+HbX2bftWspPdqh39XrcLzafV0320goTVgSqd9ZeBQp8W3XGz/YbafVVuRd+B+FxYlVHl4lTWQTLslddtGEHL1nFej4XRiTQEBACH5BAUDAP8ALAAAAAAoAB4AAAj+AP35+zeQ4L+DAg3+6zew4MGHEBFGnKgwocOHDvst1EgRIUeCGRNG1Phx4UWGHUceLNnvo0N/KDGulFmwIcyJCT+2XLiR58OdKzXmVNizo1CVDGNSfHnzJsuVF2/OpIkzJUGUJCPaJOpTa0upJGsC7XoUI0mXV61ObAkUplKEFj1K9dlvH756+yBeVJsVaEmB/O6t09bsnMSfU9MG5SpzIb+W/MCpEld05l6DSa3G1Zgs0tSShy9fPgyRnZ91PJ2qHVkTMcR3TygTBb1Ur1a4B23RuMdx7NjGt4UOrGuSnAs5WU2iLcjxZNR++hIAadNlQhJ8Kl1nHX2Y464iIYRdeMpb1nXiuRKHK0zOt6vPvW8ZJ6bNs7x85mvfkxZ5Pv7UhsD99xtZVal12U7sQWTfST+phx5IP7EFoIKKQZWeeQ/SlViAKWVEGmbN4dQcfavNlOBtTaWG0YTwCRQQACH5BAUDAP8ALAAAAAAoAB4AAAj+AP8JHCjQH8GBBgf2I7hw4T+HCh9CPEhR4MSDFw/6a/gQIcR+DhMSFFmwY8d+JEv+I+lvI8aVChcadFlRosGLF1uubDlzpEidCDUytKgyYk+RIEtyDAozocyCOZmalFqxYdKSTkNSBJkS4UyuML0yBUq0qVOPFh1OvMrzJ8mMHXti3bgP38uhJ3/uDEtTIT9867qliwm1bNi9NQtu5MnumLinWqeOXAnxrUqD2FTx44s38dWaKAXGS8Ru50fChjtb3MgxXh9zFLtu7dzXZC0p+fiGhpnzbFyCaD7B3FbDktyviSX7XulmAAkySCxc0acW5dK9smMPnCYGSBZeOFdXx+0qm+VhySaPn58sUXth3hNro8d4U2x21UGTso2d0e3v5BEBOJVOyPF2nlWpuZSQb2rtRGBslsn21H+67XbTbnDhBReGZF2HWHYZYhWZZwoxuFVlAgUEACH5BAUDAP8ALAAAAAAoAB4AAAj+AP8JHNiP4MCDA/0dVKjwX0OE/h4K7FcQ4b+C/gpWZBjRIsF+DB16dChRIcWRIhMerDjRY8aTIFkKzHgxZcuEDSWCFCnTYk+EP1FSNGnQ4UmLEVlKXCmTKEaPGmu+hHkx6kKSHZEuXbj15kyaQI9OrEhxJ0qVJIeK7Tqy4dqxYgnu23e1ZkyjYJuOXZqRH7516/hdzIr3YVykiC/iiyYuK9iQLCMXlaqx7D9zs+iOrWvXYFKUbu9JYneVsOmVJFdyNErv0Dqgk6nanO0PWJqQ/2oB0ifVqNG7cGcKbxmMgJp8F4k1gdUZLcThEFmCUgABSAsVjfjRNG32rE+T7jZjqbn0jaFl6DU5Q/W6njDssyDZJtzoG6fP9C23P70ZFONTsqnVF9ZHsO3H02xXWcWeTurBtlp8+Lk0XFc9aZRTenpNNJWCnznXnWT7XaiSgcIRhV9kZIGVWIAn3rTUf/JVJVBAACH5BAUDAP8ALAAAAAAoAB4AAAj+AP/96yfwn7+CBwsqXMiw4UGCCxMWhPjwoMSJBCFCNDhxYb+LAyM27DhS4keFGy1yvOjvZMKUGzumFEgQZEiGMQXanMiyJcec/kzS1InyJUKbFmPOTGowqMSgJENuzCg16s2cVhFqrAk1I9SVWR8OZfhVKNWbZJFe9PqR30iwcIXqNKp13716NWlS7BgU61uF/vaZW8cX5cmBT32KTWjRab93zfQdRStSZz+NKA37y/cqHsKxmUHTrYnmF2B6kt5V5oj4JearAoXocEvTGKN9ZKcu/hr6YDUDX+r941erCjO4Hin/9dmvl4QJNmDQcJWX7F/Qnw3aE3WJFLuQTkFdqsz82nrVj35lMi+ZfvV4vUsNUmVM1ONJpfRr5nQZ1Wl9wPKRRFdYAA41X1gzlVfYdXqhNWCA2WEE2Ef+GXXYZxde+N5ZEv6V132sUUgUSOlRtNdPADLnk4OLCRQQACH5BAUDAP8ALAAAAAAoAB4AAAj+AP/98yfwX7+CCA0mTHhQ4UKB/vo1bEhQYL+KEC1apEiwIkGJCDFm1Dhw4UeHJkGShNhwJMuNLUuGnJkwosiDFQ+qfHiRpE6HLUV6tCiyoM6IMjX+HBgTJc2MTZMWRJrxZMepJDFi7Ck15FaiEG9eDcqTIVOF/r7OHFs0qtGwVZkuBftw5VmEFycy3afP4NGPc3G+rfuQn7x6WIGmbdmUatGa9cDtI0xTIk6bVP/xC+INrj5miCmP5KpxKL8DnfTWi0WvLFaONRMKyRGU2Sp+ObGmbRt1azUFY+b922eMULaVeq9SDnrRF4YLSpZIQXazq97YhO/xqmQrntu3vWVdFv161eZCtzav+0Uas+lOk2kHs2SP169DpFvZC+6pFS9pp/SFBNJ4b/XHEEUlEZiVQoIlmFh938XnU0n/NQbXRJmtVZdQ9ZlUYG5AWVjfSYSp5SFIA/7HlHldSRUQACH5BAUDAP8ALAAAAAAoAB4AAAj+AP8JHOhvoMF/BfsJVGjQn8KCB/8xRCjQ4UGIESH6wxgRYUGIEzMaZDjxY8eKCSkqfHiyIkqOIWNKFDmwH8ePGhlaBJnTJMWOIVVyRKgzo82NBGsSbTnz50GZQ5u2RHoyKtCkKoPabPhUosaGKZ0WVXqRrNWaQZs63Lqwab+0ILtu/Ur0qE+PRO9WnJg2pj59U13ilTpUYRFfB/O94zdSZVuwY1PuIxBq5L5u+d4yLTnS4kEEnnb+u9fs3syVTpPeJCxRiI+D2I65xAgXpdSL1RqYqSewWaRwgpeGbQu1ZsFhJlZMqRIIGtOZwyP2/YevWKlk9DaSfGxyJd/t0mFXGm/4lu3s4Eijen4YHTXxoSY9U0yfvixOrO7BliWfciVVpWkx9Z9Mz/mE2nZxBVjbWjwtpNdtQol1knuaAWWRZtGpBd9HQdGVWlcOGhcSfcFxZZVW/wQEACH5BAUDAP8ALAAAAAAoAB4AAAj+APv9G0iw4D+BBvv5G9gPIUOHDf8tLCjQX0OBDg8aZEgx40aJBDNCVDhw4seTIEuCjLjR40aTKUuSfChyoUuMMW02hGkzoUaCEz2OlNiTpcqfGSfCfIkyptODCJeGDNoyosufIbESTdoUpFSuXQ9KLWiRolaiZnn+9Mf26NmZZReWPRsUosG5TN0K1BWGLD+XeDlORblQhBbB+/JdlMmY502E/fgZAOX33b62hC9CTrm5nwNPnPeBUyx3ps+QDk1WPPKDH8dw0QQDDTt2oLcLdQbyy+bqnNGEah2THShMBg0/gRxlw9qTbtXAKZnJckZPJVzZcr8urciSpNysCjFNq0atEXJgpS1Vzv0uMmx7oQ8/1v54dXje2Wbj3yULmLBXtxKF5xRVd5VlWm3NRXUSTrOht5lG32HG2Xf7MQgTg1UxB1RqYZ2VIX7/BQQAIfkEBQMA/wAsAAAAACgAHgAACP4A/f37168fwYID/wlM6K9fQ4P+BBpUuJBiwosLIzYcOPEixoQOK3a8iFAhR5MDK5LkaLClypUdVU502HFkwZEeUaaMeDJjToEvCVo8mVIoRJ0fGVbkybDoyow4b+bEmXPqT6AgR25UiBNoS5ApJwbtWbWs2aovRTr1OBPlUYlFv7ol6FMoyLpik4ZVyAnYR55HtVIl+hHYAFA1o9pEOjarkCB7+/HT2JQuWq5CmSqMsMmjP3z8CL8MyXTpxob+QGCKye/dPowIBWdeWPOhGRuvTbILF1pi26pUqaJbUUdeQXPJ0jHNi7ms3JzbokQ59EhVN4dEMy4ti7plR33QklNl82x37WWTJbGb1YqUPF2sDNWzhZ32p96zf7nXB56VuVP45Q02U0nmmbXVfAgSNViCC2InU03uPWQUeY0xpxZ/Cbo3FYB2vZVYgY01RWB5mpkVEAAh+QQFAwD/ACwAAAAAKAAeAAAI/gD/9fvnzx/Bgv8SKlRoEKHAgwMXSiQ4sV8/hAYvRpQY0eBCjxJBMnz4UGTCjBgJDtw4MmTCiycpshzokOTEmwtX4txpsifFnQ912rxp8qfFnwxrlsS5UWjGiiFZFv14cKpNfzCXvmw6E6hAjyxzih0aMyzYmCNFqrP38irVnFPNJtR1AI5XpGjlzuxHDkGYfSUzdjz7tC3HjQXXfNhnsWFThWG5fs06EsiZifw6RjxqkbJXmEfMiPSHj19Ix20bGn7a0F8lF/U25nv3NutmnmHtObnzDms8be1qt4T80mPhh+n+9InEaha4zJO33saJFeTZfd2caZNHHOljzi0vURYtrHms+ZGIoZIdftew2NtWUzNdL5OiyO8uaXZsaRzx0fnk5fTfaCf9hxdNSc13lXXdJaURg/TFBNJg1LkXn1FHTYUVTGEd1J56SgV1U4cBAQAh+QQBAwD/ACwAAAAAKAAeAAAI/gD/+evX71/BfwgTEkzIsKA/hgYbQpzo7yHDhxYPIrQ4saDGhBwvKoSoMeTGkRBNnqQocmXGiDAnChTYbyDChSQ9ytwp8yPNlRJ77lSJEqhMkw89vtx4sObMozmPHqwY8SPSpAJVasRJEmvDkBZt+qQ61qDPiera/HrKc2RGq1GBJYigq2pEolu9Dv0H78GWfD9BKsRotuVFmwkzacAHVrBBpGapPk6JEAsWiXCzZuW4NahFO1duJuTn1PNkt6Jf9rtFIx7HffmaOn4atmjMf/r6CHpX8166e0FJQi0pOB6jRKuQOUtHk/BGm5y7AnXaz5w2cfRmC8foXOTUw5qLTRLdy5L2adHouUId7Pxt252lhSIuzPZ81drwZ86vKNu7edrjOaaTgGfBxF99wRE1XnzBpXZWgZLdNlSEZ4WVVEjqFcgSTlM5J9t8CAUEADs="
        },
        "introText": "Welcome to finAPI Web Form. Please follow the on-page instructions."
      },
      "functionality": {
        "bankBanner": "RENDER",
        "progressBar": "RENDER",
        "bankLoginHint": "EXPANDED",
        "termsAndConditionsText": "BASIC",
        "storeSecrets": "RENDER",
        "storeSecretsSap": "IMPLICIT_APPROVAL",
        "bankDetails": "LOCKED",
        "header": "RENDER",
        "language": {
          "selector": "RENDER",
          "locked": "DE"
        },
        "tuvLogo": "RENDER",
        "skipConfirmationView": true,
        "accountSelectionConfiguration": {
          "mode": "NONE",
          "preselected": true
        },
        "hidePaymentSummary": true,
        "hidePaymentOverview": true
      },
      "aspect": {
        "colorScheme": {
          "brand": "#00ADDF",
          "secondary": "#00ADDF",
          "text": {
            "primary": "#232323",
            "secondary": "#848484"
          }
        },
        "text": {
          "fontFamily": "Calibri,Roboto,\"Segoe UI\",\"Helvetica Neue\""
        },
        "theme": "DEFAULT"
      }
    }

The default Web Form styling is as below. It is the finAPI profile.  
![image-20240705-134442.png](https://documentation.finapi.io/__attachments/a_2266dafc4c6b5e06d5299f39e150dabf0adad99b637e9f65488d63423750e4fe/image-20240705-134442.png?cb=3acd9596988ef84718698ca435be4f5a)
Default web form

### Parameters

Many of the API parameters can be customized. Some of them are highlighted below.

**Legend**:

* Text in **RED** - Description of what can be customized

* Text in **BLACK** - The API parameter to use for your integration

![finapi_white_labeling.png](https://documentation.finapi.io/__attachments/a_2f3e8dbb2821755e86b5278816a432ae14408127eb33586bd6569a39c34f5da7/finapi_white_labeling.png?cb=aeaa15854ae8814f9483b390472971f7)
Web form "Payment with account ID"

![image-20240705-164442.png](https://documentation.finapi.io/__attachments/a_05780475d74cf61910365cfd9b6c15848ed18d5849c5eeb3688a4b149d33ba35/image-20240705-164442.png?cb=ae95a3d325cb2a6e36370a9168f44cc0)
Web form "Import a bank connection"

## Special cases

### Account selection view

Profile section: `functionality.accountSelectionConfiguration`

You can provide your end users with an option to explicitly choose which account must remain in the imported bank connection. In that case, the web form will include an additional view at the end of every iteration where the end user can see all accounts that have been added during the iteration.

#### Case 1 - Allow selection of multiple accounts

JSON

    "accountSelectionConfiguration": {
      "mode": "MULTIPLE",
      "preselected": true
    }

![image-20240705-150026.png](https://documentation.finapi.io/__attachments/a_00870bd182e60d284a339c92c5f65ecc189085bb776f14f7d1fc4e59f717b9eb/image-20240705-150026.png?cb=75312b8eeb434e66524de5d9c22c1de0)
"Account selection" view

#### Case 2 - Allow selection of only one account

JSON

    "accountSelectionConfiguration": {
      "mode": "SINGLE",
      "preselected": false
    }

![image-20250603-123115.png](https://documentation.finapi.io/__attachments/a_434f95a285688e92d02b1ebb870d42e58dc0d246a73e5f0db365d2c3108f7ae7/image-20250603-123115.png?cb=4aa68ccf8bddac8219fcd236fd71c287)

### Skip confirmation view

Profile section: `functionality.skipConfirmationView`

Even though by default the web form will provide the end user at the end of the import or update flow with an overview page where all imported/updates accounts are listed, you might want to implement it differently, in your application or website. In such cases, it might be useful to use the "Skip confirmation view" option that will disable the default confirmation view. Instead, the end user will be directly returned to your application or website. In order to provide the best user experience, we urge you to also use the functionality of ["redirect URLs"](https://documentation.finapi.io/webform/for-best-results.md#Enhance-end-user-experience!) (for standalone web form integration) or ["frontend callbacks"](https://documentation.finapi.io/webform/embedded-web-form-2-0.md#Frontend-callbacks) (for embedded web form integration).  
![image-20240709-162039.png](https://documentation.finapi.io/__attachments/a_1dc5ee81c1c166e94410e2c2cc90c1e322477c26b5ed9311f8a690e4928cd804/image-20240709-162039.png?cb=265f915d2b44214d57f405d016a711df)
"Confirmation" view

In case you would like to use one of the options **below** , please create a profile with all the parameters you are looking to customize. You can also configure these special parameters with the values allowed in the documentation. Then contact our support ([support@finapi.io](mailto:support@finapi.io)) with the profile ID, explain your use case, and we will update the profile accordingly.

### Hide Payment Summary

Profile section: `functionality.hidePaymentSummary`

This white labeling option is meant for specific customers whose business cases involve initiating money transfers on behalf of other businesses or individuals. For example, payroll processing customers. Using this option, customers can initiate payments, with the web form intentionally omitting the counterparty data in the payment summary. Thus, the end-user initiating the payment will not be able to see sensitive information like someone else's salary on the Web Form.  
This feature does not work with the new Verification of Payee (VoP) flow, as VoP requires the disclosure of at least some payment counterparty information.

### Implicit Approval

Profile section: `functionality.storeSecrets`

Think well over your use case before using the setting `storeSecrets = IMPLICIT_APPROVAL`. Consult with our support team in case you want more details. `IMPLICIT_APPROVAL` implies that the end user will not see the checkboxes for "Save PIN" and "Save TAN Procedure" on the web form. But we will store provided credentials and preferred TAN procedure anyway. In order to keep it clear and fully transparent to the end users, the Terms and Conditions text on the web form when this parameter is used will be a special (and explanatory) one.  
This white labeling option is useful and relevant only to use cases that need access to accounts ++**once**++ (for ex., import accounts and immediately followed by payment initiation once). It optimizes the workflow for such use cases. But this option is not relevant for use cases like the full AIS service. In the case of customers using the full AIS service, this API parameter leads to a bad user experience for end-users.

### "Terms and Conditions" text

Profile section: `functionality.termsAndConditionsText`

In case there is a need for more explicit "Terms and Conditions" text - where it's explicitly mentioned that both "Account Information Services" and "Payment Initiation Services" will be used within the connection via finAPI - you can find useful this profile configuration option.

### Accessibility Act

Please be aware that only the default colors of the Web Form guarantee compliance with the contrast requirements of the Accessibility Act. You are responsible for ensuring that your implementation meets these requirements.

---
language: "en"
---
# Payments Public Documentation Home

The purpose of this documentation is to provide a better understanding of the finAPI Payment services and support our customers with the integration. This serves as a companion to the Open API documentation.

## Welcome to finAPI Payments

finAPI Payments solution allows initiating payments directly from a bank account with instant confirmation of the payment initiation status.

## Supported Payment Options

We support the following payment options:

* **SEPA Credit Transfer**

* **SEPA Core Direct Debit**

* **SEPA B2B Direct Debit**

* **SEPA Instant Credit Transfer\***

* **SEPA Standing Order\***

* **Domestic Transfers (Czech Republic)**

* **Predefined SEPA Credit Transfer**

* **Predefined SEPA Instant Credit Transfer\***

* **Predefined SEPA Standing Order\***

**\*** This payment option is only available for a limited number of banks. Please contact our [++support@finapi.io++](mailto:support@finapi.io)to request more details.

Both single and bulk payment requests are supported. It is also possible to schedule a payment (i.e. provide an execution date in the future). Additionally, you can also create a Link or QR Code as a SEPA payment or standing order.

## API References

Documentation for Payments API is part of our Access API. They are interconnected and work together. For more information, please check [finAPI API Access Documentation](https://docs.finapi.io/#overview).

For more details on Predefined Payments (QR Code \& Link), please check LINK

For more details on the Webform, please check [finAPI API Web Form 2.0 Documentation](https://docs.finapi.io/?product=web_form_2.0).  
Not sure if you need a web form? Please check [our webform page](https://documentation.finapi.io/webform.md).

---
language: "en"
---
# Authorization and Creation of a User Identity

finAPI follows the OAuth 2.0 Standard for authorizing applications and users within them. OAuth uses the terminology of clients and users. A client represents an application that calls finAPI services. A service call might be in the context of a user of the client (e.g: getting a user's bank connections), or outside any user context (e.g.: editing your client's configuration, or creating a new user for your client). In any case, every service call must be authorized by an `access_token`. The documentation below describes how to set up clients users, or for the client itself.

## Step 1: Get authorized as a client in Access

The prerequisite for getting authorized as a client (i.e application) is having a valid set of client credentials: `client_id` and `client_secret`.

To get authorized as a client, make a call to Access [**POST /oauth/token**](https://docs.finapi.io/#post-/oauth/token) and pass the following request parameters:

* `grant_type=client_credentials`

* `client_id`

* `client_secret`

The client authorization request response:

    {
      "access_token": "fnsXpguIBkChhCsN8bVty9Y68AsUvJYyXUILcsFBvWABF03k8Ov68Ev2BTyANuBjyX8r9XuuTajNM2zZnhZMDjKWHN4lbRSRcVhg9_PcE7eeXHm0t28ZjzM4TJlrupZD",
      "token_type": "bearer",
      "expires_in": 3599,
      "scope": "all"
    }

If you are using [Open API UI](https://docs.finapi.io/), to get authorized **as a Client** , use the obtained `access_token` as input for ++**QUICK AUTH**++ **.**

## Step 2: Create an Access user

The major prerequisite for creating a user is getting authorized as a client with the help of the obtained `access_token` in **Step 1**.

To create a user, make a call to Access [**POST /users**](https://docs.finapi.io/#post-/api/v1/users) and pass the following request body:

    {
      "id": "username",
      "password": "password",
      "email": "email@localhost.de",
      "phone": "+49 99 999999-999",
      "isAutoUpdateEnabled": false
    }

The user creation request response:

    {
      "id": "username",
      "password": "password",
      "email": "email@localhost.de",
      "phone": "+49 99 999999-999",
      "isAutoUpdateEnabled": false
    }

## Step 3: Get authorized as a user

The major prerequisite for creating a user is getting the user's data, such as `password` and id (`username`) from **Step 2**.

To get authorized as a user, make a call to Access [**POST /oauth/token**](https://docs.finapi.io/#post-/oauth/token) and pass the following request parameters:

* `grant_type=password`

* `client_id`

* `client_secret`

* `username`

* `password`

The user authorization request response:

    {
      "access_token": "nnsXpguIBkChhCsN8bVty9Y68AsUvJYyXUILcsFBvWABF03k8Ov68Ev2BTyANuBjyX8r9XuuTajNM2zZnhZMDjKWHN4lbRSRcVhg9_PcE7eeXHm0t28ZjzM4TJlrupZD",
      "token_type": "bearer",
      "expires_in": 3599,
      "scope": "all"
    }

If you are using [Open API UI](https://docs.finapi.io/), to get authorized **as a User** , again use the obtained `access_token` as input for ++**QUICK AUTH**++ **.**  
At finAPI, we develop our own integrated high-level Open API UI that abstracts away paths and low-level technical details, as well as constantly enhancing its UI in order to make sure it is the simplest to use. Our customers just have to enter some values to authorize themselves, once done our API services will start working immediately.

However, in case you prefer to use some other lower-level external REST-tools, we would like to draw your attention to the CURL section in the Response of each Request (specifically, in the Response area of each Request, the CURL section is next to the Response Headers section to the right). There you can see the low-level Request that was generated by each specific API call. This "CURL" request is in general similar to how you should execute the same API call using Postman. Therefore, it can be a good reference when it comes to using external REST-tools.

---
language: "en"
---
# Czech Republic Domestic Transfers

The same payment endpoints can be used for initiating Czech Republic domestic transfers as SEPA transfers, except there are some differences in the transfer payload.

It is possible to initiate a CZ domestic transfer by providing only the following data:

* IBAN/accountId of the sender account;

* IBAN of the recipient account (CZ-based IBANs only);

* amount and currency (CZK)

**POST** `/api/webForms/paymentWithAccountId`

    {  
      "sender": {
        "accountId": 42
      },
      "orders": [
        {
          "amount": {
            "value": 100,
            "currency": "CZK"
          },
          "recipient": {
            "iban": "CZ6650514376917266931472"
          }
        }
      ]
    }

Additionally, it is possible to submit remittance information with the transfer. Both unstructured and structured remittance information is supported.

**Example with the (additional and optional) remittance information:**

**POST** `/api/webForms/paymentWithAccountId`

    {  
      "sender": {
        "accountId": 42
      },
      "orders": [
        {
          "amount": {
            "value": 100,
            "currency": "CZK"
          },
          "recipient": {
            "iban": "CZ6650514376917266931472"
          },
          "purpose": "Unstrustured remittance information goes here",
          "structuredRemittanceInformation": [
            "VS:501",
            "KS:9",
            "SS:1005"
          ]
        }
      ]
    }

`structuredRemittanceInformation`, when provided, should carry remittance information in a specific format with the variable symbol (VS), constant symbol (KS), and specific symbol (SS). All 3 are optional.  
Please note, that you can also submit VS, KS, and SS values in an unstructured way inside the `purpose` attribute, however, it may make it difficult for the recipient to automatically parse these values.

`endToEndId` and `counterpartName` will be disregarded and not submitted to the bank for the CZ domestic transfers as these attributes are not part of the payment schema.

---
language: "en"
---
# Czech Republic SEPA Transfers

Banks from the Czech Republic might consider SEPA transfers to an account in another country as a foreign or cross-border payment. As such, additional rules might apply to complete the transaction.

## Raiffeisen bank

In particular, Raiffeisen CZ requires the counterparty address to be provided, similar to how it works in their online banking portal or in-person transfers at a branch office. You can find more details in [this attachment.](https://www.rb.cz/attachments/platebni-styk/zps-EN.pdf)

For more information, please refer to [Raiffeisen Payment Services.](https://www.rb.cz/en/information-services/platebni-styk)

---
language: "en"
---
# Domestic Transfers

FinAPI is currently supporting the following countries for domestic transfers:

* [Czech Republic](https://documentation.finapi.io/payments/czech-republic-domestic-transfers.md)

---
language: "en"
---
# FAQ

---
language: "en"
---
# Getting Started

---
language: "en"
---
# How to Build Payments Dashboard with Web Form 2.0

If applicable to your use case, you could aggregate all initiated payments and build a dashboard for your application following the simple steps below.

For each user you created, authorize yourself as the user (sequentially) and get all the web forms they initiated. This call should be executed [**from Web Form 2.0**](https://docs.finapi.io/?product=web_form_2.0).

    GET /api/webForms

For each web form in the returned API object, gather all the payment ID(s). You could also gather web form statistics based on web form status and web form type.

Authorize yourself with the same user token [**in Access**](https://docs.finapi.io/?product=access) and find out the payment status [**from Access**](https://docs.finapi.io/?product=access)for each payment ID(s) from the above array. You can gather payment statistics based on the API object.

    GET /payments

---
language: "en"
---
# How to get the payment initiation status

To get the status of the payment initiation, please use the [**Get payments**](https://docs.finapi.io/?product=access#tag--Payments)service:

    GET /payments?ids=$paymentId

Please note that the `SUCCESSFUL` status indicates that the payment has been successfully **initiated**at the bank. The bank will then execute the payment according to their backend procedures \& timeframes.

For SEPA **Instant** Credit Transfers, the status `SUCCESSFUL` indicates that the payment has been settled successfully (i.e. settled on the debtor and the creditor account).

For SEPA Standing Orders, the status `SUCCESSFUL` means that the standing order has been successfully registered at the bank. The standing order will then be executed at the bank according to the requested schedule. Please note, that we could only provide the standing order initiation status. If later the user cancels the standing order at the bank, this will not change the initiation status at finAPI.

In some rare cases`, the payment status may remain PENDING upon finalizing the payment initiation`. This could happen in the following scenarios:

* There was an issue with retrieving the payment initiation status at the bank;

* Upon retrieving the payment initiation status at the bank, the bank returned the intermediary status: `RCVD` (Received) or `PDNG` (Pending). Based on this status, we cannot tell if the payment initiation was SUCCESSFUL or UNSUCCESSFUL;

* The user has abandoned the payment initiation process (either before or after authorizing the payment);

In these cases, we will attempt to retrieve the payment initiation status again at the bank. If an attempt is successful, we will update the status from `PENDING` to `SUCCESSFUL` or `UNSUCCESSFUL`.

---
language: "en"
---
# How to initiate a payment

## Different ways to initiate payments

To cater to different use cases we allow two ways to initiate payments:

### Initiate a payment from an account.

This option would appeal for the use cases when the payment function is to be used in combination with importing the bank account information (like balances and transactions). Once the account is imported from the bank, the payment can be initiated from the imported account.

**Note:** Initiation of the SEPA Direct Debits (B2B and Core) is only possible in this way.

For the detailed flows, please refer to the following pages:

[Initiate a Payment from an Account - with Web Form (Recommended Option)](https://documentation.finapi.io/payments/initiate-a-payment-from-an-account-with-web-form-r.md)

[Initiate a Payment from an Account - no Web Form (Licensed Customers Only)](https://documentation.finapi.io/payments/initiate-a-payment-from-an-account-no-web-form-lic.md)

### Initiate a standalone payment

This option is more practical for use cases when the main objective is to only initiate a payment and user bank data download is not required.

**Note:** at the moment, we do not offer an option to initiate direct debits with the standalone payment workflow. Please refer to the Initiate a payment from an account option if you are interested in SEPA Direct Debits.

For the detailed flows, please refer to the following pages:

[Initiate a Standalone Payment - with Web Form (Recommended Option)](https://documentation.finapi.io/payments/initiate-a-standalone-payment-with-web-form-recomm.md)

[Initiate a Standalone Payment- no Web Form (Licensed Customers Only)](https://documentation.finapi.io/payments/initiate-a-standalone-payment-no-web-form-licensed.md)

### Initiate a predefined standalone payment

This option is more practical when you want to offer a QR Code or Link that an end user can open with the main objective to only initiate a payment and user bank data download is not required.

**Note:**at the moment, we do not offer an option to initiate direct debits with the predefined standalone payment workflow. Please refer to the Initiate a payment from an account option if you are interested in SEPA Direct Debits.

For the detailed flows, please refer to the following pages:

[Initiate a Standalone Payment - with Web Form (Recommended Option)](https://documentation.finapi.io/payments/initiate-a-standalone-payment-with-web-form-recomm.md)

[Initiate a Standalone Payment- no Web Form (Licensed Customers Only)](https://documentation.finapi.io/payments/initiate-a-standalone-payment-no-web-form-licensed.md)

---
language: "en"
---
# Initiate a Payment from an Account - no Web Form (Licensed Customers Only)

To use your PSD2 license with the finAPI APIs, please refer to the necessary steps to register the certificate with us and complete the TPP registration of the banks to which you plan to connect.

For more information, please refer to [Licensed customers](https://documentation.finapi.io/access/licensed-customers.md)

## Pre-requisites

* [Access User Token has been created.](https://documentation.finapi.io/payments/authorization-and-creation-of-a-user-identity.md)

* [An account has been imported.](https://documentation.finapi.io/access/import-a-new-bank-connection-no-web-form-licensed-.md)

## Step 1 - Create a payment

To initiate a Direct Debit, trigger [**Create direct debit**](https://docs.finapi.io/?product=access#tag--Payments) endpoint. Provide `accountId` of an imported account to indicate the sender account.

    POST /payments/directDebits

To initiate a SEPA Credit Transfer or SEPA Instant Credit Transfer, trigger[**Create money transfer**](https://docs.finapi.io/?product=access#tag--Payments) endpoint. Provide `accountId` of an imported account to indicate the sender account.

    POST /payments/moneyTransfers

There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).

## Step 2 - Submit payment

Execute [**Submit payment**](https://docs.finapi.io/?product=access#tag--Payments) service:

    POST /payments/submit

The payload and the flow varies based on the SCA approach offered by the bank (in the API: properties of the bank interface (`bank.interface.properties`).

Some banks have implemented the `Embedded SCA` approach, where the user credentials and the second factor can be submitted to the bank via the TPP.

Some banks will require a redirect to the bank server to complete the authentication and second-factor verification, this is the so-called `Redirect SCA`.

Some banks allow the authorisation with the `Decoupled SCA` approach, where users could authenticate and authorise a transaction via the mobile app or an authorisation device.  
The combination of different SCA approaches is also possible. For example Embedded + Decoupled: a user will provide the login credentials to a TPP and then a push notification will be sent to the mobile application.

Please make sure your application can dynamically handle all variations.

Please refer to the [API specification](https://docs.finapi.io/?product=access#post-/api/v1/payments/submit) for more details.  
It is mandatory to indicate the interface that should be used for the payment submission.

If you are not familiar with the interfaces which are supported by finAPI, please check [Interfaces](https://documentation.finapi.io/access/interfaces.md) .

Please see below the examples of the flows for each SCA approach: Redirect, Embedded and Decoupled.

### Redirect approach

|                                                                                                                                                                                                                                                                                                                         **Step**                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit payment** **Mandatory request fields** * `paymentID` * `interface` * `redirectUrl` * URL of the client's endpoint that handles a redirect from the bank * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the payment along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                    | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "redirectUrl": "https://customer1.io", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "idontexist" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Step #2** **Receive a redirect URL** **How to recognise the step** Field `errors.multiStepAuthentication.status` has `REDIRECT_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `redirectUrl` * `redirectContext` * `redirectContextField` **Explanation** The API builds a redirect URL that will route the end-user to a page on the bank side, where the user can complete the authentication process. In this step, the client's application should store values from `redirectContext` and `redirectContextField` fields internally, as they will be required on the subsequent steps. | HTTP/1.1 510 { "errors": [ { "message": null, "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "288c0a78c6596e8f02f70a21e731d46a", "status": "REDIRECT_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": "https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0", "redirectContext": "976641d2-c03f-4919-8dac-16ccfd24b4e0", "redirectContextField": "state", "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 11:20:21.261", "requestId": "selfgen-fece3d6c-a0f0-43ea-a910-7e9ca7a7b1f6", "endpoint": "POST /payments/moneyTransfers", "authContext": "1/18", "bank": "DEMO0002 - finAPI Test Redirect Bank" } |
| **Step #3** **Redirect to bank** The client application should redirect the end-user to the given redirectUrl. **Example** GET https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0 HTTP/1.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         ||
| **Step #4** **Redirect back** When the end-user successfully completes the authentication process on the bank's side, he is redirected to the URL given in step #1. Additionally, the bank adds some more data to the URL (as query parameters). But the most important part for the client application is this `state` parameter (generally speaking, the name of the parameter is provided in step #2 as a value of `redirectContextField` field): the client application can use its value to recognize the end-user that was redirected by the bank - the value should match the one given on a step #2 in `redirectContext` field. **Example** GET https://customer1.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70 HTTP/1.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ||
| **Step #5** **Submit payment** **Mandatory request fields** * all fields from the previous request * `hash` * `redirectCallback` * the whole query string received on a step #4 **Explanation** The client application submits a query string as a value of `redirectCallback` field. The API processes the given string, extracts required data and continues the authentication process.                                                                                                                                                                                                                                                                | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "redirectUrl": "https://customer1.io", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "idontexist" } ], "multiStepAuthentication": { "hash": "288c0a78c6596e8f02f70a21e731d46a", "redirectCallback": "state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70" } }                                                                                                                                                                                                                                                                                           |
| **Step #6** **Bank connection** The API completes the payment initiation process and returns a bank connection resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | HTTP/1.1 201 { "id": 46, "bankId": 280002, "name": null, "bankingUserId": null, "bankingCustomerId": null, "bankingPin": null, "type": "ONLINE", "updateStatus": "IN_PROGRESS", "categorizationStatus": "READY", ... }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |

### Embedded approach

|                                                                                                                                                                                                                                                                                                                                                                                                                               **Step**                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                                              **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit payment** **Mandatory request fields** * `paymentId` * `interface` * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the payment along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **Step #2** **Receive a list of two step procedures** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `TWO_STEP_PROCEDURE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `twoStepProcedures` **Explanation** If the bank decides, it responses with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And then the client application should ask the end-user to choose one of the offered two-step procedures.                                                                                                                                                                                                                                                                                   | HTTP/1.1 510 { "errors": [ { "message": "SCA method selection is required", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "status": "TWO_STEP_PROCEDURE_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": [ { "procedureId": "DEMO-TSP-01", "procedureName": "SMS", "procedureChallengeType": "TEXT", "implicitExecute": false }, { "procedureId": "DEMO-TSP-02", "procedureName": "PUSH", "procedureChallengeType": "TEXT", "implicitExecute": false } ], "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 08:13:32.155", "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399", "endpoint": "/payments/moneyTransfers", "authContext": "1/18", "bank": "DEMO0001- FinAPI Test Bank" } |
| **Step #3** **Submit payment** (an optional step) **Mandatory request fields** * all fields from the previous request * `multiStepAuthentication.hash` * the value should be taken from the response on step #2 * `twoStepProcedureId` * field `procedureId` of the chosen two-step procedure **Explanation** The client application asks the end-user to choose a two-step procedure and then submits it to the API. Value of `hash` field points to the original request.                                                                                                                                                                                                                                                                                                                                                                                          | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "twoStepProcedureId": "DEMO-TSP-01" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **Step #4** **Receive an MSA challenge message** **How to recognise the step** Field `errors.multiStepAuthentication.status` has `CHALLENGE_RESPONSE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * hash * status * the following fields are presented depending on the two-step procedure type: * for type = `TEXT`: * challengeMessage * for type = `PHOTO`: * photoTanMimeType * photoTanData * for type = `FLICKER_CODE`**\***: * opticalData **\*** Note: feel free to use the flicker code template prepared by finAPI: [Flicker Code Template](https://documentation.finapi.io/access/flicker-code-template.md) **Explanation** When the two-step procedure is chosen (either by the bank or by the end-user), the API responds with details for the end-user. The client application should show this info to the end-user and ask for an answer. | HTTP/1.1 510 { "errors": [ { "message": "An additional authentication is required. Please enter the following code: 123456", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "status": "CHALLENGE_RESPONSE_REQUIRED", "challengeMessage": "An additional authentication is required. Please enter the following code: 123456", "answerFieldLabel": "TAN", "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2021-10-11 16:20:12.744", "requestId": "selfgen-8b108042-6c2c-4724-b345-2bf983ab0659", "endpoint": "POST /payments/submit", "authContext": "2/1534168", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                        |
| **Step #5** **Submit Payment** **Mandatory request fields** * all fields from the previous request * `challengeResponse` * the answer from the end-user **Explanation** The client application asks for the challenge response and submits it back to the API. Value of `hash` field points to the original request.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "twoStepProcedureId": "DEMO-TSP-01", "challengeResponse": "123456" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| **Step #6** **Payment submission result** The API completes the payment initiation process and returns a payment resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | HTTP/1.1 200 { "id": 1, "accountId": 111111100, "type": "MONEY_TRANSFER", "amount": 99.99, "orderCount": 1, "status": "SUCCESSFUL", "bankMessage": "Success", "requestDate": "2021-10-11 16:18:53.000", "executionDate": "2021-10-11 16:28:17.000" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |

### Decoupled Approach

|                                                                                                                                                                                                                                                                                     **Step**                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit payment** **Mandatory request fields** * `paymentId` * `interface` * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the payment along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                                 | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Step #2** **Receive a list of two step procedures** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `TWO_STEP_PROCEDURE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `twoStepProcedures` **Explanation** If the bank decides, it responds with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And then the client application should ask the end-user to choose one of the offered two-step procedures. | HTTP/1.1 510 { "errors": [ { "message": "SCA method selection is required", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "TWO_STEP_PROCEDURE_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": [ { "procedureId": "DEMO-TSP-01", "procedureName": "SMS", "procedureChallengeType": "TEXT", "implicitExecute": false }, { "procedureId": "DEMO-TSP-02", "procedureName": "PUSH", "procedureChallengeType": "TEXT", "implicitExecute": false } ], "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 08:13:32.155", "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399", "endpoint": "POST /payments/moneyTransfers", "authContext": "1/18", "bank": "DEMO0001- FinAPI Test Bank" } |
| **Step #3** **Submit payment** (an optional step) **Mandatory request fields** * all fields from the previous request * `multiStepAuthentication.hash` * the value should be taken from the response on step #2 * `twoStepProcedureId` * field `procedureId` of the chosen two-step procedure **Explanation** The client application asks the end-user to choose a two-step procedure and then submits it to the API. Value of `hash` field points to the original request.                                                                                                       | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "twoStepProcedureId": "DEMO-TSP-02" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Step #4** **Receive an error message that the decoupled approach is required** **How to recognise the step** Field `errors.multiStepAuthentication.status` has `DECOUPLED_AUTH_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `challengeMessage` * if any message was provided by the bank **Explanation** If the chosen two-step procedure was of a decoupled type, the API responds with this error. The client application should notify the end-user that the bank will send a notification.                  | HTTP/1.1 510 { "errors": [ { "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "DECOUPLED_AUTH_REQUIRED", "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 10:35:17.682", "requestId": "selfgen-9f035aca-d094-42d7-9285-a3eae9d5a4a9", "endpoint": "POST /payments/moneyTransfers", "authContext": "1/18", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                                                                           |
| **Step #5** **Submit payment** **Mandatory request fields** * all fields from the previous request * `decoupledCallback` * this is a boolean field that signals to the API that the end-user is already informed about the decoupled authorization and might have already approved it. **Explanation** The client application asks the API to check the status of the authentication process. Value of `hash` field points to the original request.                                                                                                                               | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 277672, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "twoStepProcedureId": "DEMO-TSP-02", "decoupledCallback": true } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Step #6** **Receive an error message that the decoupled authentication is still in progress** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `DECOUPLED_AUTH_IN_PROGRESS` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` **Explanation** The API returns this error if the authentication is still not completed on the bank side. The client application should continue repeating step #5 while the API returns this error.                                             | HTTP/1.1 510 { "errors": [ { "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "DECOUPLED_AUTH_IN_PROGRESS", "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 10:42:54.468", "requestId": "selfgen-5801b1be-0e09-4d2a-99a2-a748d7ee6d7e", "endpoint": "POST /payments/moneyTransfers", "authContext": "1/18", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                                                                        |
| **Step #6** **Payment submission result** The API completes the payment initiation process and returns a payment resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                        | HTTP/1.1 200 { "id": 1, "accountId": 111111100, "type": "MONEY_TRANSFER", "amount": 99.99, "orderCount": 1, "status": "SUCCESSFUL", "bankMessage": "Success", "requestDate": "2021-10-11 16:18:53.000", "executionDate": "2021-10-11 16:28:17.000" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

## Step 3 - Get the Payment status (Optional)

If upon completion of the steps described in Step 2 above, the `status `of the payment initiation is still `PENDING`, there is a chance that the bank has not returned the final payment status yet or there was an error when trying to obtain the payment initiation status. Several attempts will be made in the background to obtain it (for more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md)).

You can call [**Get payments**](https://docs.finapi.io/?product=access#tag--Payments) to obtain the latest payment status.

---
language: "en"
---
# Initiate a Payment from an Account -  with Web Form (Recommended Option)

## Prerequisites

* [Access User Token has been created.](https://documentation.finapi.io/payments/authorization-and-creation-of-a-user-identity.md)

* [An account has been imported.](https://documentation.finapi.io/access/import-a-new-bank-connection-no-web-form-licensed-.md)

## Step 1 - Initiate a payment

To initiate a Direct Debit, use the following service ([API reference](https://docs.finapi.io/?product=web_form_2.0#post-/api/webForms/directDebitWithAccountId)):

    POST /api/webForms/directDebitWithAccountId

To initiate a SEPA Credit Transfer or SEPA Instant Credit Transfer, use the following service ([API reference](https://docs.finapi.io/?product=web_form_2.0#post-/api/webForms/paymentWithAccountId)):

    POST /api/webForms/paymentWithAccountId

There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md)

## Step 2 - User to log in at the bank and authorise the payment

As a result of Step 1, the web form is generated. You can find the URL of the web form in the response:

    url: "https://webform.finapi.io/wf/946db09e-5bfc-11eb-ae93-0242ac130002"

The webform has to be presented to the user to authorise the payment (login at the bank and enter a TAN/authorise the payment via the authorisation app or device).  
You have two options how to present the webform to the user:

* Embed the web form into your application. How to: [Embedded Web Form 2.0](https://documentation.finapi.io/webform/embedded-web-form-2-0.md)

* Redirect the user to the Web Form URL in the browser.

There are several branding and customization possibilities available for the web form. Please check out the web form documentation: [White labeling](https://documentation.finapi.io/webform/white-labeling.md)

## Step 3 - Check the status of the Web Form

To retrieve the status of the web form, you can either call the [**Get a web form service**](https://docs.finapi.io/?product=web_form_2.0#get-/api/webForms/-id-)or register to receive a callback once the web form is completed (callback URL must have been registered during Step 1).

Note that the `paymentId` is returned in the response (in the `payload` object) to get the status of the payment initiation in the next step.

More details are available here: [Web Form 2.0 Basics \| Want to know web form status?](https://documentation.finapi.io/webform/web-form-2-0-basics.md#Want-to-know-web-form-status?)

## Step 4 - Check the status of the payment initiation

To retrieve the status of the payment initiation, get the `paymentId` from Step 3 and execute [**Get payments**](https://docs.finapi.io/?product=access#tag--Payments):

    GET /payments?ids=$paymentId

For more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md).

---
language: "en"
---
# Initiate a Predefined Standalone Standing Order- with Web Form

## Pre-requisites

* Client Token with the scope predefinedpayment:manager as scope.

## Step 1 - Initiate standing order

To initiate a SEPA Standing Order through a payment link or QR Code use the [**Create a standing order request endpoint**](https://docs.finapi.io/#post-/payment/createStandingOrder).

    POST /payment/createStandingOrder

To create a predefined standing order you also need to provide your Client ID and Secret from your default client in the API.

If the IBAN and name of the sender account are already known, we recommend including them in the standing order initiation payload to avoid the possibility that several SCAs will be required.

If the IBAN or name of the sender account is not known, it is still possible to initiate a standing order without the sender info and the end user will have to select the Bank or IBAN on the Web Form (see the next step) and potentially provide their name manually.  
There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).

## Step 2 - The user has to log in at the bank and authorize the standing order

As a result of Step 1, a link and base64 code are generated. Activating either will trigger the generation of the corresponding web form. You can find the URL of the web form in the response:

    "link": "https://di-predefined-payment-finapi-general-staging.finapi.io:443/api/v1",
    "qrCode": "iVBORw0KGgoAAAANSUhEUgAAAPUAAAD1CAAAAACt2uy5AAAQuElEQVR4XtWPwZIlOXLE9v9"

The web form has to be presented to the user. If the sender's IBAN was not provided in Step 1, the user will have to either enter the IBAN into the web form or search for a bank first. Once the sender account is selected, the user will proceed to the standing order authorization.

## Step 3 - Check the status of the web form

To retrieve the status of the web form, you can either call the [**Get a web form service**](https://docs.finapi.io/?product=web_form_2.0#get-/api/webForms/-id-)or a callback can be sent of completion to a callback URL provided in the standing order initiation payload during Step 1.

Note the `standingOrderId` returned in the response (in the `payload` object) to get the status of the standing order initiation in the next step.

More details are available here: [Web Form 2.0 Basics \| Want to know web form status?](https://documentation.finapi.io/webform/web-form-2-0-basics.md#Want-to-know-web-form-status?)

## Step 4 - Check the status of the standing order initiation

To retrieve the status of the standing order initiation, get the `standingOrderId` from Step 3 and execute [**Get Standing Orders**](https://docs.finapi.io/?product=access#tag--Standing-Orders):

    GET /standingOrders?ids=$standingOrderId

For more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md).

---
language: "en"
---
# Initiate a Standalone Payment- no Web Form (Licensed Customers Only)

To be able to use your PSD2 license with the finAPI APIs, please refer to the necessary steps to register the certificate with us and complete the TPP registration of the banks to which you plan to connect.

For more information, please refer to [Licensed customers](https://documentation.finapi.io/access/licensed-customers.md)

## Pre-requisites

* [Access User Token has been created.](https://documentation.finapi.io/payments/authorization-and-creation-of-a-user-identity.md)

* [Bank has been selected](https://documentation.finapi.io/payments/search-for-a-bank.md).

## Step 1 - Create a payment

To initiate a SEPA Credit Transfer or SEPA Instant Credit Transfer, trigger[**Create money transfer**](https://docs.finapi.io/?product=access#tag--Payments) endpoint. Provide `IBAN` to indicate the sender account.

    POST /payments/moneyTransfers

There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).

Note: for Direct Debits initiation, please refer to [Initiate a Payment from an Account - no Web Form (Licensed Customers Only)](https://documentation.finapi.io/payments/initiate-a-payment-from-an-account-no-web-form-lic.md) as standalone Direct Debit initiation is not supported.

## Step 2 - Submit payment

Execute [**Submit payment**](https://docs.finapi.io/?product=access#tag--Payments) service:

    POST /payments/submit

The payload and the flow varies based on the SCA approach offered by the bank (in the API: properties of the bank interface (`bank.interface.properties`).

Some banks have implemented the `Embedded SCA` approach, where the user credentials and the second factor can be submitted to the bank via the TPP.

Some banks will require a redirect to the bank server to complete the authentication and second-factor verification, this is the so-called `Redirect SCA`.

Some banks allow authorization with the `Decoupled SCA` approach, where users could authenticate and authorize a transaction via the mobile app or an authorisation device.  
The combination of different SCA approaches is also possible. For example Embedded + Decoupled: a user will provide the login credentials to a TPP and then a push notification will be sent to the mobile application.

Please make sure your application is able to dynamically handle all variations.

Please refer to the [API specification](https://docs.finapi.io/?product=access#post-/api/v1/payments/submit) for more details.  
It is mandatory to indicate the interface that should be used for the payment submission.

If you are not familiar with the interfaces which are supported by finAPI, please check [Interfaces](https://documentation.finapi.io/access/interfaces.md) .

Please see below the examples of the flows for each SCA approach: Redirect, Embedded and Decoupled.

### Redirect approach

|                                                                                                                                                                                                                                                                                                                         **Step**                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                   **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                    |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit payment** **Mandatory request fields** * `paymentID` * `interface` * `redirectUrl` * URL of the client's endpoint that handles a redirect from the bank * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the payment along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                    | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "redirectUrl": "https://customer1.io", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "idontexist" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **Step #2** **Receive a redirect URL** **How to recorecognize step** Field `errors.multiStepAuthentication.status` has `REDIRECT_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `redirectUrl` * `redirectContext` * `redirectContextField` **Explanation** The API builds a redirect URL that will route the end-user to a page on the bank side, where the user can complete the authentication process. In this step, the client's application should store values from `redirectContext` and `redirectContextField` fields internally, as they will be required on the subsequent steps. | HTTP/1.1 510 { "errors": [ { "message": null, "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "288c0a78c6596e8f02f70a21e731d46a", "status": "REDIRECT_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": "https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0", "redirectContext": "976641d2-c03f-4919-8dac-16ccfd24b4e0", "redirectContextField": "state", "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 11:20:21.261", "requestId": "selfgen-fece3d6c-a0f0-43ea-a910-7e9ca7a7b1f6", "endpoint": "POST /payments/moneyTransfers/submit", "authContext": "1/18", "bank": "DEMO0002 - finAPI Test Redirect Bank" } |
| **Step #3** **Redirect to bank** The client application should redirect the end-user to the given redirectUrl. **Example** GET https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0 HTTP/1.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ||
| **Step #4** **Redirect back** When the end-user successfully completes the authentication process on the bank's side, he is redirected to the URL given in step #1. Additionally, the bank adds some more data to the URL (as query parameters). But the most important part for the client application is this `state` parameter (generally speaking, the name of the parameter is provided in step #2 as a value of `redirectContextField` field): the client application can use its value to recognize the end-user that was redirected by the bank - the value should match the one given on a step #2 in `redirectContext` field. **Example** GET https://customer1.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70 HTTP/1.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ||
| **Step #5** **Submit payment** **Mandatory request fields** * all fields from the previous request * `hash` * `redirectCallback` * the whole query string received on a step #4 **Explanation** The client application submits a query string as a value of `redirectCallback` field. The API processes the given string, extracts required data and continues the authentication process.                                                                                                                                                                                                                                                                | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "redirectUrl": "https://customer1.io", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "idontexist" } ], "multiStepAuthentication": { "hash": "288c0a78c6596e8f02f70a21e731d46a", "redirectCallback": "state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70" } }                                                                                                                                                                                                                                                                                                  |
| **Step #6** **Bank connection** The API completes the payment initiation process and returns a payment resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | HTTP/1.1 200 { "id": 1, "accountId": 111111100, "type": "MONEY_TRANSFER", "amount": 99.99, "orderCount": 1, "status": "SUCCESSFUL", "bankMessage": "Success", "requestDate": "2021-10-11 16:18:53.000", "executionDate": "2021-10-11 16:28:17.000" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

### Embedded approach

|                                                                                                                                                                                                                                                                                                                                                                                                                               **Step**                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                                                 **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit payment** **Mandatory request fields** * `paymentId` * `interface` * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the payment along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **Step #2** **Receive a list of two step procedures** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `TWO_STEP_PROCEDURE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `twoStepProcedures` **Explanation** If the bank decides, it responses with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And then the client application should ask the end-user to choose one of the offered two-step procedures.                                                                                                                                                                                                                                                                                   | HTTP/1.1 510 { "errors": [ { "message": "SCA method selection is required", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "status": "TWO_STEP_PROCEDURE_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": [ { "procedureId": "DEMO-TSP-01", "procedureName": "SMS", "procedureChallengeType": "TEXT", "implicitExecute": false }, { "procedureId": "DEMO-TSP-02", "procedureName": "PUSH", "procedureChallengeType": "TEXT", "implicitExecute": false } ], "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 08:13:32.155", "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399", "endpoint": "/payments/moneyTransfers/submit", "authContext": "1/18", "bank": "DEMO0001- FinAPI Test Bank" } |
| **Step #3** **Submit payment** (an optional step) **Mandatory request fields** * all fields from the previous request * `multiStepAuthentication.hash` * the value should be taken from the response on step #2 * `twoStepProcedureId` * field `procedureId` of the chosen two-step procedure **Explanation** The client application asks the end-user to choose a two-step procedure and then submits it to the API. Value of `hash` field points to the original request.                                                                                                                                                                                                                                                                                                                                                                                          | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "twoStepProcedureId": "DEMO-TSP-01" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **Step #4** **Receive an MSA challenge message** **How to recognise the step** Field `errors.multiStepAuthentication.status` has `CHALLENGE_RESPONSE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * hash * status * the following fields are presented depending on the two-step procedure type: * for type = `TEXT`: * challengeMessage * for type = `PHOTO`: * photoTanMimeType * photoTanData * for type = `FLICKER_CODE`**\***: * opticalData **\*** Note: feel free to use the flicker code template prepared by finAPI: [Flicker Code Template](https://documentation.finapi.io/access/flicker-code-template.md) **Explanation** When the two-step procedure is chosen (either by the bank or by the end-user), the API responds with details for the end-user. The client application should show this info to the end-user and ask for an answer. | HTTP/1.1 510 { "errors": [ { "message": "An additional authentication is required. Please enter the following code: 123456", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "status": "CHALLENGE_RESPONSE_REQUIRED", "challengeMessage": "An additional authentication is required. Please enter the following code: 123456", "answerFieldLabel": "TAN", "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2021-10-11 16:20:12.744", "requestId": "selfgen-8b108042-6c2c-4724-b345-2bf983ab0659", "endpoint": "POST /payments/moneyTransfers/submit", "authContext": "2/1534168", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                |
| **Step #5** **Submit Payment** **Mandatory request fields** * all fields from the previous request * `challengeResponse` * the answer from the end-user **Explanation** The client application asks for the challenge response and submits it back to the API. Value of `hash` field points to the original request.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "twoStepProcedureId": "DEMO-TSP-01", "challengeResponse": "123456" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **Step #6** **Payment submission result** The API completes the payment initiation process and returns a payment resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | HTTP/1.1 200 { "id": 1, "accountId": 111111100, "type": "MONEY_TRANSFER", "amount": 99.99, "orderCount": 1, "status": "SUCCESSFUL", "bankMessage": "Success", "requestDate": "2021-10-11 16:18:53.000", "executionDate": "2021-10-11 16:28:17.000" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

### Decoupled Approach

| **Step** | **Request/response example** |
|----------|------------------------------|

|                                                                                                                                                                                                                                                                                      **Step**                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                    **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit payment** **Mandatory request fields** * `paymentId` * `interface` * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the payment along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                                  | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Step #2** **Receive a list of two step procedures** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `TWO_STEP_PROCEDURE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `twoStepProcedures` **Explanation** If the bank decides, it responses with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And then the client application should ask the end-user to choose one of the offered two-step procedures. | HTTP/1.1 510 { "errors": [ { "message": "SCA method selection is required", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "TWO_STEP_PROCEDURE_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": [ { "procedureId": "DEMO-TSP-01", "procedureName": "SMS", "procedureChallengeType": "TEXT", "implicitExecute": false }, { "procedureId": "DEMO-TSP-02", "procedureName": "PUSH", "procedureChallengeType": "TEXT", "implicitExecute": false } ], "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 08:13:32.155", "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399", "endpoint": "POST /payments/moneyTransfers/submit", "authContext": "1/18", "bank": "DEMO0001- FinAPI Test Bank" } |
| **Step #3** **Submit payment** (an optional step) **Mandatory request fields** * all fields from the previous request * `multiStepAuthentication.hash` * the value should be taken from the response on step #2 * `twoStepProcedureId` * field `procedureId` of the chosen two-step procedure **Explanation** The client application asks the end-user to choose a two-step procedure and then submits it to the API. Value of `hash` field points to the original request.                                                                                                        | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "twoStepProcedureId": "DEMO-TSP-02" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Step #4** **Receive an error message that the decoupled approach is required** **How to recognise the step** Field `errors.multiStepAuthentication.status` has `DECOUPLED_AUTH_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `challengeMessage` * if any message was provided by the bank **Explanation** If the chosen two-step procedure was of a decoupled type, the API responds with this error. The client application should notify the end-user that the bank will send a notification.                   | HTTP/1.1 510 { "errors": [ { "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "DECOUPLED_AUTH_REQUIRED", "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 10:35:17.682", "requestId": "selfgen-9f035aca-d094-42d7-9285-a3eae9d5a4a9", "endpoint": "POST /payments/moneyTransfers/submit", "authContext": "1/18", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                                                                           |
| **Step #5** **Submit payment** **Mandatory request fields** * all fields from the previous request * `decoupledCallback` * this is a boolean field that signals to the API that the end-user is already informed about the decoupled authorization and might have already approved it. **Explanation** The client application asks the API to check the status of the authentication process. Value of `hash` field points to the original request.                                                                                                                                | POST /payments/moneyTransfers HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "paymentId": 277672, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "twoStepProcedureId": "DEMO-TSP-02", "decoupledCallback": true } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Step #6** **Receive an error message that the decoupled authentication is still in progress** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `DECOUPLED_AUTH_IN_PROGRESS` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` **Explanation** The API returns this error if the authentication is still not completed on the bank side. The client application should continue repeating step #5 while the API returns this error.                                              | HTTP/1.1 510 { "errors": [ { "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "DECOUPLED_AUTH_IN_PROGRESS", "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 10:42:54.468", "requestId": "selfgen-5801b1be-0e09-4d2a-99a2-a748d7ee6d7e", "endpoint": "POST /payments/moneyTransfers/submit", "authContext": "1/18", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                                                                        |
| **Step #6** **Payment submission result** The API completes the payment initiation process and returns a payment resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | HTTP/1.1 200 { "id": 1, "accountId": 111111100, "type": "MONEY_TRANSFER", "amount": 99.99, "orderCount": 1, "status": "SUCCESSFUL", "bankMessage": "Success", "requestDate": "2021-10-11 16:18:53.000", "executionDate": "2021-10-11 16:28:17.000" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

## Step 3 - Get the Payment status (Optional)

If upon completion of the steps described in Step 2 above, the `status `of the payment initiation is still `PENDING`, there is a chance that the bank has not returned the final payment status yet or there was an error when trying to obtain the payment initiation status and several attempts will be made in the background to obtain it (for more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md)).

You can call [**Get payments**](https://docs.finapi.io/?product=access#tag--Payments) to obtain the latest payment status.

## Step 4 - Delete User (Optional)

If for your use-case you do not need to save the user to re-use it later, we recommend that you delete the user once the payment initiation has been finalized via [**Delete the authorized user**](https://docs.finapi.io/?product=access#tag--Users) endpoint:

    DELETE /users

---
language: "en"
---
# Initiate a Standalone Payment - with Web Form (Recommended Option)

## Pre-requisites

* [Access User Token has been created.](https://documentation.finapi.io/payments/authorization-and-creation-of-a-user-identity.md)

## Step 1 - Initiate payment

To initiate a SEPA Credit Transfer or SEPA Instant Credit Transfer, use the [**Create a standalone payment endpoint**](https://docs.finapi.io/?product=web_form_2.0#post-/api/webForms/standalonePayment):

    POST /api/webForms/standalonePayment

If the IBAN of the sender account is already known, we recommend including it in the payment initiation payload to avoid the possibility that several SCAs will be required.

If the IBAN of the sender account is not known, it is still possible to initiate a payment without the sender account and the user will have to select the Bank or IBAN on the Web Form (see the next step).  
There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).  
Note: for Direct Debits initiation, please refer to [Initiate a Payment from an Account - with Web Form (Recommended Option)](https://documentation.finapi.io/payments/initiate-a-payment-from-an-account-with-web-form-r.md) as standalone Direct Debit initiation is not supported.

## Step 2 - The user to log in at the bank and authorize the payment

As a result of Step 1, the web form is generated. You can find the URL of the web form in the response:

    url: "https://webform.finapi.io/wf/946db09e-5bfc-11eb-ae93-0242ac130002"

The web form has to be presented to the user. If the sender's IBAN was not provided in Step 1, the user will have to either enter the IBAN into the web form or search for a bank first. Once the sender account is selected, the user will proceed to the payment authorization.  
You have two options for how to present the webform to the user:

* Embed the web form into your application. How to: [Embedded Web Form 2.0](https://documentation.finapi.io/webform/embedded-web-form-2-0.md)

* Redirect the user to the Web Form URL in the browser.

There are several branding and customization possibilities available for the web form. Please check out the web form documentation: [White labeling](https://documentation.finapi.io/webform/white-labeling.md)

## Step 3 - Check the status of the web form

To retrieve the status of the web form, you can either call the [**Get a web form service**](https://docs.finapi.io/?product=web_form_2.0#get-/api/webForms/-id-)or a callback can be sent of completion to a callback URL provided in the payment initiation payload during Step 1.

Note the `paymentId` returned in the response (in the `payload` object) to get the status of the payment initiation in the next step.

More details are available here: [Web Form 2.0 Basics \| Want to know web form status?](https://documentation.finapi.io/webform/web-form-2-0-basics.md#Want-to-know-web-form-status?)

## Step 4 - Check the status of the payment initiation

To retrieve the status of the payment initiation, get the `paymentId `from Step 3 and execute [**Get payments**](https://docs.finapi.io/?product=access#tag--Payments):

    GET /payments?ids=$paymentId

For more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md).

## Step 5 - Delete User (Optional)

If for your use case you do not need to save the user to re-use it later, we recommend that you delete the user once the payment initiation has been finalized via [**Delete the authorized user**](https://docs.finapi.io/?product=access#tag--Users) endpoint:

    DELETE /users

---
language: "en"
---
# Initiate a Standalone Predefined Payment - with Web Form

## Pre-requisites

* Client Token with the scope predefinedpayment:manager as scope.

  * client ID and Secret needed are the same as for creating users

## Step 1 - Initiate payment

To initiate a SEPA Credit Transfer or SEPA Instant Credit Transfer through a payment link or QR Code, use the [**Create a standalone predefined payment request endpoint**](https://docs.finapi.io/#post-/payment/createStandalonePayment).

    POST /payment/createStandalonePayment

To create a predefined payment you also need to provide your Client ID and Secret from your default client in the API.

If the IBAN and name of the sender account are already known, we recommend including them in the payment initiation payload to avoid the possibility that several SCAs will be required.

If the IBAN or name of the sender account is not known, it is still possible to initiate a payment without the sender info and the end user will have to select the Bank or IBAN on the Web Form (see the next step) and potentially provide their name manually.  
There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).

## Step 2 - The user has to log in at the bank and authorize the payment

As a result of Step 1, a link and base64 code are generated. Activating either will trigger the generation of the corresponding web form. You can find the URL of the web form and the base64 code in the response:

    "link": "https://di-predefined-payment-finapi-general-staging.finapi.io:443/api/v1",
    "qrCode": "iVBORw0KGgoAAAANSUhEUgAAAPUAAAD1CAAAAACt2uy5AAAQuElEQVR4XtWPwZIlOXLE9v9"

The web form has to be presented to the user. If the sender's IBAN was not provided in Step 1, the user will have to either enter the IBAN into the web form or search for a bank first. Once the sender account is selected, the user will proceed to the payment authorization.

## Step 3 - Check the status of the web form

To retrieve the status of the web form, you can either call the [**Get a web form service**](https://docs.finapi.io/?product=web_form_2.0#get-/api/webForms/-id-)or a callback can be sent of completion to a callback URL provided in the payment initiation payload during Step 1.

Note the `paymentId` returned in the response (in the `payload` object) to get the status of the payment initiation in the next step.

More details are available here: [Web Form 2.0 Basics \| Want to know web form status?](https://documentation.finapi.io/webform/web-form-2-0-basics.md#Want-to-know-web-form-status?)

## Step 4 - Check the status of the payment initiation

To retrieve the status of the payment initiation, get the `paymentId `from Step 3 and execute [**Get payments**](https://docs.finapi.io/?product=access#tag--Payments):

    GET /payments?ids=$paymentId

For more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md).

---
language: "en"
---
# Initiate a Standalone Standing Order- no Web Form (Licensed Customers Only)

To be able to use your PSD2 license with the finAPI APIs, please refer to the necessary steps to register the certificate with us and complete the TPP registration of the banks to which you plan to connect.

For more information, please refer to [Licensed customers](https://documentation.finapi.io/access/licensed-customers.md)

## Pre-requisites

* [Access User Token has been created.](https://documentation.finapi.io/payments/authorization-and-creation-of-a-user-identity.md)

* [Bank has been selected](https://documentation.finapi.io/payments/search-for-a-bank.md).

## Step 1 - Create a standing order

To initiate a SEPA Standing Order, trigger[**Create standing order**](https://docs.finapi.io/?product=access#tag--Standing-Orders) endpoint. Provide `IBAN` to indicate the sender account.

    POST /standingOrders

There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).

## Step 2 - Submit standing order

Execute [**Submit standing order**](https://docs.finapi.io/?product=access#tag--Standing-Orders) service:

    POST /standingOrders/submit

The payload and the flow varies based on the SCA approach offered by the bank (in the API: properties of the bank interface (`bank.interface.properties`).

Some banks have implemented the `Embedded SCA` approach, where the user credentials and the second factor can be submitted to the bank via the TPP.

Some banks will require a redirect to the bank server to complete the authentication and second-factor verification, this is the so-called `Redirect SCA`.

Some banks allow authorization with the `Decoupled SCA` approach, where users could authenticate and authorize a transaction via the mobile app or an authorization device.  
The combination of different SCA approaches is also possible. For example Embedded + Decoupled: a user will provide the login credentials to a TPP and then a push notification will be sent to the mobile application.

Please make sure your application can dynamically handle all variations.

Please refer to the [API specification](https://docs.finapi.io/?product=access#post-/api/v1/standingOrders/submit) for more details.  
It is mandatory to indicate the interface that should be used for the standing order submission.

If you are unfamiliar with the interfaces supported by finAPI, please check [Interfaces](https://documentation.finapi.io/access/interfaces.md) .

Please see below the examples of the flows for each SCA approach: Redirect, Embedded, and Decoupled.

### Redirect approach

|                                                                                                                                                                                                                                                                                                                        **Step**                                                                                                                                                                                                                                                                                                                         |                                                                                                                                                                                                                                                                                                                                                                               **Request/response example**                                                                                                                                                                                                                                                                                                                                                                               |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit standing order** **Mandatory request fields** * `standingOrderId` * `interface` * `redirectUrl` * URL of the client's endpoint that handles a redirect from the bank * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the standing order along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                              | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "redirectUrl": "https://customer1.io", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "idontexist" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| **Step #2** **Receive a redirect URL** **How to recognize the step** Field `errors.multiStepAuthentication.status` has `REDIRECT_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `redirectUrl` * `redirectContext` * `redirectContextField` **Explanation** The API builds a redirect URL that will route tenuserser to a page on the bank side, where the user can complete the authentication process. In this step, the client's application should store values from `redirectContext` and `redirectContextField` fields internally, as they will be requiredinn the subsequent steps. | HTTP/1.1 510 { "errors": [ { "message": null, "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "288c0a78c6596e8f02f70a21e731d46a", "status": "REDIRECT_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": "https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0", "redirectContext": "976641d2-c03f-4919-8dac-16ccfd24b4e0", "redirectContextField": "state", "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 11:20:21.261", "requestId": "selfgen-fece3d6c-a0f0-43ea-a910-7e9ca7a7b1f6", "endpoint": "POST /standingOrders/submit", "authContext": "1/18", "bank": "DEMO0002 - finAPI Test Redirect Bank" } |
| **Step #3** **Redirect to bank** The client application should redirect the end-user to the given redirectUrl. **Example** GET https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0 HTTP/1.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     ||
| **Step #4** **Redirect back** When the end-user successfully completes the authentication process on the bank's side, he is redirected to the URL given in step #1. Additionally, the bank adds some more data to the URL (as query parameters). But the most important part for the client application is this `state` parameter (generally speaking, the name of the parameter is provided in step #2 as a value of `redirectContextField` field): the client application can use its value to recognize the end-user that was redirected by the bank - the value should match the one given on a step #2 in `redirectContext` field. **Example** GET https://customer1.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70 HTTP/1.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ||
| **Step #5** **Submit standing order** **Mandatory request fields** * all fields from the previous request * `hash` * `redirectCallback` * the whole query string received on step #4 **Explanation** The client application submits a query string as a value of `the redirectCallback` field. The API processes the given string, extracts required data, and continues the authentication process.                                                                                                                                                                                                                                                    | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "redirectUrl": "https://customer1.io", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "idontexist" } ], "multiStepAuthentication": { "hash": "288c0a78c6596e8f02f70a21e731d46a", "redirectCallback": "state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70" } }                                                                                                                                                                                                                                                                                     |
| **Step #6** **Standing Order submission result** The API completes the standing order initiation process and returns a bank standing order resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | HTTP/1.1 200 { id: 1, accountId: 1, iban: "string", amount: 99.99, currency: "EUR", startDate: "2023-01-01 00.00.00.000", endDate: "2023-01-01 00.00.00.000", frequency: "MONTHLY", dayOfExecution: 31, requestDate: "2019-01-01 00:00:00.000", requestCompletionDate: "2019-01-01 00:00:00.000", status: "OPEN", bankMessage: "string" }                                                                                                                                                                                                                                                                                                                                                                                                                                                |

### Embedded approach

|                                                                                                                                                                                                                                                                                                                                                                                                                               **Step**                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                                             **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit standing order** **Mandatory request fields** * `standingOrderId` * `interface` * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the standing order along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **Step #2** **Receive a list of two step procedures** (an optional step) **How to recognize the step** Field `errors.multiStepAuthentication.status` has `TWO_STEP_PROCEDURE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `twoStepProcedures` **Explanation** If the bank decides, it responds with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And then the client application should ask the end-user to choose one of the offered two-step procedures.                                                                                                                                                                                                                                                                                    | HTTP/1.1 510 { "errors": [ { "message": "SCA method selection is required", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "status": "TWO_STEP_PROCEDURE_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": [ { "procedureId": "DEMO-TSP-01", "procedureName": "SMS", "procedureChallengeType": "TEXT", "implicitExecute": false }, { "procedureId": "DEMO-TSP-02", "procedureName": "PUSH", "procedureChallengeType": "TEXT", "implicitExecute": false } ], "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 08:13:32.155", "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399", "endpoint": "/standingOrders/submit", "authContext": "1/18", "bank": "DEMO0001- FinAPI Test Bank" } |
| **Step #3** **Submit standing order** (an optional step) **Mandatory request fields** * all fields from the previous request * `multiStepAuthentication.hash` * the value should be taken from the response on step #2 * `twoStepProcedureId` * field `procedureId` of the chosen two-step procedure **Explanation** The client application asks the end-user to choose a two-step procedure and then submits it to the API. The value of the `hash` field points to the original request.                                                                                                                                                                                                                                                                                                                                                                           | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "twoStepProcedureId": "DEMO-TSP-01" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **Step #4** **Receive an MSA challenge message** **How to recognize the step** Field `errors.multiStepAuthentication.status` has `CHALLENGE_RESPONSE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * hash * status * the following fields are presented depending on the two-step procedure type: * for type = `TEXT`: * challengeMessage * for type = `PHOTO`: * photoTanMimeType * photoTanData * for type = `FLICKER_CODE`**\***: * opticalData **\*** Note: feel free to use the flicker code template prepared by finAPI: [Flicker Code Template](https://documentation.finapi.io/access/flicker-code-template.md) **Explanation** When the two-step procedure is chosen (either by the bank or by the end user), the API responds with details for the end user. The client application should show this info to the end-user and ask for an answer. | HTTP/1.1 510 { "errors": [ { "message": "An additional authentication is required. Please enter the following code: 123456", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "status": "CHALLENGE_RESPONSE_REQUIRED", "challengeMessage": "An additional authentication is required. Please enter the following code: 123456", "answerFieldLabel": "TAN", "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2021-10-11 16:20:12.744", "requestId": "selfgen-8b108042-6c2c-4724-b345-2bf983ab0659", "endpoint": "POST /standingOrders/submit", "authContext": "2/1534168", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                |
| **Step #5** **Submit Standing Order** **Mandatory request fields** * all fields from the previous request * `challengeResponse` * the answer from the end-user **Explanation** The client application asks for the challenge response and submits it back to the API. The valuethe of `hash` field points to the original request.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "651d37f0aeb5f326bc5ed60a404d8a72", "twoStepProcedureId": "DEMO-TSP-01", "challengeResponse": "123456" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **Step #6** **Standing Order submission result** The API completes the standing order initiation process and returns a standing order resource.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | HTTP/1.1 200 { id: 1, accountId: 1, iban: "string", amount: 99.99, currency: "EUR", startDate: "2023-01-01 00.00.00.000", endDate: "2023-01-01 00.00.00.000", frequency: "MONTHLY", dayOfExecution: 31, requestDate: "2019-01-01 00:00:00.000", requestCompletionDate: "2019-01-01 00:00:00.000", status: "OPEN", bankMessage: "string" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

### Decoupled Approach

|                                                                                                                                                                                                                                                                                      **Step**                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                               **Request/response example**                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Step #1** **Submit standing order** **Mandatory request fields** * `standingOrderId` * `interface` * `loginCredentials` * if the chosen bank interface has any items in `loginCredentials` field **Explanation** The client application submits the standing order along with the user bank credentials if they are required by the bank interface.                                                                                                                                                                                                                              | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ] }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| **Step #2** **Receive a list of ttwo-stepprocedures** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `TWO_STEP_PROCEDURE_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `twoStepProcedures` **Explanation** If the bank decides, it responses with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And then the client application should ask the end-user to choose one of the offered two-step procedures. | HTTP/1.1 510 { "errors": [ { "message": "SCA method selection is required", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "TWO_STEP_PROCEDURE_REQUIRED", "challengeMessage": null, "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": [ { "procedureId": "DEMO-TSP-01", "procedureName": "SMS", "procedureChallengeType": "TEXT", "implicitExecute": false }, { "procedureId": "DEMO-TSP-02", "procedureName": "PUSH", "procedureChallengeType": "TEXT", "implicitExecute": false } ], "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 08:13:32.155", "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399", "endpoint": "POST /standingOrders/submit", "authContext": "1/18", "bank": "DEMO0001- FinAPI Test Bank" } |
| **Step #3** **Submit standing order** (an optional step) **Mandatory request fields** * all fields from the previous request * `multiStepAuthentication.hash` * the value should be taken from the response on step #2 * `twoStepProcedureId` * field `procedureId` of the chosen two-step procedure **Explanation** The client application asks the end-user to choose a two-step procedure and then submits it to the API. The value of the `hash` field points to the original request.                                                                                         | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "twoStepProcedureId": "DEMO-TSP-02" } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| **Step #4** **Receive an error message that the decoupled approach is required** **How to recognize the step** Field `errors.multiStepAuthentication.status` has `DECOUPLED_AUTH_REQUIRED` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` * `challengeMessage` * if any message was provided by the bank **Explanation** If the chosen two-step procedure was of a decoupled type, the API responds with this error. The client application should notify the end-user that the bank will send a notification.                   | HTTP/1.1 510 { "errors": [ { "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "DECOUPLED_AUTH_REQUIRED", "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 10:35:17.682", "requestId": "selfgen-9f035aca-d094-42d7-9285-a3eae9d5a4a9", "endpoint": "POST /standingOrders/submit", "authContext": "1/18", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                                                                           |
| **Step #5** **Submit standing order** **Mandatory request fields** * all fields from the previous request * `decoupledCallback` * this is a boolean field that signals to the API that the end-user is already informed about the decoupled authorization and might have already approved it. **Explanation** The client application asks the API to check the status of the authentication process. Value of `hash` field points to the original request.                                                                                                                         | POST /standingOrders/submit HTTP/1.1 Content-Type: application/json Accept: application/json Authorization: Bearer <user's access token> { "standingOrderId": 1, "interface": "XS2A", "loginCredentials": [ { "label": "Onlinebanking-ID", "value": "demo" }, { "label": "PIN", "value": "demo" } ], "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "twoStepProcedureId": "DEMO-TSP-02", "decoupledCallback": true } }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **Step #6** **Receive an error message that the decoupled authentication is still in progress** (an optional step) **How to recognise the step** Field `errors.multiStepAuthentication.status` has `DECOUPLED_AUTH_IN_PROGRESS` value. **Mandatory response fields of** `multiStepAuthentication`**object:** * `hash` * `status` **Explanation** The API returns this error if the authentication is still not completed on the bank side. The client application should continue repeating step #5 while the API returns this error.                                              | HTTP/1.1 510 { "errors": [ { "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "code": "ADDITIONAL_AUTHENTICATION_REQUIRED", "type": "BUSINESS", "multiStepAuthentication": { "hash": "112c3581b39fc95a1f979d0d73f14dfb", "status": "DECOUPLED_AUTH_IN_PROGRESS", "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung", "answerFieldLabel": null, "redirectUrl": null, "redirectContext": null, "redirectContextField": null, "twoStepProcedures": null, "photoTanMimeType": null, "photoTanData": null, "opticalData": null } } ], "date": "2019-11-27 10:42:54.468", "requestId": "selfgen-5801b1be-0e09-4d2a-99a2-a748d7ee6d7e", "endpoint": "POST /standingOrders/submit", "authContext": "1/18", "bank": "DEMO0001 - finAPI Test Bank" }                                                                                                                                                        |
| **Step #6** **Standing order submission result** The API completes the standing order initiation process and returns a standing order resource.                                                                                                                                                                                                                                                                                                                                                                                                                                    | HTTP/1.1 200 { id: 1, accountId: 1, iban: "string", amount: 99.99, currency: "EUR", startDate: "2023-01-01 00.00.00.000", endDate: "2023-01-01 00.00.00.000", frequency: "MONTHLY", dayOfExecution: 31, requestDate: "2019-01-01 00:00:00.000", requestCompletionDate: "2019-01-01 00:00:00.000", status: "OPEN", bankMessage: "string" }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

## Step 3 - Get the Standing Order initiation status (Optional)

If upon completion of the steps described in Step 2 above, the `status `of the standing order initiation is still `PENDING`, there is a chance that the bank has not returned the final standing order initiation status yet or there was an error when trying to obtain the standing order initiation status and several attempts will be made in the background to obtain it (for more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md)).

You can call [**Get standing orders**](https://docs.finapi.io/?product=access#tag--Standing-Orders) to obtain the latest standing order initiation status.

## Step 4 - Delete User (Optional)

If for your use-case you do not need to save the user to re-use it later, we recommend that you delete the user once the standing order initiation has been finalized via [**Delete the authorized user**](https://docs.finapi.io/?product=access#tag--Users) endpoint:

    DELETE /users

---
language: "en"
---
# Initiate a Standalone Standing Order- with Web Form (Recommended Option)

## Pre-requisites

* [Access User Token has been created.](https://documentation.finapi.io/payments/authorization-and-creation-of-a-user-identity.md)

## Step 1 - Initiate standing order

To initiate a SEPA Standing Order use the [**Create a standing order endpoint**](https://docs.finapi.io/?product=web_form_2.0#post-/api/webForms/standingOrder):

    POST /api/webForms/standingOrder

If the IBAN of the sender account is already known, we recommend including it in the standing order initiation payload to avoid the possibility that several SCAs will be required.

If the IBAN of the sender account is not known, it is still possible to initiate a standing order without the sender account and the user will have to select the Bank or IBAN on the Web Form (see the next step).  
There are some payment data validations that we recommend being implemented to avoid bank payment rejections. Please refer to [Payment Data Validation](https://documentation.finapi.io/payments/payment-data-validation.md).

## Step 2 - The user to log in at the bank and authorize the standing order

As a result of Step 1, the web form is generated. You can find the URL of the web form in the response:

    url: "https://webform.finapi.io/wf/946db09e-5bfc-11eb-ae93-0242ac130002"

The web form has to be presented to the user. If the sender's IBAN was not provided in Step 1, the user will have to either enter the IBAN into the web form or search for a bank first. Once the sender account is selected, the user will proceed to the standing order authorization.  
You have two options for how to present the webform to the user:

* Embed the web form into your application. How to: [Embedded Web Form 2.0](https://documentation.finapi.io/webform/embedded-web-form-2-0.md)

* Redirect the user to the Web Form URL in the browser.

There are several branding and customization possibilities available for the web form. Please check out the web form documentation: [White labeling](https://documentation.finapi.io/webform/white-labeling.md)

## Step 3 - Check the status of the web form

To retrieve the status of the web form, you can either call the [**Get a web form service**](https://docs.finapi.io/?product=web_form_2.0#get-/api/webForms/-id-)or a callback can be sent of completion to a callback URL provided in the standing order initiation payload during Step 1.

Note the `standingOrderId` returned in the response (in the `payload` object) to get the status of the standing order initiation in the next step.

More details are available here: [Web Form 2.0 Basics \| Want to know web form status?](https://documentation.finapi.io/webform/web-form-2-0-basics.md#Want-to-know-web-form-status?)

## Step 4 - Check the status of the standing order initiation

To retrieve the status of the standing order initiation, get the `standingOrderId` from Step 3 and execute [**Get Standing Orders**](https://docs.finapi.io/?product=access#tag--Standing-Orders):

    GET /standingOrders?ids=$standingOrderId

For more details, please refer to [How to get the payment initiation status](https://documentation.finapi.io/payments/how-to-get-the-payment-initiation-status.md).

## Step 5 - Delete User (Optional)

If for your use case you do not need to save the user to re-use it later, we recommend that you delete the user once the standing order initiation has been finalized via [**Delete the authorized user**](https://docs.finapi.io/?product=access#tag--Users) endpoint:

    DELETE /users

---
language: "en"
---
# Payment Data Validation

We advise our customers to follow the below recommendations when it comes to submitting the payment data to finAPI to avoid possible payment rejections at the bank.

1. API parameter `purpose` - Please don't exceed 140 characters in the purpose.

2. Supported character set - Depending on the bank's technology stack and other requirements, special characters in the input might lead to failed payments. We strongly urge customers to stick to the character set below. This impacts the API parameters `purpose`, `endToEndId`, `counterpartName`.

   a b c d e f g h i j k l m n o p q r s t u v w x y z

   A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

   0 1 2 3 4 5 6 7 8 9

   / - ? : ( ) . , ' +

   Space

   Some banks support umlauts (`ä`, `Ä`, `ö`, `Ö`, `ü`, `Ü`, `ß`) while some don't. The simplest solution to ensure high success rates would be to substitute umlauts with `ae`, `AE`, `oe`, `OE`, `ue`, `UE`, `ss` respectively.

3. For **Qonto**: The maximum allowed amount of payments is 30,000€. Payments with a larger amount will get rejected.

## Bank-specific payment constraints

Starting with API V2, we provide information about constraints that only apply to certain banks in the `BankInterface.paymentConstraints` object which is returned by the [Get a Bank](https://docs.finapi.io/#get-/api/v2/banks/-id-) and [Get and search all banks](https://docs.finapi.io/#get-/api/v2/banks) services and is also contained in the [Get a bank connection](https://docs.finapi.io/#get-/api/v2/bankConnections/-id-) service response.

Please check the documentation for the available constraints.

If a constraint applies to a bank (the flag is set to true) and a payment issued for the bank doesn't fulfill it, we will reject the payment during payment creation already, to avoid it being rejected later by the bank.

Payment constraints metadata are currently provided for SEPA and domestic money transfers.

Please check the bank's payment constraints upfront before creating a payment, to avoid payment creation being rejected.

---
language: "en"
---
# Search for a Bank

Before you proceed with initiating a payment, you need to select a bank that will be used to send the payment.  
For the customers using Web Form 2.0 the bank search can be done by the user in the web form itself, so this step is optional.

## Prerequisites

* [Access User Token has been created](https://documentation.finapi.io/access/authorization-and-creation-of-a-user-identity.md).

## Search for a Bank

Execute [**Get and search all banks**](https://docs.finapi.io/?product=access#tag--Banks) service:

    GET /banks

There are multiple filter parameters available, please refer to the API documentation for more details.

The search result will return the list of banks that you can present to the user for selection. We recommend displaying the bank's `name`, `BLZ` and `city` as some banks may have identical/similar names.

Once the bank is selected, note its `id` and supported interfaces as these parameters will be required for the payment initiation.  
To check if finAPI supports the payment initiation and support payment options for a particular bank, refer to the `paymentCapabilities` returned in the response for each supported bank interface.

---
language: "en"
---
# SEPA transfers

---
language: "en"
---
# Try finAPI Payments in Sandbox

## Request Sandbox Access

If you already have your client credentials for the finAPI Sandbox environment, then you can skip this step.

To request access to finAPI Sandbox, please place your order online here: <https://www.finapi.io/jetzt-bestellen/> and indicate that you need the finAPI Payments module.

You will then receive your client credentials.

## KYC Process

If you want to test finAPI Payments with real bank accounts, you will have to go through the KYC process. Our support team will guide you through the process.

It is, however, possible to test the payment initiation process with the test banks provided by finAPI and [Demobank](https://documentation.finapi.io/finAPIdemobank/). For that, the KYC process is not required.

## Test Banks

finAPI provides a range of test banks that can be used to test various payment options and simulate different SCA approaches.

For more details, please refer to [finAPI Test Banks](https://documentation.finapi.io/access/finapi-test-banks.md)

---
language: "en"
---
# What is the difference between SEPA and a domestic transfer?

In finAPI, we support two different types of transfers:

* SEPA

* Domestic Transfer

Internally, we differentiate the payments based on the area and the currency :  

|                    |       **SEPA**       |  **Domestic Transfer**  |
|--------------------|----------------------|-------------------------|
| Region of transfer | Everywhere in Europe | Within the same country |
| Currency           | EUR                  | not EUR                 |

---
language: "en"
---
# XS2A Public Documentation Home

The purpose of this documentation is to provide a better understanding of the finAPI XS2A Solutions and support TPPs with the integration. This serves as a companion to the Open API documentation.

## Welcome to finAPI XS2A Server

finAPI XS2A Server is a fully Berlin-Group compliant XS2A Server Solution.

## Getting started as a TPP

To get started with your Integration, please refer to our [TPP Developer's Guide](https://documentation.finapi.io/xs2a/tpp-developer-s-guide.md).

Please check also the [FAQ](https://documentation.finapi.io/xs2a/faq.md) for the most important questions.

The OpenAPI definition with further explanations for each endpoint can be found [here](https://docs.finapi.io/?product=xs2a).

---
language: "en"
---
# 01. Getting Started

## **About the Service**

XS2A is an interface that allows your application to communicate with payment and account services of various banks under PSD2 regulations.

The finAPI XS2A API is 100% compliant with the Berlin Group Standard.

This documentation is about a so-called Sandbox service that provides the possibility to test the access to bank data via the XS2A interface using test data.

The OpenAPI Definition with examples and additional hints is available under <https://docs.finapi.io/?product=xs2a>

## **How to Register**

For XS2A Sandbox, no client registration is required.

## **XS2A API Access**

In order to access XS2A API, several prerequisites must be met first, which are provided and authorised by third parties.

1. You must be registered as a PSP at NCA of your country (Bafin in Germany, FMA in Austria)

2. You must obtain a valid PSD2-compliant client certificate to authenticate your application to the XS2A API (see for example here <https://www.bundesdruckerei.de/en/Service-Support/Service/Certificates-PSD2> on how to obtain a valid certificate)

## Further Information

* [Terms and Definitions](https://documentation.finapi.io/xs2a/12-terms-and-definitions.md)
* [XS2A Character Set](https://documentation.finapi.io/xs2a/08-xs2a-character-set.md)
* [Supported Authentication Methods](https://documentation.finapi.io/xs2a/02-supported-authentication-methods.md)
* [XS2A Error Handling](https://documentation.finapi.io/xs2a/07-xs2a-error-handling.md)
* [(OLD) Sandbox Test Accounts and Test Data](https://documentation.finapi.io/xs2a/09-sandbox-test-accounts-and-test-data.md)
* [(NEW) Sandbox Test Accounts and Test Data](https://documentation.finapi.io/xs2a/new-sandbox-test-accounts-and-test-data.md)
* [Resource validity time](https://documentation.finapi.io/xs2a/15-resource-validity-time.md)

---
language: "en"
---
# 02. PIS - Payments

* [Payment Products and Services](https://documentation.finapi.io/xs2a/11-payment-products-and-models.md)
* [Initiation and Authorisation of a Payment in Steps](https://documentation.finapi.io/xs2a/03-how-to-initiate-and-authorise-a-payment.md)
* [How to cancel a payment](https://documentation.finapi.io/xs2a/18-how-to-cancel-a-payment.md)
* [Instant Payments](https://documentation.finapi.io/xs2a/instant-payments.md)

---
language: "en"
---
# Supported Authentication Methods

## **General information**

XS2A interface offers embedded, decoupled and redirect SCA approaches with a selection of SCA methods as mechanisms of payments and consent authorisation.

Within the embedded approach, the communication between PSU and ASPSP is done through XS2A and TPP interfaces where

* ASPSP validates PSU credentials and the 2nd factor;

* XS2A provides TPP with authorisation instructions and error information;

* TPP provides PSU with authorisation instructions and error information.

The step when PSU receives the 2nd factor from ASPSP is handled directly between PSU and ASPSP - outside the embedded SCA flow.

Within the decoupled approach, the communication between PSU and ASPSP is done through XS2A and TPP interfaces where

* ASPSP validates PSU credentials and the 2nd factor;

* XS2A provides TPP with authorisation instructions and error information;

* TPP provides PSU with authorisation instructions and error information.

The steps when PSU receives the 2nd factor from ASPSP and provides it back to ASPSP for validation are handled directly between PSU and ASPSP - outside the decoupled SCA flow.

Within the redirect approach, the communication between PSU and ASPSP is done directly with a link, which is provided in the response of the API and which has to be shown by the TPP to the PSU in a web view.

## **Flow diagrams**

The diagrams below give a high-level overview of the embedded SCA message flow during payments and consent authorisation.

### Consent creation and authorisation

![01_TPP_Consent_Creation.png](https://documentation.finapi.io/__attachments/a_d7f7ce4495ccdd76ef7a311eede60616a9e0acd2d7962bd43163a17ccb8bf55e/01_TPP_Consent_Creation.png?cb=f0e92f654c1116b52fccb7229c505c16)

If an authorisation is rejected, the status of the resource to be authorised does not change. Only the authorisation status itself is set to `failed`.

[PlantUML Link for better readability](https://www.plantuml.com/plantuml/png/pLTHRzis47xNhxXv3zsCn5u3xCM0XoQnkmL8KQDsW07p7ixKoI92anf9EGsw_FUHbAM8ZjNCMzhj9Qt8x-vu7x-xezyOYzgM6v6yogqjp6WuB0HAlp9WQZCqz4T9aj5fod6jSPDyOtFQ432XojGmBDmE6RwMYRdbia07WHMosxLMfKmlbL0Qxd9kAKbUOMcLB3ShqedbLb1ogQGXQO5fGikL19GfE5IkD3TX9I6tKe6JyHWkFP2WjXkFazdy1av_WiLiDe8hoIsl7AaCs9xpn64yzDVvsVa8-ltP-_a2XjlNmntGzFjBby2zK9YEuDDkzI7n-4UxBGgU-ZCmqfPddA6bfMnMpRsq-74fGr1gpg39g58pXpHawzMvHLiQ64DF4oE-fRIt2rOdj0DUfKiPsIobuF9s7AxkFABBapJtomr7qRvZx5aQXf-Qi0_3w38SG_-CZMQXyTmm50NOuyamV9uZ1uf8AGiVQMPAdpX9orbp-y782MO47xogZGMheD1gorFoCaaz78MffLP_m_GZor6kQLzmBSmJMc_-BgjkA_fsW54inSAK4xJuy7BaDsjxaPi8v_FPVERpg9cAW4u70T12TeTrfs-JErhAK-1PPG3-Ya2JBRM4NnQB6Ppzy7fNvUwOlXqOgpI1TiVWpWaub-Wza304fxKfIY2jbQwFrN2qxtEFmYSgAoBTUBM5YY91hEuhk4KkS2K8vfVdy8uSBwcp7NTp5rjiAekZE7HyeRnlcxUSPafxag_Icjg3i8XgmOq55I5FZc3r-gdvCrLf0eDnILRKTHOcovKoRSgYqgkkfBtxaWKOrnyUEBO3_OVb6FA-upQ7DT-IRD5mhApsxO5_LbhtP28XQH9eoLd9J85LJztzDdrtCPrCfXFu4oRJo_Sti-lfvFUJghRN94c7l7sXa_l3SXI2v9eQPrNypwapIVnZeu1liopxaLOm8UO-1QNmLgYx10024orr-FDXKMY5B8Vnuxa2zfaEuJug1LGAfBGNh3hbxsHiICvhgm3kbBpQk7Flwo09DbBvTQQLCQCgdy1Ok0uuSzHboApIpertErXAzxSURgQYCeBbZhDr3WY62WoNu6US907VqM0zW0kKjvwaxmTmPI5t_oDfG9NME8SXQ4YPIqlQ-QH1TSoZn5VFzDQrkoq4nuWVkrQ5EF7cKjeSBToXQUIJrlgnZMewL5kK9eV5XvjfMqzXyUtvzNnwI2lz_fNJjjvKwSv9Rqa3hXmHa7690en5I_t-0UrqbVM1rqrmnOrJKySJCVYgfBRNw7wU_gj65rn--Kv6CWsZL6atAjiLYyHWkbbHcXuesAwAhPlALoZOtG2hyw65Hcaml0Q2dsVUbQsQ2_3M36jjFLP2fjN6QpNKNx3uSdFDC8mdSdXbVXr1X2YTuwqP8w7azn-V__z6Ky-edkyrlGF3gnVwJU-WrY-K4eJo17fMbzJpVat961cJbUAaSjJBqFtJwzR_yQqbL6X7LSIFjAeXLatmoSziC9N5CLqgcBpWhylQJyWYJZXvGp8jD-8l)

PlantUML Diagram Code  

    @startuml
    'https://plantuml.com/sequence-diagram
    !theme cloudscape-design
    skinparam backgroundColor white

    'autonumber
    title
    Consent creation and authorisation
    end title

    == Create Consent ==
    PSU -> TPP: Initiation of consent creation
    TPP -> XS2A: **POST /v1/consents**\npayload: {consent}
    XS2A -> XS2A: validate certificate\nvalidate syntax\ncreate consent resource\nset consentStatus = "received"
    XS2A --> TPP: consentId\nconsentStatus\nlink=startAuthorisation

    == Start Consent Authorisation ==
    TPP -> XS2A: **POST /v1/consents/{consentId}/authorisations**
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate consentId\ncreate authorisation resource\nset scaStatus = "received"
    XS2A --> TPP: scaStatus\nlink=updatePsuAuthentication
    TPP --> PSU: Request to provide credentials

    == Credentials Exchange ==
    PSU -> TPP: Credentials
    TPP -> XS2A: **PUT /v1/consents/{consentId}/authorisations/{authorisationId}:**\npayload: {psuData}
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate consentId\nvalidate authorisationId
    XS2A -> ASPSP: **Request authorisation**
    ASPSP -> ASPSP: validate syntax\nvalidate psu credentials:\n- if valid then return HTTP 201 Created\nand store required data\n- else - return an error
    ASPSP --> XS2A: HTTP 201 Created
    XS2A -> XS2A: set scaStatus = "psuAuthenticated"

    == Selection of available SCA Methods ==
    XS2A -> ASPSP: **Request available SCA methods**
    ASPSP -> ASPSP: validate syntax\nvalidate if any SCA methods available for psuId:\n- if SCA methods available then return list of SCA methods,\n- else - return an error
    ASPSP --> XS2A: List of SCA methods
    XS2A --> TPP: scaStatus\nlink=selectAuthenticationMethod
    TPP --> PSU: Request to choose SCA method
    PSU -> TPP: Select SCA method
    TPP -> XS2A: **PUT /v1/consents/{consentId}/authorisations/{authorisationId}**\npayload: {authenticationMethodId}
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate consentId\nvalidate authorisationId
    XS2A -> ASPSP: **Request SCA with given SCA method**
    ASPSP -> ASPSP: validate syntax\nvalidate if given SCA method is available for psuId:\n- if yes then return related info to given SCA method [EMBEDDED | DECOUPLED],\nand generate and send challenge to given psuId,\n- else - return an error

    group #fff5eb Decoupled Flow
        ASPSP -> XS2A: SCA approach = DECOUPLED
        XS2A -> XS2A: set scaStatus = "scaMethodSelected"
        XS2A --> TPP: scaStatus\nchosenScaMethod
        TPP --> PSU: Request to complete authorisation

        note across: ASPSP sends the 2nd factor to PSU.\nPSU provides given 2nd factor through a separate channel (e.g. Bank app). It happens outside the XS2A interface.

        ASPSP -> ASPSP: validate syntax\nvalidate if received challenge data equals to the challenge data\nthat was generated and sent to given psuId:\n- if yes then push TRUE,\n- else - push FALSE
        ASPSP -> XS2A: **Inform XS2A Server about final state**
        XS2A -> XS2A: validate authorisationId\nset scaStatus = "finalised"\nset consentStatus = "valid"
        TPP -> XS2A: **GET /v1/consents/{consentId}/authorisations/{authorisationId}**
        XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate consentId\nvalidate authorisationId
    end

    == or ==

    group #fffaec Embedded Flow
        ASPSP --> XS2A: SCA approach = EMBEDDED
        XS2A -> XS2A: set scaStatus = "scaMethodSelected"
        XS2A --> TPP: scaStatus\nchosenScaMethod\nlink=authoriseTransaction
        TPP --> PSU: Request to provide 2nd factor
        PSU -> TPP: 2nd factor received from the Bank
        TPP -> XS2A: **PUT /v1/consents/{consentId}/authorisations/{authorisationId}**\npayload: {scaAuthenticationData}
        XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate consentId\nvalidate authorisationId
        XS2A -> ASPSP: **Request given SCA data authorisation**
        ASPSP -> ASPSP: validate syntax\nvalidate if received challenge data equals to the challenge data\nthat was generated and sent to given psuId:\n- if yes then return "TRUE",\n- else - return "FALSE"
        ASPSP --> XS2A: Boolean, "true" if successful, else "false"
        XS2A -> XS2A: set scaStatus = "finalised"\nset consentStatus = "valid"
    end

    XS2A --> TPP: scaStatus
    TPP --> PSU: Inform about consent creation status
    TPP -> XS2A: **GET /v1/consents/{consentId}/status**
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate consentId
    XS2A -> TPP: consentStatus

    @enduml

More details about consent authorisation are available at [Creation and Authorisation of an AIS Consent in Steps](https://documentation.finapi.io/xs2a/04-how-to-create-and-authorise-an-ais-consent.md)

### Payment initiation and authorisation

![02_TPP_Payment_Authorisation.png](https://documentation.finapi.io/__attachments/a_194b33c737455ea24cfc48402b80c04c50f305985a69d50e23daa989d7cb89cb/02_TPP_Payment_Authorisation.png?cb=fb8b7b91cb304722c8c584b1aa887113)

If an authorisation is rejected, the status of the resource to be authorised does not change. Only the authorisation status itself is set to `failed`.

[PlantUML Link for better readability](https://www.plantuml.com/plantuml/png/pLZVRzis47xNNt7p7he9IRmMs8i13qrjTmlGeaRi30FcFLoeaqL49ZsISXfq-T_77s4bMLPQ5rcxbxGYxmVlk-yxodgf3IfJRShaMM7CLe-6mss9mgsSCRaPQlgx8i7eDEEuLhX9lZC5RGXOAQjCCzpQ7T9yBH9zmyKMhGbS8xjPArc9R29BgU2su8QIv1bMHefgSqqgCToKbCpnRaF2m8NWXgFXKW2A3CuhKqZ5jLz9oAu4ysGyXeaYD0JHSpnEveihEFq5blFvg1b8vh0DHedTSXP_B5wSZo1Dv-yMInZkdWy_F1YSQb8xpkY-NjagcLNCtAVfIjYrKc8sWhXxdxXGTSWTbZnpfsAa3CyvGqChyN5Ltmc3xrU2XQC_1055MbQAMKjD9guk39fAmnW6bvFVfuE7H0_bHQEBR2MCGg6HkLA3pqgKNDoCVJlR03hO5cuvejO6s67uvGZLAnUPHojDXzWChzFqY-2g5-gg8uIj17j0QeOrY8eOyHrb-q16euXQjNMPvhfoo90md0NehB5tiXmRmQMJWZPW9DZYTpmZO8eoPuwbZkoCpp1xpmeKQzhdQCEcW_lLqy4-_D1wjcQZFJBhQee6xv-iE_NQNkQF6SuNyyNS5HgXR3Sobmem1Wn5tN9Jn1MmiT6ooKTfX7laRBfgjcYq4gV0y-00hj6Wo5HAm6_BvHnU_FJyORpOMjmSqaOg0cNFocqGdzv5e58Jd4PN541AIHMF5O7inDp3kSFLROjzbhD1k5GIYmCDTyXBl2u95fDpU4iMlCpwZli1RdjiWiTH65gyKDmrtUkWhcCEv8iiGdlGh0LroRK1sR8yEGBLDrttJsXRUmJRmWxGzSgR5LBg9cGj0OUMD7U_gepRAiO3TLcZRobg1upNxPhlI3HmEf9t7N_WZtBlZdIBQOfAfoFW8fTWP3VSdxEthsRJwMmA_y1qDdbtDNypc_vr4iI_9a7ArsqVDDa_hC2o9B6cEfZF_nXzayIz26tX-ppFVwPhc1ApZoLbyBgKjma012JgLhdpuTRo0ra1u_fStlOJ8yG-10O4Yb8s25vz-h0yroGMqSiRzsf2RkovztcGU1yXtJfJKkjHgCSZvji1BqG6EJ8ZbGjZmvwjXFqRxr0Te6oP5HQpTG48chRec-2kKa4b_41dwpDuXUB6WVJZ6LmOAEp_I6YGbT4se4iQIkR2aB8nwImSyoZonLU7Hjlj5e95nDtkHleyxSsLC0KQk4NzaJvPv8zfiwRBscsb2rXUNiqQV0gBhy_VB6Q7k9Ac5yBAO1FANP3QaGAyja10pWMMe0qQIjC3tEcJzO6NA1-AQykcdbVLyybo4fYsDmX_dNtH81n-zYJqIV_xKKSYyvUnL30UDoMDn62skQOiEw3eFac7gVDL5Frm1SPwQ5d_QdXKx46RJUrwy-OjM6_LKicLt3WoUu5wZszuCsg6xKi_lEr-7SQuBBqNP7qHMLzi-wRf_tzKnLjkuARLuC3rD_0JQt1G3A-aB0d52GoCgcZWukgACT8whygJ46YGe_rdS5WWHmodE9k2W7j4qtuB30Cr3D4O37ZzMK477pSDvc6t-ya2Gc2O5CHktCHuch7u-LFnA7vtwHnPjeVOPMWkgvGYKOCJyxVmUQAB84Hxyeewcgoh2Hd39FD6_I-jhKHE8FKpq7kkJLijdIysdZXv9UgVIhpavgwhfvwVGkqZVrwpsktfChx7Fdb98dCV2Vy5)

PlantUML Diagram Code  

    @startuml
    'https://plantuml.com/sequence-diagram
    !theme cloudscape-design
    skinparam backgroundColor white

    'autonumber
    title
    Payment Initiation and Authorisation
    end title

    == Create Payment ==
    PSU -> TPP: Initiation of payment
    TPP -> XS2A: **POST /v1/{payment-service}/{payment-product}**\npayload: {payment}
    XS2A -> XS2A: validate certificate\nvalidate syntax\ncreate payment resource\nset paymentStatus = "RCVD"
    XS2A --> TPP: paymentId\ntransactionStatus\nlink=startAuthorisation

    == Start Payment Authorisation ==
    TPP -> XS2A: **POST /v1/{payment-service}/{payment-product}/{paymentId}**\n**/authorisations**
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate paymentId\ncreate authorisation resource\nset scaStatus = "received"
    XS2A --> TPP: scaStatus\nlink=updatePsuAuthentication
    TPP --> PSU: Request to provide credentials

    == Credentials Exchange ==
    PSU -> TPP: Credentials
    TPP -> XS2A: **PUT /v1/{payment-service}/{payment-product}/{paymentId}**\n**/authorisations/{authorisationId}:**\npayload: {psuData}
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate paymentId\nvalidate authorisationId
    XS2A -> ASPSP: **Request authorisation for a payment**\n**with payment data**
    ASPSP -> ASPSP: validate syntax\nvalidate psu credentials:\n- if valid then return HTTP 201 Created\nand store required data\n- else - return an error
    ASPSP --> XS2A: HTTP 201 Created
    XS2A -> XS2A: set scaStatus = "psuAuthenticated"

    == Selection of available SCA Methods ==
    XS2A -> ASPSP: **Request available SCA methods**
    ASPSP -> ASPSP: validate syntax\nvalidate if any SCA methods available for psuId:\n- if SCA methods available then return list of SCA methods,\n- else - return an error
    ASPSP --> XS2A: List of SCA methods
    XS2A --> TPP: scaStatus\nlink=selectAuthenticationMethod
    TPP --> PSU: Request to choose SCA method
    PSU -> TPP: Select SCA method
    TPP -> XS2A: **PUT /v1/{payment-service}/{payment-product}/{paymentId}**\n**/authorisations/{authorisationId}**\npayload: {authenticationMethodId}
    XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate paymentId\nvalidate authorisationId
    XS2A -> ASPSP: **Request SCA with given SCA method**
    ASPSP -> ASPSP: validate syntax\nvalidate if given SCA method is available for psuId:\n- if yes then return related info to given SCA method [EMBEDDED | DECOUPLED],\nand generate and send challenge to given psuId,\n- else - return an error

    group #fff5eb Decoupled Flow
        ASPSP -> XS2A: SCA approach = DECOUPLED
        XS2A -> XS2A: set scaStatus = "scaMethodSelected"
        XS2A --> TPP: scaStatus\nchosenScaMethod
        TPP --> PSU: Request to complete authorisation

        note across: ASPSP sends the 2nd factor to PSU.\nPSU provides given 2nd factor through a separate channel (e.g. Bank app). It happens outside the XS2A interface.

        ASPSP -> ASPSP: validate syntax\nvalidate if received challenge data equals to the challenge data\nthat was generated and sent to given psuId:\n- if yes then push TRUE,\n- else - push FALSE
        ASPSP -> XS2A: **Inform XS2A Server about final state**
        XS2A -> XS2A: validate authorisationId\nset scaStatus = "finalised"\nset paymentStatus = "ACTC"
        TPP -> XS2A: **GET /v1/{payment-service}/{payment-product}/{paymentId}/**\n**/authorisations/{authorisationId}**
        XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate paymentId\nvalidate authorisationId
    end

    == or ==

    group #fffaec Embedded Flow
        ASPSP --> XS2A: SCA approach = EMBEDDED
        XS2A -> XS2A: set scaStatus = "scaMethodSelected"
        XS2A --> TPP: scaStatus\nchosenScaMethod\nlink=authoriseTransaction
        TPP --> PSU: Request to provide 2nd factor
        PSU -> TPP: 2nd factor received from the Bank
        TPP -> XS2A: **PUT /v1/{payment-service}/{payment-product}/{paymentId}**\n**/authorisations/{authorisationId}**\npayload: {scaAuthenticationData}
        XS2A -> XS2A: validate certificate\nvalidate syntax\nvalidate paymentId\nvalidate authorisationId
        XS2A -> ASPSP: **Request given SCA data authorisation**
        ASPSP -> ASPSP: validate syntax\nvalidate if received challenge data equals to the challenge data\nthat was generated and sent to given psuId:\n- if yes then return "TRUE",\n- else - return "FALSE"
        ASPSP --> XS2A: Boolean, "true" if successful, else "false"
        XS2A -> XS2A: set scaStatus = "finalised"\nset paymentStatus= "ACTC"
    end

    XS2A --> TPP: scaStatus
    TPP --> PSU: Inform about payment initiation status

    == Payment and Authorisation Status Check ==
    TPP -> XS2A: **GET /v1/{payment-service}/{payment-product}/{paymentId}**\n**/authorisations/{authorisationId}**
    XS2A -> XS2A: validate certificate\nvalidate paymentId\nvalidate syntax
    XS2A --> TPP: Return current payment authorisation status
    TPP -> XS2A: **GET /v1/{payment-service}/{payment-product}/{paymentId}/status**
    XS2A -> XS2A: validate certificate\nvalidate paymentId\nvalidate syntax
    XS2A -> ASPSP: **Request payment status from ASPSP**
    ASPSP -> ASPSP: validate paymentId\n- if paymentId exists then return transactionStatus and funds availability,\n- else - return error
    ASPSP --> XS2A: payment status
    XS2A --> TPP: Return current payment status
    TPP -> PSU: Inform about current payment status

    @enduml

More details about payment authorisation are available at [Initiation and Authorisation of a Payment in Steps](https://documentation.finapi.io/xs2a/03-how-to-initiate-and-authorise-a-payment.md).

### Redirect Flow

![03_authorisation_redirect.png](https://documentation.finapi.io/__attachments/a_948ce61fcbf47c7151e926169101c1ad113b534ac89d4112c8c674104a5734eb/03_authorisation_redirect.png?cb=7012351c18a5562791187ff8ec0e993e)

If an authorisation is rejected, the status of the resource to be authorised does not change. Only the authorisation status itself is set to `failed`.

[PlantUML Link for better readability](https://www.plantuml.com/plantuml/png/jLLDRzj64BtlhvZgabYGh2P7eGgYgaug86W4KsuBL3sCTeVYGijTTdSfrt3ztyiXbmwb52XyoCNmpiURZtcFUXyY-bYNHhmgOgp2V3Qh35gsN4jNpWBzLPELD5KQ3nvByLqig2IGnjKgIAmQ3mLzi28SjQsm2O4zokF1kzggbJFEmtsX8mdn2kleR5tkoOkeeo7naInvDF31k7l8cyXRKjgJZB2iO-6y3XYriuAiWYv3Y4rs1zDtiDrivh2sEkes15mE5JwKP2CqEDBPmF--ljUnW2PbklxfIZGvdFfxzdOvX_5uypdRmkpqPlP72W__98ZmvtYyiyt3E5HpU4p-9uP-J35FWd6-u9tGQ8MHG9AFEjSI8-tiipKys8X_xwpqn4zFmTLUDX618eI8iGwBaIT9-aHgbB3xELFzjU86slhycAIy2HXjZulsaETxUyd4iqUjdcOup0_ZyJSTyXbycMso3JUujhdpPVS6tBiwmbb7WCm41tjwjfE2fZQU7InDDzYMQ247jIvwPk34awz2GtIUsYAzQx3IdxVR3Rpz_WsisfaLz-4JY-zkFor-QFumEMD1a7jd8tEPgSxzlxkuyo1nPxkZIkmrmSVaK6vp3fyhic6O0Dh2RxJ_LTFzpd81umwwMrYsMWh1WgnQNP6DMYRLMFWHxR5FxCJrFBcmBXAu4tckEKbMs1O4U8wJglHRPLF48mMe34hYrdZ-L0KgxqvQaOBz0zixtEkTNUQH_1SB51YWPmiWqwasZQQnOW1ICubMaZ6ahYQW8vHrYE2fSZuoI28SquLVxQO3-MQQw_wEQPbVNRngKD1JNz7b_y529XXZ7vhkRABEV6Tr3WyK9bpIGbM70aRRsxkRKUknxipnOVafkncbwWDE9HNmCubWC4xYqbb3ZKulX1eaPbty0aQvjcXOAQDEYKaUMH9aUxJHG2p90QFbQhjA_VKavVu-tco1USs4BjauxJawlRjTm-jGIqaXN34aUtznnuk87BMfFLsDnu01Ub_xmv7knOdytHTYiMZ8pbEYWSNY_9F6lVpF5wrTsuk_P5fTIBE34U8zMSM_bly2)

PlantUML Diagram Code  

    @startuml
    'https://plantuml.com/sequence-diagram
    !theme cloudscape-design
    skinparam backgroundColor white

    'autonumber
    title
    General Flow for Redirect Authorisation
    end title

    PSU -> TPP: Initiation of payment or consent (with PSU-ID)
    TPP -> XS2A: **POST /v1/[consents|payments]**\npayload: {consent} or {payment}
    XS2A -> XS2A: validate certificate\nvalidate syntax\ncreate resource\nset status="received"
    XS2A --> TPP: consentId or paymentId, status, link=startAuthorisation

    TPP -> XS2A: **POST /v1/[consents|payments]/{id}/authorisations**
    XS2A -> XS2A: validate certificate\nvalidate syntax\ncreate resource\nset status="received"

    XS2A -> ASPSP: **Inform ASPSP about authorisation and to be authorised data**\npayload: consent or payment
    ASPSP -> ASPSP: validate syntax and PSU-ID
    ASPSP -> ASPSP: store data
    ASPSP --> XS2A: **HTTP 201 Created**\nredirectURL=<URL of the frontend for auth>
    XS2A --> TPP: redirectURL\nlink=scaRedirect
    TPP --> PSU: Opens redirectURL in WebView\nfor login and SCA

    group Authentication on Bank WebView
    PSU --> ASPSP:
    note over PSU, ASPSP: The authentication and SCA validation takes place in the WebView provided by the ASPSP.\nAfter the ASPSP has received a result (approved/cancelled), it must report the status to the XS2A server.
    ASPSP --> PSU:
    ASPSP -> ASPSP: prepare result of authorisation and sent to given PSU-ID:\nif yes, then push "TRUE"\nif no, then push "FALSE"
    ASPSP -> XS2A: **Inform XS2A about the status of the authorisation**

    XS2A -> XS2A: scaStatus = "finalised"\nset consentStatus="valid" or paymentStatus= "ACTC"
    ASPSP --> TPP: **GET <URL from TPP-Redirect-URI (success) or TPP-Nok-Redirect-URI (failure)** as Redirect back to the TPP
    end

    == Optional ==
    TPP -> XS2A: **GET /v1/[consents|payments]/{id}/status**
    XS2A -> XS2A: validate certificate\nvalidate id
    XS2A --> TPP: status

    @enduml

It is important, that for the redirect flow, the PSU-ID is also requested from the PSU. There is no need to ask for the password! The PSU-ID is used as identifier for the data provided by the TPP and by the ASPSP to connect everything securely together.

## **Supported SCA methods**

Currently, supported SCA methods

* `CHIP_OTP` - triggers embedded SCA

* `SMS_OTP` - triggers embedded SCA

* `PUSH_OTP` - triggers decoupled SCA

More information about SCA methods can be found in [(OLD) Sandbox Test Accounts and Test Data](https://documentation.finapi.io/xs2a/09-sandbox-test-accounts-and-test-data.md)

### Format for ChipTAN

If a Bank supports ChipTAN, a possible flicker image is provided in the fields `image` or `imageLink`.

For manual data entry, the Bank can return a structure in the `data` field.

As a rule, the information about the manual flicker is Base64-encoded and should correspond to the following structure:
JSON

    {
      "startCode": "12233",
      "infoMessage": "Payment 100 € and account DE12345",
      "manualMessage": "Please press F and enter the start code",
      "flicker": "77819192836"
    }

However, this is only a recommendation to the bank. Therefore, please check the Bank's PSD2 information page to see whether further or different information has been documented there.

---
language: "en"
---
# 03. AIS - Account Information

* [Creation and Authorisation of an AIS Consent in Steps](https://documentation.finapi.io/xs2a/04-how-to-create-and-authorise-an-ais-consent.md)
* [How to Access Account Balances and Transactions](https://documentation.finapi.io/xs2a/05-how-to-access-account-balances-and-transactions.md)
* [How to access transactions older than 90 days (from current date)](https://documentation.finapi.io/xs2a/13-how-to-access-transactions-older-than-90-days-f.md)
* [How to delete an AIS consent](https://documentation.finapi.io/xs2a/17-how-to-delete-an-ais-consent.md)
* [XS2A Consent Models and Access Rights](https://documentation.finapi.io/xs2a/10-xs2a-consent-models-and-access-rights.md)
* [Consent frequency validation](https://documentation.finapi.io/xs2a/16-consent-frequency-validation.md)

[Next Page](https://documentation.finapi.io/llms-full.txt/1)
