From ca0168b2021c6b66fa9caf1b2a20ea822b2447bb Mon Sep 17 00:00:00 2001
From: Valentyn Berezin <vbe@adorsys.com.ua>
Date: Thu, 22 Apr 2021 22:01:18 +0300
Subject: [PATCH 1/6] Initial consent error handling

---
 .../api/errors/ProcessErrorStrings.java       |  8 ++--
 .../xs2a/ais/Xs2aConsentErrorHandler.java     | 44 +++++--------------
 2 files changed, 14 insertions(+), 38 deletions(-)

diff --git a/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java b/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java
index 7df02cdf54..3826d2b96e 100644
--- a/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java
+++ b/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java
@@ -1,9 +1,9 @@
 package de.adorsys.opba.protocol.api.errors;
 
-public final class ProcessErrorStrings {
-    // needed for checkstyle
-    private ProcessErrorStrings() {
-    }
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class ProcessErrorStrings {
 
     public static final String CONSENT_UNKNOWN = "CONSENT_UNKNOWN";
     public static final String CONSENT_EXPIRED = "CONSENT_EXPIRED";
diff --git a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
index 3b15529066..1e67adb153 100644
--- a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
+++ b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
@@ -6,6 +6,8 @@
 import de.adorsys.opba.protocol.api.errors.ProcessErrorStrings;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableProcessError;
 import de.adorsys.xs2a.adapter.api.exception.ErrorResponseException;
+import de.adorsys.xs2a.adapter.api.model.MessageCode;
+import de.adorsys.xs2a.adapter.api.model.TppMessage;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.engine.delegate.DelegateExecution;
 import org.springframework.context.ApplicationEventPublisher;
@@ -27,17 +29,17 @@ private void tryHandleConsentException(DelegateExecution execution, ErrorRespons
             throw ex;
         }
 
-        if (isTppMessage(ex, "ACCESS_EXCEEDED")) {
+        if (isTppMessage(ex, MessageCode.ACCESS_EXCEEDED)) {
             eventPublisher.publishEvent(new InternalReturnableProcessError(execution.getRootProcessInstanceId(), execution.getId(),
                 ProcessErrorStrings.CONSENT_ACCESS_EXCEEDED_LIMIT));
             return;
         }
-        if (isTppMessage(ex, "CONSENT_UNKNOWN")) {
+        if (isTppMessage(ex, MessageCode.CONSENT_UNKNOWN)) {
             eventPublisher.publishEvent(new InternalReturnableProcessError(execution.getRootProcessInstanceId(), execution.getId(),
                 ProcessErrorStrings.CONSENT_UNKNOWN));
             return;
         }
-        if (isTppMessage(ex, "CONSENT_EXPIRED")) {
+        if (isTppMessage(ex, MessageCode.CONSENT_EXPIRED)) {
             eventPublisher.publishEvent(new InternalReturnableProcessError(execution.getRootProcessInstanceId(), execution.getId(),
                 ProcessErrorStrings.CONSENT_EXPIRED));
             return;
@@ -45,37 +47,11 @@ private void tryHandleConsentException(DelegateExecution execution, ErrorRespons
         throw ex;
     }
 
-    private boolean isTppMessage(ErrorResponseException ex, String searchText) {
-        log.debug("I am looking for {} in {}", searchText, ex.getMessage());
-        try {
-            ObjectMapper objectMapper = new ObjectMapper();
-            String message = ex.getMessage();
-            JsonNode object = objectMapper.readTree(message);
-            JsonNode tppMessagesNode = object.get("tppMessages");
-            if (tppMessagesNode.isArray()) {
-                ArrayNode tppMessages = (ArrayNode) tppMessagesNode;
-                for (int i = 0; i < tppMessages.size(); i++) {
-                    JsonNode singleTppMessageNode = tppMessages.get(i);
-                    if (singleTppMessageNode != null) {
-                        JsonNode singleTppMessageNodeCode = singleTppMessageNode.get("code");
-                        if (singleTppMessageNodeCode != null) {
-                            if (searchText.equalsIgnoreCase(singleTppMessageNodeCode.textValue())) {
-                                log.error("FOUND ERROR: {}", searchText);
-                                return true;
-                            }
-                        } else {
-                            log.warn("error during errorhandling: message {} had no code element", message);
-                        }
-                    } else {
-                        log.warn("error during errorhandling: message {} had unknown element", message);
-                    }
-                }
-            }
-
-        } catch (Exception ex2) {
-            ex2.printStackTrace();
-            log.error("exception {} during parsing exception {}", ex2.getMessage(), ex.getMessage());
+    private boolean isTppMessage(ErrorResponseException ex, MessageCode code) {
+        if (ex.getErrorResponse().isEmpty() || null == ex.getErrorResponse().get().getTppMessages()) {
+            return false;
         }
-        return false;
+
+        return ex.getErrorResponse().get().getTppMessages().stream().anyMatch(it -> code.equals(it.getCode()));
     }
 }

From e773ced4012c58254561c552c8e4d508946c691e Mon Sep 17 00:00:00 2001
From: Valentyn Berezin <vbe@adorsys.com.ua>
Date: Thu, 22 Apr 2021 22:02:52 +0300
Subject: [PATCH 2/6] Initial consent error handling

---
 .../protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
index 1e67adb153..3fe0ce012f 100644
--- a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
+++ b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
@@ -25,7 +25,7 @@ public void tryActionOrHandleConsentErrors(DelegateExecution execution, Applicat
     }
 
     private void tryHandleConsentException(DelegateExecution execution, ErrorResponseException ex, ApplicationEventPublisher eventPublisher) {
-        if (!ex.getErrorResponse().isPresent() || null == ex.getErrorResponse().get().getTppMessages()) {
+        if (ex.getErrorResponse().isEmpty() || null == ex.getErrorResponse().get().getTppMessages()) {
             throw ex;
         }
 

From 80fbc04523a5a1f389c4f90dba56a1df7e1a02fa Mon Sep 17 00:00:00 2001
From: Valentyn Berezin <vbe@adorsys.com.ua>
Date: Thu, 22 Apr 2021 23:30:26 +0300
Subject: [PATCH 3/6] Improved mapping handling

---
 ...RuntimeErrorResultWithOwnResponseCode.java | 15 ++++++---
 .../src/main/resources/application.yml        |  5 +++
 .../hbci/entrypoint/HbciOutcomeMapper.java    |  4 +--
 .../api/errors/ProcessErrorConsentGone.java   |  9 +++++
 .../api/errors/ProcessErrorStrings.java       | 11 -------
 ...rnalReturnableConsentGoneProcessError.java | 18 ++++++++++
 .../InternalReturnableProcessError.java       | 15 ---------
 .../bpmnshared/outcome/OutcomeMapper.java     |  4 +--
 .../ProcessEventHandlerRegistrar.java         |  6 ++--
 ...plication-test-one-time-postgres-ramfs.yml |  5 +++
 .../config/aspspmessages/AspspMessages.java   |  5 +++
 .../xs2a/entrypoint/Xs2aOutcomeMapper.java    |  6 ++--
 .../xs2a/ais/Xs2aConsentErrorHandler.java     | 33 ++++++++-----------
 .../src/main/resources/application.yml        |  5 +++
 14 files changed, 80 insertions(+), 61 deletions(-)
 create mode 100644 opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorConsentGone.java
 delete mode 100644 opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java
 create mode 100644 opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableConsentGoneProcessError.java
 delete mode 100644 opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableProcessError.java

diff --git a/opba-banking-protocol-facade/src/main/java/de/adorsys/opba/protocol/facade/dto/result/torest/redirectable/FacadeRuntimeErrorResultWithOwnResponseCode.java b/opba-banking-protocol-facade/src/main/java/de/adorsys/opba/protocol/facade/dto/result/torest/redirectable/FacadeRuntimeErrorResultWithOwnResponseCode.java
index 26f2de3cd5..051a91694d 100644
--- a/opba-banking-protocol-facade/src/main/java/de/adorsys/opba/protocol/facade/dto/result/torest/redirectable/FacadeRuntimeErrorResultWithOwnResponseCode.java
+++ b/opba-banking-protocol-facade/src/main/java/de/adorsys/opba/protocol/facade/dto/result/torest/redirectable/FacadeRuntimeErrorResultWithOwnResponseCode.java
@@ -1,7 +1,7 @@
 package de.adorsys.opba.protocol.facade.dto.result.torest.redirectable;
 
 import de.adorsys.opba.protocol.api.dto.result.body.ReturnableProcessErrorResult;
-import de.adorsys.opba.protocol.api.errors.ProcessErrorStrings;
+import de.adorsys.opba.protocol.api.errors.ProcessErrorConsentGone;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
@@ -19,6 +19,7 @@ public class FacadeRuntimeErrorResultWithOwnResponseCode<T> extends FacadeRuntim
 
     private static final int CONSENT_UNKNOWN_RESPONSE_CODE = 410;
     private static final int CONSENT_EXPIRED_RESPONSE_CODE = 410;
+    private static final int CONSENT_INVALID_RESPONSE_CODE = 410;
     private static final int CONSENT_USAGE_LIMIT_EXCEEDED_HTTP_RESPONSE_CODE = 429;
 
     private int responseCode = DEFAULT_RESPONSE_CODE;
@@ -34,16 +35,20 @@ default FacadeRuntimeErrorResultWithOwnResponseCode map(ReturnableProcessErrorRe
             FacadeRuntimeErrorResultWithOwnResponseCode mapped = new FacadeRuntimeErrorResultWithOwnResponseCode<>();
             map(result, mapped);
             mapped.getHeaders().put(X_ERROR_CODE, result.getErrorCodeString());
-            switch (result.getErrorCodeString()) {
-                case ProcessErrorStrings.CONSENT_ACCESS_EXCEEDED_LIMIT:
+            var code = ProcessErrorConsentGone.valueOf(result.getErrorCodeString());
+            switch (code) {
+                case CONSENT_ACCESS_EXCEEDED_LIMIT:
                     mapped.setResponseCode(CONSENT_USAGE_LIMIT_EXCEEDED_HTTP_RESPONSE_CODE);
                     break;
-                case ProcessErrorStrings.CONSENT_UNKNOWN:
+                case CONSENT_UNKNOWN:
                     mapped.setResponseCode(CONSENT_UNKNOWN_RESPONSE_CODE);
                     break;
-                case ProcessErrorStrings.CONSENT_EXPIRED:
+                case CONSENT_EXPIRED:
                     mapped.setResponseCode(CONSENT_EXPIRED_RESPONSE_CODE);
                     break;
+                case CONSENT_INVALID:
+                    mapped.setResponseCode(CONSENT_INVALID_RESPONSE_CODE);
+                    break;
                 default:
                     mapped.setResponseCode(DEFAULT_RESPONSE_CODE);
                     log.error("did not find specific error for {} to map to specific response code.", result.getErrorCodeString());
diff --git a/opba-embedded-starter/src/main/resources/application.yml b/opba-embedded-starter/src/main/resources/application.yml
index 15b899561e..f9f114c908 100644
--- a/opba-embedded-starter/src/main/resources/application.yml
+++ b/opba-embedded-starter/src/main/resources/application.yml
@@ -233,6 +233,11 @@ protocol:
       invalid-consent: FORMAT_ERROR
       missing-oauth2-token: TOKEN_INVALID
       missing-oauth2-token-message: Please retrieve token first
+      consent-gone:
+        ACCESS_EXCEEDED: CONSENT_ACCESS_EXCEEDED_LIMIT
+        CONSENT_UNKNOWN: CONSENT_UNKNOWN
+        CONSENT_EXPIRED: CONSENT_EXPIRED
+        CONSENT_INVALID: CONSENT_INVALID
     pkcs12:
       keystore: sample-qwac.keystore
       password: password
diff --git a/opba-protocols/hbci-protocol/src/main/java/de/adorsys/opba/protocol/hbci/entrypoint/HbciOutcomeMapper.java b/opba-protocols/hbci-protocol/src/main/java/de/adorsys/opba/protocol/hbci/entrypoint/HbciOutcomeMapper.java
index 9cace46fe0..6813ec864e 100644
--- a/opba-protocols/hbci-protocol/src/main/java/de/adorsys/opba/protocol/hbci/entrypoint/HbciOutcomeMapper.java
+++ b/opba-protocols/hbci-protocol/src/main/java/de/adorsys/opba/protocol/hbci/entrypoint/HbciOutcomeMapper.java
@@ -14,7 +14,7 @@
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ConsentAcquired;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ProcessResponse;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.Redirect;
-import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableProcessError;
+import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableConsentGoneProcessError;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ValidationProblem;
 import de.adorsys.opba.protocol.bpmnshared.outcome.OutcomeMapper;
 import lombok.RequiredArgsConstructor;
@@ -80,7 +80,7 @@ public void onConsentAcquired(ConsentAcquired acquired) {
     }
 
     @Override
-    public void onReturnableProcessError(InternalReturnableProcessError internalReturnableProcessError) {
+    public void onReturnableProcessError(InternalReturnableConsentGoneProcessError internalReturnableProcessError) {
         throw new RuntimeException("NYI");
     }
 
diff --git a/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorConsentGone.java b/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorConsentGone.java
new file mode 100644
index 0000000000..20fbd40444
--- /dev/null
+++ b/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorConsentGone.java
@@ -0,0 +1,9 @@
+package de.adorsys.opba.protocol.api.errors;
+
+public enum ProcessErrorConsentGone {
+
+    CONSENT_UNKNOWN,
+    CONSENT_INVALID,
+    CONSENT_EXPIRED,
+    CONSENT_ACCESS_EXCEEDED_LIMIT;
+}
diff --git a/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java b/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java
deleted file mode 100644
index 3826d2b96e..0000000000
--- a/opba-protocols/opba-protocol-api/src/main/java/de/adorsys/opba/protocol/api/errors/ProcessErrorStrings.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.adorsys.opba.protocol.api.errors;
-
-import lombok.experimental.UtilityClass;
-
-@UtilityClass
-public class ProcessErrorStrings {
-
-    public static final String CONSENT_UNKNOWN = "CONSENT_UNKNOWN";
-    public static final String CONSENT_EXPIRED = "CONSENT_EXPIRED";
-    public static final String CONSENT_ACCESS_EXCEEDED_LIMIT = "CONSENT_ACCESS_EXCEEDED_LIMIT";
-}
diff --git a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableConsentGoneProcessError.java b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableConsentGoneProcessError.java
new file mode 100644
index 0000000000..de7bf7aaa1
--- /dev/null
+++ b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableConsentGoneProcessError.java
@@ -0,0 +1,18 @@
+package de.adorsys.opba.protocol.bpmnshared.dto.messages;
+
+import de.adorsys.opba.protocol.api.errors.ProcessErrorConsentGone;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Getter
+public class InternalReturnableConsentGoneProcessError extends ProcessErrorWithRootProcessId {
+
+    private final ProcessErrorConsentGone consentGone;
+
+    public InternalReturnableConsentGoneProcessError(String rootProcessId, String executionId, ProcessErrorConsentGone processError) {
+        super(rootProcessId, executionId, processError.name(), true);
+        this.consentGone = processError;
+        log.debug("create ReturnableProcessError {} {} {}", rootProcessId, executionId, processError.name());
+    }
+}
diff --git a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableProcessError.java b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableProcessError.java
deleted file mode 100644
index e9f0d3c8dd..0000000000
--- a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/dto/messages/InternalReturnableProcessError.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.adorsys.opba.protocol.bpmnshared.dto.messages;
-
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-@Getter
-public class InternalReturnableProcessError extends ProcessErrorWithRootProcessId {
-    private String processErrorString;
-    public InternalReturnableProcessError(String rootProcessId, String executionId, String processErrorString) {
-        super(rootProcessId, executionId, processErrorString, true);
-        this.processErrorString = processErrorString;
-        log.debug("create ReturnableProcessError {} {} {}", rootProcessId, executionId, processErrorString);
-    }
-}
diff --git a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/outcome/OutcomeMapper.java b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/outcome/OutcomeMapper.java
index 066a03e6a8..96d87697f8 100644
--- a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/outcome/OutcomeMapper.java
+++ b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/outcome/OutcomeMapper.java
@@ -3,7 +3,7 @@
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ConsentAcquired;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ProcessResponse;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.Redirect;
-import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableProcessError;
+import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableConsentGoneProcessError;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ValidationProblem;
 
 /**
@@ -16,6 +16,6 @@ public interface OutcomeMapper<T> {
     void onRedirect(Redirect redirectResult);
     void onValidationProblem(ValidationProblem problem);
     void onConsentAcquired(ConsentAcquired acquired);
-    void onReturnableProcessError(InternalReturnableProcessError internalReturnableProcessError);
+    void onReturnableProcessError(InternalReturnableConsentGoneProcessError internalReturnableProcessError);
     void onError();
 }
diff --git a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/service/eventbus/ProcessEventHandlerRegistrar.java b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/service/eventbus/ProcessEventHandlerRegistrar.java
index eadc1bbaf5..0966977890 100644
--- a/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/service/eventbus/ProcessEventHandlerRegistrar.java
+++ b/opba-protocols/protocol-bpmn-shared/src/main/java/de/adorsys/opba/protocol/bpmnshared/service/eventbus/ProcessEventHandlerRegistrar.java
@@ -3,7 +3,7 @@
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ConsentAcquired;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ProcessResponse;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.Redirect;
-import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableProcessError;
+import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableConsentGoneProcessError;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ValidationProblem;
 import de.adorsys.opba.protocol.bpmnshared.outcome.OutcomeMapper;
 import lombok.RequiredArgsConstructor;
@@ -35,8 +35,8 @@ public <T> void addHandler(String processId, OutcomeMapper<T> mapper) {
         handler.add(
                 processId,
                 procResult -> {
-                    if (procResult instanceof InternalReturnableProcessError) {
-                        mapper.onReturnableProcessError((InternalReturnableProcessError) procResult);
+                    if (procResult instanceof InternalReturnableConsentGoneProcessError) {
+                        mapper.onReturnableProcessError((InternalReturnableConsentGoneProcessError) procResult);
                     } else if (procResult instanceof ProcessResponse) {
                         mapper.onSuccess((ProcessResponse) procResult);
                     } else if (procResult instanceof Redirect) {
diff --git a/opba-protocols/xs2a-protocol-tests/xs2a-bdd-tests-common/src/main/resources/application-test-one-time-postgres-ramfs.yml b/opba-protocols/xs2a-protocol-tests/xs2a-bdd-tests-common/src/main/resources/application-test-one-time-postgres-ramfs.yml
index b92f958b1d..a1ab5cc218 100644
--- a/opba-protocols/xs2a-protocol-tests/xs2a-bdd-tests-common/src/main/resources/application-test-one-time-postgres-ramfs.yml
+++ b/opba-protocols/xs2a-protocol-tests/xs2a-bdd-tests-common/src/main/resources/application-test-one-time-postgres-ramfs.yml
@@ -224,6 +224,11 @@ protocol:
       invalid-consent: FORMAT_ERROR
       missing-oauth2-token: TOKEN_INVALID
       missing-oauth2-token-message: Please retrieve token first
+      consent-gone:
+        ACCESS_EXCEEDED: CONSENT_ACCESS_EXCEEDED_LIMIT
+        CONSENT_UNKNOWN: CONSENT_UNKNOWN
+        CONSENT_EXPIRED: CONSENT_EXPIRED
+        CONSENT_INVALID: CONSENT_INVALID
     pkcs12:
       keystore: sample-qwac.keystore
       password: password
diff --git a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/config/aspspmessages/AspspMessages.java b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/config/aspspmessages/AspspMessages.java
index 7065b6a173..001bd33edc 100644
--- a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/config/aspspmessages/AspspMessages.java
+++ b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/config/aspspmessages/AspspMessages.java
@@ -1,5 +1,6 @@
 package de.adorsys.opba.protocol.xs2a.config.aspspmessages;
 
+import de.adorsys.opba.protocol.api.errors.ProcessErrorConsentGone;
 import de.adorsys.xs2a.adapter.api.model.MessageCode;
 import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -7,6 +8,7 @@
 import org.springframework.validation.annotation.Validated;
 
 import javax.validation.constraints.NotEmpty;
+import java.util.Map;
 import java.util.Set;
 
 import static de.adorsys.opba.protocol.xs2a.config.ConfigConst.XS2A_PROTOCOL_CONFIG_PREFIX;
@@ -34,6 +36,9 @@ public class AspspMessages {
     @NotEmpty
     private Set<MessageCode> invalidConsent;
 
+    @NotEmpty
+    private Map<MessageCode, ProcessErrorConsentGone> consentGone;
+
     /**
      * Represents message templates for the missing OAuth2 token case.
      * TODO: https://github.com/adorsys/open-banking-gateway/issues/976
diff --git a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/entrypoint/Xs2aOutcomeMapper.java b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/entrypoint/Xs2aOutcomeMapper.java
index b3d46da751..28e8a94c23 100644
--- a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/entrypoint/Xs2aOutcomeMapper.java
+++ b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/entrypoint/Xs2aOutcomeMapper.java
@@ -17,7 +17,7 @@
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ProcessResponse;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.Redirect;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.RedirectToAspsp;
-import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableProcessError;
+import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableConsentGoneProcessError;
 import de.adorsys.opba.protocol.bpmnshared.dto.messages.ValidationProblem;
 import de.adorsys.opba.protocol.bpmnshared.outcome.OutcomeMapper;
 import lombok.RequiredArgsConstructor;
@@ -82,8 +82,8 @@ public void onConsentAcquired(ConsentAcquired acquired) {
     }
 
     @Override
-    public void onReturnableProcessError(InternalReturnableProcessError internalReturnableProcessError) {
-        channel.complete(new ReturnableProcessErrorResult<T>(internalReturnableProcessError.getProcessErrorString()));
+    public void onReturnableProcessError(InternalReturnableConsentGoneProcessError internalReturnableProcessError) {
+        channel.complete(new ReturnableProcessErrorResult<>(internalReturnableProcessError.getConsentGone().name()));
     }
 
     @Override
diff --git a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
index 3fe0ce012f..3e32f18fed 100644
--- a/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
+++ b/opba-protocols/xs2a-protocol/src/main/java/de/adorsys/opba/protocol/xs2a/service/xs2a/ais/Xs2aConsentErrorHandler.java
@@ -1,13 +1,10 @@
 package de.adorsys.opba.protocol.xs2a.service.xs2a.ais;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import de.adorsys.opba.protocol.api.errors.ProcessErrorStrings;
-import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableProcessError;
+import de.adorsys.opba.protocol.bpmnshared.dto.messages.InternalReturnableConsentGoneProcessError;
+import de.adorsys.opba.protocol.xs2a.config.aspspmessages.AspspMessages;
 import de.adorsys.xs2a.adapter.api.exception.ErrorResponseException;
 import de.adorsys.xs2a.adapter.api.model.MessageCode;
-import de.adorsys.xs2a.adapter.api.model.TppMessage;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.engine.delegate.DelegateExecution;
 import org.springframework.context.ApplicationEventPublisher;
@@ -15,7 +12,11 @@
 
 @Slf4j
 @Service
+@RequiredArgsConstructor
 public class Xs2aConsentErrorHandler {
+
+    private final AspspMessages messages;
+
     public void tryActionOrHandleConsentErrors(DelegateExecution execution, ApplicationEventPublisher eventPublisher, Runnable tryCreate) {
         try {
             tryCreate.run();
@@ -29,21 +30,13 @@ private void tryHandleConsentException(DelegateExecution execution, ErrorRespons
             throw ex;
         }
 
-        if (isTppMessage(ex, MessageCode.ACCESS_EXCEEDED)) {
-            eventPublisher.publishEvent(new InternalReturnableProcessError(execution.getRootProcessInstanceId(), execution.getId(),
-                ProcessErrorStrings.CONSENT_ACCESS_EXCEEDED_LIMIT));
-            return;
-        }
-        if (isTppMessage(ex, MessageCode.CONSENT_UNKNOWN)) {
-            eventPublisher.publishEvent(new InternalReturnableProcessError(execution.getRootProcessInstanceId(), execution.getId(),
-                ProcessErrorStrings.CONSENT_UNKNOWN));
-            return;
-        }
-        if (isTppMessage(ex, MessageCode.CONSENT_EXPIRED)) {
-            eventPublisher.publishEvent(new InternalReturnableProcessError(execution.getRootProcessInstanceId(), execution.getId(),
-                ProcessErrorStrings.CONSENT_EXPIRED));
-            return;
+        for (var message : messages.getConsentGone().entrySet()) {
+            if (isTppMessage(ex, message.getKey())) {
+                eventPublisher.publishEvent(new InternalReturnableConsentGoneProcessError(execution.getRootProcessInstanceId(), execution.getId(), message.getValue()));
+                return;
+            }
         }
+
         throw ex;
     }
 
diff --git a/opba-protocols/xs2a-protocol/src/main/resources/application.yml b/opba-protocols/xs2a-protocol/src/main/resources/application.yml
index 2ac4f7815e..e15841f1c2 100644
--- a/opba-protocols/xs2a-protocol/src/main/resources/application.yml
+++ b/opba-protocols/xs2a-protocol/src/main/resources/application.yml
@@ -106,6 +106,11 @@ protocol:
       invalid-consent: FORMAT_ERROR
       missing-oauth2-token: TOKEN_INVALID
       missing-oauth2-token-message: Please retrieve token first
+      consent-gone:
+        ACCESS_EXCEEDED: CONSENT_ACCESS_EXCEEDED_LIMIT
+        CONSENT_UNKNOWN: CONSENT_UNKNOWN
+        CONSENT_EXPIRED: CONSENT_EXPIRED
+        CONSENT_INVALID: CONSENT_INVALID
     pkcs12:
       keystore: sample-qwac.keystore
       password: password

From 901eb8c35f0842fb3e5005d68237f61d15e9874e Mon Sep 17 00:00:00 2001
From: Valentyn Berezin <vbe@adorsys.com.ua>
Date: Fri, 23 Apr 2021 13:09:25 +0300
Subject: [PATCH 4/6] Implemented consent DELETE Api

---
 .../src/main/resources/static/fintech_api.yml | 32 +++++++++++++++++++
 .../FinTechAccountInformationImpl.java        | 10 ++++++
 .../repositories/ConsentRepository.java       |  4 +++
 .../fintech/impl/service/ConsentService.java  |  7 ++++
 4 files changed, 53 insertions(+)

diff --git a/fintech-examples/fintech-api/src/main/resources/static/fintech_api.yml b/fintech-examples/fintech-api/src/main/resources/static/fintech_api.yml
index bc2f396aba..f9ac1401fd 100644
--- a/fintech-examples/fintech-api/src/main/resources/static/fintech_api.yml
+++ b/fintech-examples/fintech-api/src/main/resources/static/fintech_api.yml
@@ -418,6 +418,31 @@ paths:
         "401":
           $ref: "#/components/responses/401_Unauthorized"
 
+  /v1/ais/banks/{bank-id}/consents:
+    delete:
+      tags:
+        - FinTechAccountInformation
+      operationId: aisConsentsDELETE
+      summary: Deletes all consents that are associated with bank
+      description: Deletes all consents that are associated with bank
+      parameters:
+        #path
+        - $ref: "#/components/parameters/bank-id"
+
+        #header
+        - $ref: "#/components/parameters/X-Request-ID"
+        - $ref: "#/components/parameters/X-XSRF-TOKEN"
+
+      security:
+        - sessionCookie: [ ]
+      responses:
+        "200":
+          $ref: "#/components/responses/200_ConsentRemovalResult"
+        "401":
+          $ref: "#/components/responses/401_Unauthorized"
+        "404":
+          $ref: "#/components/responses/404_NotFound"
+
   /v1/consent/{userid}/{password}:
     get:
       summary: ask for existing consent of user
@@ -958,6 +983,13 @@ components:
           schema:
             type: object
 
+    200_ConsentRemovalResult:
+      description: List of all removed consents
+      content:
+        application/json:
+          schema:
+            type: object
+
   schemas:
     paymentInitiationWithStatusResponse:
       description: response from open banking gateway
diff --git a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java
index 4fc132fbb5..00a59b37da 100644
--- a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java
+++ b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java
@@ -7,6 +7,7 @@
 import de.adorsys.opba.fintech.impl.controller.utils.LoTRetrievalInformation;
 import de.adorsys.opba.fintech.impl.database.entities.SessionEntity;
 import de.adorsys.opba.fintech.impl.service.AccountService;
+import de.adorsys.opba.fintech.impl.service.ConsentService;
 import de.adorsys.opba.fintech.impl.service.SessionLogicService;
 import de.adorsys.opba.fintech.impl.service.TransactionService;
 import lombok.RequiredArgsConstructor;
@@ -16,6 +17,7 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import java.time.LocalDate;
+import java.util.Map;
 import java.util.UUID;
 
 @Slf4j
@@ -26,6 +28,7 @@ public class FinTechAccountInformationImpl implements FinTechAccountInformationA
     private final SessionLogicService sessionLogicService;
     private final AccountService accountService;
     private final TransactionService transactionService;
+    private final ConsentService consentService;
 
     @Override
     public ResponseEntity<AccountList> aisAccountsGET(String bankId, UUID xRequestID, String xsrfToken,
@@ -56,4 +59,11 @@ public ResponseEntity<TransactionsResponse> aisTransactionsGET(String bankId, St
                 transactionService.listTransactions(sessionEntity, fintechRedirectURLOK, fintechRedirectURLNOK,
                 bankId, accountId, dateFrom, dateTo, entryReferenceFrom, bookingStatus, deltaList, LoTRetrievalInformation.valueOf(loTRetrievalInformation), online));
     }
+
+    @Override
+    public ResponseEntity<Object> aisConsentsDELETE(String bankId, UUID xRequestID, String X_XSRF_TOKEN) {
+        SessionEntity sessionEntity = sessionLogicService.getSession();
+        consentService.deleteAllConsentsOfBank(sessionEntity, bankId);
+        return ResponseEntity.ok().body(Map.of());
+    }
 }
diff --git a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/database/repositories/ConsentRepository.java b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/database/repositories/ConsentRepository.java
index 64f6615c3d..5b5fc7e392 100644
--- a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/database/repositories/ConsentRepository.java
+++ b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/database/repositories/ConsentRepository.java
@@ -3,6 +3,7 @@
 import de.adorsys.opba.fintech.impl.database.entities.ConsentEntity;
 import de.adorsys.opba.fintech.impl.database.entities.UserEntity;
 import de.adorsys.opba.fintech.impl.tppclients.ConsentType;
+import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.repository.CrudRepository;
 
 import java.util.List;
@@ -18,4 +19,7 @@ List<ConsentEntity> findListByUserEntityAndBankIdAndConsentTypeAndConsentConfirm
         bankId, ConsentType consentType, Boolean consentConfirmed);
 
     List<ConsentEntity> findByUserEntityAndConsentTypeAndConsentConfirmedOrderByCreationTimeDesc(UserEntity userEntity, ConsentType consentType, Boolean consentConfirmed);
+
+    @Modifying
+    long deleteByUserEntityAndBankId(UserEntity entity, String bankId);
 }
diff --git a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/service/ConsentService.java b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/service/ConsentService.java
index 090e690ad6..0f876c2e83 100644
--- a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/service/ConsentService.java
+++ b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/service/ConsentService.java
@@ -1,5 +1,6 @@
 package de.adorsys.opba.fintech.impl.service;
 
+import de.adorsys.opba.fintech.impl.database.entities.SessionEntity;
 import de.adorsys.opba.fintech.impl.database.repositories.ConsentRepository;
 import de.adorsys.opba.fintech.impl.properties.TppProperties;
 import de.adorsys.opba.fintech.impl.tppclients.TppConsentClient;
@@ -9,6 +10,7 @@
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 
+import javax.transaction.Transactional;
 import java.util.UUID;
 
 import static de.adorsys.opba.fintech.impl.tppclients.Consts.COMPUTE_FINTECH_ID;
@@ -50,4 +52,9 @@ public boolean confirmPayment(String authId, UUID xRequestId) {
         log.debug("consent confirmation response code: {}", statusCode);
         return statusCode.is2xxSuccessful();
     }
+
+    @Transactional
+    public void deleteAllConsentsOfBank(SessionEntity sessionEntity, String bankId) {
+        consentRepository.deleteByUserEntityAndBankId(sessionEntity.getUserEntity(), bankId);
+    }
 }

From 015622a8800abc035a99c8188cb17246ea685b8b Mon Sep 17 00:00:00 2001
From: Valentyn Berezin <vbe@adorsys.com.ua>
Date: Fri, 23 Apr 2021 13:30:34 +0300
Subject: [PATCH 5/6] Update UI API and add 'Delete in Fintech' button

---
 fintech-examples/fintech-ui/package.json      |   2 +-
 .../src/app/api/.openapi-generator/VERSION    |   2 +-
 .../fintech-ui/src/app/api/README.md          |  25 ++
 .../fintech-ui/src/app/api/api.module.ts      |  11 +-
 .../fintech-ui/src/app/api/api/api.ts         |   4 +-
 .../api/finTechAccountInformation.service.ts  | 263 ++++++++++++++----
 .../api/api/finTechAuthorization.service.ts   | 233 +++++++++++-----
 .../app/api/api/finTechBankSearch.service.ts  | 142 +++++++---
 .../finTechOauth2Authentication.service.ts    |  61 +++-
 ...intechRetrieveAllSinglePayments.service.ts |  77 +++--
 .../api/api/fintechRetrieveConsent.service.ts | 137 +++++++++
 .../fintechSinglePaymentInitiation.service.ts |  93 +++++--
 .../src/app/api/model/accountBalance.ts       |   2 +-
 .../src/app/api/model/accountDetails.ts       |   2 +-
 .../app/api/model/analyticsReportDetails.ts   |  71 +++++
 .../fintech-ui/src/app/api/model/models.ts    |   1 +
 .../src/app/api/model/transactionsResponse.ts |   5 +
 .../src/app/api/model/userProfile.ts          |   2 +-
 .../app/bank/settings/settings.component.html |  10 +-
 .../app/bank/settings/settings.component.ts   |   8 +-
 20 files changed, 920 insertions(+), 231 deletions(-)
 create mode 100644 fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveConsent.service.ts
 create mode 100644 fintech-examples/fintech-ui/src/app/api/model/analyticsReportDetails.ts

diff --git a/fintech-examples/fintech-ui/package.json b/fintech-examples/fintech-ui/package.json
index 7b0094b0f7..86b09df3fa 100644
--- a/fintech-examples/fintech-ui/package.json
+++ b/fintech-examples/fintech-ui/package.json
@@ -3,7 +3,7 @@
   "version": "0.0.0",
   "scripts": {
     "ng": "ng",
-    "openapi-gen": "openapi-generator generate -g typescript-angular -o src/app/api -i ../fintech-api/src/main/resources/static/fintech_api.yml",
+    "openapi-gen": "openapi-generator generate -g typescript-angular -o src/app/api -i ../fintech-api/src/main/resources/static/fintech_api.yml --skip-validate-spec",
     "start": "npm run serve",
     "serve": "ng serve --port=4444 --proxy-config=proxy.conf.json",
     "serve:dev": "ng serve --port=4444 --proxy-config=proxy-conf-dev-backend.js",
diff --git a/fintech-examples/fintech-ui/src/app/api/.openapi-generator/VERSION b/fintech-examples/fintech-ui/src/app/api/.openapi-generator/VERSION
index 078bf8b7dd..ecedc98d1d 100644
--- a/fintech-examples/fintech-ui/src/app/api/.openapi-generator/VERSION
+++ b/fintech-examples/fintech-ui/src/app/api/.openapi-generator/VERSION
@@ -1 +1 @@
-4.2.2
\ No newline at end of file
+4.3.1
\ No newline at end of file
diff --git a/fintech-examples/fintech-ui/src/app/api/README.md b/fintech-examples/fintech-ui/src/app/api/README.md
index 6fdf5e362f..e0c9192e33 100644
--- a/fintech-examples/fintech-ui/src/app/api/README.md
+++ b/fintech-examples/fintech-ui/src/app/api/README.md
@@ -92,6 +92,31 @@ export function apiConfigFactory (): Configuration => {
 export class AppModule {}
 ```
 
+```
+// configuring providers with an authentication service that manages your access tokens
+import { ApiModule, Configuration } from '';
+
+@NgModule({
+    imports: [ ApiModule ],
+    declarations: [ AppComponent ],
+    providers: [
+      {
+        provide: Configuration,
+        useFactory: (authService: AuthService) => new Configuration(
+          {
+            basePath: environment.apiUrl,
+            accessToken: authService.getAccessToken.bind(authService)
+          }
+        ),
+        deps: [AuthService],
+        multi: false
+      }
+    ],
+    bootstrap: [ AppComponent ]
+})
+export class AppModule {}
+```
+
 ```
 import { DefaultApi } from '';
 
diff --git a/fintech-examples/fintech-ui/src/app/api/api.module.ts b/fintech-examples/fintech-ui/src/app/api/api.module.ts
index 92fa029b8a..8dad7db14b 100644
--- a/fintech-examples/fintech-ui/src/app/api/api.module.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api.module.ts
@@ -8,22 +8,17 @@ import { FinTechAuthorizationService } from './api/finTechAuthorization.service'
 import { FinTechBankSearchService } from './api/finTechBankSearch.service';
 import { FinTechOauth2AuthenticationService } from './api/finTechOauth2Authentication.service';
 import { FintechRetrieveAllSinglePaymentsService } from './api/fintechRetrieveAllSinglePayments.service';
+import { FintechRetrieveConsentService } from './api/fintechRetrieveConsent.service';
 import { FintechSinglePaymentInitiationService } from './api/fintechSinglePaymentInitiation.service';
 
 @NgModule({
   imports:      [],
   declarations: [],
   exports:      [],
-  providers: [
-    FinTechAccountInformationService,
-    FinTechAuthorizationService,
-    FinTechBankSearchService,
-    FinTechOauth2AuthenticationService,
-    FintechRetrieveAllSinglePaymentsService,
-    FintechSinglePaymentInitiationService ]
+  providers: []
 })
 export class ApiModule {
-    public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders {
+    public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders<ApiModule> {
         return {
             ngModule: ApiModule,
             providers: [ { provide: Configuration, useFactory: configurationFactory } ]
diff --git a/fintech-examples/fintech-ui/src/app/api/api/api.ts b/fintech-examples/fintech-ui/src/app/api/api/api.ts
index 06fe459d81..f15065d372 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/api.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/api.ts
@@ -8,6 +8,8 @@ export * from './finTechOauth2Authentication.service';
 import { FinTechOauth2AuthenticationService } from './finTechOauth2Authentication.service';
 export * from './fintechRetrieveAllSinglePayments.service';
 import { FintechRetrieveAllSinglePaymentsService } from './fintechRetrieveAllSinglePayments.service';
+export * from './fintechRetrieveConsent.service';
+import { FintechRetrieveConsentService } from './fintechRetrieveConsent.service';
 export * from './fintechSinglePaymentInitiation.service';
 import { FintechSinglePaymentInitiationService } from './fintechSinglePaymentInitiation.service';
-export const APIS = [FinTechAccountInformationService, FinTechAuthorizationService, FinTechBankSearchService, FinTechOauth2AuthenticationService, FintechRetrieveAllSinglePaymentsService, FintechSinglePaymentInitiationService];
+export const APIS = [FinTechAccountInformationService, FinTechAuthorizationService, FinTechBankSearchService, FinTechOauth2AuthenticationService, FintechRetrieveAllSinglePaymentsService, FintechRetrieveConsentService, FintechSinglePaymentInitiationService];
diff --git a/fintech-examples/fintech-ui/src/app/api/api/finTechAccountInformation.service.ts b/fintech-examples/fintech-ui/src/app/api/api/finTechAccountInformation.service.ts
index e900915269..c30d2481e2 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/finTechAccountInformation.service.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/finTechAccountInformation.service.ts
@@ -1,9 +1,9 @@
 /**
  * Open Banking Gateway FinTech Example API
- * This is a sample API that shows how to develop FinTech use cases that invoke banking APIs.  #### User Agent and Cookies This Api assumes * that the PsuUserAgent (hosting the FinTechUI) is a modern web browser that stores httpOnly cookies sent with the redirect under the given domain and path as defined by [RFC 6265](https://tools.ietf.org/html/rfc6265). * that any other PsuUserAgent like a native mobile or a desktop application can simulate this same behavior of a modern browser with respect to Cookies.  #### SessionCookies and XSRF After a PSU is authenticated with the FinTech environment (either through the simple login interface defined here, or through an identity provider), the FinTechApi will establish a session with the FinTechUI. This is done by the mean of using a cookie called SessionCookie. This SessionCookie is protected by a corresponding xsrfToken. The response that sets a SessionCookie also carries a corresponding xsrfToken in the response header named \"X-XSRF-TOKEN\".  It is the responsibility of the FinTechUI to : * parse and store this xsrfToken so that a refresh of a browser window can work. This shall be done using user agent capabilities. A web browser application might decide to store the xsrfToken in the browser localStorage, as the cookie we set are all considered persistent. * make sure that each subsequent request that is carrying the SessionCookie also carries the corresponding xsrfToken as header field (see the request path). * remove this xsrfToken from the localStorage when the corresponding SessionCookie is deleted by a server response (setting cookie value to null).  The main difference between an xsrfToken and a SessionCookie is that the sessionCookie is automatically sent with each matching request. The xsrfToken must be explicitely read and sent by application.  #### API- vs. UI-Redirection For simplicity, this Framework is designed to redirect to FinTechUI not to FinTechApi.  #### Explicite vs. Implicite Redirection We define an \"Implicite redirection\" a case where a web browser react to 30X reponse and automatically redirects to the attached endpoint. We define an \"Explicite Redirection\" as a case where the UI-Application reacts to a 20X response, explicitely parses the attached __Location__ header an uses it to reload the new page in the browser window (or start the new UI-Application in case of native apps).  This framework advocates for explicite redirection passing a __20X__ response to the FinTechUI toghether with the __Location__ parameter.  Processing a response that initiates a redirect, the FinTechUI makes sure following happens, * that the exisitng __SessionCookie__ is deleted, as the user will not have a chance for an explicite logout, * that the corresponding xsrfToken is deleted from the local storage, * that a RedirectCookie set is stored (in case UI is not a web browser), so the user can be authenticated against it when sent back to the FinTechUI. The expiration of the RedirectCookie shall be set to the expected duration of the redirect, * that the corresponding xsrfToken is stored in the local storage (under the same cookie path as the RedirectCookie)  #### Redirecting to the ConsentAuthorisationApi For a redirection to the ConsentAuthorisationApi, a generated AUTH-ID is added to the cookie path and used to distinguish authorization processes from each order. This information (AUTH-ID) must be contained in the back redirect url sent to the ConsentAuthorisationApi in the back channel, so that the FinTechUI can invoke the correct code2Token endpoint when activated.
+ * This is a sample API that shows how to develop FinTech use cases that invoke banking APIs.  #### User Agent and Cookies This Api assumes * that the PsuUserAgent (hosting the FinTechUI) is a modern web browser that stores httpOnly cookies sent with the redirect under the given domain and path as defined by [RFC 6265](https://tools.ietf.org/html/rfc6265). * that any other PsuUserAgent like a native mobile or a desktop application can simulate this same behavior of a modern browser with respect to Cookies.  #### SessionCookies and XSRF After a PSU is authenticated with the FinTech environment (either through the simple login interface defined here, or through an identity provider), the FinTechApi will establish a session with the FinTechUI. This is done by the mean of using a cookie called SessionCookie. This SessionCookie is protected by a corresponding xsrfToken. The response that sets a SessionCookie also carries a corresponding xsrfToken in the response header named \"X-XSRF-TOKEN\".  It is the responsibility of the FinTechUI to : * parse and store this xsrfToken so that a refresh of a browser window can work. This shall be done using user agent capabilities. A web browser application might decide to store the xsrfToken in the browser localStorage, as the cookie we set are all considered persistent. * make sure that each subsequent request that is carrying the SessionCookie also carries the corresponding xsrfToken as header field (see the request path). * remove this xsrfToken from the localStorage when the corresponding SessionCookie is deleted by a server response (setting cookie value to null).  The main difference between an xsrfToken and a SessionCookie is that the sessionCookie is automatically sent with each matching request. The xsrfToken must be explicitely read and sent by application.  #### API- vs. UI-Redirection For simplicity, this Framework is designed to redirect to FinTechUI not to FinTechApi.  #### Explicite vs. Implicite Redirection We define an \"Implicite redirection\" a case where a web browser react to 30X reponse and automatically redirects to the attached endpoint. We define an \"Explicite Redirection\" as a case where the UI-Application reacts to a 20X response, explicitely parses the attached __Location__ header an uses it to reload the new page in the browser window (or start the new UI-Application in case of native apps).  This framework advocates for explicite redirection passing a __20X__ response to the FinTechUI toghether with the __Location__ parameter.  Processing a response that initiates a redirect, the FinTechUI makes sure following happens, * that the exisitng __SessionCookie__ is deleted, as the user will not have a chance for an explicite logout, * that the corresponding xsrfToken is deleted from the local storage, * that a RedirectCookie set is stored (in case UI is not a web browser), so the user can be authenticated against it when sent back to the FinTechUI. The expiration of the RedirectCookie shall be set to the expected duration of the redirect, * that the corresponding xsrfToken is stored in the local storage (under the same cookie path as the RedirectCookie)  #### Redirecting to the ConsentAuthorisationApi For a redirection to the ConsentAuthorisationApi, a generated AUTH-ID is added to the cookie path and used to distinguish authorization processes from each order. This information (AUTH-ID) must be contained in the back redirect url sent to the ConsentAuthorisationApi in the back channel, so that the FinTechUI can invoke the correct code2Token endpoint when activated. 
  *
  * The version of the OpenAPI document: 1.0.0
- *
+ * 
  *
  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
  * https://openapi-generator.tech
@@ -17,10 +17,10 @@ import { HttpClient, HttpHeaders, HttpParams,
 import { CustomHttpParameterCodec }                          from '../encoder';
 import { Observable }                                        from 'rxjs';
 
-import { AccountList } from '../model/accountList';
-import { ErrorResponse } from '../model/errorResponse';
-import { PsuMessage } from '../model/psuMessage';
-import { TransactionsResponse } from '../model/transactionsResponse';
+import { AccountList } from '../model/models';
+import { ErrorResponse } from '../model/models';
+import { PsuMessage } from '../model/models';
+import { TransactionsResponse } from '../model/models';
 
 import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
 import { Configuration }                                     from '../configuration';
@@ -52,32 +52,68 @@ export class FinTechAccountInformationService {
 
 
 
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
     /**
      * Provides list of available accounts for the given bank
-     * Read the identifiers of the available payment accounts.  If required by the bank, PSU consent will be obtained before returning the list of bank accounts.  Returns all identifiers of the accounts, to which an account access has been granted to by the PSU. In addition, relevant information about the accounts and hyperlinks to corresponding account information resources are provided if a related consent has been already granted.
-     * @param bankId
-     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well.
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie.
-     * @param fintechRedirectURLOK
-     * @param fintechRedirectURLNOK
-     * @param loARetrievalInformation
+     * Read the identifiers of the available payment accounts.  If required by the bank, PSU consent will be obtained before returning the list of bank accounts.  Returns all identifiers of the accounts, to which an account access has been granted to by the PSU. In addition, relevant information about the accounts and hyperlinks to corresponding account information resources are provided if a related consent has been already granted. 
+     * @param bankId 
+     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param fintechRedirectURLOK 
+     * @param fintechRedirectURLNOK 
+     * @param loARetrievalInformation 
      * @param withBalance Provides balances for the given accounts
-     * @param online If false, new data will be requested and cache will be updated
+     * @param online If true, new data will be requested and cache will be updated 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public aisAccountsGET(bankId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe?: 'body', reportProgress?: boolean): Observable<AccountList>;
-    public aisAccountsGET(bankId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<AccountList>>;
-    public aisAccountsGET(bankId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<AccountList>>;
-    public aisAccountsGET(bankId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public aisAccountsGET(bankId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<AccountList>;
+    public aisAccountsGET(bankId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<AccountList>>;
+    public aisAccountsGET(bankId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<AccountList>>;
+    public aisAccountsGET(bankId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loARetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', withBalance?: boolean, online?: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (bankId === null || bankId === undefined) {
             throw new Error('Required parameter bankId was null or undefined when calling aisAccountsGET.');
         }
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling aisAccountsGET.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling aisAccountsGET.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling aisAccountsGET.');
         }
         if (fintechRedirectURLOK === null || fintechRedirectURLOK === undefined) {
             throw new Error('Required parameter fintechRedirectURLOK was null or undefined when calling aisAccountsGET.');
@@ -91,18 +127,20 @@ export class FinTechAccountInformationService {
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (withBalance !== undefined && withBalance !== null) {
-            queryParameters = queryParameters.set('withBalance', <any>withBalance);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>withBalance, 'withBalance');
         }
         if (online !== undefined && online !== null) {
-            queryParameters = queryParameters.set('online', <any>online);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>online, 'online');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
         if (fintechRedirectURLOK !== undefined && fintechRedirectURLOK !== null) {
             headers = headers.set('Fintech-Redirect-URL-OK', String(fintechRedirectURLOK));
@@ -115,19 +153,101 @@ export class FinTechAccountInformationService {
         }
 
         // authentication (sessionCookie) required
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        if (this.configuration.apiKeys) {
+            const key: string | undefined = this.configuration.apiKeys["sessionCookie"] || this.configuration.apiKeys["sessionCookie"];
+            if (key) {
+            }
+        }
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<AccountList>(`${this.configuration.basePath}/v1/ais/banks/${encodeURIComponent(String(bankId))}/accounts`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
+                withCredentials: this.configuration.withCredentials,
+                headers: headers,
+                observe: observe,
+                reportProgress: reportProgress
+            }
+        );
+    }
+
+    /**
+     * Deletes all consents that are associated with bank
+     * Deletes all consents that are associated with bank
+     * @param bankId 
+     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+     * @param reportProgress flag to report request and response progress.
+     */
+    public aisConsentsDELETE(bankId: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<object>;
+    public aisConsentsDELETE(bankId: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<object>>;
+    public aisConsentsDELETE(bankId: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<object>>;
+    public aisConsentsDELETE(bankId: string, xRequestID: string, xXSRFTOKEN: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
+        if (bankId === null || bankId === undefined) {
+            throw new Error('Required parameter bankId was null or undefined when calling aisConsentsDELETE.');
+        }
+        if (xRequestID === null || xRequestID === undefined) {
+            throw new Error('Required parameter xRequestID was null or undefined when calling aisConsentsDELETE.');
+        }
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling aisConsentsDELETE.');
+        }
+
+        let headers = this.defaultHeaders;
+        if (xRequestID !== undefined && xRequestID !== null) {
+            headers = headers.set('X-Request-ID', String(xRequestID));
+        }
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
+        }
+
+        // authentication (sessionCookie) required
+        if (this.configuration.apiKeys) {
+            const key: string | undefined = this.configuration.apiKeys["sessionCookie"] || this.configuration.apiKeys["sessionCookie"];
+            if (key) {
+            }
+        }
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
+        if (httpHeaderAcceptSelected !== undefined) {
+            headers = headers.set('Accept', httpHeaderAcceptSelected);
+        }
+
+
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
+        return this.httpClient.delete<object>(`${this.configuration.basePath}/v1/ais/banks/${encodeURIComponent(String(bankId))}/consents`,
+            {
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
@@ -139,26 +259,26 @@ export class FinTechAccountInformationService {
     /**
      * Returns the list of transactions of the given account
      * Returns the list of transactions of the given account.
-     * @param bankId
-     * @param accountId
-     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well.
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie.
-     * @param fintechRedirectURLOK
-     * @param fintechRedirectURLNOK
-     * @param loTRetrievalInformation
-     * @param dateFrom Conditional: Starting date (inclusive the date dateFrom) of the transaction list, mandated if no delta access is required.  For booked transactions, the relevant date is the booking date.  For pending transactions, the relevant date is the entry date, which may not be transparent neither in this API nor other channels of the ASPSP.
-     * @param dateTo End date (inclusive the data dateTo) of the transaction list, default is \&quot;now\&quot; if not given.  Might be ignored if a delta function is used.  For booked transactions, the relevant date is the booking date.  For pending transactions, the relevant date is the entry date, which may not be transparent neither in this API nor other channels of the ASPSP.
-     * @param entryReferenceFrom This data attribute is indicating that the AISP is in favour to get all transactions after the transaction with identification entryReferenceFrom alternatively to the above defined period. This is a implementation of a delta access. If this data element is contained, the entries \&quot;dateFrom\&quot; and \&quot;dateTo\&quot; might be ignored by the ASPSP if a delta report is supported.  Optional if supported by API provider.
-     * @param bookingStatus Permitted codes are   * \&quot;booked\&quot;,   * \&quot;pending\&quot; and   * \&quot;both\&quot; To support the \&quot;pending\&quot; and \&quot;both\&quot; feature is optional for the ASPSP, Error code if not supported in the online banking frontend Default is \&quot;booked\&quot;
-     * @param deltaList This data attribute is indicating that the AISP is in favour to get all transactions after the last report access for this PSU on the addressed account. This is another implementation of a delta access-report.  This delta indicator might be rejected by the ASPSP if this function is not supported.  Optional if supported by API provider
-     * @param online If false, new data will be requested and cache will be updated
+     * @param bankId 
+     * @param accountId 
+     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param fintechRedirectURLOK 
+     * @param fintechRedirectURLNOK 
+     * @param loTRetrievalInformation 
+     * @param dateFrom Conditional: Starting date (inclusive the date dateFrom) of the transaction list, mandated if no delta access is required.  For booked transactions, the relevant date is the booking date.  For pending transactions, the relevant date is the entry date, which may not be transparent neither in this API nor other channels of the ASPSP. 
+     * @param dateTo End date (inclusive the data dateTo) of the transaction list, default is \&quot;now\&quot; if not given.  Might be ignored if a delta function is used.  For booked transactions, the relevant date is the booking date.  For pending transactions, the relevant date is the entry date, which may not be transparent neither in this API nor other channels of the ASPSP. 
+     * @param entryReferenceFrom This data attribute is indicating that the AISP is in favour to get all transactions after the transaction with identification entryReferenceFrom alternatively to the above defined period. This is a implementation of a delta access. If this data element is contained, the entries \&quot;dateFrom\&quot; and \&quot;dateTo\&quot; might be ignored by the ASPSP if a delta report is supported.  Optional if supported by API provider. 
+     * @param bookingStatus Permitted codes are   * \&quot;booked\&quot;,   * \&quot;pending\&quot; and   * \&quot;both\&quot; To support the \&quot;pending\&quot; and \&quot;both\&quot; feature is optional for the ASPSP, Error code if not supported in the online banking frontend Default is \&quot;booked\&quot; 
+     * @param deltaList This data attribute is indicating that the AISP is in favour to get all transactions after the last report access for this PSU on the addressed account. This is another implementation of a delta access-report.  This delta indicator might be rejected by the ASPSP if this function is not supported.  Optional if supported by API provider 
+     * @param online If true, new data will be requested and cache will be updated 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe?: 'body', reportProgress?: boolean): Observable<TransactionsResponse>;
-    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<TransactionsResponse>>;
-    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<TransactionsResponse>>;
-    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<TransactionsResponse>;
+    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<TransactionsResponse>>;
+    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<TransactionsResponse>>;
+    public aisTransactionsGET(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, loTRetrievalInformation: 'FROM_TPP_WITH_AVAILABLE_CONSENT' | 'FROM_TPP_WITH_NEW_CONSENT', dateFrom?: string, dateTo?: string, entryReferenceFrom?: string, bookingStatus?: 'booked' | 'pending' | 'both', deltaList?: boolean, online?: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (bankId === null || bankId === undefined) {
             throw new Error('Required parameter bankId was null or undefined when calling aisTransactionsGET.');
         }
@@ -168,8 +288,8 @@ export class FinTechAccountInformationService {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling aisTransactionsGET.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling aisTransactionsGET.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling aisTransactionsGET.');
         }
         if (fintechRedirectURLOK === null || fintechRedirectURLOK === undefined) {
             throw new Error('Required parameter fintechRedirectURLOK was null or undefined when calling aisTransactionsGET.');
@@ -183,30 +303,36 @@ export class FinTechAccountInformationService {
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (dateFrom !== undefined && dateFrom !== null) {
-            queryParameters = queryParameters.set('dateFrom', <any>dateFrom);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>dateFrom, 'dateFrom');
         }
         if (dateTo !== undefined && dateTo !== null) {
-            queryParameters = queryParameters.set('dateTo', <any>dateTo);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>dateTo, 'dateTo');
         }
         if (entryReferenceFrom !== undefined && entryReferenceFrom !== null) {
-            queryParameters = queryParameters.set('entryReferenceFrom', <any>entryReferenceFrom);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>entryReferenceFrom, 'entryReferenceFrom');
         }
         if (bookingStatus !== undefined && bookingStatus !== null) {
-            queryParameters = queryParameters.set('bookingStatus', <any>bookingStatus);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>bookingStatus, 'bookingStatus');
         }
         if (deltaList !== undefined && deltaList !== null) {
-            queryParameters = queryParameters.set('deltaList', <any>deltaList);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>deltaList, 'deltaList');
         }
         if (online !== undefined && online !== null) {
-            queryParameters = queryParameters.set('online', <any>online);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>online, 'online');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
         if (fintechRedirectURLOK !== undefined && fintechRedirectURLOK !== null) {
             headers = headers.set('Fintech-Redirect-URL-OK', String(fintechRedirectURLOK));
@@ -219,19 +345,34 @@ export class FinTechAccountInformationService {
         }
 
         // authentication (sessionCookie) required
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        if (this.configuration.apiKeys) {
+            const key: string | undefined = this.configuration.apiKeys["sessionCookie"] || this.configuration.apiKeys["sessionCookie"];
+            if (key) {
+            }
+        }
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<TransactionsResponse>(`${this.configuration.basePath}/v1/ais/banks/${encodeURIComponent(String(bankId))}/accounts/${encodeURIComponent(String(accountId))}/transactions`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
diff --git a/fintech-examples/fintech-ui/src/app/api/api/finTechAuthorization.service.ts b/fintech-examples/fintech-ui/src/app/api/api/finTechAuthorization.service.ts
index 0bba6b26d1..938016cc90 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/finTechAuthorization.service.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/finTechAuthorization.service.ts
@@ -17,10 +17,10 @@ import { HttpClient, HttpHeaders, HttpParams,
 import { CustomHttpParameterCodec }                          from '../encoder';
 import { Observable }                                        from 'rxjs';
 
-import { ErrorResponse } from '../model/errorResponse';
-import { InlineResponse200 } from '../model/inlineResponse200';
-import { LoginRequest } from '../model/loginRequest';
-import { PsuMessage } from '../model/psuMessage';
+import { ErrorResponse } from '../model/models';
+import { InlineResponse200 } from '../model/models';
+import { LoginRequest } from '../model/models';
+import { PsuMessage } from '../model/models';
 
 import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
 import { Configuration }                                     from '../configuration';
@@ -52,6 +52,42 @@ export class FinTechAuthorizationService {
 
 
 
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
     /**
      * Oauth2 callback to identify user.
      * Oauth2 callback to authenticate user using some Oauth2 identity provider account. Provider id is set inside state. 
@@ -62,10 +98,10 @@ export class FinTechAuthorizationService {
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe?: 'body', reportProgress?: boolean): Observable<InlineResponse200>;
-    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<InlineResponse200>>;
-    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<InlineResponse200>>;
-    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<InlineResponse200>;
+    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<InlineResponse200>>;
+    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<InlineResponse200>>;
+    public callbackGetLogin(code: string, state: string, scope: string, error?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (code === null || code === undefined) {
             throw new Error('Required parameter code was null or undefined when calling callbackGetLogin.');
         }
@@ -78,33 +114,46 @@ export class FinTechAuthorizationService {
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (code !== undefined && code !== null) {
-            queryParameters = queryParameters.set('code', <any>code);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>code, 'code');
         }
         if (state !== undefined && state !== null) {
-            queryParameters = queryParameters.set('state', <any>state);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>state, 'state');
         }
         if (scope !== undefined && scope !== null) {
-            queryParameters = queryParameters.set('scope', <any>scope);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>scope, 'scope');
         }
         if (error !== undefined && error !== null) {
-            queryParameters = queryParameters.set('error', <any>error);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>error, 'error');
         }
 
         let headers = this.defaultHeaders;
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<InlineResponse200>(`${this.configuration.basePath}/v1/login/oauth2`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
@@ -120,14 +169,14 @@ export class FinTechAuthorizationService {
      * @param okOrNotok 
      * @param redirectCode 
      * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
-    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
-    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
-    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<any>;
+    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<any>>;
+    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<any>>;
+    public fromConsentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (authId === null || authId === undefined) {
             throw new Error('Required parameter authId was null or undefined when calling fromConsentGET.');
         }
@@ -140,36 +189,46 @@ export class FinTechAuthorizationService {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling fromConsentGET.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling fromConsentGET.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling fromConsentGET.');
         }
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (redirectCode !== undefined && redirectCode !== null) {
-            queryParameters = queryParameters.set('redirectCode', <any>redirectCode);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>redirectCode, 'redirectCode');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<any>(`${this.configuration.basePath}/v1/${encodeURIComponent(String(authId))}/fromConsent/${encodeURIComponent(String(okOrNotok))}`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
@@ -185,14 +244,14 @@ export class FinTechAuthorizationService {
      * @param okOrNotok 
      * @param redirectCode 
      * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
-    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
-    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
-    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, X_XSRF_TOKEN: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<any>;
+    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<any>>;
+    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<any>>;
+    public fromPaymentGET(authId: string, okOrNotok: 'OK' | 'NOT_OK', redirectCode: string, xRequestID: string, xXSRFTOKEN: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (authId === null || authId === undefined) {
             throw new Error('Required parameter authId was null or undefined when calling fromPaymentGET.');
         }
@@ -205,36 +264,46 @@ export class FinTechAuthorizationService {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling fromPaymentGET.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling fromPaymentGET.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling fromPaymentGET.');
         }
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (redirectCode !== undefined && redirectCode !== null) {
-            queryParameters = queryParameters.set('redirectCode', <any>redirectCode);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>redirectCode, 'redirectCode');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<any>(`${this.configuration.basePath}/v1/${encodeURIComponent(String(authId))}/fromPayment/${encodeURIComponent(String(okOrNotok))}`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
@@ -251,10 +320,10 @@ export class FinTechAuthorizationService {
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe?: 'body', reportProgress?: boolean): Observable<InlineResponse200>;
-    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<InlineResponse200>>;
-    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<InlineResponse200>>;
-    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<InlineResponse200>;
+    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<InlineResponse200>>;
+    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<InlineResponse200>>;
+    public loginPOST(xRequestID: string, loginRequest: LoginRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling loginPOST.');
         }
@@ -267,11 +336,14 @@ export class FinTechAuthorizationService {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
@@ -286,9 +358,15 @@ export class FinTechAuthorizationService {
             headers = headers.set('Content-Type', httpContentTypeSelected);
         }
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.post<InlineResponse200>(`${this.configuration.basePath}/v1/login`,
             loginRequest,
             {
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
@@ -301,43 +379,58 @@ export class FinTechAuthorizationService {
      * logs out user
      * If user can be authenticated, user will be logged out.
      * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public logoutPOST(xRequestID: string, X_XSRF_TOKEN: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
-    public logoutPOST(xRequestID: string, X_XSRF_TOKEN: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
-    public logoutPOST(xRequestID: string, X_XSRF_TOKEN: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
-    public logoutPOST(xRequestID: string, X_XSRF_TOKEN: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public logoutPOST(xRequestID: string, xXSRFTOKEN: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<any>;
+    public logoutPOST(xRequestID: string, xXSRFTOKEN: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<any>>;
+    public logoutPOST(xRequestID: string, xXSRFTOKEN: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<any>>;
+    public logoutPOST(xRequestID: string, xXSRFTOKEN: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling logoutPOST.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling logoutPOST.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling logoutPOST.');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
 
         // authentication (sessionCookie) required
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        if (this.configuration.apiKeys) {
+            const key: string | undefined = this.configuration.apiKeys["sessionCookie"] || this.configuration.apiKeys["sessionCookie"];
+            if (key) {
+            }
+        }
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.post<any>(`${this.configuration.basePath}/v1/logout`,
             null,
             {
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
diff --git a/fintech-examples/fintech-ui/src/app/api/api/finTechBankSearch.service.ts b/fintech-examples/fintech-ui/src/app/api/api/finTechBankSearch.service.ts
index cd14d0a864..cd2c26c86d 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/finTechBankSearch.service.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/finTechBankSearch.service.ts
@@ -17,10 +17,10 @@ import { HttpClient, HttpHeaders, HttpParams,
 import { CustomHttpParameterCodec }                          from '../encoder';
 import { Observable }                                        from 'rxjs';
 
-import { ErrorResponse } from '../model/errorResponse';
-import { InlineResponse2001 } from '../model/inlineResponse2001';
-import { InlineResponse2002 } from '../model/inlineResponse2002';
-import { PsuMessage } from '../model/psuMessage';
+import { ErrorResponse } from '../model/models';
+import { InlineResponse2001 } from '../model/models';
+import { InlineResponse2002 } from '../model/models';
+import { PsuMessage } from '../model/models';
 
 import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
 import { Configuration }                                     from '../configuration';
@@ -52,24 +52,60 @@ export class FinTechBankSearchService {
 
 
 
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
     /**
      * Request the profile of the bank identified with id (bankId).
      * Request the profile of the bank identified with id (bankId).
      * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
      * @param bankId Identifier of the bank to be loaded.
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public bankProfileGET(xRequestID: string, X_XSRF_TOKEN: string, bankId: string, observe?: 'body', reportProgress?: boolean): Observable<InlineResponse2002>;
-    public bankProfileGET(xRequestID: string, X_XSRF_TOKEN: string, bankId: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<InlineResponse2002>>;
-    public bankProfileGET(xRequestID: string, X_XSRF_TOKEN: string, bankId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<InlineResponse2002>>;
-    public bankProfileGET(xRequestID: string, X_XSRF_TOKEN: string, bankId: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public bankProfileGET(xRequestID: string, xXSRFTOKEN: string, bankId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<InlineResponse2002>;
+    public bankProfileGET(xRequestID: string, xXSRFTOKEN: string, bankId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<InlineResponse2002>>;
+    public bankProfileGET(xRequestID: string, xXSRFTOKEN: string, bankId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<InlineResponse2002>>;
+    public bankProfileGET(xRequestID: string, xXSRFTOKEN: string, bankId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling bankProfileGET.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling bankProfileGET.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling bankProfileGET.');
         }
         if (bankId === null || bankId === undefined) {
             throw new Error('Required parameter bankId was null or undefined when calling bankProfileGET.');
@@ -77,31 +113,47 @@ export class FinTechBankSearchService {
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (bankId !== undefined && bankId !== null) {
-            queryParameters = queryParameters.set('bankId', <any>bankId);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>bankId, 'bankId');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
 
         // authentication (sessionCookie) required
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        if (this.configuration.apiKeys) {
+            const key: string | undefined = this.configuration.apiKeys["sessionCookie"] || this.configuration.apiKeys["sessionCookie"];
+            if (key) {
+            }
+        }
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<InlineResponse2002>(`${this.configuration.basePath}/v1/search/bankProfile`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
@@ -114,22 +166,22 @@ export class FinTechBankSearchService {
      * Issues an incremental bank search request to the FinTechApi.
      * Issues an incremental bank search request to the FinTechApi.
      * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
      * @param keyword 
      * @param start 
      * @param max 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public bankSearchGET(xRequestID: string, X_XSRF_TOKEN: string, keyword: string, start?: number, max?: number, observe?: 'body', reportProgress?: boolean): Observable<InlineResponse2001>;
-    public bankSearchGET(xRequestID: string, X_XSRF_TOKEN: string, keyword: string, start?: number, max?: number, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<InlineResponse2001>>;
-    public bankSearchGET(xRequestID: string, X_XSRF_TOKEN: string, keyword: string, start?: number, max?: number, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<InlineResponse2001>>;
-    public bankSearchGET(xRequestID: string, X_XSRF_TOKEN: string, keyword: string, start?: number, max?: number, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public bankSearchGET(xRequestID: string, xXSRFTOKEN: string, keyword: string, start?: number, max?: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<InlineResponse2001>;
+    public bankSearchGET(xRequestID: string, xXSRFTOKEN: string, keyword: string, start?: number, max?: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<InlineResponse2001>>;
+    public bankSearchGET(xRequestID: string, xXSRFTOKEN: string, keyword: string, start?: number, max?: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<InlineResponse2001>>;
+    public bankSearchGET(xRequestID: string, xXSRFTOKEN: string, keyword: string, start?: number, max?: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling bankSearchGET.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling bankSearchGET.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling bankSearchGET.');
         }
         if (keyword === null || keyword === undefined) {
             throw new Error('Required parameter keyword was null or undefined when calling bankSearchGET.');
@@ -137,37 +189,55 @@ export class FinTechBankSearchService {
 
         let queryParameters = new HttpParams({encoder: this.encoder});
         if (keyword !== undefined && keyword !== null) {
-            queryParameters = queryParameters.set('keyword', <any>keyword);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>keyword, 'keyword');
         }
         if (start !== undefined && start !== null) {
-            queryParameters = queryParameters.set('start', <any>start);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>start, 'start');
         }
         if (max !== undefined && max !== null) {
-            queryParameters = queryParameters.set('max', <any>max);
+          queryParameters = this.addToHttpParams(queryParameters,
+            <any>max, 'max');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
 
         // authentication (sessionCookie) required
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        if (this.configuration.apiKeys) {
+            const key: string | undefined = this.configuration.apiKeys["sessionCookie"] || this.configuration.apiKeys["sessionCookie"];
+            if (key) {
+            }
+        }
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<InlineResponse2001>(`${this.configuration.basePath}/v1/search/bankSearch`,
             {
                 params: queryParameters,
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
diff --git a/fintech-examples/fintech-ui/src/app/api/api/finTechOauth2Authentication.service.ts b/fintech-examples/fintech-ui/src/app/api/api/finTechOauth2Authentication.service.ts
index 82e36f1f2a..79a9d29dcd 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/finTechOauth2Authentication.service.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/finTechOauth2Authentication.service.ts
@@ -48,6 +48,42 @@ export class FinTechOauth2AuthenticationService {
 
 
 
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
     /**
      * Identifies the PSU in the Realm of the FinTechApi using his Gmail or other IDP provider account.
      * Use Oauth2 for Gmail users\&#39; account to identify him 
@@ -56,10 +92,10 @@ export class FinTechOauth2AuthenticationService {
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe?: 'body', reportProgress?: boolean): Observable<any>;
-    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
-    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
-    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<any>;
+    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<HttpResponse<any>>;
+    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<HttpEvent<any>>;
+    public oauthLoginPOST(xRequestID: string, idpProvider: 'gmail', observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined}): Observable<any> {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling oauthLoginPOST.');
         }
@@ -72,18 +108,27 @@ export class FinTechOauth2AuthenticationService {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.post<any>(`${this.configuration.basePath}/v1/oauth2/${encodeURIComponent(String(idpProvider))}/login`,
             null,
             {
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
diff --git a/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveAllSinglePayments.service.ts b/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveAllSinglePayments.service.ts
index e47557badc..7ce7c7465e 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveAllSinglePayments.service.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveAllSinglePayments.service.ts
@@ -17,8 +17,8 @@ import { HttpClient, HttpHeaders, HttpParams,
 import { CustomHttpParameterCodec }                          from '../encoder';
 import { Observable }                                        from 'rxjs';
 
-import { ErrorResponse } from '../model/errorResponse';
-import { PaymentInitiationWithStatusResponse } from '../model/paymentInitiationWithStatusResponse';
+import { ErrorResponse } from '../model/models';
+import { PaymentInitiationWithStatusResponse } from '../model/models';
 
 import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
 import { Configuration }                                     from '../configuration';
@@ -50,20 +50,56 @@ export class FintechRetrieveAllSinglePaymentsService {
 
 
 
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
     /**
      * Ask for all payments of this account
      * This method is used to get payment status.
      * @param bankId 
      * @param accountId 
      * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'body', reportProgress?: boolean): Observable<Array<PaymentInitiationWithStatusResponse>>;
-    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Array<PaymentInitiationWithStatusResponse>>>;
-    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Array<PaymentInitiationWithStatusResponse>>>;
-    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<Array<PaymentInitiationWithStatusResponse>>;
+    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<Array<PaymentInitiationWithStatusResponse>>>;
+    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<Array<PaymentInitiationWithStatusResponse>>>;
+    public retrieveAllSinglePayments(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (bankId === null || bankId === undefined) {
             throw new Error('Required parameter bankId was null or undefined when calling retrieveAllSinglePayments.');
         }
@@ -73,30 +109,39 @@ export class FintechRetrieveAllSinglePaymentsService {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling retrieveAllSinglePayments.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling retrieveAllSinglePayments.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling retrieveAllSinglePayments.');
         }
 
         let headers = this.defaultHeaders;
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
 
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.get<Array<PaymentInitiationWithStatusResponse>>(`${this.configuration.basePath}/v1/pis/banks/${encodeURIComponent(String(bankId))}/accounts/${encodeURIComponent(String(accountId))}/payments/single`,
             {
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
diff --git a/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveConsent.service.ts b/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveConsent.service.ts
new file mode 100644
index 0000000000..1012a08dfe
--- /dev/null
+++ b/fintech-examples/fintech-ui/src/app/api/api/fintechRetrieveConsent.service.ts
@@ -0,0 +1,137 @@
+/**
+ * Open Banking Gateway FinTech Example API
+ * This is a sample API that shows how to develop FinTech use cases that invoke banking APIs.  #### User Agent and Cookies This Api assumes * that the PsuUserAgent (hosting the FinTechUI) is a modern web browser that stores httpOnly cookies sent with the redirect under the given domain and path as defined by [RFC 6265](https://tools.ietf.org/html/rfc6265). * that any other PsuUserAgent like a native mobile or a desktop application can simulate this same behavior of a modern browser with respect to Cookies.  #### SessionCookies and XSRF After a PSU is authenticated with the FinTech environment (either through the simple login interface defined here, or through an identity provider), the FinTechApi will establish a session with the FinTechUI. This is done by the mean of using a cookie called SessionCookie. This SessionCookie is protected by a corresponding xsrfToken. The response that sets a SessionCookie also carries a corresponding xsrfToken in the response header named \"X-XSRF-TOKEN\".  It is the responsibility of the FinTechUI to : * parse and store this xsrfToken so that a refresh of a browser window can work. This shall be done using user agent capabilities. A web browser application might decide to store the xsrfToken in the browser localStorage, as the cookie we set are all considered persistent. * make sure that each subsequent request that is carrying the SessionCookie also carries the corresponding xsrfToken as header field (see the request path). * remove this xsrfToken from the localStorage when the corresponding SessionCookie is deleted by a server response (setting cookie value to null).  The main difference between an xsrfToken and a SessionCookie is that the sessionCookie is automatically sent with each matching request. The xsrfToken must be explicitely read and sent by application.  #### API- vs. UI-Redirection For simplicity, this Framework is designed to redirect to FinTechUI not to FinTechApi.  #### Explicite vs. Implicite Redirection We define an \"Implicite redirection\" a case where a web browser react to 30X reponse and automatically redirects to the attached endpoint. We define an \"Explicite Redirection\" as a case where the UI-Application reacts to a 20X response, explicitely parses the attached __Location__ header an uses it to reload the new page in the browser window (or start the new UI-Application in case of native apps).  This framework advocates for explicite redirection passing a __20X__ response to the FinTechUI toghether with the __Location__ parameter.  Processing a response that initiates a redirect, the FinTechUI makes sure following happens, * that the exisitng __SessionCookie__ is deleted, as the user will not have a chance for an explicite logout, * that the corresponding xsrfToken is deleted from the local storage, * that a RedirectCookie set is stored (in case UI is not a web browser), so the user can be authenticated against it when sent back to the FinTechUI. The expiration of the RedirectCookie shall be set to the expected duration of the redirect, * that the corresponding xsrfToken is stored in the local storage (under the same cookie path as the RedirectCookie)  #### Redirecting to the ConsentAuthorisationApi For a redirection to the ConsentAuthorisationApi, a generated AUTH-ID is added to the cookie path and used to distinguish authorization processes from each order. This information (AUTH-ID) must be contained in the back redirect url sent to the ConsentAuthorisationApi in the back channel, so that the FinTechUI can invoke the correct code2Token endpoint when activated. 
+ *
+ * The version of the OpenAPI document: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional }                      from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+         HttpResponse, HttpEvent, HttpParameterCodec }       from '@angular/common/http';
+import { CustomHttpParameterCodec }                          from '../encoder';
+import { Observable }                                        from 'rxjs';
+
+
+import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
+import { Configuration }                                     from '../configuration';
+
+
+
+@Injectable({
+  providedIn: 'root'
+})
+export class FintechRetrieveConsentService {
+
+    protected basePath = 'http://localhost';
+    public defaultHeaders = new HttpHeaders();
+    public configuration = new Configuration();
+    public encoder: HttpParameterCodec;
+
+    constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
+        if (configuration) {
+            this.configuration = configuration;
+        }
+        if (typeof this.configuration.basePath !== 'string') {
+            if (typeof basePath !== 'string') {
+                basePath = this.basePath;
+            }
+            this.configuration.basePath = basePath;
+        }
+        this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
+    }
+
+
+
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
+    /**
+     * ask for existing consent of user
+     * This method is disabled by default. It can be enabled by profile \&quot;CONSENT_RETRIEVAL\&quot;
+     * @param userid 
+     * @param password 
+     * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+     * @param reportProgress flag to report request and response progress.
+     */
+    public retrieveConsent(userid: string, password: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<object>;
+    public retrieveConsent(userid: string, password: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<object>>;
+    public retrieveConsent(userid: string, password: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<object>>;
+    public retrieveConsent(userid: string, password: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
+        if (userid === null || userid === undefined) {
+            throw new Error('Required parameter userid was null or undefined when calling retrieveConsent.');
+        }
+        if (password === null || password === undefined) {
+            throw new Error('Required parameter password was null or undefined when calling retrieveConsent.');
+        }
+
+        let headers = this.defaultHeaders;
+
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
+        if (httpHeaderAcceptSelected !== undefined) {
+            headers = headers.set('Accept', httpHeaderAcceptSelected);
+        }
+
+
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
+        return this.httpClient.get<object>(`${this.configuration.basePath}/v1/consent/${encodeURIComponent(String(userid))}/${encodeURIComponent(String(password))}`,
+            {
+                responseType: <any>responseType,
+                withCredentials: this.configuration.withCredentials,
+                headers: headers,
+                observe: observe,
+                reportProgress: reportProgress
+            }
+        );
+    }
+
+}
diff --git a/fintech-examples/fintech-ui/src/app/api/api/fintechSinglePaymentInitiation.service.ts b/fintech-examples/fintech-ui/src/app/api/api/fintechSinglePaymentInitiation.service.ts
index 438b568f99..9c454bb1d6 100644
--- a/fintech-examples/fintech-ui/src/app/api/api/fintechSinglePaymentInitiation.service.ts
+++ b/fintech-examples/fintech-ui/src/app/api/api/fintechSinglePaymentInitiation.service.ts
@@ -1,9 +1,9 @@
 /**
  * Open Banking Gateway FinTech Example API
- * This is a sample API that shows how to develop FinTech use cases that invoke banking APIs.  #### User Agent and Cookies This Api assumes * that the PsuUserAgent (hosting the FinTechUI) is a modern web browser that stores httpOnly cookies sent with the redirect under the given domain and path as defined by [RFC 6265](https://tools.ietf.org/html/rfc6265). * that any other PsuUserAgent like a native mobile or a desktop application can simulate this same behavior of a modern browser with respect to Cookies.  #### SessionCookies and XSRF After a PSU is authenticated with the FinTech environment (either through the simple login interface defined here, or through an identity provider), the FinTechApi will establish a session with the FinTechUI. This is done by the mean of using a cookie called SessionCookie. This SessionCookie is protected by a corresponding xsrfToken. The response that sets a SessionCookie also carries a corresponding xsrfToken in the response header named \"X-XSRF-TOKEN\".  It is the responsibility of the FinTechUI to : * parse and store this xsrfToken so that a refresh of a browser window can work. This shall be done using user agent capabilities. A web browser application might decide to store the xsrfToken in the browser localStorage, as the cookie we set are all considered persistent. * make sure that each subsequent request that is carrying the SessionCookie also carries the corresponding xsrfToken as header field (see the request path). * remove this xsrfToken from the localStorage when the corresponding SessionCookie is deleted by a server response (setting cookie value to null).  The main difference between an xsrfToken and a SessionCookie is that the sessionCookie is automatically sent with each matching request. The xsrfToken must be explicitely read and sent by application.  #### API- vs. UI-Redirection For simplicity, this Framework is designed to redirect to FinTechUI not to FinTechApi.  #### Explicite vs. Implicite Redirection We define an \"Implicite redirection\" a case where a web browser react to 30X reponse and automatically redirects to the attached endpoint. We define an \"Explicite Redirection\" as a case where the UI-Application reacts to a 20X response, explicitely parses the attached __Location__ header an uses it to reload the new page in the browser window (or start the new UI-Application in case of native apps).  This framework advocates for explicite redirection passing a __20X__ response to the FinTechUI toghether with the __Location__ parameter.  Processing a response that initiates a redirect, the FinTechUI makes sure following happens, * that the exisitng __SessionCookie__ is deleted, as the user will not have a chance for an explicite logout, * that the corresponding xsrfToken is deleted from the local storage, * that a RedirectCookie set is stored (in case UI is not a web browser), so the user can be authenticated against it when sent back to the FinTechUI. The expiration of the RedirectCookie shall be set to the expected duration of the redirect, * that the corresponding xsrfToken is stored in the local storage (under the same cookie path as the RedirectCookie)  #### Redirecting to the ConsentAuthorisationApi For a redirection to the ConsentAuthorisationApi, a generated AUTH-ID is added to the cookie path and used to distinguish authorization processes from each order. This information (AUTH-ID) must be contained in the back redirect url sent to the ConsentAuthorisationApi in the back channel, so that the FinTechUI can invoke the correct code2Token endpoint when activated.
+ * This is a sample API that shows how to develop FinTech use cases that invoke banking APIs.  #### User Agent and Cookies This Api assumes * that the PsuUserAgent (hosting the FinTechUI) is a modern web browser that stores httpOnly cookies sent with the redirect under the given domain and path as defined by [RFC 6265](https://tools.ietf.org/html/rfc6265). * that any other PsuUserAgent like a native mobile or a desktop application can simulate this same behavior of a modern browser with respect to Cookies.  #### SessionCookies and XSRF After a PSU is authenticated with the FinTech environment (either through the simple login interface defined here, or through an identity provider), the FinTechApi will establish a session with the FinTechUI. This is done by the mean of using a cookie called SessionCookie. This SessionCookie is protected by a corresponding xsrfToken. The response that sets a SessionCookie also carries a corresponding xsrfToken in the response header named \"X-XSRF-TOKEN\".  It is the responsibility of the FinTechUI to : * parse and store this xsrfToken so that a refresh of a browser window can work. This shall be done using user agent capabilities. A web browser application might decide to store the xsrfToken in the browser localStorage, as the cookie we set are all considered persistent. * make sure that each subsequent request that is carrying the SessionCookie also carries the corresponding xsrfToken as header field (see the request path). * remove this xsrfToken from the localStorage when the corresponding SessionCookie is deleted by a server response (setting cookie value to null).  The main difference between an xsrfToken and a SessionCookie is that the sessionCookie is automatically sent with each matching request. The xsrfToken must be explicitely read and sent by application.  #### API- vs. UI-Redirection For simplicity, this Framework is designed to redirect to FinTechUI not to FinTechApi.  #### Explicite vs. Implicite Redirection We define an \"Implicite redirection\" a case where a web browser react to 30X reponse and automatically redirects to the attached endpoint. We define an \"Explicite Redirection\" as a case where the UI-Application reacts to a 20X response, explicitely parses the attached __Location__ header an uses it to reload the new page in the browser window (or start the new UI-Application in case of native apps).  This framework advocates for explicite redirection passing a __20X__ response to the FinTechUI toghether with the __Location__ parameter.  Processing a response that initiates a redirect, the FinTechUI makes sure following happens, * that the exisitng __SessionCookie__ is deleted, as the user will not have a chance for an explicite logout, * that the corresponding xsrfToken is deleted from the local storage, * that a RedirectCookie set is stored (in case UI is not a web browser), so the user can be authenticated against it when sent back to the FinTechUI. The expiration of the RedirectCookie shall be set to the expected duration of the redirect, * that the corresponding xsrfToken is stored in the local storage (under the same cookie path as the RedirectCookie)  #### Redirecting to the ConsentAuthorisationApi For a redirection to the ConsentAuthorisationApi, a generated AUTH-ID is added to the cookie path and used to distinguish authorization processes from each order. This information (AUTH-ID) must be contained in the back redirect url sent to the ConsentAuthorisationApi in the back channel, so that the FinTechUI can invoke the correct code2Token endpoint when activated. 
  *
  * The version of the OpenAPI document: 1.0.0
- *
+ * 
  *
  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
  * https://openapi-generator.tech
@@ -17,8 +17,8 @@ import { HttpClient, HttpHeaders, HttpParams,
 import { CustomHttpParameterCodec }                          from '../encoder';
 import { Observable }                                        from 'rxjs';
 
-import { ErrorResponse } from '../model/errorResponse';
-import { SinglePaymentInitiationRequest } from '../model/singlePaymentInitiationRequest';
+import { ErrorResponse } from '../model/models';
+import { SinglePaymentInitiationRequest } from '../model/models';
 
 import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
 import { Configuration }                                     from '../configuration';
@@ -50,24 +50,60 @@ export class FintechSinglePaymentInitiationService {
 
 
 
+    private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+        if (typeof value === "object" && value instanceof Date === false) {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value);
+        } else {
+            httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+        }
+        return httpParams;
+    }
+
+    private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+        if (value == null) {
+            return httpParams;
+        }
+
+        if (typeof value === "object") {
+            if (Array.isArray(value)) {
+                (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+            } else if (value instanceof Date) {
+                if (key != null) {
+                    httpParams = httpParams.append(key,
+                        (value as Date).toISOString().substr(0, 10));
+                } else {
+                   throw Error("key may not be null if value is Date");
+                }
+            } else {
+                Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+                    httpParams, value[k], key != null ? `${key}.${k}` : k));
+            }
+        } else if (key != null) {
+            httpParams = httpParams.append(key, value);
+        } else {
+            throw Error("key may not be null if value is not object or array");
+        }
+        return httpParams;
+    }
+
     /**
      * Single payment initiation request
      * This method is used to initiate a payment at the Fintech Server.
-     * @param bankId
-     * @param accountId
-     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well.
-     * @param X_XSRF_TOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie.
-     * @param fintechRedirectURLOK
-     * @param fintechRedirectURLNOK
+     * @param bankId 
+     * @param accountId 
+     * @param xRequestID Unique ID that identifies this request through common workflow. Must be contained in HTTP Response as well. 
+     * @param xXSRFTOKEN XSRF parameter used to validate a SessionCookie or RedirectCookie. 
+     * @param fintechRedirectURLOK 
+     * @param fintechRedirectURLNOK 
      * @param singlePaymentInitiationRequest Single payment initiation request
-     * @param xPisPsuAuthenticationRequired If false, login form to OPBA will not be displayed as there might be nothing to share for payments, so that authentication is not necessary. If absent or true - login form for payments will be displayed.
+     * @param xPisPsuAuthenticationRequired If false, login form to OPBA will not be displayed as there might be nothing to share for payments, so that authentication is not necessary. If absent or true - login form for payments will be displayed. 
      * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
      * @param reportProgress flag to report request and response progress.
      */
-    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe?: 'body', reportProgress?: boolean): Observable<any>;
-    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
-    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
-    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, X_XSRF_TOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
+    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<any>;
+    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<any>>;
+    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<any>>;
+    public initiateSinglePayment(bankId: string, accountId: string, xRequestID: string, xXSRFTOKEN: string, fintechRedirectURLOK: string, fintechRedirectURLNOK: string, singlePaymentInitiationRequest: SinglePaymentInitiationRequest, xPisPsuAuthenticationRequired?: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
         if (bankId === null || bankId === undefined) {
             throw new Error('Required parameter bankId was null or undefined when calling initiateSinglePayment.');
         }
@@ -77,8 +113,8 @@ export class FintechSinglePaymentInitiationService {
         if (xRequestID === null || xRequestID === undefined) {
             throw new Error('Required parameter xRequestID was null or undefined when calling initiateSinglePayment.');
         }
-        if (X_XSRF_TOKEN === null || X_XSRF_TOKEN === undefined) {
-            throw new Error('Required parameter X_XSRF_TOKEN was null or undefined when calling initiateSinglePayment.');
+        if (xXSRFTOKEN === null || xXSRFTOKEN === undefined) {
+            throw new Error('Required parameter xXSRFTOKEN was null or undefined when calling initiateSinglePayment.');
         }
         if (fintechRedirectURLOK === null || fintechRedirectURLOK === undefined) {
             throw new Error('Required parameter fintechRedirectURLOK was null or undefined when calling initiateSinglePayment.');
@@ -94,8 +130,8 @@ export class FintechSinglePaymentInitiationService {
         if (xRequestID !== undefined && xRequestID !== null) {
             headers = headers.set('X-Request-ID', String(xRequestID));
         }
-        if (X_XSRF_TOKEN !== undefined && X_XSRF_TOKEN !== null) {
-            headers = headers.set('X-XSRF-TOKEN', String(X_XSRF_TOKEN));
+        if (xXSRFTOKEN !== undefined && xXSRFTOKEN !== null) {
+            headers = headers.set('X-XSRF-TOKEN', String(xXSRFTOKEN));
         }
         if (xPisPsuAuthenticationRequired !== undefined && xPisPsuAuthenticationRequired !== null) {
             headers = headers.set('X-Pis-Psu-Authentication-Required', String(xPisPsuAuthenticationRequired));
@@ -107,11 +143,14 @@ export class FintechSinglePaymentInitiationService {
             headers = headers.set('Fintech-Redirect-URL-NOK', String(fintechRedirectURLNOK));
         }
 
-        // to determine the Accept header
-        const httpHeaderAccepts: string[] = [
-            'application/json'
-        ];
-        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+        if (httpHeaderAcceptSelected === undefined) {
+            // to determine the Accept header
+            const httpHeaderAccepts: string[] = [
+                'application/json'
+            ];
+            httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+        }
         if (httpHeaderAcceptSelected !== undefined) {
             headers = headers.set('Accept', httpHeaderAcceptSelected);
         }
@@ -126,9 +165,15 @@ export class FintechSinglePaymentInitiationService {
             headers = headers.set('Content-Type', httpContentTypeSelected);
         }
 
+        let responseType: 'text' | 'json' = 'json';
+        if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
+            responseType = 'text';
+        }
+
         return this.httpClient.post<any>(`${this.configuration.basePath}/v1/pis/banks/${encodeURIComponent(String(bankId))}/accounts/${encodeURIComponent(String(accountId))}/payments/single`,
             singlePaymentInitiationRequest,
             {
+                responseType: <any>responseType,
                 withCredentials: this.configuration.withCredentials,
                 headers: headers,
                 observe: observe,
diff --git a/fintech-examples/fintech-ui/src/app/api/model/accountBalance.ts b/fintech-examples/fintech-ui/src/app/api/model/accountBalance.ts
index 989ef34643..c23463625e 100644
--- a/fintech-examples/fintech-ui/src/app/api/model/accountBalance.ts
+++ b/fintech-examples/fintech-ui/src/app/api/model/accountBalance.ts
@@ -16,7 +16,7 @@ export interface AccountBalance {
     balanceAmount?: Amount;
     balanceType?: string;
     iban?: string;
-    lastChangeDateTime?: Date;
+    lastChangeDateTime?: string;
     lastCommittedTransaction?: string;
     referenceDate?: string;
 }
diff --git a/fintech-examples/fintech-ui/src/app/api/model/accountDetails.ts b/fintech-examples/fintech-ui/src/app/api/model/accountDetails.ts
index 75356efdd0..26cb0ecd3c 100644
--- a/fintech-examples/fintech-ui/src/app/api/model/accountDetails.ts
+++ b/fintech-examples/fintech-ui/src/app/api/model/accountDetails.ts
@@ -76,7 +76,7 @@ export interface AccountDetails {
      * Specifications that might be provided by the ASPSP:   - characteristics of the account   - characteristics of the relevant card 
      */
     details?: string;
-    links?: LinksAccountDetails;
+    _links?: LinksAccountDetails;
     /**
      * Name of the legal account owner. If there is more than one owner, then e.g. two names might be noted here.
      */
diff --git a/fintech-examples/fintech-ui/src/app/api/model/analyticsReportDetails.ts b/fintech-examples/fintech-ui/src/app/api/model/analyticsReportDetails.ts
new file mode 100644
index 0000000000..7538548862
--- /dev/null
+++ b/fintech-examples/fintech-ui/src/app/api/model/analyticsReportDetails.ts
@@ -0,0 +1,71 @@
+/**
+ * Open Banking Gateway FinTech Example API
+ * This is a sample API that shows how to develop FinTech use cases that invoke banking APIs.  #### User Agent and Cookies This Api assumes * that the PsuUserAgent (hosting the FinTechUI) is a modern web browser that stores httpOnly cookies sent with the redirect under the given domain and path as defined by [RFC 6265](https://tools.ietf.org/html/rfc6265). * that any other PsuUserAgent like a native mobile or a desktop application can simulate this same behavior of a modern browser with respect to Cookies.  #### SessionCookies and XSRF After a PSU is authenticated with the FinTech environment (either through the simple login interface defined here, or through an identity provider), the FinTechApi will establish a session with the FinTechUI. This is done by the mean of using a cookie called SessionCookie. This SessionCookie is protected by a corresponding xsrfToken. The response that sets a SessionCookie also carries a corresponding xsrfToken in the response header named \"X-XSRF-TOKEN\".  It is the responsibility of the FinTechUI to : * parse and store this xsrfToken so that a refresh of a browser window can work. This shall be done using user agent capabilities. A web browser application might decide to store the xsrfToken in the browser localStorage, as the cookie we set are all considered persistent. * make sure that each subsequent request that is carrying the SessionCookie also carries the corresponding xsrfToken as header field (see the request path). * remove this xsrfToken from the localStorage when the corresponding SessionCookie is deleted by a server response (setting cookie value to null).  The main difference between an xsrfToken and a SessionCookie is that the sessionCookie is automatically sent with each matching request. The xsrfToken must be explicitely read and sent by application.  #### API- vs. UI-Redirection For simplicity, this Framework is designed to redirect to FinTechUI not to FinTechApi.  #### Explicite vs. Implicite Redirection We define an \"Implicite redirection\" a case where a web browser react to 30X reponse and automatically redirects to the attached endpoint. We define an \"Explicite Redirection\" as a case where the UI-Application reacts to a 20X response, explicitely parses the attached __Location__ header an uses it to reload the new page in the browser window (or start the new UI-Application in case of native apps).  This framework advocates for explicite redirection passing a __20X__ response to the FinTechUI toghether with the __Location__ parameter.  Processing a response that initiates a redirect, the FinTechUI makes sure following happens, * that the exisitng __SessionCookie__ is deleted, as the user will not have a chance for an explicite logout, * that the corresponding xsrfToken is deleted from the local storage, * that a RedirectCookie set is stored (in case UI is not a web browser), so the user can be authenticated against it when sent back to the FinTechUI. The expiration of the RedirectCookie shall be set to the expected duration of the redirect, * that the corresponding xsrfToken is stored in the local storage (under the same cookie path as the RedirectCookie)  #### Redirecting to the ConsentAuthorisationApi For a redirection to the ConsentAuthorisationApi, a generated AUTH-ID is added to the cookie path and used to distinguish authorization processes from each order. This information (AUTH-ID) must be contained in the back redirect url sent to the ConsentAuthorisationApi in the back channel, so that the FinTechUI can invoke the correct code2Token endpoint when activated. 
+ *
+ * The version of the OpenAPI document: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+/**
+ * JSON based analytics report. This account report contains transaction categorization result. 
+ */
+export interface AnalyticsReportDetails { 
+    /**
+     * The id of transaction this analytics result refers to.
+     */
+    transactionId?: string;
+    /**
+     * Main category of the booking.
+     */
+    mainCategory?: string;
+    /**
+     * Sub category of the booking.
+     */
+    subCategory?: string;
+    /**
+     * Specification of the booking.
+     */
+    specification?: string;
+    /**
+     * Related account.
+     */
+    otherAccount?: string;
+    /**
+     * Logo.
+     */
+    logo?: string;
+    /**
+     * Homepage.
+     */
+    homepage?: string;
+    /**
+     * Hotline.
+     */
+    hotline?: string;
+    /**
+     * Email.
+     */
+    email?: string;
+    /**
+     * Custom information about analyzed transaction.
+     */
+    custom?: { [key: string]: string; };
+    /**
+     * Rules that were used to analyze.
+     */
+    usedRules?: Array<string>;
+    /**
+     * Classification next booking date.
+     */
+    nextBookingDate?: string;
+    /**
+     * Classification cycle result.
+     */
+    cycle?: string;
+}
+
diff --git a/fintech-examples/fintech-ui/src/app/api/model/models.ts b/fintech-examples/fintech-ui/src/app/api/model/models.ts
index b372391f79..32c3c686e3 100644
--- a/fintech-examples/fintech-ui/src/app/api/model/models.ts
+++ b/fintech-examples/fintech-ui/src/app/api/model/models.ts
@@ -6,6 +6,7 @@ export * from './accountReport';
 export * from './accountStatus';
 export * from './address';
 export * from './amount';
+export * from './analyticsReportDetails';
 export * from './bankDescriptor';
 export * from './bankProfile';
 export * from './errorResponse';
diff --git a/fintech-examples/fintech-ui/src/app/api/model/transactionsResponse.ts b/fintech-examples/fintech-ui/src/app/api/model/transactionsResponse.ts
index b3a92672cb..7601d965a7 100644
--- a/fintech-examples/fintech-ui/src/app/api/model/transactionsResponse.ts
+++ b/fintech-examples/fintech-ui/src/app/api/model/transactionsResponse.ts
@@ -11,6 +11,7 @@
  */
 import { AccountReference } from './accountReference';
 import { AccountReport } from './accountReport';
+import { AnalyticsReportDetails } from './analyticsReportDetails';
 
 
 /**
@@ -19,5 +20,9 @@ import { AccountReport } from './accountReport';
 export interface TransactionsResponse { 
     account?: AccountReference;
     transactions?: AccountReport;
+    /**
+     * Array of transaction details.
+     */
+    analytics?: Array<AnalyticsReportDetails>;
 }
 
diff --git a/fintech-examples/fintech-ui/src/app/api/model/userProfile.ts b/fintech-examples/fintech-ui/src/app/api/model/userProfile.ts
index b4b4c347d0..335c108303 100644
--- a/fintech-examples/fintech-ui/src/app/api/model/userProfile.ts
+++ b/fintech-examples/fintech-ui/src/app/api/model/userProfile.ts
@@ -13,6 +13,6 @@
 
 export interface UserProfile { 
     name?: string;
-    lastLogin?: Date;
+    lastLogin?: string;
 }
 
diff --git a/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.html b/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.html
index 1846adb164..e4d8ca77c0 100644
--- a/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.html
+++ b/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.html
@@ -68,8 +68,16 @@ <h4 class="text-secondary">Payments</h4>
             <label for="payment">Payment requires authentication</label>
           </div>
         </div>
+        <div class="form-group">
+          <h4 class="text-secondary">Other settings</h4>
+          <button
+            (click)="onDelete()"
+            class="btn btn-primary w-100"
+            id="do_delete_in_fintech"
+            type="button"
+          >Delete consent in FinTech Server</button>
+        </div>
       </section>
-
       <div class="d-sm-flex">
         <button (click)="onNavigateBack()" class="btn btn-outline-secondary w-100 mr-4" id="do_deny">Cancel</button>
         <button
diff --git a/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.ts b/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.ts
index b92785be52..78364903b8 100644
--- a/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.ts
+++ b/fintech-examples/fintech-ui/src/app/bank/settings/settings.component.ts
@@ -4,6 +4,7 @@ import { Location } from '@angular/common';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { LoARetrievalInformation, LoTRetrievalInformation } from '../../models/consts';
 import { StorageService } from '../../services/storage.service';
+import {FinTechAccountInformationService} from "../../api";
 
 @Component({
   selector: 'app-settings',
@@ -24,7 +25,8 @@ export class SettingsComponent implements OnInit {
     private location: Location,
     private route: ActivatedRoute,
     private formBuilder: FormBuilder,
-    private storageService: StorageService
+    private storageService: StorageService,
+    private accountService: FinTechAccountInformationService
   ) {}
 
   ngOnInit() {
@@ -45,6 +47,10 @@ export class SettingsComponent implements OnInit {
     this.onNavigateBack();
   }
 
+  onDelete() {
+    this.accountService.aisConsentsDELETE(this.bankId, '', '').subscribe();
+  }
+
   onNavigateBack() {
     this.location.back();
   }

From ab946d70ba44368cd789944683977d5e411965b8 Mon Sep 17 00:00:00 2001
From: Valentyn Berezin <vbe@adorsys.com.ua>
Date: Fri, 23 Apr 2021 14:14:49 +0300
Subject: [PATCH 6/6] Make checkstyle happy

---
 .../fintech/impl/controller/FinTechAccountInformationImpl.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java
index 00a59b37da..e701dc144c 100644
--- a/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java
+++ b/fintech-examples/fintech-impl/src/main/java/de/adorsys/opba/fintech/impl/controller/FinTechAccountInformationImpl.java
@@ -61,7 +61,7 @@ public ResponseEntity<TransactionsResponse> aisTransactionsGET(String bankId, St
     }
 
     @Override
-    public ResponseEntity<Object> aisConsentsDELETE(String bankId, UUID xRequestID, String X_XSRF_TOKEN) {
+    public ResponseEntity<Object> aisConsentsDELETE(String bankId, UUID xRequestID, String xsrfToken) {
         SessionEntity sessionEntity = sessionLogicService.getSession();
         consentService.deleteAllConsentsOfBank(sessionEntity, bankId);
         return ResponseEntity.ok().body(Map.of());