Bug: [FEATURE] [ACI] Setup mandate and network token flow added and existing flows fixed



Setup mandate and networkToken flow added for ACI connector.
While doing payments, we were not validating the capture method in the request payload. Instead, we were directly treating it as automatic capture which was causing capture to fail. Made changes in API contracts in both request and response and status mapping for capture.
diff --git a/config/config.example.toml b/config/config.example.toml
index d2bbb75a04e..b725be102c1 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -541,8 +541,8 @@ wallet.google_pay = { connector_list = "bankofamerica,authorizedotnet,cybersourc
 bank_redirect.giropay = { connector_list = "globalpay" }
 
 [mandates.supported_payment_methods]
-card.credit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv"
-card.debit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv"
+card.credit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv"
+card.debit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv"
 wallet.paypal = { connector_list = "adyen,novalnet" }                                          # Mandate supported payment method type and connector for wallets
 pay_later.klarna = { connector_list = "adyen" }                                       # Mandate supported payment method type and connector for pay_later
 bank_debit.ach = { connector_list = "gocardless,adyen" }                              # Mandate supported payment method type and connector for bank_debit
diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml
index 15665793cca..c756b0a9e9c 100644
--- a/config/deployments/integration_test.toml
+++ b/config/deployments/integration_test.toml
@@ -231,8 +231,8 @@ bank_debit.ach = { connector_list = "gocardless,adyen,stripe" }
 bank_debit.becs = { connector_list = "gocardless,stripe,adyen" }
 bank_debit.bacs = { connector_list = "stripe,gocardless" }
 bank_debit.sepa = { connector_list = "gocardless,adyen,stripe,deutschebank" }
-card.credit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
-card.debit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.credit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.debit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
 pay_later.klarna.connector_list = "adyen,aci"
 wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon,bankofamerica,nexinets,novalnet,nuvei,authorizedotnet,wellsfargo"
 wallet.samsung_pay.connector_list = "cybersource"
diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index 3843682e910..f685bbe2787 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -231,8 +231,8 @@ bank_debit.ach = { connector_list = "gocardless,adyen,stripe" }
 bank_debit.becs = { connector_list = "gocardless,stripe,adyen" }
 bank_debit.bacs = { connector_list = "stripe,gocardless" }
 bank_debit.sepa = { connector_list = "gocardless,adyen,stripe,deutschebank" }
-card.credit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
-card.debit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.credit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.debit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
 pay_later.klarna.connector_list = "adyen,aci"
 wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon,bankofamerica,nexinets,novalnet,nuvei,authorizedotnet,wellsfargo"
 wallet.samsung_pay.connector_list = "cybersource"
diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml
index 3fd60dfe8f9..9ed89a01c9b 100644
--- a/config/deployments/sandbox.toml
+++ b/config/deployments/sandbox.toml
@@ -238,8 +238,8 @@ bank_debit.ach = { connector_list = "gocardless,adyen,stripe" }
 bank_debit.becs = { connector_list = "gocardless,stripe,adyen" }
 bank_debit.bacs = { connector_list = "stripe,gocardless" }
 bank_debit.sepa = { connector_list = "gocardless,adyen,stripe,deutschebank" }
-card.credit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
-card.debit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.credit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.debit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
 pay_later.klarna.connector_list = "adyen,aci"
 wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon,bankofamerica,nexinets,novalnet,nuvei,authorizedotnet,wellsfargo,worldpayvantiv"
 wallet.samsung_pay.connector_list = "cybersource"
diff --git a/config/development.toml b/config/development.toml
index 0454eb1931c..940e43b50ca 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -1081,8 +1081,8 @@ bank_debit.ach = { connector_list = "gocardless,adyen,stripe" }
 bank_debit.becs = { connector_list = "gocardless,stripe,adyen" }
 bank_debit.bacs = { connector_list = "stripe,gocardless" }
 bank_debit.sepa = { connector_list = "gocardless,adyen,stripe,deutschebank" }
-card.credit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
-card.debit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.credit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
+card.debit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,archipel,worldpayvantiv,payload"
 pay_later.klarna.connector_list = "adyen,aci"
 wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon,bankofamerica,nuvei,nexinets,novalnet,authorizedotnet,wellsfargo,worldpayvantiv"
 wallet.samsung_pay.connector_list = "cybersource"
diff --git a/config/docker_compose.toml b/config/docker_compose.toml
index b154cea783b..d299323f2c1 100644
--- a/config/docker_compose.toml
+++ b/config/docker_compose.toml
@@ -1009,8 +1009,8 @@ wallet.google_pay = { connector_list = "stripe,cybersource,adyen,bankofamerica,a
 wallet.apple_pay = { connector_list = "stripe,adyen,cybersource,noon,bankofamerica,authorizedotnet,novalnet,multisafepay,wellsfargo,nuvei" }
 wallet.samsung_pay = { connector_list = "cybersource" }
 wallet.paypal = { connector_list = "adyen,novalnet,authorizedotnet" }
-card.credit = { connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,elavon,xendit,novalnet,bamboraapac,archipel,wellsfargo,worldpayvantiv,payload" }
-card.debit = { connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,elavon,xendit,novalnet,bamboraapac,archipel,wellsfargo,worldpayvantiv,payload" }
+card.credit = { connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,elavon,xendit,novalnet,bamboraapac,archipel,wellsfargo,worldpayvantiv,payload" }
+card.debit = { connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,elavon,xendit,novalnet,bamboraapac,archipel,wellsfargo,worldpayvantiv,payload" }
 bank_debit.ach = { connector_list = "gocardless,adyen" }
 bank_debit.becs = { connector_list = "gocardless" }
 bank_debit.bacs = { connector_list = "adyen" }
diff --git a/crates/hyperswitch_connectors/src/connectors/aci.rs b/crates/hyperswitch_connectors/src/connectors/aci.rs
index 59c89ae9771..96c3a059c22 100644
--- a/crates/hyperswitch_connectors/src/connectors/aci.rs
+++ b/crates/hyperswitch_connectors/src/connectors/aci.rs
@@ -96,7 +96,7 @@ impl ConnectorCommon for Aci {
             .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
         Ok(vec![(
             headers::AUTHORIZATION.to_string(),
-            auth.api_key.into_masked(),
+            format!("Bearer {}", auth.api_key.peek()).into_masked(),
         )])
     }
 
@@ -161,31 +161,133 @@ impl api::PaymentToken for Aci {}
 impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
     for Aci
 {
-    // Not Implemented (R)
+    fn build_request(
+        &self,
+        _req: &RouterData<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(errors::ConnectorError::NotSupported {
+            message: "Payment method tokenization not supported".to_string(),
+            connector: "ACI",
+        }
+        .into())
+    }
 }
 
 impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Aci {
-    // Not Implemented (R)
+    fn build_request(
+        &self,
+        _req: &RouterData<Session, PaymentsSessionData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(errors::ConnectorError::NotSupported {
+            message: "Payment sessions not supported".to_string(),
+            connector: "ACI",
+        }
+        .into())
+    }
 }
 
 impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken> for Aci {
-    // Not Implemented (R)
+    fn build_request(
+        &self,
+        _req: &RouterData<AccessTokenAuth, AccessTokenRequestData, AccessToken>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(errors::ConnectorError::NotSupported {
+            message: "Access token authentication not supported".to_string(),
+            connector: "ACI",
+        }
+        .into())
+    }
 }
 
 impl api::MandateSetup for Aci {}
 
 impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData> for Aci {
-    // Issue: #173
-    fn build_request(
+    fn get_headers(
+        &self,
+        req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
+        let mut header = vec![(
+            headers::CONTENT_TYPE.to_string(),
+            self.common_get_content_type().to_string().into(),
+        )];
+        let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
+        header.append(&mut api_key);
+        Ok(header)
+    }
+
+    fn get_content_type(&self) -> &'static str {
+        self.common_get_content_type()
+    }
+
+    fn get_url(
         &self,
         _req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        Ok(format!("{}v1/registrations", self.base_url(connectors)))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
         _connectors: &Connectors,
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let connector_req = aci::AciMandateRequest::try_from(req)?;
+        Ok(RequestContent::FormUrlEncoded(Box::new(connector_req)))
+    }
+
+    fn build_request(
+        &self,
+        req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        connectors: &Connectors,
     ) -> CustomResult<Option<Request>, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("Setup Mandate flow for Aci".to_string()).into())
+        Ok(Some(
+            RequestBuilder::new()
+                .method(Method::Post)
+                .url(&self.get_url(req, connectors)?)
+                .attach_default_headers()
+                .headers(self.get_headers(req, connectors)?)
+                .set_body(self.get_request_body(req, connectors)?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<
+        RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        errors::ConnectorError,
+    > {
+        let response: aci::AciMandateResponse = res
+            .response
+            .parse_struct("AciMandateResponse")
+            .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,
+        })
+        .change_context(errors::ConnectorError::ResponseHandlingFailed)
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
     }
 }
 
-// TODO: Investigate unexplained error in capture flow from connector.
 impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> for Aci {
     fn get_headers(
         &self,
@@ -409,8 +511,6 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
         req: &PaymentsAuthorizeRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        // encode only for for urlencoded things.
-
         let amount = convert_amount(
             self.amount_converter,
             req.request.minor_amount,
@@ -724,14 +824,13 @@ fn decrypt_aci_webhook_payload(
     Ok(ciphertext_and_tag)
 }
 
-// TODO: Test this webhook flow once dashboard access is available.
 #[async_trait::async_trait]
 impl IncomingWebhook for Aci {
     fn get_webhook_source_verification_algorithm(
         &self,
         _request: &IncomingWebhookRequestDetails<'_>,
     ) -> CustomResult<Box<dyn crypto::VerifySignature + Send>, errors::ConnectorError> {
-        Ok(Box::new(crypto::NoAlgorithm))
+        Ok(Box::new(crypto::HmacSha256))
     }
 
     fn get_webhook_source_verification_signature(
@@ -899,15 +998,15 @@ static ACI_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = LazyLo
         enums::CaptureMethod::Manual,
     ];
 
-    let supported_card_network = vec![
+    let supported_card_networks = vec![
+        common_enums::CardNetwork::Visa,
+        common_enums::CardNetwork::Mastercard,
         common_enums::CardNetwork::AmericanExpress,
+        common_enums::CardNetwork::JCB,
         common_enums::CardNetwork::DinersClub,
         common_enums::CardNetwork::Discover,
-        common_enums::CardNetwork::JCB,
-        common_enums::CardNetwork::Maestro,
-        common_enums::CardNetwork::Mastercard,
         common_enums::CardNetwork::UnionPay,
-        common_enums::CardNetwork::Visa,
+        common_enums::CardNetwork::Maestro,
     ];
 
     let mut aci_supported_payment_methods = SupportedPaymentMethods::new();
@@ -944,9 +1043,9 @@ static ACI_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = LazyLo
             specific_features: Some(
                 api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                     api_models::feature_matrix::CardSpecificFeatures {
-                        three_ds: common_enums::FeatureStatus::NotSupported,
+                        three_ds: common_enums::FeatureStatus::Supported,
                         no_three_ds: common_enums::FeatureStatus::Supported,
-                        supported_card_networks: supported_card_network.clone(),
+                        supported_card_networks: supported_card_networks.clone(),
                     }
                 }),
             ),
@@ -963,14 +1062,15 @@ static ACI_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = LazyLo
             specific_features: Some(
                 api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                     api_models::feature_matrix::CardSpecificFeatures {
-                        three_ds: common_enums::FeatureStatus::NotSupported,
+                        three_ds: common_enums::FeatureStatus::Supported,
                         no_three_ds: common_enums::FeatureStatus::Supported,
-                        supported_card_networks: supported_card_network.clone(),
+                        supported_card_networks: supported_card_networks.clone(),
                     }
                 }),
             ),
         },
     );
+
     aci_supported_payment_methods.add(
         enums::PaymentMethod::BankRedirect,
         enums::PaymentMethodType::Eps,
@@ -1051,6 +1151,7 @@ static ACI_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = LazyLo
             specific_features: None,
         },
     );
+
     aci_supported_payment_methods.add(
         enums::PaymentMethod::PayLater,
         enums::PaymentMethodType::Klarna,
@@ -1061,6 +1162,7 @@ static ACI_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = LazyLo
             specific_features: None,
         },
     );
+
     aci_supported_payment_methods
 });
 
diff --git a/crates/hyperswitch_connectors/src/connectors/aci/transformers.rs b/crates/hyperswitch_connectors/src/connectors/aci/transformers.rs
index 3edd04f8308..c3f5e53d9a4 100644
--- a/crates/hyperswitch_connectors/src/connectors/aci/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/aci/transformers.rs
@@ -4,10 +4,15 @@ use common_enums::enums;
 use common_utils::{id_type, pii::Email, request::Method, types::StringMajorUnit};
 use error_stack::report;
 use hyperswitch_domain_models::{
-    payment_method_data::{BankRedirectData, Card, PayLaterData, PaymentMethodData, WalletData},
+    network_tokenization::NetworkTokenNumber,
+    payment_method_data::{
+        BankRedirectData, Card, NetworkTokenData, PayLaterData, PaymentMethodData, WalletData,
+    },
     router_data::{ConnectorAuthType, RouterData},
+    router_flow_types::SetupMandate,
     router_request_types::{
         PaymentsAuthorizeData, PaymentsCancelData, PaymentsSyncData, ResponseId,
+        SetupMandateRequestData,
     },
     router_response_types::{
         MandateReference, PaymentsResponseData, RedirectForm, RefundsResponseData,
@@ -25,7 +30,10 @@ use url::Url;
 use super::aci_result_codes::{FAILURE_CODES, PENDING_CODES, SUCCESSFUL_CODES};
 use crate::{
     types::{RefundsResponseRouterData, ResponseRouterData},
-    utils::{self, PhoneDetailsData, RouterData as _},
+    utils::{
+        self, CardData, NetworkTokenData as NetworkTokenDataTrait, PaymentsAuthorizeRequestData,
+        PhoneDetailsData, RouterData as _,
+    },
 };
 
 type Error = error_stack::Report<errors::ConnectorError>;
@@ -54,8 +62,8 @@ impl GetCaptureMethod for PaymentsCancelData {
 
 #[derive(Debug, Serialize)]
 pub struct AciRouterData<T> {
-    amount: StringMajorUnit,
-    router_data: T,
+    pub amount: StringMajorUnit,
+    pub router_data: T,
 }
 
 impl<T> From<(StringMajorUnit, T)> for AciRouterData<T> {
@@ -114,6 +122,24 @@ pub struct AciCancelRequest {
     pub payment_type: AciPaymentType,
 }
 
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AciMandateRequest {
+    pub entity_id: Secret<String>,
+    pub payment_brand: PaymentBrand,
+    #[serde(flatten)]
+    pub payment_details: PaymentDetails,
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AciMandateResponse {
+    pub id: String,
+    pub result: ResultCode,
+    pub build_number: String,
+    pub timestamp: String,
+}
+
 #[derive(Debug, Clone, Serialize)]
 #[serde(untagged)]
 pub enum PaymentDetails {
@@ -123,6 +149,7 @@ pub enum PaymentDetails {
     Wallet(Box<WalletPMData>),
     Klarna,
     Mandate,
+    AciNetworkToken(Box<AciNetworkTokenData>),
 }
 
 impl TryFrom<(&WalletData, &PaymentsAuthorizeRouterData)> for PaymentDetails {
@@ -321,21 +348,117 @@ impl
     }
 }
 
+fn get_aci_payment_brand(
+    card_network: Option<common_enums::CardNetwork>,
+    is_network_token_flow: bool,
+) -> Result<PaymentBrand, Error> {
+    match card_network {
+        Some(common_enums::CardNetwork::Visa) => Ok(PaymentBrand::Visa),
+        Some(common_enums::CardNetwork::Mastercard) => Ok(PaymentBrand::Mastercard),
+        Some(common_enums::CardNetwork::AmericanExpress) => Ok(PaymentBrand::AmericanExpress),
+        Some(common_enums::CardNetwork::JCB) => Ok(PaymentBrand::Jcb),
+        Some(common_enums::CardNetwork::DinersClub) => Ok(PaymentBrand::DinersClub),
+        Some(common_enums::CardNetwork::Discover) => Ok(PaymentBrand::Discover),
+        Some(common_enums::CardNetwork::UnionPay) => Ok(PaymentBrand::UnionPay),
+        Some(common_enums::CardNetwork::Maestro) => Ok(PaymentBrand::Maestro),
+        Some(unsupported_network) => Err(errors::ConnectorError::NotSupported {
+            message: format!(
+                "Card network {:?} is not supported by ACI",
+                unsupported_network
+            ),
+            connector: "ACI",
+        })?,
+        None => {
+            if is_network_token_flow {
+                Ok(PaymentBrand::Visa)
+            } else {
+                Err(errors::ConnectorError::MissingRequiredField {
+                    field_name: "card.card_network",
+                }
+                .into())
+            }
+        }
+    }
+}
+
 impl TryFrom<(Card, Option<Secret<String>>)> for PaymentDetails {
     type Error = Error;
     fn try_from(
         (card_data, card_holder_name): (Card, Option<Secret<String>>),
     ) -> Result<Self, Self::Error> {
+        let card_expiry_year = card_data.get_expiry_year_4_digit();
+
+        let payment_brand = get_aci_payment_brand(card_data.card_network, false)?;
+
         Ok(Self::AciCard(Box::new(CardDetails {
             card_number: card_data.card_number,
-            card_holder: card_holder_name.unwrap_or(Secret::new("".to_string())),
-            card_expiry_month: card_data.card_exp_month,
-            card_expiry_year: card_data.card_exp_year,
+            card_holder: card_holder_name.ok_or(errors::ConnectorError::MissingRequiredField {
+                field_name: "card_holder_name",
+            })?,
+            card_expiry_month: card_data.card_exp_month.clone(),
+            card_expiry_year,
             card_cvv: card_data.card_cvc,
+            payment_brand,
         })))
     }
 }
 
+impl
+    TryFrom<(
+        &AciRouterData<&PaymentsAuthorizeRouterData>,
+        &NetworkTokenData,
+    )> for PaymentDetails
+{
+    type Error = Error;
+    fn try_from(
+        value: (
+            &AciRouterData<&PaymentsAuthorizeRouterData>,
+            &NetworkTokenData,
+        ),
+    ) -> Result<Self, Self::Error> {
+        let (_item, network_token_data) = value;
+        let token_number = network_token_data.get_network_token();
+        let payment_brand = get_aci_payment_brand(network_token_data.card_network.clone(), true)?;
+        let aci_network_token_data = AciNetworkTokenData {
+            token_type: AciTokenAccountType::Network,
+            token_number,
+            token_expiry_month: network_token_data.get_network_token_expiry_month(),
+            token_expiry_year: network_token_data.get_expiry_year_4_digit(),
+            token_cryptogram: Some(
+                network_token_data
+                    .get_cryptogram()
+                    .clone()
+                    .unwrap_or_default(),
+            ),
+            payment_brand,
+        };
+        Ok(Self::AciNetworkToken(Box::new(aci_network_token_data)))
+    }
+}
+
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum AciTokenAccountType {
+    Network,
+}
+
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AciNetworkTokenData {
+    #[serde(rename = "tokenAccount.type")]
+    pub token_type: AciTokenAccountType,
+    #[serde(rename = "tokenAccount.number")]
+    pub token_number: NetworkTokenNumber,
+    #[serde(rename = "tokenAccount.expiryMonth")]
+    pub token_expiry_month: Secret<String>,
+    #[serde(rename = "tokenAccount.expiryYear")]
+    pub token_expiry_year: Secret<String>,
+    #[serde(rename = "tokenAccount.cryptogram")]
+    pub token_cryptogram: Option<Secret<String>>,
+    #[serde(rename = "paymentBrand")]
+    pub payment_brand: PaymentBrand,
+}
+
 #[derive(Debug, Clone, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct BankRedirectionPMData {
@@ -365,7 +488,7 @@ pub struct WalletPMData {
     account_id: Option<Secret<String>>,
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize)]
+#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
 #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 pub enum PaymentBrand {
     Eps,
@@ -379,6 +502,23 @@ pub enum PaymentBrand {
     Mbway,
     #[serde(rename = "ALIPAY")]
     AliPay,
+    // Card network brands
+    #[serde(rename = "VISA")]
+    Visa,
+    #[serde(rename = "MASTER")]
+    Mastercard,
+    #[serde(rename = "AMEX")]
+    AmericanExpress,
+    #[serde(rename = "JCB")]
+    Jcb,
+    #[serde(rename = "DINERS")]
+    DinersClub,
+    #[serde(rename = "DISCOVER")]
+    Discover,
+    #[serde(rename = "UNIONPAY")]
+    UnionPay,
+    #[serde(rename = "MAESTRO")]
+    Maestro,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq, Serialize)]
@@ -393,6 +533,8 @@ pub struct CardDetails {
     pub card_expiry_year: Secret<String>,
     #[serde(rename = "card.cvv")]
     pub card_cvv: Secret<String>,
+    #[serde(rename = "paymentBrand")]
+    pub payment_brand: PaymentBrand,
 }
 
 #[derive(Debug, Clone, Serialize)]
@@ -460,6 +602,9 @@ impl TryFrom<&AciRouterData<&PaymentsAuthorizeRouterData>> for AciPaymentsReques
     fn try_from(item: &AciRouterData<&PaymentsAuthorizeRouterData>) -> Result<Self, Self::Error> {
         match item.router_data.request.payment_method_data.clone() {
             PaymentMethodData::Card(ref card_data) => Self::try_from((item, card_data)),
+            PaymentMethodData::NetworkToken(ref network_token_data) => {
+                Self::try_from((item, network_token_data))
+            }
             PaymentMethodData::Wallet(ref wallet_data) => Self::try_from((item, wallet_data)),
             PaymentMethodData::PayLater(ref pay_later_data) => {
                 Self::try_from((item, pay_later_data))
@@ -487,7 +632,6 @@ impl TryFrom<&AciRouterData<&PaymentsAuthorizeRouterData>> for AciPaymentsReques
             | PaymentMethodData::Voucher(_)
             | PaymentMethodData::OpenBanking(_)
             | PaymentMethodData::CardToken(_)
-            | PaymentMethodData::NetworkToken(_)
             | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                 Err(errors::ConnectorError::NotImplemented(
                     utils::get_unimplemented_payment_method_error_message("Aci"),
@@ -574,7 +718,34 @@ impl TryFrom<(&AciRouterData<&PaymentsAuthorizeRouterData>, &Card)> for AciPayme
             txn_details,
             payment_method,
             instruction,
-            shopper_result_url: None,
+            shopper_result_url: item.router_data.request.router_return_url.clone(),
+        })
+    }
+}
+
+impl
+    TryFrom<(
+        &AciRouterData<&PaymentsAuthorizeRouterData>,
+        &NetworkTokenData,
+    )> for AciPaymentsRequest
+{
+    type Error = Error;
+    fn try_from(
+        value: (
+            &AciRouterData<&PaymentsAuthorizeRouterData>,
+            &NetworkTokenData,
+        ),
+    ) -> Result<Self, Self::Error> {
+        let (item, network_token_data) = value;
+        let txn_details = get_transaction_details(item)?;
+        let payment_method = PaymentDetails::try_from((item, network_token_data))?;
+        let instruction = get_instruction_details(item);
+
+        Ok(Self {
+            txn_details,
+            payment_method,
+            instruction,
+            shopper_result_url: item.router_data.request.router_return_url.clone(),
         })
     }
 }
@@ -609,11 +780,16 @@ fn get_transaction_details(
     item: &AciRouterData<&PaymentsAuthorizeRouterData>,
 ) -> Result<TransactionDetails, error_stack::Report<errors::ConnectorError>> {
     let auth = AciAuthType::try_from(&item.router_data.connector_auth_type)?;
+    let payment_type = if item.router_data.request.is_auto_capture()? {
+        AciPaymentType::Debit
+    } else {
+        AciPaymentType::Preauthorization
+    };
     Ok(TransactionDetails {
         entity_id: auth.entity_id,
         amount: item.amount.to_owned(),
         currency: item.router_data.request.currency.to_string(),
-        payment_type: AciPaymentType::Debit,
+        payment_type,
     })
 }
 
@@ -650,6 +826,61 @@ impl TryFrom<&PaymentsCancelRouterData> for AciCancelRequest {
     }
 }
 
+impl TryFrom<&RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>>
+    for AciMandateRequest
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+
+    fn try_from(
+        item: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+    ) -> Result<Self, Self::Error> {
+        let auth = AciAuthType::try_from(&item.connector_auth_type)?;
+
+        let (payment_brand, payment_details) = match &item.request.payment_method_data {
+            PaymentMethodData::Card(card_data) => {
+                let brand = get_aci_payment_brand(card_data.card_network.clone(), false)?;
+                match brand {
+                    PaymentBrand::Visa
+                    | PaymentBrand::Mastercard
+                    | PaymentBrand::AmericanExpress => {}
+                    _ => Err(errors::ConnectorError::NotSupported {
+                        message: "Payment method not supported for mandate setup".to_string(),
+                        connector: "ACI",
+                    })?,
+                }
+
+                let details = PaymentDetails::AciCard(Box::new(CardDetails {
+                    card_number: card_data.card_number.clone(),
+                    card_expiry_month: card_data.card_exp_month.clone(),
+                    card_expiry_year: card_data.get_expiry_year_4_digit(),
+                    card_cvv: card_data.card_cvc.clone(),
+                    card_holder: card_data.card_holder_name.clone().ok_or(
+                        errors::ConnectorError::MissingRequiredField {
+                            field_name: "card_holder_name",
+                        },
+                    )?,
+                    payment_brand: brand.clone(),
+                }));
+
+                (brand, details)
+            }
+            _ => {
+                return Err(errors::ConnectorError::NotSupported {
+                    message: "Payment method not supported for mandate setup".to_string(),
+                    connector: "ACI",
+                }
+                .into());
+            }
+        };
+
+        Ok(Self {
+            entity_id: auth.entity_id,
+            payment_brand,
+            payment_details,
+        })
+    }
+}
+
 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "lowercase")]
 pub enum AciPaymentStatus {
@@ -674,6 +905,7 @@ fn map_aci_attempt_status(item: AciPaymentStatus, auto_capture: bool) -> enums::
         AciPaymentStatus::RedirectShopper => enums::AttemptStatus::AuthenticationPending,
     }
 }
