Bug: [FEATURE] [Deutschebank] : Implement 3ds Card Flow



### Feature Description

Implement 3ds Card Flow for Deutschebank

### Possible Implementation

Implement 3ds Card Flow for Deutschebank

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs
index 03facc2ebab..a450a30fa76 100644
--- a/crates/diesel_models/src/payment_attempt.rs
+++ b/crates/diesel_models/src/payment_attempt.rs
@@ -3426,6 +3426,10 @@ pub enum RedirectForm {
         access_token: String,
         step_up_url: String,
     },
+    DeutschebankThreeDSChallengeFlow {
+        acs_url: String,
+        creq: String,
+    },
     Payme,
     Braintree {
         client_token: String,
diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs
index 3098d27e7ec..f4d5fe5fdf1 100644
--- a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs
+++ b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs
@@ -59,7 +59,7 @@ use crate::{
     types::ResponseRouterData,
     utils::{
         self, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData,
-        RefundsRequestData,
+        RefundsRequestData, RouterData as ConnectorRouterData,
     },
 };
 
@@ -131,7 +131,7 @@ impl ConnectorCommon for Deutschebank {
     }
 
     fn get_currency_unit(&self) -> api::CurrencyUnit {
-        api::CurrencyUnit::Base
+        api::CurrencyUnit::Minor
     }
 
     fn common_get_content_type(&self) -> &'static str {
@@ -311,18 +311,30 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
         req: &PaymentsAuthorizeRouterData,
         connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        if req.request.connector_mandate_id().is_none() {
+        let event_id = req.connector_request_reference_id.clone();
+        let tx_action = if req.request.is_auto_capture()? {
+            "authorization"
+        } else {
+            "preauthorization"
+        };
+
+        if req.is_three_ds() && req.request.is_card() {
+            Ok(format!(
+                "{}/services/v2.1/headless3DSecure/event/{event_id}/{tx_action}/initialize",
+                self.base_url(connectors)
+            ))
+        } else if !req.is_three_ds() && req.request.is_card() {
+            Err(errors::ConnectorError::NotSupported {
+                message: "Non-ThreeDs".to_owned(),
+                connector: "deutschebank",
+            }
+            .into())
+        } else if req.request.connector_mandate_id().is_none() {
             Ok(format!(
                 "{}/services/v2.1/managedmandate",
                 self.base_url(connectors)
             ))
         } else {
-            let event_id = req.connector_request_reference_id.clone();
-            let tx_action = if req.request.is_auto_capture()? {
-                "authorization"
-            } else {
-                "preauthorization"
-            };
             Ok(format!(
                 "{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
                 self.base_url(connectors)
@@ -375,7 +387,19 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
     ) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> {
-        if data.request.connector_mandate_id().is_none() {
+        if data.is_three_ds() && data.request.is_card() {
+            let response: deutschebank::DeutschebankThreeDSInitializeResponse = res
+                .response
+                .parse_struct("DeutschebankPaymentsAuthorizeResponse")
+                .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+            event_builder.map(|i| i.set_response_body(&response));
+            router_env::logger::info!(connector_response=?response);
+            RouterData::try_from(ResponseRouterData {
+                response,
+                data: data.clone(),
+                http_code: res.status_code,
+            })
+        } else if data.request.connector_mandate_id().is_none() {
             let response: deutschebank::DeutschebankMandatePostResponse = res
                 .response
                 .parse_struct("DeutschebankMandatePostResponse")
@@ -437,10 +461,18 @@ impl ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResp
         } else {
             "preauthorization"
         };
-        Ok(format!(
-            "{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
-            self.base_url(connectors)
-        ))
+
+        if req.is_three_ds() && matches!(req.payment_method, enums::PaymentMethod::Card) {
+            Ok(format!(
+                "{}/services/v2.1//headless3DSecure/event/{event_id}/final",
+                self.base_url(connectors)
+            ))
+        } else {
+            Ok(format!(
+                "{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
+                self.base_url(connectors)
+            ))
+        }
     }
 
     fn get_request_body(
@@ -453,10 +485,9 @@ impl ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResp
             req.request.minor_amount,
             req.request.currency,
         )?;
-
         let connector_router_data = deutschebank::DeutschebankRouterData::from((amount, req));
         let connector_req =
-            deutschebank::DeutschebankDirectDebitRequest::try_from(&connector_router_data)?;
+            deutschebank::DeutschebankCompleteAuthorizeRequest::try_from(&connector_router_data)?;
         Ok(RequestContent::Json(Box::new(connector_req)))
     }
 
@@ -952,10 +983,20 @@ lazy_static! {
         deutschebank_supported_payment_methods.add(
             enums::PaymentMethod::BankDebit,
             enums::PaymentMethodType::Sepa,
+            PaymentMethodDetails{
+                mandates: enums::FeatureStatus::Supported,
+                refunds: enums::FeatureStatus::Supported,
+                supported_capture_methods: supported_capture_methods.clone(),
+            }
+        );
+
+        deutschebank_supported_payment_methods.add(
+            enums::PaymentMethod::Card,
+            enums::PaymentMethodType::Credit,
             PaymentMethodDetails{
                 mandates: enums::FeatureStatus::NotSupported,
-                refunds: enums::FeatureStatus::NotSupported,
-                supported_capture_methods,
+                refunds: enums::FeatureStatus::Supported,
+                supported_capture_methods: supported_capture_methods.clone(),
             }
         );
 
diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs
index 85c5fc8dc81..8133be2fa79 100644
--- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs
@@ -1,6 +1,7 @@
 use std::collections::HashMap;
 
-use common_enums::enums;
+use cards::CardNumber;
+use common_enums::{enums, PaymentMethod};
 use common_utils::{ext_traits::ValueExt, pii::Email, types::MinorUnit};
 use error_stack::ResultExt;
 use hyperswitch_domain_models::{
@@ -22,14 +23,14 @@ use hyperswitch_domain_models::{
         PaymentsCompleteAuthorizeRouterData, RefundsRouterData,
     },
 };
-use hyperswitch_interfaces::errors;
-use masking::{PeekInterface, Secret};
+use hyperswitch_interfaces::{consts, errors};
+use masking::{ExposeInterface, PeekInterface, Secret};
 use serde::{Deserialize, Serialize};
 
 use crate::{
     types::{PaymentsCancelResponseRouterData, RefundsResponseRouterData, ResponseRouterData},
     utils::{
-        self, AddressDetailsData, PaymentsAuthorizeRequestData,
+        self, AddressDetailsData, CardData, PaymentsAuthorizeRequestData,
         PaymentsCompleteAuthorizeRequestData, RefundsRequestData, RouterData as OtherRouterData,
     },
 };
@@ -129,6 +130,75 @@ pub struct DeutschebankMandatePostRequest {
 pub enum DeutschebankPaymentsRequest {
     MandatePost(DeutschebankMandatePostRequest),
     DirectDebit(DeutschebankDirectDebitRequest),
+    CreditCard(Box<DeutschebankThreeDSInitializeRequest>),
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequest {
+    means_of_payment: DeutschebankThreeDSInitializeRequestMeansOfPayment,
+    tds_20_data: DeutschebankThreeDSInitializeRequestTds20Data,
+    amount_total: DeutschebankThreeDSInitializeRequestAmountTotal,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestMeansOfPayment {
+    credit_card: DeutschebankThreeDSInitializeRequestCreditCard,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestCreditCard {
+    number: CardNumber,
+    expiry_date: DeutschebankThreeDSInitializeRequestCreditCardExpiry,
+    code: Secret<String>,
+    cardholder: Secret<String>,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestCreditCardExpiry {
+    year: Secret<String>,
+    month: Secret<String>,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestAmountTotal {
+    amount: MinorUnit,
+    currency: api_models::enums::Currency,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestTds20Data {
+    communication_data: DeutschebankThreeDSInitializeRequestCommunicationData,
+    customer_data: DeutschebankThreeDSInitializeRequestCustomerData,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestCommunicationData {
+    method_notification_url: String,
+    cres_notification_url: String,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestCustomerData {
+    billing_address: DeutschebankThreeDSInitializeRequestCustomerBillingData,
+    cardholder_email: Email,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub struct DeutschebankThreeDSInitializeRequestCustomerBillingData {
+    street: Secret<String>,
+    postal_code: Secret<String>,
+    city: String,
+    state: Secret<String>,
+    country: String,
 }
 
 impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>>
@@ -148,11 +218,9 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>>
             None => {
                 // To facilitate one-off payments via SEPA with Deutsche Bank, we are considering not storing the connector mandate ID in our system if future usage is on-session.
                 // We will only check for customer acceptance to make a one-off payment. we will be storing the connector mandate details only when setup future usage is off-session.
-                if item.router_data.request.customer_acceptance.is_some() {
-                    match item.router_data.request.payment_method_data.clone() {
-                        PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit {
-                            iban, ..
-                        }) => {
+                match item.router_data.request.payment_method_data.clone() {
+                    PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. }) => {
+                        if item.router_data.request.customer_acceptance.is_some() {
                             let billing_address = item.router_data.get_billing_address()?;
                             Ok(Self::MandatePost(DeutschebankMandatePostRequest {
                                 approval_by: DeutschebankSEPAApproval::Click,
@@ -161,17 +229,60 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>>
                                 first_name: billing_address.get_first_name()?.clone(),
                                 last_name: billing_address.get_last_name()?.clone(),
                             }))
+                        } else {
+                            Err(errors::ConnectorError::MissingRequiredField {
+                                field_name: "customer_acceptance",
+                            }
+                            .into())
                         }
-                        _ => Err(errors::ConnectorError::NotImplemented(
-                            utils::get_unimplemented_payment_method_error_message("deutschebank"),
-                        )
-                        .into()),
                     }
-                } else {
-                    Err(errors::ConnectorError::MissingRequiredField {
-                        field_name: "customer_acceptance",
+                    PaymentMethodData::Card(ccard) => {
+                        if !item.router_data.clone().is_three_ds() {
+                            Err(errors::ConnectorError::NotSupported {
+                                message: "Non-ThreeDs".to_owned(),
+                                connector: "deutschebank",
+                            }
+                            .into())
+                        } else {
+                            let billing_address = item.router_data.get_billing_address()?;
+                            Ok(Self::CreditCard(Box::new(DeutschebankThreeDSInitializeRequest {
+                                    means_of_payment: DeutschebankThreeDSInitializeRequestMeansOfPayment {
+                                        credit_card: DeutschebankThreeDSInitializeRequestCreditCard {
+                                            number: ccard.clone().card_number,
+                                            expiry_date: DeutschebankThreeDSInitializeRequestCreditCardExpiry {
+                                                year: ccard.get_expiry_year_4_digit(),
+                                                month: ccard.card_exp_month,
+                                            },
+                                            code: ccard.card_cvc,
+                                            cardholder: item.router_data.get_billing_full_name()?,
+                                        }},
+                                    amount_total: DeutschebankThreeDSInitializeRequestAmountTotal {
+                                        amount: item.amount,
+                                        currency: item.router_data.request.currency,
+                                    },
+                                    tds_20_data: DeutschebankThreeDSInitializeRequestTds20Data {
+                                        communication_data: DeutschebankThreeDSInitializeRequestCommunicationData {
+                                            method_notification_url: item.router_data.request.get_complete_authorize_url()?,
+                                            cres_notification_url: item.router_data.request.get_complete_authorize_url()?,
+                                        },
+                                        customer_data: DeutschebankThreeDSInitializeRequestCustomerData {
+                                            billing_address: DeutschebankThreeDSInitializeRequestCustomerBillingData {
+                                                street: billing_address.get_line1()?.clone(),
+                                                postal_code: billing_address.get_zip()?.clone(),
+                                                city: billing_address.get_city()?.to_string(),
+                                                state: billing_address.get_state()?.clone(),
+                                                country: item.router_data.get_billing_country()?.to_string(),
+                                            },
+                                            cardholder_email: item.router_data.request.get_email()?,
+                                        }
+                                    }
+                                })))
+                        }
                     }
-                    .into())
+                    _ => Err(errors::ConnectorError::NotImplemented(
+                        utils::get_unimplemented_payment_method_error_message("deutschebank"),
+                    )
+                    .into()),
                 }
             }
             Some(api_models::payments::MandateReferenceId::ConnectorMandateId(mandate_data)) => {
@@ -209,6 +320,138 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>>
     }
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct DeutschebankThreeDSInitializeResponse {
+    outcome: DeutschebankThreeDSInitializeResponseOutcome,
+    challenge_required: Option<DeutschebankThreeDSInitializeResponseChallengeRequired>,
+    processed: Option<DeutschebankThreeDSInitializeResponseProcessed>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct DeutschebankThreeDSInitializeResponseProcessed {
+    rc: String,
+    message: String,
+    tx_id: String,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum DeutschebankThreeDSInitializeResponseOutcome {
+    Processed,
+    ChallengeRequired,
+    MethodRequired,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct DeutschebankThreeDSInitializeResponseChallengeRequired {
+    acs_url: String,
+    creq: String,
+}
+
+impl
+    TryFrom<
+        ResponseRouterData<
+            Authorize,
+            DeutschebankThreeDSInitializeResponse,
+            PaymentsAuthorizeData,
+            PaymentsResponseData,
+        >,
+    > for RouterData<Authorize, PaymentsAuthorizeData, PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: ResponseRouterData<
+            Authorize,
+            DeutschebankThreeDSInitializeResponse,
+            PaymentsAuthorizeData,
+            PaymentsResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        match item.response.outcome {
+            DeutschebankThreeDSInitializeResponseOutcome::Processed => {
+                match item.response.processed {
+                    Some(processed) => Ok(Self {
+                        status: if is_response_success(&processed.rc) {
+                            match item.data.request.is_auto_capture()? {
+                                true => common_enums::AttemptStatus::Charged,
+                                false => common_enums::AttemptStatus::Authorized,
+                            }
+                        } else {
+                            common_enums::AttemptStatus::AuthenticationFailed
+                        },
+                        response: Ok(PaymentsResponseData::TransactionResponse {
+                            resource_id: ResponseId::ConnectorTransactionId(
+                                processed.tx_id.clone(),
+                            ),
+                            redirection_data: Box::new(None),
+                            mandate_reference: Box::new(None),
+                            connector_metadata: None,
+                            network_txn_id: None,
+                            connector_response_reference_id: Some(processed.tx_id.clone()),
+                            incremental_authorization_allowed: None,
+                            charge_id: None,
+                        }),
+                        ..item.data
+                    }),
+                    None => {
+                        let response_string = format!("{:?}", item.response);
+                        Err(
+                            errors::ConnectorError::UnexpectedResponseError(bytes::Bytes::from(
+                                response_string,
+                            ))
+                            .into(),
+                        )
+                    }
+                }
+            }
+            DeutschebankThreeDSInitializeResponseOutcome::ChallengeRequired => {
+                match item.response.challenge_required {
+                    Some(challenge) => Ok(Self {
+                        status: common_enums::AttemptStatus::AuthenticationPending,
+                        response: Ok(PaymentsResponseData::TransactionResponse {
+                            resource_id: ResponseId::NoResponseId,
+                            redirection_data: Box::new(Some(
+                                RedirectForm::DeutschebankThreeDSChallengeFlow {
+                                    acs_url: challenge.acs_url,
+                                    creq: challenge.creq,
+                                },
+                            )),
+                            mandate_reference: Box::new(None),
+                            connector_metadata: None,
+                            network_txn_id: None,
+                            connector_response_reference_id: None,
+                            incremental_authorization_allowed: None,
+                            charge_id: None,
+                        }),
+                        ..item.data
+                    }),
+                    None => {
+                        let response_string = format!("{:?}", item.response);
+                        Err(
+                            errors::ConnectorError::UnexpectedResponseError(bytes::Bytes::from(
+                                response_string,
+                            ))
+                            .into(),
+                        )
+                    }
+                }
+            }
+            DeutschebankThreeDSInitializeResponseOutcome::MethodRequired => Ok(Self {
+                status: common_enums::AttemptStatus::Failure,
+                response: Err(ErrorResponse {
+                    code: consts::NO_ERROR_CODE.to_owned(),
+                    message: "METHOD_REQUIRED Flow not supported for deutschebank 3ds payments".to_owned(),
+                    reason: Some("METHOD_REQUIRED Flow is not currently supported for deutschebank 3ds payments".to_owned()),
+                    status_code: item.http_code,
+                    attempt_status: None,
+                    connector_transaction_id: None,
+                }),
+                ..item.data
+            }),
+        }
+    }
+}
+
 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 pub enum DeutschebankSEPAMandateStatus {
@@ -450,79 +693,117 @@ pub struct DeutschebankDirectDebitRequest {
     mandate: DeutschebankMandate,
 }
 
+#[derive(Debug, Serialize)]
+#[serde(untagged)]
+pub enum DeutschebankCompleteAuthorizeRequest {
+    DeutschebankDirectDebitRequest(DeutschebankDirectDebitRequest),
+    DeutschebankThreeDSCompleteAuthorizeRequest(DeutschebankThreeDSCompleteAuthorizeRequest),
+}
+
+#[derive(Debug, Serialize, PartialEq)]
+pub struct DeutschebankThreeDSCompleteAuthorizeRequest {
+    cres: String,
+}
+
 impl TryFrom<&DeutschebankRouterData<&PaymentsCompleteAuthorizeRouterData>>
-    for DeutschebankDirectDebitRequest
+    for DeutschebankCompleteAuthorizeRequest
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
         item: &DeutschebankRouterData<&PaymentsCompleteAuthorizeRouterData>,
     ) -> Result<Self, Self::Error> {
-        let account_holder = item.router_data.get_billing_address()?.get_full_name()?;
-        let redirect_response = item.router_data.request.redirect_response.clone().ok_or(
-            errors::ConnectorError::MissingRequiredField {
-                field_name: "redirect_response",
-            },
-        )?;
-        let queries_params = redirect_response
-            .params
-            .map(|param| {
-                let mut queries = HashMap::<String, String>::new();
-                let values = param.peek().split('&').collect::<Vec<&str>>();
-                for value in values {
-                    let pair = value.split('=').collect::<Vec<&str>>();
-                    queries.insert(
-                        pair.first()
-                            .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?
-                            .to_string(),
-                        pair.get(1)
-                            .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?
-                            .to_string(),
+        if matches!(item.router_data.payment_method, PaymentMethod::Card) {
+            let redirect_response_payload = item
+                .router_data
+                .request
+                .get_redirect_response_payload()?
+                .expose();
+
+            let cres = redirect_response_payload
+                .get("cres")
+                .and_then(|v| v.as_str())
+                .map(String::from)
+                .ok_or(errors::ConnectorError::MissingRequiredField { field_name: "cres" })?;
+
+            Ok(Self::DeutschebankThreeDSCompleteAuthorizeRequest(
+                DeutschebankThreeDSCompleteAuthorizeRequest { cres },
+            ))
+        } else {
+            match item.router_data.request.payment_method_data.clone() {
+                Some(PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit {
+                    iban, ..
+                })) => {
+                    let account_holder = item.router_data.get_billing_address()?.get_full_name()?;
+                    let redirect_response =
+                        item.router_data.request.redirect_response.clone().ok_or(
+                            errors::ConnectorError::MissingRequiredField {
+                                field_name: "redirect_response",
+                            },
+                        )?;
+                    let queries_params = redirect_response
+                        .params
+                        .map(|param| {
+                            let mut queries = HashMap::<String, String>::new();
+                            let values = param.peek().split('&').collect::<Vec<&str>>();
+                            for value in values {
+                                let pair = value.split('=').collect::<Vec<&str>>();
+                                queries.insert(
+                                    pair.first()
+                                        .ok_or(
+                                            errors::ConnectorError::ResponseDeserializationFailed,
+                                        )?
+                                        .to_string(),
+                                    pair.get(1)
+                                        .ok_or(
+                                            errors::ConnectorError::ResponseDeserializationFailed,
+                                        )?
+                                        .to_string(),
+                                );
+                            }
+                            Ok::<_, errors::ConnectorError>(queries)
+                        })
+                        .transpose()?
+                        .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?;
+                    let reference = Secret::from(
+                        queries_params
+                            .get("reference")
+                            .ok_or(errors::ConnectorError::MissingRequiredField {
+                                field_name: "reference",
+                            })?
+                            .to_owned(),
                     );
-                }
-                Ok::<_, errors::ConnectorError>(queries)
-            })
-            .transpose()?
-            .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?;
-        let reference = Secret::from(
-            queries_params
-                .get("reference")
-                .ok_or(errors::ConnectorError::MissingRequiredField {
-                    field_name: "reference",
-                })?
-                .to_owned(),
-        );
-        let signed_on = queries_params
-            .get("signed_on")
-            .ok_or(errors::ConnectorError::MissingRequiredField {
-                field_name: "signed_on",
-            })?
-            .to_owned();
-
-        match item.router_data.request.payment_method_data.clone() {
-            Some(PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. })) => {
-                Ok(Self {
-                    amount_total: DeutschebankAmount {
-                        amount: item.amount,
-                        currency: item.router_data.request.currency,
-                    },
-                    means_of_payment: DeutschebankMeansOfPayment {
-                        bank_account: DeutschebankBankAccount {
-                            account_holder,
-                            iban: Secret::from(iban.peek().replace(" ", "")),
+                    let signed_on = queries_params
+                        .get("signed_on")
+                        .ok_or(errors::ConnectorError::MissingRequiredField {
+                            field_name: "signed_on",
+                        })?
+                        .to_owned();
+                    Ok(Self::DeutschebankDirectDebitRequest(
+                        DeutschebankDirectDebitRequest {
+                            amount_total: DeutschebankAmount {
+                                amount: item.amount,
+                                currency: item.router_data.request.currency,
+                            },
+                            means_of_payment: DeutschebankMeansOfPayment {
+                                bank_account: DeutschebankBankAccount {
+                                    account_holder,
+                                    iban: Secret::from(iban.peek().replace(" ", "")),
+                                },
+                            },
+                            mandate: {
+                                DeutschebankMandate {
+                                    reference,
+                                    signed_on,
+                                }
+                            },
                         },
-                    },
-                    mandate: {
-                        DeutschebankMandate {
-                            reference,
-                            signed_on,
-                        }
-                    },
-                })
+                    ))
+                }
+                _ => Err(errors::ConnectorError::NotImplemented(
+                    utils::get_unimplemented_payment_method_error_message("deutschebank"),
+                )
+                .into()),
             }
-            _ => Err(errors::ConnectorError::NotImplemented(
-                utils::get_unimplemented_payment_method_error_message("deutschebank"),
-            )
-            .into()),
         }
     }
 }
@@ -636,6 +917,8 @@ impl
 #[serde(rename_all = "UPPERCASE")]
 pub enum DeutschebankTransactionKind {
     Directdebit,
+    #[serde(rename = "CREDITCARD_3DS20")]
+    Creditcard3ds20,
 }
 
 #[derive(Debug, Serialize, PartialEq)]
@@ -649,10 +932,24 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsCaptureRouterData>> for Deutscheba
     fn try_from(
         item: &DeutschebankRouterData<&PaymentsCaptureRouterData>,
     ) -> Result<Self, Self::Error> {
-        Ok(Self {
-            changed_amount: item.amount,
-            kind: DeutschebankTransactionKind::Directdebit,
-        })
+        if matches!(item.router_data.payment_method, PaymentMethod::BankDebit) {
+            Ok(Self {
+                changed_amount: item.amount,
+                kind: DeutschebankTransactionKind::Directdebit,
+            })
+        } else if item.router_data.is_three_ds()
+            && matches!(item.router_data.payment_method, PaymentMethod::Card)
+        {
+            Ok(Self {
+                changed_amount: item.amount,
+                kind: DeutschebankTransactionKind::Creditcard3ds20,
+            })
+        } else {
+            Err(errors::ConnectorError::NotImplemented(
+                utils::get_unimplemented_payment_method_error_message("deutschebank"),
+            )
+            .into())
+        }
     }
 }
 
@@ -772,10 +1069,21 @@ pub struct DeutschebankReversalRequest {
 
 impl TryFrom<&PaymentsCancelRouterData> for DeutschebankReversalRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(_item: &PaymentsCancelRouterData) -> Result<Self, Self::Error> {
-        Ok(Self {
-            kind: DeutschebankTransactionKind::Directdebit,
-        })
+    fn try_from(item: &PaymentsCancelRouterData) -> Result<Self, Self::Error> {
+        if matches!(item.payment_method, PaymentMethod::BankDebit) {
+            Ok(Self {
+                kind: DeutschebankTransactionKind::Directdebit,
+            })
+        } else if item.is_three_ds() && matches!(item.payment_method, PaymentMethod::Card) {
+            Ok(Self {
+                kind: DeutschebankTransactionKind::Creditcard3ds20,
+            })
+        } else {
+            Err(errors::ConnectorError::NotImplemented(
+                utils::get_unimplemented_payment_method_error_message("deutschebank"),
+            )
+            .into())
+        }
     }
 }
 
@@ -815,10 +1123,24 @@ pub struct DeutschebankRefundRequest {
 impl<F> TryFrom<&DeutschebankRouterData<&RefundsRouterData<F>>> for DeutschebankRefundRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &DeutschebankRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
-        Ok(Self {
-            changed_amount: item.amount.to_owned(),
-            kind: DeutschebankTransactionKind::Directdebit,
-        })
+        if matches!(item.router_data.payment_method, PaymentMethod::BankDebit) {
+            Ok(Self {
+                changed_amount: item.amount,
+                kind: DeutschebankTransactionKind::Directdebit,
+            })
+        } else if item.router_data.is_three_ds()
+            && matches!(item.router_data.payment_method, PaymentMethod::Card)
+        {
+            Ok(Self {
+                changed_amount: item.amount,
+                kind: DeutschebankTransactionKind::Creditcard3ds20,
+            })
+        } else {
+            Err(errors::ConnectorError::NotImplemented(
+                utils::get_unimplemented_payment_method_error_message("deutschebank"),
+            )
+            .into())
+        }
     }
 }
 
diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs
index 61453f36b84..613797e2988 100644
--- a/crates/hyperswitch_domain_models/src/router_response_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_response_types.rs
@@ -236,6 +236,10 @@ pub enum RedirectForm {
         access_token: String,
         step_up_url: String,
     },
+    DeutschebankThreeDSChallengeFlow {
+        acs_url: String,
+        creq: String,
+    },
     Payme,
     Braintree {
         client_token: String,
@@ -313,6 +317,9 @@ impl From<RedirectForm> for diesel_models::payment_attempt::RedirectForm {
                 access_token,
                 step_up_url,
             },
+            RedirectForm::DeutschebankThreeDSChallengeFlow { acs_url, creq } => {
+                Self::DeutschebankThreeDSChallengeFlow { acs_url, creq }
+            }
             RedirectForm::Payme => Self::Payme,
             RedirectForm::Braintree {
                 client_token,
@@ -392,6 +399,9 @@ impl From<diesel_models::payment_attempt::RedirectForm> for RedirectForm {
                 access_token,
                 step_up_url,
             },
+            diesel_models::RedirectForm::DeutschebankThreeDSChallengeFlow { acs_url, creq } => {
+                Self::DeutschebankThreeDSChallengeFlow { acs_url, creq }
+            }
             diesel_models::payment_attempt::RedirectForm::Payme => Self::Payme,
             diesel_models::payment_attempt::RedirectForm::Braintree {
                 client_token,
diff --git a/crates/router/src/configs/defaults/payment_connector_required_fields.rs b/crates/router/src/configs/defaults/payment_connector_required_fields.rs
index 9e42aec4a51..b4ada6fd8fe 100644
--- a/crates/router/src/configs/defaults/payment_connector_required_fields.rs
+++ b/crates/router/src/configs/defaults/payment_connector_required_fields.rs
@@ -941,6 +941,129 @@ impl Default for settings::RequiredFields {
                                     ),
                                 }
                             ),
+                            (
+                                enums::Connector::Deutschebank,
+                                RequiredFieldFinal {
+                                    mandate: HashMap::new(),
+                                    non_mandate : HashMap::from(
+                                        [
+                                            (
+                                                "payment_method_data.card.card_number".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_number".to_string(),
+                                                    display_name: "card_number".to_string(),
+                                                    field_type: enums::FieldType::UserCardNumber,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "payment_method_data.card.card_exp_month".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_exp_month".to_string(),
+                                                    display_name: "card_exp_month".to_string(),
+                                                    field_type: enums::FieldType::UserCardExpiryMonth,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "payment_method_data.card.card_exp_year".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_exp_year".to_string(),
+                                                    display_name: "card_exp_year".to_string(),
+                                                    field_type: enums::FieldType::UserCardExpiryYear,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "payment_method_data.card.card_cvc".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_cvc".to_string(),
+                                                    display_name: "card_cvc".to_string(),
+                                                    field_type: enums::FieldType::UserCardCvc,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "email".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "email".to_string(),
+                                                    display_name: "email".to_string(),
+                                                    field_type: enums::FieldType::UserEmailAddress,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.line1".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.line1".to_string(),
+                                                    display_name: "line1".to_string(),
+                                                    field_type: enums::FieldType::UserAddressLine1,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.city".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.city".to_string(),
+                                                    display_name: "city".to_string(),
+                                                    field_type: enums::FieldType::UserAddressCity,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.state".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.state".to_string(),
+                                                    display_name: "state".to_string(),
+                                                    field_type: enums::FieldType::UserAddressState,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.zip".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.zip".to_string(),
+                                                    display_name: "zip".to_string(),
+                                                    field_type: enums::FieldType::UserAddressPincode,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.country".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.country".to_string(),
+                                                    display_name: "country".to_string(),
+                                                    field_type: enums::FieldType::UserAddressCountry{
+                                                        options: vec![
+                                                            "ALL".to_string(),
+                                                        ]
+                                                    },
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.first_name".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.first_name".to_string(),
+                                                    display_name: "first_name".to_string(),
+                                                    field_type: enums::FieldType::UserFullName,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.last_name".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.last_name".to_string(),
+                                                    display_name: "last_name".to_string(),
+                                                    field_type: enums::FieldType::UserFullName,
+                                                    value: None,
+                                                }
+                                            )
+                                        ]
+                                    ),
+                                    common: HashMap::new(),
+                                }
+                            ),
                             (
                                 enums::Connector::Dlocal,
                                 RequiredFieldFinal {
@@ -4138,6 +4261,129 @@ impl Default for settings::RequiredFields {
                                     ),
                                 }
                             ),
+                            (
+                                enums::Connector::Deutschebank,
+                                RequiredFieldFinal {
+                                    mandate: HashMap::new(),
+                                    non_mandate : HashMap::from(
+                                        [
+                                            (
+                                                "payment_method_data.card.card_number".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_number".to_string(),
+                                                    display_name: "card_number".to_string(),
+                                                    field_type: enums::FieldType::UserCardNumber,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "payment_method_data.card.card_exp_month".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_exp_month".to_string(),
+                                                    display_name: "card_exp_month".to_string(),
+                                                    field_type: enums::FieldType::UserCardExpiryMonth,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "payment_method_data.card.card_exp_year".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_exp_year".to_string(),
+                                                    display_name: "card_exp_year".to_string(),
+                                                    field_type: enums::FieldType::UserCardExpiryYear,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "payment_method_data.card.card_cvc".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.card.card_cvc".to_string(),
+                                                    display_name: "card_cvc".to_string(),
+                                                    field_type: enums::FieldType::UserCardCvc,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "email".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "email".to_string(),
+                                                    display_name: "email".to_string(),
+                                                    field_type: enums::FieldType::UserEmailAddress,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.line1".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.line1".to_string(),
+                                                    display_name: "line1".to_string(),
+                                                    field_type: enums::FieldType::UserAddressLine1,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.city".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.city".to_string(),
+                                                    display_name: "city".to_string(),
+                                                    field_type: enums::FieldType::UserAddressCity,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.state".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.state".to_string(),
+                                                    display_name: "state".to_string(),
+                                                    field_type: enums::FieldType::UserAddressState,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.zip".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.zip".to_string(),
+                                                    display_name: "zip".to_string(),
+                                                    field_type: enums::FieldType::UserAddressPincode,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.country".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.country".to_string(),
+                                                    display_name: "country".to_string(),
+                                                    field_type: enums::FieldType::UserAddressCountry{
+                                                        options: vec![
+                                                            "ALL".to_string(),
+                                                        ]
+                                                    },
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.first_name".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.first_name".to_string(),
+                                                    display_name: "first_name".to_string(),
+                                                    field_type: enums::FieldType::UserFullName,
+                                                    value: None,
+                                                }
+                                            ),
+                                            (
+                                                "billing.address.last_name".to_string(),
+                                                RequiredFieldInfo {
+                                                    required_field: "payment_method_data.billing.address.last_name".to_string(),
+                                                    display_name: "last_name".to_string(),
+                                                    field_type: enums::FieldType::UserFullName,
+                                                    value: None,
+                                                }
+                                            )
+                                        ]
+                                    ),
+                                    common: HashMap::new(),
+                                }
+                            ),
                             (
                                 enums::Connector::Dlocal,
                                 RequiredFieldFinal {
diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs
index cac856b2c48..0c2cc0bb86f 100644
--- a/crates/router/src/services/api.rs
+++ b/crates/router/src/services/api.rs
@@ -1532,6 +1532,46 @@ pub fn build_redirection_form(
               </script>")))
             }}
         }
+        RedirectForm::DeutschebankThreeDSChallengeFlow { acs_url, creq } => {
+            maud::html! {
+                (maud::DOCTYPE)
+                html {
+                    head {
+                        meta name="viewport" content="width=device-width, initial-scale=1";
+                    }
+
+                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {
+                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }
+
+                        (PreEscaped(r#"<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js"></script>"#))
+
+                        (PreEscaped(r#"
+                            <script>
+                            var anime = bodymovin.loadAnimation({
+                                container: document.getElementById('loader1'),
+                                renderer: 'svg',
+                                loop: true,
+                                autoplay: true,
+                                name: 'hyperswitch loader',
+                                animationData: {"v":"4.8.0","meta":{"g":"LottieFiles AE 3.1.1","a":"","k":"","d":"","tc":""},"fr":29.9700012207031,"ip":0,"op":31.0000012626559,"w":400,"h":250,"nm":"loader_shape","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[278.25,202.671,0],"ix":2},"a":{"a":0,"k":[23.72,23.72,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[12.935,0],[0,-12.936],[-12.935,0],[0,12.935]],"o":[[-12.952,0],[0,12.935],[12.935,0],[0,-12.936]],"v":[[0,-23.471],[-23.47,0.001],[0,23.471],[23.47,0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":19.99,"s":[100]},{"t":29.9800012211104,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[23.72,23.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":48.0000019550801,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"square 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[196.25,201.271,0],"ix":2},"a":{"a":0,"k":[22.028,22.03,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.914,0],[0,0],[0,-1.914],[0,0],[-1.914,0],[0,0],[0,1.914],[0,0]],"o":[[0,0],[-1.914,0],[0,0],[0,1.914],[0,0],[1.914,0],[0,0],[0,-1.914]],"v":[[18.313,-21.779],[-18.312,-21.779],[-21.779,-18.313],[-21.779,18.314],[-18.312,21.779],[18.313,21.779],[21.779,18.314],[21.779,-18.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14.99,"s":[100]},{"t":24.9800010174563,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[22.028,22.029],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Triangle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[116.25,200.703,0],"ix":2},"a":{"a":0,"k":[27.11,21.243,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.558,-0.879],[0,0],[-1.133,0],[0,0],[0.609,0.947],[0,0]],"o":[[-0.558,-0.879],[0,0],[-0.609,0.947],[0,0],[1.133,0],[0,0],[0,0]],"v":[[1.209,-20.114],[-1.192,-20.114],[-26.251,18.795],[-25.051,20.993],[25.051,20.993],[26.251,18.795],[1.192,-20.114]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9.99,"s":[100]},{"t":19.9800008138021,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.11,21.243],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":48.0000019550801,"st":0,"bm":0}],"markers":[]}
+                            })
+                            </script>
+                            "#))
+
+                        h3 style="text-align: center;" { "Please wait while we process your payment..." }
+                    }
+                    (PreEscaped(format!("<form id=\"PaReqForm\" method=\"POST\" action=\"{acs_url}\">
+                        <input type=\"hidden\" name=\"creq\" value=\"{creq}\">
+                        </form>")))
+                    (PreEscaped(format!("<script>
+                        {logging_template}
+                        window.onload = function() {{
+                        var paReqForm = document.querySelector('#PaReqForm'); if(paReqForm) paReqForm.submit();
+                        }}
+                    </script>")))
+                }
+            }
+        }
         RedirectForm::Payme => {
             maud::html! {
                 (maud::DOCTYPE)

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Implement Card 3ds for Deutschebank

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->

https://testmerch.directpos.de/rest-api/apidoc/v2.1/index.html#creditCard3DSecureInitializingThePaymentSsteps1_4


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->

**Cypress Tests**

**1. No3DSManualCapture**

![image](https://github.com/user-attachments/assets/cca4c8ed-2205-419b-8eb4-4759daf20f8a)

**2. 3DSAutoCapture**

![image](https://github.com/user-attachments/assets/38318c13-fba1-40f9-a4a8-16ee655e6127)

**3. 3DSManualCapture**

![image](https://github.com/user-attachments/assets/58c72d9d-9668-49dd-a8af-20c6f7407b2c)

**4. No3DSAutoCapture**

![image](https://github.com/user-attachments/assets/bc0b897d-5f45-4878-9a98-1498e8c9ce82)

**5. VoidPayment**

![image](https://github.com/user-attachments/assets/3cedc848-9b4c-4d95-bc66-9019085648d1)

**6. SyncPayment**

![image](https://github.com/user-attachments/assets/b4508f59-95b7-49e7-b079-df8933b38c3e)

**7. RefundPayment**

![image](https://github.com/user-attachments/assets/b8372b26-3945-47b6-afa7-06ca75b267f9)

**8. SyncRefund**

![image](https://github.com/user-attachments/assets/625f7bab-1c1f-4e89-8c89-9c4793cf78d9)


Note: Currently, no 3ds for card payments are not being supported for Deutschebank. Hence, no 3ds flows are expected to return an error message saying that the payment method type is not supported, and has been handled in the cypress tests accordingly. 


**Postman Tests**

**1. Authorize (Manual)**

 - Request
 
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "business_country": "US",
    "business_label": "default",
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "cybersourcecustomer",
    "email": "guest@example.com",
    "name": "Cardholder",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "authentication_type": "three_ds",
    "return_url": "https://duck.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4761739090000088",
            "card_exp_month": "12",
            "card_exp_year": "34",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123"
        }
    },
    "customer_acceptance": {
        "acceptance_type": "online"
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari",
            "last_name": "sundari"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari",
            "last_name": "sundari"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    }
}'
```
- Response

```
{
    "payment_id": "pay_PS9a7QNMXDs1Qr3GjLSV",
    "merchant_id": "postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6",
    "status": "requires_customer_action",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "deutschebank",
    "client_secret": "pay_PS9a7QNMXDs1Qr3GjLSV_secret_dfXLVVwCzeorfBNuOGCD",
    "created": "2024-12-16T11:36:46.533Z",
    "currency": "USD",
    "customer_id": "cybersourcecustomer",
    "customer": {
        "id": "cybersourcecustomer",
        "name": "Cardholder",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0088",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "476173",
            "card_extended_bin": null,
            "card_exp_month": "12",
            "card_exp_year": "34",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "Cardholder",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_PS9a7QNMXDs1Qr3GjLSV/postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6/pay_PS9a7QNMXDs1Qr3GjLSV_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": "deutschebank_US_default",
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "cybersourcecustomer",
        "created_at": 1734349006,
        "expires": 1734352606,
        "secret": "epk_0036b25eb0ef4d599e0b2957ff64beb3"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T11:51:46.533Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-12-16T11:36:49.083Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
```

**2. Capture (Manual)**

 - Request
 
```
curl --location 'http://localhost:8080/payments/pay_PS9a7QNMXDs1Qr3GjLSV/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp' \
--data '{
    "amount_to_capture": 6540,
    "statement_descriptor_name": "Joseph",
    "statement_descriptor_suffix": "JS"
}'
```

- Response 

```
{
    "payment_id": "pay_PS9a7QNMXDs1Qr3GjLSV",
    "merchant_id": "postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6",
    "status": "succeeded",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 6540,
    "connector": "deutschebank",
    "client_secret": "pay_PS9a7QNMXDs1Qr3GjLSV_secret_dfXLVVwCzeorfBNuOGCD",
    "created": "2024-12-16T11:36:46.533Z",
    "currency": "USD",
    "customer_id": "cybersourcecustomer",
    "customer": {
        "id": "cybersourcecustomer",
        "name": "Cardholder",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0088",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "476173",
            "card_extended_bin": null,
            "card_exp_month": "12",
            "card_exp_year": "34",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "Cardholder",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": "deutschebank_US_default",
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "nAYkZmc4a3I6pxU53fJzNP",
    "frm_message": null,
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T11:51:46.533Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": "pm_RncRqkyYbJrKGoU8Ywnr",
    "payment_method_status": null,
    "updated": "2024-12-16T11:37:16.619Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
```

**3. Authorize + Capture**

 - Request

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "business_country": "US",
    "business_label": "default",
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "cybersourcecustomer",
    "email": "guest@example.com",
    "name": "Cardholder",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "authentication_type": "three_ds",
    "return_url": "https://duck.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4761739090000088",
            "card_exp_month": "12",
            "card_exp_year": "34",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123"
        }
    },
    "customer_acceptance": {
        "acceptance_type": "online"
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari",
            "last_name": "sundari"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari",
            "last_name": "sundari"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    }
}'
```

- Response

```
{
    "payment_id": "pay_4ueYRDmGUyI31AuqI0ea",
    "merchant_id": "postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6",
    "status": "requires_customer_action",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "deutschebank",
    "client_secret": "pay_4ueYRDmGUyI31AuqI0ea_secret_IixVMy93O7YiEP4JJGpN",
    "created": "2024-12-16T11:43:10.558Z",
    "currency": "USD",
    "customer_id": "cybersourcecustomer",
    "customer": {
        "id": "cybersourcecustomer",
        "name": "Cardholder",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0088",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "476173",
            "card_extended_bin": null,
            "card_exp_month": "12",
            "card_exp_year": "34",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "Cardholder",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_4ueYRDmGUyI31AuqI0ea/postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6/pay_4ueYRDmGUyI31AuqI0ea_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": "deutschebank_US_default",
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "cybersourcecustomer",
        "created_at": 1734349390,
        "expires": 1734352990,
        "secret": "epk_df66b67348a9425dabef0cf41381d6f4"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T11:58:10.558Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-12-16T11:43:14.008Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
```

**4. PSync**

 - Request

```
curl --location 'http://localhost:8080/payments/pay_4ueYRDmGUyI31AuqI0ea?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp'
```

- Response

```
{
    "payment_id": "pay_4ueYRDmGUyI31AuqI0ea",
    "merchant_id": "postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6",
    "status": "succeeded",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 6540,
    "connector": "deutschebank",
    "client_secret": "pay_4ueYRDmGUyI31AuqI0ea_secret_IixVMy93O7YiEP4JJGpN",
    "created": "2024-12-16T11:43:10.558Z",
    "currency": "USD",
    "customer_id": "cybersourcecustomer",
    "customer": {
        "id": "cybersourcecustomer",
        "name": "Cardholder",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0088",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "476173",
            "card_extended_bin": null,
            "card_exp_month": "12",
            "card_exp_year": "34",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": "sundari"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "Cardholder",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": "deutschebank_US_default",
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "nVHvIf4P3jcAovFh4yPRTj",
    "frm_message": null,
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T11:58:10.558Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": "pm_nsOk8a7WMuZY0WZfZaNb",
    "payment_method_status": "active",
    "updated": "2024-12-16T11:45:26.008Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
```

**5. Refund**

 - Request

```
curl --location 'http://localhost:8080/refunds' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp' \
--data '{
    "payment_id": "pay_ySLbJ4uxZJbOwybYIOxJ",
    "amount": 6540,
    "reason": "Customer returned product",
    "refund_type": "instant",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```

- Response

```
{
    "refund_id": "ref_UbPDiWkAlJ3YXxAVydkh",
    "payment_id": "pay_ySLbJ4uxZJbOwybYIOxJ",
    "amount": 6540,
    "currency": "USD",
    "status": "succeeded",
    "reason": "Customer returned product",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "error_message": null,
    "error_code": null,
    "created_at": "2024-12-16T11:47:19.520Z",
    "updated_at": "2024-12-16T11:47:21.373Z",
    "connector": "deutschebank",
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "split_refunds": null
}
```

**6. RSync**

 - Request

```
curl --location 'http://localhost:8080/refunds/ref_UbPDiWkAlJ3YXxAVydkh' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp'
```

- Response

```
{
    "refund_id": "ref_UbPDiWkAlJ3YXxAVydkh",
    "payment_id": "pay_ySLbJ4uxZJbOwybYIOxJ",
    "amount": 6540,
    "currency": "USD",
    "status": "succeeded",
    "reason": "Customer returned product",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "error_message": null,
    "error_code": null,
    "created_at": "2024-12-16T11:47:19.520Z",
    "updated_at": "2024-12-16T11:47:21.373Z",
    "connector": "deutschebank",
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "split_refunds": null
}
```

**7. Cancel/Void**

 - Request

```
curl --location 'http://localhost:8080/payments/pay_jtzc7sPBlQ6sNNgoPG7D/cancel' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_o6c9H4UPb00h8hMpjOww9sHv5IWOqwTuJrNC45fOVdUdPOs0sjRQ7peoX7KgqRWp' \
--data '{
    "cancellation_reason": "requested_by_customer"
}'
```

- Response

```
{
    "payment_id": "pay_jtzc7sPBlQ6sNNgoPG7D",
    "merchant_id": "postman_merchant_GHAction_89b212fc-9f25-469f-ba4b-1a3288efcdd6",
    "status": "cancelled",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": "deutschebank",
    "client_secret": "pay_jtzc7sPBlQ6sNNgoPG7D_secret_nRyINaFU4g6pBbm8id0r",
    "created": "2024-12-16T11:51:03.676Z",
    "currency": "USD",
    "customer_id": "cybersourcecustomer",
    "customer": {
        "id": "cybersourcecustomer",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0088",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "476173",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "likhin",
            "last_name": "bopanna"
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "likhin",
            "last_name": "bopanna"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": "requested_by_customer",
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": null,
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "pZEtlCeAsWQZqLpBNhZto5",
    "frm_message": null,
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590045"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hwz1M9UiyP6KcFovaoe2",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_tQJBbQeTqAOBfStOjwz6",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T12:06:03.676Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": "pm_lbLyNoKaCcTRjxwQKYON",
    "payment_method_status": null,
    "updated": "2024-12-16T11:51:35.365Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
```

**8. Supported Payments**

-Request

```
curl --location --request GET 'http://localhost:8080/feature_matrix' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_jfD66VYra1Ckqm2IxU5cy1N4chjamXfyyOyXUqNEmHv0pSyCjZh3DvqOBKR0HyU8' \
--header 'X-Merchant-Id: postman_merchant_GHAction_32615a11-9334-48e0-8c5f-767da86facd7' \
--data '{
    
}'
```

-Response

```
{
    "connector_count": 3,
    "connectors": [
        {
            "name": "bambora",
            "description": "Bambora is a leading online payment provider in Canada and United States.",
            "category": "payment_gateway",
            "supported_payment_methods": [
                {
                    "payment_method": "card",
                    "payment_method_type": "credit",
                    "mandates": "not_supported",
                    "refunds": "supported",
                    "supported_capture_methods": [
                        "automatic",
                        "manual",
                        "sequential_automatic"
                    ],
                    "supported_countries": [
                        "CA",
                        "US"
                    ],
                    "supported_currencies": [
                        "USD"
                    ]
                },
                {
                    "payment_method": "card",
                    "payment_method_type": "credit",
                    "mandates": "not_supported",
                    "refunds": "supported",
                    "supported_capture_methods": [
                        "automatic",
                        "manual",
                        "sequential_automatic"
                    ],
                    "supported_countries": [
                        "US",
                        "CA"
                    ],
                    "supported_currencies": [
                        "USD"
                    ]
                }
            ],
            "supported_webhook_flows": []
        },
        {
            "name": "deutschebank",
            "description": "Deutsche Bank is a German multinational investment bank and financial services company ",
            "category": "bank_acquirer",
            "supported_payment_methods": [
                {
                    "payment_method": "card",
                    "payment_method_type": "credit",
                    "mandates": "not_supported",
                    "refunds": "supported",
                    "supported_capture_methods": [
                        "automatic",
                        "manual",
                        "sequential_automatic"
                    ],
                    "supported_countries": null,
                    "supported_currencies": null
                },
                {
                    "payment_method": "bank_debit",
                    "payment_method_type": "sepa",
                    "mandates": "supported",
                    "refunds": "supported",
                    "supported_capture_methods": [
                        "automatic",
                        "manual",
                        "sequential_automatic"
                    ],
                    "supported_countries": null,
                    "supported_currencies": null
                }
            ],
            "supported_webhook_flows": []
        },
        {
            "name": "zsl",
            "description": "Zsl is a payment gateway operating in China, specializing in facilitating local bank transfers",
            "category": "payment_gateway",
            "supported_payment_methods": [
                {
                    "payment_method": "bank_transfer",
                    "payment_method_type": "local_bank_transfer",
                    "mandates": "not_supported",
                    "refunds": "not_supported",
                    "supported_capture_methods": [
                        "automatic"
                    ],
                    "supported_countries": [
                        "CN"
                    ],
                    "supported_currencies": [
                        "CNY"
                    ]
                }
            ],
            "supported_webhook_flows": []
        }
    ]
}
```

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