+
 impl FromStr for AciPaymentStatus {
     type Err = error_stack::Report<errors::ConnectorError>;
     fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -696,10 +928,8 @@ impl FromStr for AciPaymentStatus {
 pub struct AciPaymentsResponse {
     id: String,
     registration_id: Option<Secret<String>>,
-    // ndc is an internal unique identifier for the request.
     ndc: String,
     timestamp: String,
-    // Number useful for support purposes.
     build_number: String,
     pub(super) result: ResultCode,
     pub(super) redirect: Option<AciRedirectionData>,
@@ -717,15 +947,24 @@ pub struct AciErrorResponse {
 #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct AciRedirectionData {
-    method: Option<Method>,
-    parameters: Vec<Parameters>,
-    url: Url,
+    pub method: Option<Method>,
+    pub parameters: Vec<Parameters>,
+    pub url: Url,
+    pub preconditions: Option<Vec<PreconditionData>>,
+}
+
+#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PreconditionData {
+    pub method: Option<Method>,
+    pub parameters: Vec<Parameters>,
+    pub url: Url,
 }
 
 #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
 pub struct Parameters {
-    name: String,
-    value: String,
+    pub name: String,
+    pub value: String,
 }
 
 #[derive(Default, Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
@@ -863,12 +1102,45 @@ pub struct AciCaptureResultDetails {
     extended_description: String,
     #[serde(rename = "clearingInstituteName")]
     clearing_institute_name: String,
-    connector_tx_id1: String,
-    connector_tx_id3: String,
-    connector_tx_id2: String,
+    connector_tx_i_d1: String,
+    connector_tx_i_d3: String,
+    connector_tx_i_d2: String,
     acquirer_response: String,
 }
 
+#[derive(Debug, Default, Clone, Deserialize)]
+pub enum AciCaptureStatus {
+    Succeeded,
+    Failed,
+    #[default]
+    Pending,
+}
+
+impl FromStr for AciCaptureStatus {
+    type Err = error_stack::Report<errors::ConnectorError>;
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        if FAILURE_CODES.contains(&s) {
+            Ok(Self::Failed)
+        } else if PENDING_CODES.contains(&s) {
+            Ok(Self::Pending)
+        } else if SUCCESSFUL_CODES.contains(&s) {
+            Ok(Self::Succeeded)
+        } else {
+            Err(report!(errors::ConnectorError::UnexpectedResponseError(
+                bytes::Bytes::from(s.to_owned())
+            )))
+        }
+    }
+}
+
+fn map_aci_capture_status(item: AciCaptureStatus) -> enums::AttemptStatus {
+    match item {
+        AciCaptureStatus::Succeeded => enums::AttemptStatus::Charged,
+        AciCaptureStatus::Failed => enums::AttemptStatus::Failure,
+        AciCaptureStatus::Pending => enums::AttemptStatus::Pending,
+    }
+}
+
 impl<F, T> TryFrom<ResponseRouterData<F, AciCaptureResponse, T, PaymentsResponseData>>
     for RouterData<F, T, PaymentsResponseData>
 {
@@ -877,10 +1149,7 @@ impl<F, T> TryFrom<ResponseRouterData<F, AciCaptureResponse, T, PaymentsResponse
         item: ResponseRouterData<F, AciCaptureResponse, T, PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
         Ok(Self {
-            status: map_aci_attempt_status(
-                AciPaymentStatus::from_str(&item.response.result.code)?,
-                false,
-            ),
+            status: map_aci_capture_status(AciCaptureStatus::from_str(&item.response.result.code)?),
             reference_id: Some(item.response.referenced_id.clone()),
             response: Ok(PaymentsResponseData::TransactionResponse {
                 resource_id: ResponseId::ConnectorTransactionId(item.response.id.clone()),
@@ -963,7 +1232,6 @@ impl From<AciRefundStatus> for enums::RefundStatus {
 #[serde(rename_all = "camelCase")]
 pub struct AciRefundResponse {
     id: String,
-    //ndc is an internal unique identifier for the request.
     ndc: String,
     timestamp: String,
     build_number: String,
@@ -987,6 +1255,58 @@ impl<F> TryFrom<RefundsResponseRouterData<F, AciRefundResponse>> for RefundsRout
     }
 }
 
+impl
+    TryFrom<
+        ResponseRouterData<
+            SetupMandate,
+            AciMandateResponse,
+            SetupMandateRequestData,
+            PaymentsResponseData,
+        >,
+    > for RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+
+    fn try_from(
+        item: ResponseRouterData<
+            SetupMandate,
+            AciMandateResponse,
+            SetupMandateRequestData,
+            PaymentsResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        let mandate_reference = Some(MandateReference {
+            connector_mandate_id: Some(item.response.id.clone()),
+            payment_method_id: None,
+            mandate_metadata: None,
+            connector_mandate_request_reference_id: None,
+        });
+
+        let status = if SUCCESSFUL_CODES.contains(&item.response.result.code.as_str()) {
+            enums::AttemptStatus::Charged
+        } else if FAILURE_CODES.contains(&item.response.result.code.as_str()) {
+            enums::AttemptStatus::Failure
+        } else {
+            enums::AttemptStatus::Pending
+        };
+
+        Ok(Self {
+            status,
+            response: Ok(PaymentsResponseData::TransactionResponse {
+                resource_id: ResponseId::ConnectorTransactionId(item.response.id.clone()),
+                redirection_data: Box::new(None),
+                mandate_reference: Box::new(mandate_reference),
+                connector_metadata: None,
+                network_txn_id: None,
+                connector_response_reference_id: Some(item.response.id),
+                incremental_authorization_allowed: None,
+                charges: None,
+            }),
+            ..item.data
+        })
+    }
+}
+
 #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
 pub enum AciWebhookEventType {
     Payment,
diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs
index 9d3544d5cee..f50a7c16075 100644
--- a/crates/router/tests/connectors/aci.rs
+++ b/crates/router/tests/connectors/aci.rs
@@ -1,456 +1,559 @@
-#![allow(clippy::print_stdout)]
+use std::str::FromStr;
 
-use std::{borrow::Cow, marker::PhantomData, str::FromStr, sync::Arc};
-
-use common_utils::id_type;
-use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails};
+use hyperswitch_domain_models::{
+    address::{Address, AddressDetails, PhoneDetails},
+    payment_method_data::{Card, PaymentMethodData},
+    router_request_types::AuthenticationData,
+};
 use masking::Secret;
-use router::{
-    configs::settings::Settings,
-    core::payments,
-    db::StorageImpl,
-    routes, services,
-    types::{self, storage::enums, PaymentAddress},
+use router::types::{self, storage::enums, PaymentAddress};
+
+use crate::{
+    connector_auth,
+    utils::{self, ConnectorActions, PaymentInfo},
 };
-use tokio::sync::oneshot;
-
-use crate::{connector_auth::ConnectorAuthentication, utils};
-
-fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
-    let auth = ConnectorAuthentication::new()
-        .aci
-        .expect("Missing ACI connector authentication configuration");
-
-    let merchant_id = id_type::MerchantId::try_from(Cow::from("aci")).unwrap();
-
-    types::RouterData {
-        flow: PhantomData,
-        merchant_id,
-        customer_id: Some(id_type::CustomerId::try_from(Cow::from("aci")).unwrap()),
-        tenant_id: id_type::TenantId::try_from_string("public".to_string()).unwrap(),
-        connector: "aci".to_string(),
-        payment_id: uuid::Uuid::new_v4().to_string(),
-        attempt_id: uuid::Uuid::new_v4().to_string(),
-        status: enums::AttemptStatus::default(),
-        auth_type: enums::AuthenticationType::NoThreeDs,
-        payment_method: enums::PaymentMethod::Card,
-        connector_auth_type: utils::to_connector_auth_type(auth.into()),
-        description: Some("This is a test".to_string()),
-        payment_method_status: None,
-        request: types::PaymentsAuthorizeData {
-            amount: 1000,
-            currency: enums::Currency::USD,
-            payment_method_data: types::domain::PaymentMethodData::Card(types::domain::Card {
-                card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
-                card_exp_month: Secret::new("10".to_string()),
-                card_exp_year: Secret::new("2025".to_string()),
-                card_cvc: Secret::new("999".to_string()),
-                card_issuer: None,
-                card_network: None,
-                card_type: None,
-                card_issuing_country: None,
-                bank_code: None,
-                nick_name: Some(Secret::new("nick_name".into())),
-                card_holder_name: Some(Secret::new("card holder name".into())),
-                co_badged_card_data: None,
-            }),
-            confirm: true,
-            statement_descriptor_suffix: None,
-            statement_descriptor: None,
-            setup_future_usage: None,
-            mandate_id: None,
-            off_session: None,
-            setup_mandate_details: None,
-            capture_method: None,
-            browser_info: None,
-            order_details: None,
-            order_category: None,
-            email: None,
-            customer_name: None,
-            session_token: None,
-            enrolled_for_3ds: false,
-            related_transaction_id: None,
-            payment_experience: None,
-            payment_method_type: None,
-            router_return_url: None,
-            webhook_url: None,
-            complete_authorize_url: None,
-            customer_id: None,
-            surcharge_details: None,
-            request_incremental_authorization: false,
-            metadata: None,
-            authentication_data: None,
-            customer_acceptance: None,
-            locale: None,
-            enable_partial_authorization: None,
-            ..utils::PaymentAuthorizeType::default().0
-        },
-        response: Err(types::ErrorResponse::default()),
-        address: PaymentAddress::new(
+
+#[derive(Clone, Copy)]
+struct AciTest;
+impl ConnectorActions for AciTest {}
+impl utils::Connector for AciTest {
+    fn get_data(&self) -> types::api::ConnectorData {
+        use router::connector::Aci;
+        utils::construct_connector_data_old(
+            Box::new(Aci::new()),
+            types::Connector::Aci,
+            types::api::GetToken::Connector,
             None,
+        )
+    }
+
+    fn get_auth_token(&self) -> types::ConnectorAuthType {
+        utils::to_connector_auth_type(
+            connector_auth::ConnectorAuthentication::new()
+                .aci
+                .expect("Missing connector authentication configuration")
+                .into(),
+        )
+    }
+
+    fn get_name(&self) -> String {
+        "aci".to_string()
+    }
+}
+
+static CONNECTOR: AciTest = AciTest {};
+
+fn get_default_payment_info() -> Option<PaymentInfo> {
+    Some(PaymentInfo {
+        address: Some(PaymentAddress::new(
             None,
             Some(Address {
                 address: Some(AddressDetails {
                     first_name: Some(Secret::new("John".to_string())),
                     last_name: Some(Secret::new("Doe".to_string())),
+                    line1: Some(Secret::new("123 Main St".to_string())),
+                    city: Some("New York".to_string()),
+                    state: Some(Secret::new("NY".to_string())),
+                    zip: Some(Secret::new("10001".to_string())),
+                    country: Some(enums::CountryAlpha2::US),
                     ..Default::default()
                 }),
                 phone: Some(PhoneDetails {
-                    number: Some(Secret::new("9123456789".to_string())),
-                    country_code: Some("+351".to_string()),
+                    number: Some(Secret::new("+1234567890".to_string())),
+                    country_code: Some("+1".to_string()),
                 }),
                 email: None,
             }),
             None,
-        ),
-        connector_meta_data: None,
-        connector_wallets_details: None,
-        amount_captured: None,
-        minor_amount_captured: None,
-        access_token: None,
-        session_token: None,
-        reference_id: None,
-        payment_method_token: None,
-        connector_customer: None,
-        recurring_mandate_payment_data: None,
-        connector_response: None,
-        preprocessing_id: None,
-        connector_request_reference_id: uuid::Uuid::new_v4().to_string(),
-        #[cfg(feature = "payouts")]
-        payout_method_data: None,
-        #[cfg(feature = "payouts")]
-        quote_id: None,
-        test_mode: None,
-        payment_method_balance: None,
-        connector_api_version: None,
-        connector_http_status_code: None,
-        apple_pay_flow: None,
-        external_latency: None,
-        frm_metadata: None,
-        refund_id: None,
-        dispute_id: None,
-        integrity_check: Ok(()),
-        additional_merchant_data: None,
-        header_payload: None,
-        connector_mandate_request_reference_id: None,
-        authentication_id: None,
-        psd2_sca_exemption_type: None,
-        raw_connector_response: None,
-        is_payment_id_from_merchant: None,
-        l2_l3_data: None,
-        minor_amount_capturable: None,
-    }
+            None,
+        )),
+        ..Default::default()
+    })
 }
 
-fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
-    let auth = ConnectorAuthentication::new()
-        .aci
-        .expect("Missing ACI connector authentication configuration");
-
-    let merchant_id = id_type::MerchantId::try_from(Cow::from("aci")).unwrap();
-
-    types::RouterData {
-        flow: PhantomData,
-        merchant_id,
-        customer_id: Some(id_type::CustomerId::try_from(Cow::from("aci")).unwrap()),
-        tenant_id: id_type::TenantId::try_from_string("public".to_string()).unwrap(),
-        connector: "aci".to_string(),
-        payment_id: uuid::Uuid::new_v4().to_string(),
-        attempt_id: uuid::Uuid::new_v4().to_string(),
-        payment_method_status: None,
-        status: enums::AttemptStatus::default(),
-        payment_method: enums::PaymentMethod::Card,
-        auth_type: enums::AuthenticationType::NoThreeDs,
-        connector_auth_type: utils::to_connector_auth_type(auth.into()),
-        description: Some("This is a test".to_string()),
-        request: types::RefundsData {
-            payment_amount: 1000,
-            currency: enums::Currency::USD,
-
-            refund_id: uuid::Uuid::new_v4().to_string(),
-            connector_transaction_id: String::new(),
-            refund_amount: 100,
-            webhook_url: None,
-            connector_metadata: None,
-            reason: None,
-            connector_refund_id: None,
-            browser_info: None,
-            ..utils::PaymentRefundType::default().0
-        },
-        response: Err(types::ErrorResponse::default()),
-        address: PaymentAddress::default(),
-        connector_meta_data: None,
-        connector_wallets_details: None,
-        amount_captured: None,
-        minor_amount_captured: None,
-        access_token: None,
-        session_token: None,
-        reference_id: None,
-        payment_method_token: None,
-        connector_customer: None,
-        recurring_mandate_payment_data: None,
-        connector_response: None,
-        preprocessing_id: None,
-        connector_request_reference_id: uuid::Uuid::new_v4().to_string(),
-        #[cfg(feature = "payouts")]
-        payout_method_data: None,
-        #[cfg(feature = "payouts")]
-        quote_id: None,
-        test_mode: None,
-        payment_method_balance: None,
-        connector_api_version: None,
-        connector_http_status_code: None,
-        apple_pay_flow: None,
-        external_latency: None,
-        frm_metadata: None,
-        refund_id: None,
-        dispute_id: None,
-        integrity_check: Ok(()),
-        additional_merchant_data: None,
-        header_payload: None,
-        connector_mandate_request_reference_id: None,
-        authentication_id: None,
-        psd2_sca_exemption_type: None,
-        raw_connector_response: None,
-        is_payment_id_from_merchant: None,
-        l2_l3_data: None,
-        minor_amount_capturable: None,
-    }
+fn get_payment_authorize_data() -> Option<types::PaymentsAuthorizeData> {
+    Some(types::PaymentsAuthorizeData {
+        payment_method_data: PaymentMethodData::Card(Card {
+            card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
+            card_exp_month: Secret::new("10".to_string()),
+            card_exp_year: Secret::new("2025".to_string()),
+            card_cvc: Secret::new("999".to_string()),
+            card_holder_name: Some(Secret::new("John Doe".to_string())),
+            ..utils::CCardType::default().0
+        }),
+        ..utils::PaymentAuthorizeType::default().0
+    })
+}
+
+fn get_threeds_payment_authorize_data() -> Option<types::PaymentsAuthorizeData> {
+    Some(types::PaymentsAuthorizeData {
+        payment_method_data: PaymentMethodData::Card(Card {
+            card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
+            card_exp_month: Secret::new("10".to_string()),
+            card_exp_year: Secret::new("2025".to_string()),
+            card_cvc: Secret::new("999".to_string()),
+            card_holder_name: Some(Secret::new("John Doe".to_string())),
+            ..utils::CCardType::default().0
+        }),
+        enrolled_for_3ds: true,
+        authentication_data: Some(AuthenticationData {
+            eci: Some("05".to_string()),
+            cavv: Secret::new("jJ81HADVRtXfCBATEp01CJUAAAA".to_string()),
+            threeds_server_transaction_id: Some("9458d8d4-f19f-4c28-b5c7-421b1dd2e1aa".to_string()),
+            message_version: Some(common_utils::types::SemanticVersion::new(2, 1, 0)),
+            ds_trans_id: Some("97267598FAE648F28083B2D2AF7B1234".to_string()),
+            created_at: common_utils::date_time::now(),
+            challenge_code: Some("01".to_string()),
+            challenge_cancel: None,
+            challenge_code_reason: Some("01".to_string()),
+            message_extension: None,
+            acs_trans_id: None,
+            authentication_type: None,
+        }),
+        ..utils::PaymentAuthorizeType::default().0
+    })
 }
 
 #[actix_web::test]
-async fn payments_create_success() {
-    let conf = Settings::new().unwrap();
-    let tx: oneshot::Sender<()> = oneshot::channel().0;
-
-    let app_state = Box::pin(routes::AppState::with_storage(
-        conf,
-        StorageImpl::PostgresqlTest,
-        tx,
-        Box::new(services::MockApiClient),
-    ))
-    .await;
-    let state = Arc::new(app_state)
-        .get_session_state(
-            &id_type::TenantId::try_from_string("public".to_string()).unwrap(),
+async fn should_only_authorize_payment() {
+    let response = CONNECTOR
+        .authorize_payment(get_payment_authorize_data(), get_default_payment_info())
+        .await
+        .expect("Authorize payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Authorized);
+}
+
+#[actix_web::test]
+async fn should_capture_authorized_payment() {
+    let response = CONNECTOR
+        .authorize_and_capture_payment(
+            get_payment_authorize_data(),
             None,
-            || {},
+            get_default_payment_info(),
         )
-        .unwrap();
+        .await
+        .expect("Capture payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Charged);
+}
 
-    use router::connector::Aci;
-    let connector = utils::construct_connector_data_old(
-        Box::new(Aci::new()),
-        types::Connector::Aci,
-        types::api::GetToken::Connector,
-        None,
+#[actix_web::test]
+async fn should_partially_capture_authorized_payment() {
+    let response = CONNECTOR
+        .authorize_and_capture_payment(
+            get_payment_authorize_data(),
+            Some(types::PaymentsCaptureData {
+                amount_to_capture: 50,
+                ..utils::PaymentCaptureType::default().0
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .expect("Capture payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Charged);
+}
+
+#[actix_web::test]
+async fn should_sync_authorized_payment() {
+    let authorize_response = CONNECTOR
+        .authorize_payment(get_payment_authorize_data(), get_default_payment_info())
+        .await
+        .expect("Authorize payment response");
+    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
+    let response = CONNECTOR
+        .psync_retry_till_status_matches(
+            enums::AttemptStatus::Authorized,
+            Some(types::PaymentsSyncData {
+                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
+                    txn_id.unwrap(),
+                ),
+                ..Default::default()
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .expect("PSync response");
+    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
+}
+
+#[actix_web::test]
+async fn should_void_authorized_payment() {
+    let response = CONNECTOR
+        .authorize_and_void_payment(
+            get_payment_authorize_data(),
+            Some(types::PaymentsCancelData {
+                connector_transaction_id: String::from(""),
+                cancellation_reason: Some("requested_by_customer".to_string()),
+                ..Default::default()
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .expect("Void payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Voided);
+}
+
+#[actix_web::test]
+async fn should_refund_manually_captured_payment() {
+    let response = CONNECTOR
+        .capture_payment_and_refund(
+            get_payment_authorize_data(),
+            None,
+            None,
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
     );
-    let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
-        types::api::Authorize,
-        types::PaymentsAuthorizeData,
-        types::PaymentsResponseData,
-    > = connector.connector.get_connector_integration();
-    let request = construct_payment_router_data();
-    let response = services::api::execute_connector_processing_step(
-        &state,
-        connector_integration,
-        &request,
-        payments::CallConnectorAction::Trigger,
-        None,
-        None,
-    )
-    .await
-    .unwrap();
-    assert!(
-        response.status == enums::AttemptStatus::Charged,
-        "The payment failed"
+}
+
+#[actix_web::test]
+async fn should_partially_refund_manually_captured_payment() {
+    let response = CONNECTOR
+        .capture_payment_and_refund(
+            get_payment_authorize_data(),
+            None,
+            Some(types::RefundsData {
+                refund_amount: 50,
+                ..utils::PaymentRefundType::default().0
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
     );
 }
 
 #[actix_web::test]
-#[ignore]
-async fn payments_create_failure() {
-    {
-        let conf = Settings::new().unwrap();
-        use router::connector::Aci;
-        let tx: oneshot::Sender<()> = oneshot::channel().0;
-
-        let app_state = Box::pin(routes::AppState::with_storage(
-            conf,
-            StorageImpl::PostgresqlTest,
-            tx,
-            Box::new(services::MockApiClient),
-        ))
-        .await;
-        let state = Arc::new(app_state)
-            .get_session_state(
-                &id_type::TenantId::try_from_string("public".to_string()).unwrap(),
-                None,
-                || {},
-            )
-            .unwrap();
-        let connector = utils::construct_connector_data_old(
-            Box::new(Aci::new()),
-            types::Connector::Aci,
-            types::api::GetToken::Connector,
+async fn should_sync_manually_captured_refund() {
+    let refund_response = CONNECTOR
+        .capture_payment_and_refund(
+            get_payment_authorize_data(),
             None,
-        );
-        let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
-            types::api::Authorize,
-            types::PaymentsAuthorizeData,
-            types::PaymentsResponseData,
-        > = connector.connector.get_connector_integration();
-        let mut request = construct_payment_router_data();
-        request.request.payment_method_data =
-            types::domain::PaymentMethodData::Card(types::domain::Card {
-                card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
-                card_exp_month: Secret::new("10".to_string()),
-                card_exp_year: Secret::new("2025".to_string()),
-                card_cvc: Secret::new("99".to_string()),
-                card_issuer: None,
-                card_network: None,
-                card_type: None,
-                card_issuing_country: None,
-                bank_code: None,
-                nick_name: Some(Secret::new("nick_name".into())),
-                card_holder_name: Some(Secret::new("card holder name".into())),
-                co_badged_card_data: None,
-            });
-
-        let response = services::api::execute_connector_processing_step(
-            &state,
-            connector_integration,
-            &request,
-            payments::CallConnectorAction::Trigger,
             None,
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    let response = CONNECTOR
+        .rsync_retry_till_status_matches(
+            enums::RefundStatus::Success,
+            refund_response.response.unwrap().connector_refund_id,
             None,
+            get_default_payment_info(),
         )
         .await
-        .is_err();
-        println!("{response:?}");
-        assert!(response, "The payment was intended to fail but it passed");
-    }
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+#[actix_web::test]
+async fn should_make_payment() {
+    let authorize_response = CONNECTOR
+        .make_payment(get_payment_authorize_data(), get_default_payment_info())
+        .await
+        .unwrap();
+    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
 }
 
 #[actix_web::test]
-async fn refund_for_successful_payments() {
-    let conf = Settings::new().unwrap();
-    use router::connector::Aci;
-    let connector = utils::construct_connector_data_old(
-        Box::new(Aci::new()),
-        types::Connector::Aci,
-        types::api::GetToken::Connector,
-        None,
+async fn should_sync_auto_captured_payment() {
+    let authorize_response = CONNECTOR
+        .make_payment(get_payment_authorize_data(), get_default_payment_info())
+        .await
+        .unwrap();
+    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
+    assert_ne!(txn_id, None, "Empty connector transaction id");
+    let response = CONNECTOR
+        .psync_retry_till_status_matches(
+            enums::AttemptStatus::Charged,
+            Some(types::PaymentsSyncData {
+                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
+                    txn_id.unwrap(),
+                ),
+                capture_method: Some(enums::CaptureMethod::Automatic),
+                ..Default::default()
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(response.status, enums::AttemptStatus::Charged,);
+}
+
+#[actix_web::test]
+async fn should_refund_auto_captured_payment() {
+    let response = CONNECTOR
+        .make_payment_and_refund(
+            get_payment_authorize_data(),
+            None,
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
     );
-    let tx: oneshot::Sender<()> = oneshot::channel().0;
-
-    let app_state = Box::pin(routes::AppState::with_storage(
-        conf,
-        StorageImpl::PostgresqlTest,
-        tx,
-        Box::new(services::MockApiClient),
-    ))
-    .await;
-    let state = Arc::new(app_state)
-        .get_session_state(
-            &id_type::TenantId::try_from_string("public".to_string()).unwrap(),
+}
+
+#[actix_web::test]
+async fn should_partially_refund_succeeded_payment() {
+    let refund_response = CONNECTOR
+        .make_payment_and_refund(
+            get_payment_authorize_data(),
+            Some(types::RefundsData {
+                refund_amount: 50,
+                ..utils::PaymentRefundType::default().0
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        refund_response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+#[actix_web::test]
+async fn should_refund_succeeded_payment_multiple_times() {
+    CONNECTOR
+        .make_payment_and_multiple_refund(
+            get_payment_authorize_data(),
+            Some(types::RefundsData {
+                refund_amount: 50,
+                ..utils::PaymentRefundType::default().0
+            }),
+            get_default_payment_info(),
+        )
+        .await;
+}
+
+#[actix_web::test]
+async fn should_sync_refund() {
+    let refund_response = CONNECTOR
+        .make_payment_and_refund(
+            get_payment_authorize_data(),
             None,
-            || {},
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    let response = CONNECTOR
+        .rsync_retry_till_status_matches(
+            enums::RefundStatus::Success,
+            refund_response.response.unwrap().connector_refund_id,
+            None,
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+#[actix_web::test]
+async fn should_fail_payment_for_incorrect_cvc() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: PaymentMethodData::Card(Card {
+                    card_cvc: Secret::new("12345".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            get_default_payment_info(),
         )
+        .await
         .unwrap();
-    let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
-        types::api::Authorize,
-        types::PaymentsAuthorizeData,
-        types::PaymentsResponseData,
-    > = connector.connector.get_connector_integration();
-    let request = construct_payment_router_data();
-    let response = services::api::execute_connector_processing_step(
-        &state,
-        connector_integration,
-        &request,
-        payments::CallConnectorAction::Trigger,
-        None,
-        None,
-    )
-    .await
-    .unwrap();
     assert!(
-        response.status == enums::AttemptStatus::Charged,
-        "The payment failed"
+        response.response.is_err(),
+        "Payment should fail with incorrect CVC"
     );
-    let connector_integration: services::BoxedRefundConnectorIntegrationInterface<
-        types::api::Execute,
-        types::RefundsData,
-        types::RefundsResponseData,
-    > = connector.connector.get_connector_integration();
-    let mut refund_request = construct_refund_router_data();
-    refund_request.request.connector_transaction_id = match response.response.unwrap() {
-        types::PaymentsResponseData::TransactionResponse { resource_id, .. } => {
-            resource_id.get_connector_transaction_id().unwrap()
-        }
-        _ => panic!("Connector transaction id not found"),
-    };
-    let response = services::api::execute_connector_processing_step(
-        &state,
-        connector_integration,
-        &refund_request,
-        payments::CallConnectorAction::Trigger,
-        None,
-        None,
-    )
-    .await
-    .unwrap();
-    println!("{response:?}");
+}
+
+#[actix_web::test]
+async fn should_fail_payment_for_invalid_exp_month() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: PaymentMethodData::Card(Card {
+                    card_exp_month: Secret::new("20".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
     assert!(
-        response.response.unwrap().refund_status == enums::RefundStatus::Success,
-        "The refund transaction failed"
+        response.response.is_err(),
+        "Payment should fail with invalid expiry month"
     );
 }
 
 #[actix_web::test]
-#[ignore]
-async fn refunds_create_failure() {
-    let conf = Settings::new().unwrap();
-    use router::connector::Aci;
-    let connector = utils::construct_connector_data_old(
-        Box::new(Aci::new()),
-        types::Connector::Aci,
-        types::api::GetToken::Connector,
-        None,
+async fn should_fail_payment_for_incorrect_expiry_year() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: PaymentMethodData::Card(Card {
+                    card_exp_year: Secret::new("2000".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert!(
+        response.response.is_err(),
+        "Payment should fail with incorrect expiry year"
     );
-    let tx: oneshot::Sender<()> = oneshot::channel().0;
-
-    let app_state = Box::pin(routes::AppState::with_storage(
-        conf,
-        StorageImpl::PostgresqlTest,
-        tx,
-        Box::new(services::MockApiClient),
-    ))
-    .await;
-    let state = Arc::new(app_state)
-        .get_session_state(
-            &id_type::TenantId::try_from_string("public".to_string()).unwrap(),
-            None,
-            || {},
+}
+
+#[actix_web::test]
+async fn should_fail_void_payment_for_auto_capture() {
+    let authorize_response = CONNECTOR
+        .make_payment(get_payment_authorize_data(), get_default_payment_info())
+        .await
+        .unwrap();
+    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
+    assert_ne!(txn_id, None, "Empty connector transaction id");
+    let void_response = CONNECTOR
+        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
+        .await
+        .unwrap();
+    assert!(
+        void_response.response.is_err(),
+        "Void should fail for already captured payment"
+    );
+}
+
+#[actix_web::test]
+async fn should_fail_capture_for_invalid_payment() {
+    let capture_response = CONNECTOR
+        .capture_payment("123456789".to_string(), None, get_default_payment_info())
+        .await
+        .unwrap();
+    assert!(
+        capture_response.response.is_err(),
+        "Capture should fail for invalid payment ID"
+    );
+}
+
+#[actix_web::test]
+async fn should_fail_for_refund_amount_higher_than_payment_amount() {
+    let response = CONNECTOR
+        .make_payment_and_refund(
+            get_payment_authorize_data(),
+            Some(types::RefundsData {
+                refund_amount: 150,
+                ..utils::PaymentRefundType::default().0
+            }),
+            get_default_payment_info(),
         )
+        .await
+        .unwrap();
+    assert!(
+        response.response.is_err(),
+        "Refund should fail when amount exceeds payment amount"
+    );
+}
+
+#[actix_web::test]
+#[ignore]
+async fn should_make_threeds_payment() {
+    let authorize_response = CONNECTOR
+        .make_payment(
+            get_threeds_payment_authorize_data(),
+            get_default_payment_info(),
+        )
+        .await
         .unwrap();
-    let connector_integration: services::BoxedRefundConnectorIntegrationInterface<
-        types::api::Execute,
-        types::RefundsData,
-        types::RefundsResponseData,
-    > = connector.connector.get_connector_integration();
-    let mut request = construct_refund_router_data();
-    request.request.connector_transaction_id = "1234".to_string();
-    let response = services::api::execute_connector_processing_step(
-        &state,
-        connector_integration,
-        &request,
-        payments::CallConnectorAction::Trigger,
-        None,
-        None,
-    )
-    .await
-    .is_err();
-    println!("{response:?}");
-    assert!(response, "The refund was intended to fail but it passed");
+
+    assert!(
+        authorize_response.status == enums::AttemptStatus::AuthenticationPending
+            || authorize_response.status == enums::AttemptStatus::Charged,
+        "3DS payment should result in AuthenticationPending or Charged status, got: {:?}",
+        authorize_response.status
+    );
+
+    if let Ok(types::PaymentsResponseData::TransactionResponse {
+        redirection_data, ..
+    }) = &authorize_response.response
+    {
+        if authorize_response.status == enums::AttemptStatus::AuthenticationPending {
+            assert!(
+                redirection_data.is_some(),
+                "3DS flow should include redirection data for authentication"
+            );
+        }
+    }
+}
+
+#[actix_web::test]
+#[ignore]
+async fn should_authorize_threeds_payment() {
+    let response = CONNECTOR
+        .authorize_payment(
+            get_threeds_payment_authorize_data(),
+            get_default_payment_info(),
+        )
+        .await
+        .expect("Authorize 3DS payment response");
+
+    assert!(
+        response.status == enums::AttemptStatus::AuthenticationPending
+            || response.status == enums::AttemptStatus::Authorized,
+        "3DS authorization should result in AuthenticationPending or Authorized status, got: {:?}",
+        response.status
+    );
+}
+
+#[actix_web::test]
+#[ignore]
+async fn should_sync_threeds_payment() {
+    let authorize_response = CONNECTOR
+        .authorize_payment(
+            get_threeds_payment_authorize_data(),
+            get_default_payment_info(),
+        )
+        .await
+        .expect("Authorize 3DS payment response");
+    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
+    let response = CONNECTOR
+        .psync_retry_till_status_matches(
+            enums::AttemptStatus::AuthenticationPending,
+            Some(types::PaymentsSyncData {
+                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
+                    txn_id.unwrap(),
+                ),
+                ..Default::default()
+            }),
+            get_default_payment_info(),
+        )
+        .await
+        .expect("PSync 3DS response");
+    assert!(
+        response.status == enums::AttemptStatus::AuthenticationPending
+            || response.status == enums::AttemptStatus::Authorized,
+        "3DS sync should maintain AuthenticationPending or Authorized status"
+    );
 }
diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml
index 65fd42accf2..7508208069d 100644
--- a/loadtest/config/development.toml
+++ b/loadtest/config/development.toml
@@ -721,8 +721,8 @@ bank_debit.ach = { connector_list = "gocardless,adyen,stripe" }
 bank_debit.becs = { connector_list = "gocardless,stripe,adyen" }
 bank_debit.bacs = { connector_list = "stripe,gocardless" }
 bank_debit.sepa = { connector_list = "gocardless,adyen,stripe,deutschebank" }
-card.credit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,worldpayvantiv,payload"
-card.debit.connector_list = "checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,worldpayvantiv,payload"
+card.credit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,worldpayvantiv,payload"
+card.debit.connector_list = "aci,checkout,stripe,adyen,authorizedotnet,cybersource,datatrans,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica,braintree,nuvei,payme,wellsfargo,bamboraapac,elavon,fiuu,nexixpay,novalnet,paybox,paypal,xendit,moneris,worldpayvantiv,payload"
 pay_later.klarna.connector_list = "adyen,aci"
 wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon,bankofamerica,nexinets,novalnet,authorizedotnet"
 wallet.samsung_pay.connector_list = "cybersource"

## Type of Change
- [ ] Bugfix
- [ ] New feature
- [X] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Summary

  This PR enhances the ACI connector with comprehensive 3D Secure (3DS) authentication support and modernizes the test suite, porting behavioral improvements from the `ORCH-2/aci-fixes` branch to be compatible with
  the current upstream codebase structure.

  ### Key Changes

  - **Standalone 3DS Implementation**: Added complete 3DS authentication flow using proper `/v1/threeDSecure` endpoints (PreAuthentication and Authentication)
  - **Framework Integration**: Implemented `AciThreeDSFlow` redirect form variant with dual iframe support for precondition and authentication steps
  - **Enhanced Request Structures**: Updated request models to include all required fields matching the reference script at `@hyperswitch/tmp/poc-exipay-cnp/scripts/aci/3ds`
  - **Payment Processing Improvements**: Added network token support, payment brand mapping, and proper mandate setup functionality
  - **Security Enhancement**: Updated webhook verification from NoAlgorithm to HMAC-SHA256
  - **Modernized Test Suite**: Refactored tests to use `ConnectorActions` pattern with comprehensive coverage including positive, negative, and 3DS scenarios

  ### Technical Details

  #### Files Modified
  - `crates/hyperswitch_connectors/src/connectors/aci.rs` - Main connector implementation
  - `crates/hyperswitch_connectors/src/connectors/aci/transformers.rs` - Request/response transformers
  - `crates/hyperswitch_domain_models/src/router_response_types.rs` - RedirectForm enum extension
  - `crates/diesel_models/src/payment_attempt.rs` - Database model updates
  - `crates/router/src/services/api.rs` - Framework-level redirect handling
  - `crates/router/tests/connectors/aci.rs` - Complete test suite modernization

  #### Key Implementations
  - **3DS Request Structure**: Complete `AciStandalone3DSRequest` with all required fields including challenge indicators, enrollment flags, and proper card data handling
  - **Dual Iframe Support**: Framework-level HTML generation for both precondition and authentication iframes
  - **Payment Brand Mapping**: Support for Visa, Mastercard, American Express, JCB, and other major card networks
  - **Authentication**: Fixed authentication to use Bearer format
  - **Modern Test Architecture**: Implemented `ConnectorActions` trait pattern following project standards

  ### Test Coverage Enhancements

  #### Positive Test Scenarios
  - Manual capture flow: authorize, capture, partial capture, sync, void, refund
  - Automatic capture flow: payment, sync, refund, partial refund, multiple refunds
  - 3DS authentication flows with proper status validation

  #### Negative Test Scenarios
  - Invalid card details (CVC, expiry month, expiry year)
  - Invalid payment operations (void auto-captured, invalid payment ID)
  - Refund validation (amount exceeding payment amount)

  #### 3DS-Specific Tests
  - 3DS payment creation with authentication data
  - 3DS authorization with redirect data validation
  - 3DS payment synchronization
  - Authentication flow status verification

  ### Validation

  - ✅ All modified files pass `cargo +nightly fmt` formatting checks
  - ✅ Code follows project conventions and patterns
  - ✅ Implementation matches reference script behavior
  - ✅ Comprehensive test coverage (18+ test scenarios)
  - ✅ Modern `ConnectorActions` pattern implementation
  - ✅ Backward compatibility maintained for existing functionality

  ### Test Plan

  - [x] Manual capture flow tests (authorize, capture, void, refund, sync)
  - [x] Automatic capture flow tests (payment, refund, sync)
  - [x] Negative scenario tests (invalid inputs, edge cases)
  - [x] 3DS authentication flow tests with redirect validation
  - [x] Framework-level redirect form handling validation
  - [x] Error handling and status code validation


### Additional Changes

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

## 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)?
-->

<details>
<summary>1. Cards payment </summary>

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_Tz5ePEgSZ0NRdEOsdx3cloAjMSV3KkPbsWubLbAlSsv0ndwsblQKTkZZMu3332yC' \
--data-raw '{
    "amount": 6540,
    "currency": "EUR",
    "amount_to_capture": 6540,
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "no_three_ds",
    "setup_future_usage": "on_session", 
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "customer@gmail.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "customer_id": "customer123",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "5454545454545454",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "737",
            "card_network": "Mastercard"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 6540,
            "account_name": "transaction_processing"
        }
    ],
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "128.0.0.1"
    },
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "125.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "payment_link": false,
    "payment_link_config": {
        "theme": "",
        "logo": "",
        "seller_name": "",
        "sdk_layout": "",
        "display_sdk_only": false,
        "enabled_saved_payment_method": false
    },
    "payment_type": "normal"
}'
```

Response
```

```

</details>

2. Redirection
<img width="1721" height="1082" alt="Screenshot 2025-09-03 at 10 17 24 AM" src="https://github.com/user-attachments/assets/4e4c7059-1353-4160-b02e-bfa24fe7aa00" />


<details>
<summary>3. CIT </summary>

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_jBGr5aVyHqi26wIUT0l6VoyH0lGLSC5AcUoyoSv4MOaZDVulNKHuceiO87kr1UDn' \
--data-raw '{
    "amount": 6540,
    "currency": "EUR",
    "amount_to_capture": 6540,
    "confirm": true,
    
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "no_three_ds",
    "setup_future_usage": "off_session", 
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "customer@gmail.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "customer_id": "customer123",
    "phone_country_code": "+1",
    "routing": { 
        "type": "single",
        "data": "stripe"
    },
    "description": "Its my first payment request",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": { 
        "card": {
            "card_number": "5454545454545454",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "737",
            "card_network": "Mastercard"
        }
    },
    
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 6540,
            "account_name": "transaction_processing"
        }
    ],
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "128.0.0.1"
    },
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "125.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "payment_link": false,
    "payment_link_config": {
        "theme": "",
        "logo": "",
        "seller_name": "",
        "sdk_layout": "",
        "display_sdk_only": false,
        "enabled_saved_payment_method": false
    },
    "payment_type": "normal", 
    "request_incremental_authorization": false,
    "merchant_order_reference_id": "test_ord",
    "session_expiry": 900, 
    "mandate_data": {
        "customer_acceptance": {
            "acceptance_type": "offline",
            "accepted_at": "1963-05-03T04:07:52.723Z",
            "online": {
                "ip_address": "125.0.0.1",
                "user_agent": "amet irure esse"
            }
        },
        "mandate_type": {
            "multi_use": {
                "amount": 1000,
                "currency": "USD",
                "start_date": "2023-04-21T00:00:00Z",
                "end_date": "2023-05-21T00:00:00Z",
                "metadata": {
                    "frequency": "13"
                }
            }
        }
    }    
}'
````

Response:
```
{"payment_id":"pay_nJrHQrInwO77Uvsjrp1h","merchant_id":"merchant_1756939264","status":"requires_customer_action","amount":6540,"net_amount":6540,"shipping_cost":null,"amount_capturable":6540,"amount_received":null,"connector":"aci","client_secret":"pay_nJrHQrInwO77Uvsjrp1h_secret_klCqSLL4Va5yqCqoS7iU","created":"2025-09-03T22:48:45.789Z","currency":"EUR","customer_id":"customer123","customer":{"id":"customer123","name":"John Doe","email":"customer@gmail.com","phone":"9999999999","phone_country_code":"+1"},"description":"Its my first payment request","refunds":null,"disputes":null,"mandate_id":"man_JblRgVnFHqYNKvQIONrg","mandate_data":{"update_mandate_id":null,"customer_acceptance":{"acceptance_type":"offline","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"125.0.0.1","user_agent":"amet irure esse"}},"mandate_type":{"multi_use":{"amount":1000,"currency":"USD","start_date":"2023-04-21T00:00:00.000Z","end_date":"2023-05-21T00:00:00.000Z","metadata":{"frequency":"13"}}}},"setup_future_usage":"off_session","off_session":null,"capture_on":null,"capture_method":"automatic","payment_method":"card","payment_method_data":{"card":{"last4":"5454","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"545454","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":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"billing":{"address":{"city":"San Fransico","country":"US","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"order_details":[{"sku":null,"upc":null,"brand":null,"amount":6540,"category":null,"quantity":1,"tax_rate":null,"product_id":null,"description":null,"product_name":"Apple iphone 15","product_type":null,"sub_category":null,"total_amount":null,"commodity_code":null,"unit_of_measure":null,"product_img_link":null,"product_tax_code":null,"total_tax_amount":null,"requires_shipping":null,"unit_discount_amount":null}],"email":"customer@gmail.com","name":"John Doe","phone":"9999999999","return_url":"https://google.com/","authentication_type":"no_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_nJrHQrInwO77Uvsjrp1h/merchant_1756939264/pay_nJrHQrInwO77Uvsjrp1h_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":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"customer123","created_at":1756939725,"expires":1756943325,"secret":"epk_a1f0c3c09a644947b2fbad66699edd4d"},"manual_retry_allowed":null,"connector_transaction_id":"8ac7a4a19911957d019911c4b0db7792","frm_message":null,"metadata":{"udf1":"value1","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a4a19911957d019911c4b0db7792","payment_link":null,"profile_id":"pro_HoadX959YnH9wsndpUrq","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_PZ6v2D98umb2BxIN28tM","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-03T23:03:45.788Z","fingerprint":null,"browser_info":{"language":"nl-NL","time_zone":0,"ip_address":"128.0.0.1","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36","color_depth":24,"java_enabled":true,"screen_width":1536,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":723,"java_script_enabled":true},"payment_channel":null,"payment_method_id":"pm_Nm9GUukfMLZhXdHJSEy0","network_transaction_id":null,"payment_method_status":null,"updated":"2025-09-03T22:48:47.635Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":"test_ord","order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
```
</details>

<details>
<summary>4. Corresponding MIT </summary>

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_jBGr5aVyHqi26wIUT0l6VoyH0lGLSC5AcUoyoSv4MOaZDVulNKHuceiO87kr1UDn' \
--data '{
    "amount": 1000,
    "currency": "EUR",
    
    "customer_id": "customer123",
    "description": "Subsequent Mandate Test Payment (MIT from New CIT Demo)",
    "confirm": true,
    "off_session": true,
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_Nm9GUukfMLZhXdHJSEy0"
    }
}
'
```

Response
```
{"payment_id":"pay_tzYpHGeuRYHdPGK5M89d","merchant_id":"merchant_1756939264","status":"succeeded","amount":1000,"net_amount":1000,"shipping_cost":null,"amount_capturable":0,"amount_received":1000,"connector":"aci","client_secret":"pay_tzYpHGeuRYHdPGK5M89d_secret_AErv7wAoaKE3LP4CWUR1","created":"2025-09-03T22:49:39.145Z","currency":"EUR","customer_id":"customer123","customer":{"id":"customer123","name":"John Doe","email":"customer@gmail.com","phone":"9999999999","phone_country_code":"+1"},"description":"Subsequent Mandate Test Payment (MIT from New CIT Demo)","refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":null,"off_session":true,"capture_on":null,"capture_method":null,"payment_method":"card","payment_method_data":{"card":{"last4":"5454","card_type":null,"card_network":"Mastercard","card_issuer":null,"card_issuing_country":null,"card_isin":"545454","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":null,"billing":null,"order_details":null,"email":"customer@gmail.com","name":"John Doe","phone":"9999999999","return_url":null,"authentication_type":"no_three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"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":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"customer123","created_at":1756939779,"expires":1756943379,"secret":"epk_63a75cd297424ac8b2af9abbd2e7396b"},"manual_retry_allowed":false,"connector_transaction_id":"8ac7a49f99119578019911c57d647953","frm_message":null,"metadata":null,"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a49f99119578019911c57d647953","payment_link":null,"profile_id":"pro_HoadX959YnH9wsndpUrq","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_PZ6v2D98umb2BxIN28tM","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-03T23:04:39.145Z","fingerprint":null,"browser_info":null,"payment_channel":null,"payment_method_id":"pm_Nm9GUukfMLZhXdHJSEy0","network_transaction_id":null,"payment_method_status":"active","updated":"2025-09-03T22:49:40.001Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":"8ac7a4a299119a87019911c4af57529a","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
```

</details>

<details>
<summary>5. setup mandate </summary>

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_dVV9Je3mjaAV1ryc2n6xxIBOOiA5O7RoCqSRMpVpb9Gj9AV6dS5g3hEbMQp3K5rG' \
--data-raw '
{
    "amount": 0,
    "currency": "USD",
    "confirm": true,
    "customer_id": "tester123C",
    "email": "johndoe@gmail.com",
    "setup_future_usage": "off_session",
    "payment_type": "setup_mandate",
    "off_session": true,
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "5454545454545454",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "737",
            "card_network": "Mastercard"
        }
    },
    "mandate_data": {
        "customer_acceptance": {
            "acceptance_type": "offline",
            "accepted_at": "1963-05-03T04:07:52.723Z",
            "online": {
                "ip_address": "125.0.0.1",
                "user_agent": "amet irure esse"
            }
        },
        "mandate_type": {
            "multi_use": {
                "amount": 1000,
                "currency": "USD",
                "start_date": "2023-04-21T00:00:00Z",
                "end_date": "2023-05-21T00:00:00Z",
                "metadata": {
                    "frequency": "13"
                }
            }
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "John",
            "last_name": "Doe"
        },
        "email":"johndoe@gmail.com"
    }
}'
```

Response

```
{"payment_id":"pay_4fB1VOfBvH94w8ubEwIR","merchant_id":"merchant_1756917466","status":"succeeded","amount":0,"net_amount":0,"shipping_cost":null,"amount_capturable":0,"amount_received":null,"connector":"aci","client_secret":"pay_4fB1VOfBvH94w8ubEwIR_secret_CGiYMO43dEvBza21wCNY","created":"2025-09-03T21:43:07.598Z","currency":"USD","customer_id":"tester123C","customer":{"id":"tester123C","name":null,"email":"johndoe@gmail.com","phone":null,"phone_country_code":null},"description":null,"refunds":null,"disputes":null,"mandate_id":"man_D0PDZ3sITaf5hRKWOv9w","mandate_data":{"update_mandate_id":null,"customer_acceptance":{"acceptance_type":"offline","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"125.0.0.1","user_agent":"amet irure esse"}},"mandate_type":{"multi_use":{"amount":1000,"currency":"USD","start_date":"2023-04-21T00:00:00.000Z","end_date":"2023-05-21T00:00:00.000Z","metadata":{"frequency":"13"}}}},"setup_future_usage":"off_session","off_session":true,"capture_on":null,"capture_method":null,"payment_method":"card","payment_method_data":{"card":{"last4":"5454","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"545454","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":"John","last_name":"Doe","origin_zip":null},"phone":null,"email":"johndoe@gmail.com"},"billing":null,"order_details":null,"email":"johndoe@gmail.com","name":null,"phone":null,"return_url":null,"authentication_type":"no_three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"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":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"tester123C","created_at":1756935787,"expires":1756939387,"secret":"epk_297846ba6efb4bc1a00da345f2d56273"},"manual_retry_allowed":false,"connector_transaction_id":"8ac7a4a1990ec863019911889b7c095d","frm_message":null,"metadata":null,"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a4a1990ec863019911889b7c095d","payment_link":null,"profile_id":"pro_xtK5YkotshPxwjOySVEi","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_gnftzAdh1YZJvZj3U2nU","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-03T21:58:07.597Z","fingerprint":null,"browser_info":null,"payment_channel":null,"payment_method_id":"pm_lM41ZHCkvobdOiYZwhPr","network_transaction_id":null,"payment_method_status":"active","updated":"2025-09-03T21:43:10.100Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":"8ac7a4a1990ec863019911889b7c095d","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
```

</details>

<details>
<summary>6. MIT corresponding to setup mandate</summary>

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_T42KWe2OWnUIg0vvhyYcFu7R1lLBKCRrpLWyPb4hWHNFyyC34aN9NQjpUdLsd9t9' \
--data '{
    "amount": 1000,
    "currency": "USD",
    
    "customer_id": "tester123C",
    "description": "Subsequent Mandate Test Payment (MIT from New CIT Demo)",
    "confirm": true,
    "off_session": true,
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_lM41ZHCkvobdOiYZwhPr"
    }
}
'
```

Response

```
{"payment_id":"pay_TzRnmR2Nthv3WQbjCToR","merchant_id":"merchant_1756917466","status":"succeeded","amount":1000,"net_amount":1000,"shipping_cost":null,"amount_capturable":0,"amount_received":1000,"connector":"aci","client_secret":"pay_TzRnmR2Nthv3WQbjCToR_secret_dOfVMRSVNv25sfAoN6nO","created":"2025-09-03T21:44:32.257Z","currency":"USD","customer_id":"tester123C","customer":{"id":"tester123C","name":null,"email":"johndoe@gmail.com","phone":null,"phone_country_code":null},"description":"Subsequent Mandate Test Payment (MIT from New CIT Demo)","refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":null,"off_session":true,"capture_on":null,"capture_method":null,"payment_method":"card","payment_method_data":{"card":{"last4":"5454","card_type":null,"card_network":"Mastercard","card_issuer":null,"card_issuing_country":null,"card_isin":"545454","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":null,"billing":null,"order_details":null,"email":"johndoe@gmail.com","name":null,"phone":null,"return_url":null,"authentication_type":"no_three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"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":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"tester123C","created_at":1756935872,"expires":1756939472,"secret":"epk_a4ec4eaa5b374dc682e3fac2ad45b421"},"manual_retry_allowed":false,"connector_transaction_id":"8ac7a4a0990ed03f01991189e2d474be","frm_message":null,"metadata":null,"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a4a0990ed03f01991189e2d474be","payment_link":null,"profile_id":"pro_xtK5YkotshPxwjOySVEi","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_gnftzAdh1YZJvZj3U2nU","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-03T21:59:32.256Z","fingerprint":null,"browser_info":null,"payment_channel":null,"payment_method_id":"pm_lM41ZHCkvobdOiYZwhPr","network_transaction_id":null,"payment_method_status":"active","updated":"2025-09-03T21:44:33.883Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":"8ac7a4a1990ec863019911889b7c095d","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
```

</details>

<details>
<summary>7. Network Token  flow</summary>

I. Create ACI connector
```
curl --location 'http://localhost:8080/account/merchant_1756935953/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_HlwN4Co1MokPmoPglbMtwu0HJ25IBH6oRMWOUJuubIG71NvbeULTgz9TNjjGzlsz' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "aci",
    "connector_account_details": {
        "auth_type": "BodyKey",
        "api_key": API_KEY,
        "key1": ENTITY_ID
    },
    "test_mode": true,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "accepted_countries":null,
                    "accepted_currencies": null
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "accepted_countries": null,
                    "accepted_currencies": null
                }
            ]
        },
    ],
    "connector_webhook_details": {
        "merchant_secret": "MyWebhookSecret"
    },
    "business_label": "default"
}'
```

II. Enable UAS for profile
```
curl --location 'http://localhost:8080/configs/merchants_eligible_for_authentication_service' \
--header 'Content-Type: application/json' \
--header 'api-key: test_admin' \
--data '{
    "key": "merchants_eligible_for_authentication_service",
    "value": VALUE_HERE
}'
```

III. create ctp_mastercard
```
curl --location 'http://localhost:8080/account/merchant_1756935953/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_HlwN4Co1MokPmoPglbMtwu0HJ25IBH6oRMWOUJuubIG71NvbeULTgz9TNjjGzlsz' \
--data '{
    "connector_type": "authentication_processor",
    "connector_name": "ctp_mastercard",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": API_KEY
    },
    "test_mode": true,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "business_country": "US",
    "business_label": "default",
    "metadata": {
        "dpa_id": "DPA ID",
        "dpa_name": "TestMerchant",
        "locale": "en_AU",
        "card_brands": [
            "mastercard",
            "visa"
        ],
        "acquirer_bin": "ACQUIRER BIN",
        "acquirer_merchant_id": "ACQUIRER MERCHANT ID",
        "merchant_category_code": "0001",
        "merchant_country_code": "US"
    }
}'
```

IV. CTP profile update
```
curl --location 'http://localhost:8080/account/merchant_1756935953/business_profile/pro_kkwmU6LfcSIte3TlcHMh' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_HlwN4Co1MokPmoPglbMtwu0HJ25IBH6oRMWOUJuubIG71NvbeULTgz9TNjjGzlsz' \
--data '{
    "is_click_to_pay_enabled": true,
    "authentication_product_ids": {"click_to_pay": "mca_foGzOn6nPM6TFvwh6fhj"}
}'
```

V. create payment
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_HlwN4Co1MokPmoPglbMtwu0HJ25IBH6oRMWOUJuubIG71NvbeULTgz9TNjjGzlsz' \
--data-raw '
{
    "amount": 1130,
    "currency": "EUR",
    "confirm": false,
    "return_url": "https://hyperswitch.io",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    }
}'
```
Response
```
{"payment_id":"pay_CHQQv8xweeAmih5MdFXd","merchant_id":"merchant_1756935953","status":"requires_payment_method","amount":1130,"net_amount":1130,"shipping_cost":null,"amount_capturable":0,"amount_received":null,"connector":null,"client_secret":"pay_CHQQv8xweeAmih5MdFXd_secret_zoplDPH6fk9Qm6Recdqn","created":"2025-09-03T21:48:11.651Z","currency":"EUR","customer_id":null,"customer":null,"description":null,"refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":null,"off_session":null,"capture_on":null,"capture_method":null,"payment_method":null,"payment_method_data":null,"payment_token":null,"shipping":null,"billing":{"address":{"city":"San Fransico","country":"US","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"order_details":null,"email":null,"name":null,"phone":null,"return_url":"https://hyperswitch.io/","authentication_type":null,"statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":null,"cancellation_reason":null,"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":null,"connector_transaction_id":null,"frm_message":null,"metadata":null,"connector_metadata":null,"feature_metadata":null,"reference_id":null,"payment_link":null,"profile_id":"pro_kkwmU6LfcSIte3TlcHMh","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":null,"incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-03T22:03:11.651Z","fingerprint":null,"browser_info":null,"payment_channel":null,"payment_method_id":null,"network_transaction_id":null,"payment_method_status":null,"updated":"2025-09-03T21:48:11.673Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":null,"force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
```

VI. confirm payment
```
curl --location 'http://localhost:8080/payments/pay_CHQQv8xweeAmih5MdFXd/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: pk_dev_4c7f1ffc1dfc4e889e867ac60505d178' \
--data '{
    "payment_method": "card",
    "payment_method_type": "debit",
    "client_secret": "pay_CHQQv8xweeAmih5MdFXd_secret_zoplDPH6fk9Qm6Recdqn",
    "all_keys_required":true,
    "ctp_service_details": {
        "merchant_transaction_id": VALUE_HERE,
        "correlation_id": VALUE_HERE,
        "x_src_flow_id": VALUE_HERE
    },
    "browser_info": {
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "color_depth": 24,
        "java_enabled": true,
        "java_script_enabled": true,
        "language": "en-GB",
        "screen_height": 1440,
        "screen_width": 2560,
        "time_zone": -330,
        "user_agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36"
    }
}'
```

Response
```
{"payment_id":"pay_CHQQv8xweeAmih5MdFXd","merchant_id":"merchant_1756935953","status":"requires_customer_action","amount":1130,"net_amount":1130,"shipping_cost":null,"amount_capturable":1130,"amount_received":null,"connector":"aci","client_secret":"pay_CHQQv8xweeAmih5MdFXd_secret_zoplDPH6fk9Qm6Recdqn","created":"2025-09-03T21:48:11.651Z","currency":"EUR","customer_id":null,"customer":null,"description":null,"refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":null,"off_session":null,"capture_on":null,"capture_method":null,"payment_method":"card","payment_method_data":null,"payment_token":null,"shipping":null,"billing":{"address":{"city":"San Fransico","country":"US","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"order_details":null,"email":null,"name":null,"phone":null,"return_url":"https://hyperswitch.io/","authentication_type":"no_three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":{"type":"redirect_to_url","redirect_to_url":"http://localhost:8080/payments/redirect/pay_CHQQv8xweeAmih5MdFXd/merchant_1756935953/pay_CHQQv8xweeAmih5MdFXd_1"},"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":null,"manual_retry_allowed":null,"connector_transaction_id":"8ac7a4a1990ec8630199118d5b0d11ed","frm_message":null,"metadata":null,"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a4a1990ec8630199118d5b0d11ed","payment_link":null,"profile_id":"pro_kkwmU6LfcSIte3TlcHMh","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_bQFt1dkbAjSp6Gv6pbJR","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":{"authentication_flow":null,"electronic_commerce_indicator":"06","status":"success","ds_transaction_id":null,"version":null,"error_code":null,"error_message":null},"external_3ds_authentication_attempted":false,"expires_on":"2025-09-03T22:03:11.651Z","fingerprint":null,"browser_info":{"os_type":null,"language":"en-GB","time_zone":-330,"ip_address":"::1","os_version":null,"user_agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36","color_depth":24,"device_model":null,"java_enabled":true,"screen_width":2560,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1440,"accept_language":"en","java_script_enabled":true},"payment_channel":null,"payment_method_id":null,"network_transaction_id":null,"payment_method_status":null,"updated":"2025-09-03T21:48:20.951Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"click_to_pay","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":"{\"id\":\"8ac7a4a1990ec8630199118d5b0d11ed\",\"paymentType\":\"DB\",\"paymentBrand\":\"VISA\",\"amount\":\"11.30\",\"currency\":\"EUR\",\"descriptor\":\"3484.7818.5182 NetworkTokenChannel \",\"result\":{\"code\":\"000.200.000\",\"description\":\"transaction pending\"},\"tokenAccount\":{\"number\":\"2222030199301958\",\"type\":\"NETWORK\",\"expiryMonth\":\"10\",\"expiryYear\":\"2027\"},\"redirect\":{\"url\":\"https://eu-test.oppwa.com/connectors/demo/cybersourcerest/simulator/payment.ftl?ndcid=8a8294175d602369015d73bf009f1808_efdb58167aad468a928b44dde03c2115\",\"parameters\":[{\"name\":\"TransactionId\",\"value\":\"0000000070575071\"},{\"name\":\"uuid\",\"value\":\"8ac7a4a1990ec8630199118d5b0d11ed\"}]},\"buildNumber\":\"e05bc10dcc6acc6bd4abda346f4af077dcd905d7@2025-09-02 06:02:21 +0000\",\"timestamp\":\"2025-09-03 21:48:20+0000\",\"ndc\":\"8a8294175d602369015d73bf009f1808_efdb58167aad468a928b44dde03c2115\",\"source\":\"OPP\",\"paymentMethod\":\"NT\",\"shortId\":\"3484.7818.5182\"}","enable_partial_authorization":null}
```
</details>


<details>
<summary>7. Manual capture </summary>

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_jBGr5aVyHqi26wIUT0l6VoyH0lGLSC5AcUoyoSv4MOaZDVulNKHuceiO87kr1UDn' \
--data-raw '{
    "amount": 6540,
    "currency": "EUR",
    "amount_to_capture": 6540,
    "confirm": true,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "three_ds",
    "setup_future_usage": "on_session", 
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "customer@gmail.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "customer_id": "customer123",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "5386024192625914",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "737",
            "card_network": "Mastercard"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 6540,
            "account_name": "transaction_processing"
        }
    ],
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "128.0.0.1"
    },
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "125.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "payment_link": false,
    "payment_link_config": {
        "theme": "",
        "logo": "",
        "seller_name": "",
        "sdk_layout": "",
        "display_sdk_only": false,
        "enabled_saved_payment_method": false
    },
    "payment_type": "normal"
}
'
```

Response:
```
{"payment_id":"pay_dTlUOqtFsHTk2pYjcNDt","merchant_id":"merchant_1756939264","status":"requires_customer_action","amount":6540,"net_amount":6540,"shipping_cost":null,"amount_capturable":6540,"amount_received":null,"connector":"aci","client_secret":"pay_dTlUOqtFsHTk2pYjcNDt_secret_quBPvBLmgEoMeGq30q8W","created":"2025-09-04T12:25:30.223Z","currency":"EUR","customer_id":"customer123","customer":{"id":"customer123","name":"John Doe","email":"customer@gmail.com","phone":"9999999999","phone_country_code":"+1"},"description":"Its my first payment request","refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":"on_session","off_session":null,"capture_on":null,"capture_method":"manual","payment_method":"card","payment_method_data":{"card":{"last4":"5914","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"538602","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":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"billing":{"address":{"city":"San Fransico","country":"US","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"order_details":[{"sku":null,"upc":null,"brand":null,"amount":6540,"category":null,"quantity":1,"tax_rate":null,"product_id":null,"description":null,"product_name":"Apple iphone 15","product_type":null,"sub_category":null,"total_amount":null,"commodity_code":null,"unit_of_measure":null,"product_img_link":null,"product_tax_code":null,"total_tax_amount":null,"requires_shipping":null,"unit_discount_amount":null}],"email":"customer@gmail.com","name":"John Doe","phone":"9999999999","return_url":"https://google.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_dTlUOqtFsHTk2pYjcNDt/merchant_1756939264/pay_dTlUOqtFsHTk2pYjcNDt_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":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"customer123","created_at":1756988730,"expires":1756992330,"secret":"epk_fbfca29dcba44555b3c4abb3e7ce9b67"},"manual_retry_allowed":null,"connector_transaction_id":"8ac7a49f9912a69e019914b074cd08f8","frm_message":null,"metadata":{"udf1":"value1","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a49f9912a69e019914b074cd08f8","payment_link":null,"profile_id":"pro_HoadX959YnH9wsndpUrq","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_PZ6v2D98umb2BxIN28tM","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-04T12:40:30.223Z","fingerprint":null,"browser_info":{"language":"nl-NL","time_zone":0,"ip_address":"128.0.0.1","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36","color_depth":24,"java_enabled":true,"screen_width":1536,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":723,"java_script_enabled":true},"payment_channel":null,"payment_method_id":null,"network_transaction_id":null,"payment_method_status":null,"updated":"2025-09-04T12:25:33.311Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
````

capture after redirection:
```
curl --location 'http://localhost:8080/payments/pay_dTlUOqtFsHTk2pYjcNDt/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_jBGr5aVyHqi26wIUT0l6VoyH0lGLSC5AcUoyoSv4MOaZDVulNKHuceiO87kr1UDn' \
--data '{
  "amount_to_capture": 6540,
  "statement_descriptor_name": "Joseph",
  "statement_descriptor_prefix" :"joseph",
  "statement_descriptor_suffix": "JS"
}'
```

Response 
```
{"payment_id":"pay_dTlUOqtFsHTk2pYjcNDt","merchant_id":"merchant_1756939264","status":"succeeded","amount":6540,"net_amount":6540,"shipping_cost":null,"amount_capturable":0,"amount_received":6540,"connector":"aci","client_secret":"pay_dTlUOqtFsHTk2pYjcNDt_secret_quBPvBLmgEoMeGq30q8W","created":"2025-09-04T12:25:30.223Z","currency":"EUR","customer_id":"customer123","customer":{"id":"customer123","name":"John Doe","email":"customer@gmail.com","phone":"9999999999","phone_country_code":"+1"},"description":"Its my first payment request","refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":"on_session","off_session":null,"capture_on":null,"capture_method":"manual","payment_method":"card","payment_method_data":{"card":{"last4":"5914","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"538602","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":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"billing":{"address":{"city":"San Fransico","country":"US","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe","origin_zip":null},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"order_details":[{"sku":null,"upc":null,"brand":null,"amount":6540,"category":null,"quantity":1,"tax_rate":null,"product_id":null,"description":null,"product_name":"Apple iphone 15","product_type":null,"sub_category":null,"total_amount":null,"commodity_code":null,"unit_of_measure":null,"product_img_link":null,"product_tax_code":null,"total_tax_amount":null,"requires_shipping":null,"unit_discount_amount":null}],"email":"customer@gmail.com","name":"John Doe","phone":"9999999999","return_url":"https://google.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":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":"8ac7a4a29912ae61019914b0fd8866f5","frm_message":null,"metadata":{"udf1":"value1","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":null,"feature_metadata":{"redirect_response":null,"search_tags":null,"apple_pay_recurring_details":null,"gateway_system":"direct"},"reference_id":"8ac7a49f9912a69e019914b074cd08f8","payment_link":null,"profile_id":"pro_HoadX959YnH9wsndpUrq","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_PZ6v2D98umb2BxIN28tM","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-09-04T12:40:30.223Z","fingerprint":null,"browser_info":{"language":"nl-NL","time_zone":0,"ip_address":"128.0.0.1","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36","color_depth":24,"java_enabled":true,"screen_width":1536,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":723,"java_script_enabled":true},"payment_channel":null,"payment_method_id":"pm_dgRVnCJRHsU6c2LmY34G","network_transaction_id":null,"payment_method_status":null,"updated":"2025-09-04T12:26:08.107Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null,"is_iframe_redirection_enabled":null,"whole_connector_response":null,"enable_partial_authorization":null}
```

</details>





## 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`
- [x] I reviewed the submitted code
- [x] I added unit tests for my changes where possible
