Bug: [FEAT] [CONNECTOR: NORDEA] Implement SEPA Bank Debit



## Relevant Docs
 
- [Access Authorization API](https://developer.nordeaopenbanking.com/documentation?api=Access%20Authorization%20API) (To get Access Token)
- [Payments API SEPA Credit Transfer](https://developer.nordeaopenbanking.com/documentation?api=Payments%20API%20SEPA%20Credit%20Transfer)
- [Payment Common API](https://developer.nordeaopenbanking.com/documentation?api=Payments%20Common%20API) (I assume this doc gets updated first often)
- [Nordea developer FAQ](https://support.nordeaopenbanking.com/hc/en-us)

### Digest and Signature creation Docs

- [Digest creation and calculation FAQ](https://support.nordeaopenbanking.com/hc/en-us/articles/7951756726044-Digest-creation-calculation-FAQ)
- [eIDAS certificate](https://developer.nordeaopenbanking.com/documentation?api=Access%20Authorization%20API#authentication_with_eidas_certificate)
- [Generation of Signature](https://developer.nordeaopenbanking.com/documentation?api=Access%20Authorization%20API#testing_eidas_signature) (postman JavaScript code)

## Testing

- Nordea Playground (Try API Console): https://developer.nordeaopenbanking.com/console/
- [Personal API Postman collection v5](https://raw.githubusercontent.com/NordeaOB/swaggers/master/Nordea%20Open%20Banking%20v5%20Personal%20API.postman_collection.json)
- [Personal API Postman collection v4](https://raw.githubusercontent.com/NordeaOB/swaggers/master/Nordea%20Open%20Banking%20v4%20Personal%20API%20Example%20FI%2CDK%2CNO%20and%20SE.postman_collection.json)
diff --git a/Cargo.lock b/Cargo.lock
index c38b3966051..474d6d6f1d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4048,6 +4048,7 @@ dependencies = [
  "mime",
  "num-traits",
  "openssl",
+ "pem",
  "qrcode",
  "quick-xml",
  "rand 0.8.5",
@@ -5692,9 +5693,9 @@ dependencies = [
 
 [[package]]
 name = "pem"
-version = "3.0.4"
+version = "3.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
+checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
 dependencies = [
  "base64 0.22.1",
  "serde",
diff --git a/config/config.example.toml b/config/config.example.toml
index 3fdb96eb437..2685331d0b3 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -812,6 +812,9 @@ paypal = { country = "AD,AE,AL,AM,AR,AT,AU,AZ,BA,BB,BD,BE,BG,BH,BI,BM,BN,BO,BR,B
 [pm_filters.mifinity]
 mifinity = { country = "BR,CN,SG,MY,DE,CH,DK,GB,ES,AD,GI,FI,FR,GR,HR,IT,JP,MX,AR,CO,CL,PE,VE,UY,PY,BO,EC,GT,HN,SV,NI,CR,PA,DO,CU,PR,NL,NO,PL,PT,SE,RU,TR,TW,HK,MO,AX,AL,DZ,AS,AO,AI,AG,AM,AW,AU,AT,AZ,BS,BH,BD,BB,BE,BZ,BJ,BM,BT,BQ,BA,BW,IO,BN,BG,BF,BI,KH,CM,CA,CV,KY,CF,TD,CX,CC,KM,CG,CK,CI,CW,CY,CZ,DJ,DM,EG,GQ,ER,EE,ET,FK,FO,FJ,GF,PF,TF,GA,GM,GE,GH,GL,GD,GP,GU,GG,GN,GW,GY,HT,HM,VA,IS,IN,ID,IE,IM,IL,JE,JO,KZ,KE,KI,KW,KG,LA,LV,LB,LS,LI,LT,LU,MK,MG,MW,MV,ML,MT,MH,MQ,MR,MU,YT,FM,MD,MC,MN,ME,MS,MA,MZ,NA,NR,NP,NC,NZ,NE,NG,NU,NF,MP,OM,PK,PW,PS,PG,PH,PN,QA,RE,RO,RW,BL,SH,KN,LC,MF,PM,VC,WS,SM,ST,SA,SN,RS,SC,SL,SX,SK,SI,SB,SO,ZA,GS,KR,LK,SR,SJ,SZ,TH,TL,TG,TK,TO,TT,TN,TM,TC,TV,UG,UA,AE,UZ,VU,VN,VG,VI,WF,EH,ZM", currency = "AUD,CAD,CHF,CNY,CZK,DKK,EUR,GBP,INR,JPY,NOK,NZD,PLN,RUB,SEK,ZAR,USD,EGP,UYU,UZS" }
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
+
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
 
@@ -1188,4 +1191,4 @@ hyperswitch_ai_host = "http://0.0.0.0:8000"    # Hyperswitch ai workflow host
 [proxy_status_mapping]
 proxy_connector_http_status_code = false    # If enabled, the http status code of the connector will be proxied in the response
 [list_dispute_supported_connectors]
-connector_list = "worldpayvantiv"
\ No newline at end of file
+connector_list = "worldpayvantiv"
diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml
index 4607d92000a..1ae71b20ddf 100644
--- a/config/deployments/integration_test.toml
+++ b/config/deployments/integration_test.toml
@@ -637,6 +637,9 @@ red_pagos = { country = "UY", currency = "UYU" }
 [pm_filters.zsl]
 local_bank_transfer = { country = "CN", currency = "CNY" }
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
+
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
 apple_pay = { country = "MY", currency = "MYR" }
@@ -832,4 +835,4 @@ retry_algorithm_type = "cascading"
 click_to_pay = {connector_list = "adyen, cybersource, trustpay"}
 
 [list_dispute_supported_connectors]
-connector_list = "worldpayvantiv"
\ No newline at end of file
+connector_list = "worldpayvantiv"
diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index 7a1521001c0..e6d29112a0e 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -103,7 +103,7 @@ nexixpay.base_url = "https://xpay.nexigroup.com/api/phoenix-0.0/psp/api/v1"
 nmi.base_url = "https://secure.nmi.com/"
 nomupay.base_url = "https://payout-api.nomupay.com"
 noon.base_url = "https://api.noonpayments.com/"
-nordea.base_url = "https://openapi.portal.nordea.com"
+nordea.base_url = "https://open.nordeaopenbanking.com"
 noon.key_mode = "Live"
 novalnet.base_url = "https://payport.novalnet.de/v2"
 nuvei.base_url = "https://secure.safecharge.com/"
@@ -654,6 +654,8 @@ red_pagos = { country = "UY", currency = "UYU" }
 [pm_filters.zsl]
 local_bank_transfer = { country = "CN", currency = "CNY" }
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
 
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
@@ -843,4 +845,4 @@ click_to_pay = {connector_list = "adyen, cybersource, trustpay"}
 
 [revenue_recovery]
 monitoring_threshold_in_seconds = 60
-retry_algorithm_type = "cascading"
\ No newline at end of file
+retry_algorithm_type = "cascading"
diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml
index 88e7d4115e6..ccd5e003695 100644
--- a/config/deployments/sandbox.toml
+++ b/config/deployments/sandbox.toml
@@ -661,6 +661,9 @@ red_pagos = { country = "UY", currency = "UYU" }
 [pm_filters.zsl]
 local_bank_transfer = { country = "CN", currency = "CNY" }
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
+
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
 apple_pay = { country = "MY", currency = "MYR" }
@@ -812,7 +815,7 @@ globalpay = { long_lived_token = false, payment_method = "card", flow = "mandate
 outgoing_enabled = true
 redis_lock_expiry_seconds = 180
 
-[l2_l3_data_config]  
+[l2_l3_data_config]
 enabled = "true"
 
 [webhook_source_verification_call]
@@ -851,4 +854,4 @@ monitoring_threshold_in_seconds = 60
 retry_algorithm_type = "cascading"
 
 [list_dispute_supported_connectors]
-connector_list = "worldpayvantiv"
\ No newline at end of file
+connector_list = "worldpayvantiv"
diff --git a/config/development.toml b/config/development.toml
index 9020c89ef86..76031da5951 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -844,6 +844,9 @@ region = ""
 credit = { country = "US, CA", currency = "CAD,USD"}
 debit = { country = "US, CA", currency = "CAD,USD"}
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
+
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
 apple_pay = { country = "MY", currency = "MYR" }
@@ -1258,7 +1261,7 @@ dynamic_routing_enabled = false
 static_routing_enabled = false
 url = "http://localhost:8080"
 
-[l2_l3_data_config]  
+[l2_l3_data_config]
 enabled = "true"
 
 [grpc_client.unified_connector_service]
@@ -1293,4 +1296,4 @@ hyperswitch_ai_host = "http://0.0.0.0:8000"
 [proxy_status_mapping]
 proxy_connector_http_status_code = false    # If enabled, the http status code of the connector will be proxied in the response
 [list_dispute_supported_connectors]
-connector_list = "worldpayvantiv"
\ No newline at end of file
+connector_list = "worldpayvantiv"
diff --git a/config/docker_compose.toml b/config/docker_compose.toml
index c518574435b..d06eb47d03f 100644
--- a/config/docker_compose.toml
+++ b/config/docker_compose.toml
@@ -770,6 +770,9 @@ credit = { country = "AF,DZ,AW,AU,AZ,BS,BH,BD,BB,BZ,BM,BT,BO,BA,BW,BR,BN,BG,BI,K
 debit = { country = "AF,DZ,AW,AU,AZ,BS,BH,BD,BB,BZ,BM,BT,BO,BA,BW,BR,BN,BG,BI,KH,CA,CV,KY,CL,CO,KM,CD,CR,CZ,DK,DJ,ST,DO,EC,EG,SV,ER,ET,FK,FJ,GM,GE,GH,GI,GT,GN,GY,HT,HN,HK,HU,IS,IN,ID,IR,IQ,IE,IL,IT,JM,JP,JO,KZ,KE,KW,LA,LB,LS,LR,LY,LT,MO,MK,MG,MW,MY,MV,MR,MU,MX,MD,MN,MA,MZ,MM,NA,NZ,NI,NG,KP,NO,AR,PK,PG,PY,PE,UY,PH,PL,GB,QA,OM,RO,RU,RW,WS,SG,ST,ZA,KR,LK,SH,SD,SR,SZ,SE,CH,SY,TW,TJ,TZ,TH,TT,TN,TR,UG,UA,US,UZ,VU,VE,VN,ZM,ZW", currency = "AFN,DZD,ANG,AWG,AUD,AZN,BSD,BHD,BDT,BBD,BZD,BMD,BTN,BOB,BAM,BWP,BRL,BND,BGN,BIF,KHR,CAD,CVE,KYD,XOF,XAF,XPF,CLP,COP,KMF,CDF,CRC,EUR,CZK,DKK,DJF,DOP,XCD,EGP,SVC,ERN,ETB,EUR,FKP,FJD,GMD,GEL,GHS,GIP,GTQ,GNF,GYD,HTG,HNL,HKD,HUF,ISK,INR,IDR,IRR,IQD,ILS,JMD,JPY,JOD,KZT,KES,KWD,LAK,LBP,LSL,LRD,LYD,MOP,MKD,MGA,MWK,MYR,MVR,MRU,MUR,MXN,MDL,MNT,MAD,MZN,MMK,NAD,NPR,NZD,NIO,NGN,KPW,NOK,ARS,PKR,PAB,PGK,PYG,PEN,UYU,PHP,PLN,GBP,QAR,OMR,RON,RUB,RWF,WST,SAR,RSD,SCR,SLL,SGD,STN,SBD,SOS,ZAR,KRW,LKR,SHP,SDG,SRD,SZL,SEK,CHF,SYP,TWD,TJS,TZS,THB,TOP,TTD,TND,TRY,TMT,AED,UGX,UAH,USD,UZS,VUV,VND,YER,CNY,ZMW,ZWL" }
 credit = { country = "AF,DZ,AW,AU,AZ,BS,BH,BD,BB,BZ,BM,BT,BO,BA,BW,BR,BN,BG,BI,KH,CA,CV,KY,CL,CO,KM,CD,CR,CZ,DK,DJ,ST,DO,EC,EG,SV,ER,ET,FK,FJ,GM,GE,GH,GI,GT,GN,GY,HT,HN,HK,HU,IS,IN,ID,IR,IQ,IE,IL,IT,JM,JP,JO,KZ,KE,KW,LA,LB,LS,LR,LY,LT,MO,MK,MG,MW,MY,MV,MR,MU,MX,MD,MN,MA,MZ,MM,NA,NZ,NI,NG,KP,NO,AR,PK,PG,PY,PE,UY,PH,PL,GB,QA,OM,RO,RU,RW,WS,SG,ST,ZA,KR,LK,SH,SD,SR,SZ,SE,CH,SY,TW,TJ,TZ,TH,TT,TN,TR,UG,UA,US,UZ,VU,VE,VN,ZM,ZW", currency = "AFN,DZD,ANG,AWG,AUD,AZN,BSD,BHD,BDT,BBD,BZD,BMD,BTN,BOB,BAM,BWP,BRL,BND,BGN,BIF,KHR,CAD,CVE,KYD,XOF,XAF,XPF,CLP,COP,KMF,CDF,CRC,EUR,CZK,DKK,DJF,DOP,XCD,EGP,SVC,ERN,ETB,EUR,FKP,FJD,GMD,GEL,GHS,GIP,GTQ,GNF,GYD,HTG,HNL,HKD,HUF,ISK,INR,IDR,IRR,IQD,ILS,JMD,JPY,JOD,KZT,KES,KWD,LAK,LBP,LSL,LRD,LYD,MOP,MKD,MGA,MWK,MYR,MVR,MRU,MUR,MXN,MDL,MNT,MAD,MZN,MMK,NAD,NPR,NZD,NIO,NGN,KPW,NOK,ARS,PKR,PAB,PGK,PYG,PEN,UYU,PHP,PLN,GBP,QAR,OMR,RON,RUB,RWF,WST,SAR,RSD,SCR,SLL,SGD,STN,SBD,SOS,ZAR,KRW,LKR,SHP,SDG,SRD,SZL,SEK,CHF,SYP,TWD,TJS,TZS,THB,TOP,TTD,TND,TRY,TMT,AED,UGX,UAH,USD,UZS,VUV,VND,YER,CNY,ZMW,ZWL" }
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
+
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
 apple_pay = { country = "MY", currency = "MYR" }
@@ -1172,4 +1175,4 @@ version = "HOSTNAME"        # value of HOSTNAME from deployment which tells its
 [proxy_status_mapping]
 proxy_connector_http_status_code = false    # If enabled, the http status code of the connector will be proxied in the response
 [list_dispute_supported_connectors]
-connector_list = "worldpayvantiv"
\ No newline at end of file
+connector_list = "worldpayvantiv"
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index 50ba4dce612..3bdc756dc89 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -1210,7 +1210,9 @@ pub enum ConnectorAuthType {
         auth_key_map: HashMap<common_enums::Currency, pii::SecretSerdeValue>,
     },
     CertificateAuth {
+        // certificate should be base64 encoded
         certificate: Secret<String>,
+        // private_key should be base64 encoded
         private_key: Secret<String>,
     },
     #[default]
diff --git a/crates/common_enums/src/connector_enums.rs b/crates/common_enums/src/connector_enums.rs
index 37d9ee4b318..9e00ff366a6 100644
--- a/crates/common_enums/src/connector_enums.rs
+++ b/crates/common_enums/src/connector_enums.rs
@@ -119,7 +119,7 @@ pub enum RoutableConnectors {
     Nmi,
     Nomupay,
     Noon,
-    // Nordea,
+    Nordea,
     Novalnet,
     Nuvei,
     // Opayo, added as template code for future usage
@@ -292,7 +292,7 @@ pub enum Connector {
     Nmi,
     Nomupay,
     Noon,
-    // Nordea,
+    Nordea,
     Novalnet,
     Nuvei,
     // Opayo, added as template code for future usage
@@ -385,6 +385,7 @@ impl Connector {
                 | (Self::Globalpay, _)
                 | (Self::Jpmorgan, _)
                 | (Self::Moneris, _)
+                | (Self::Nordea, _)
                 | (Self::Paypal, _)
                 | (Self::Payu, _)
                 | (
@@ -478,7 +479,7 @@ impl Connector {
             | Self::Nexinets
             | Self::Nexixpay
             | Self::Nomupay
-            // | Self::Nordea
+            | Self::Nordea
             | Self::Novalnet
             | Self::Nuvei
             | Self::Opennode
@@ -649,7 +650,7 @@ impl From<RoutableConnectors> for Connector {
             RoutableConnectors::Nmi => Self::Nmi,
             RoutableConnectors::Nomupay => Self::Nomupay,
             RoutableConnectors::Noon => Self::Noon,
-            // RoutableConnectors::Nordea => Self::Nordea,
+            RoutableConnectors::Nordea => Self::Nordea,
             RoutableConnectors::Novalnet => Self::Novalnet,
             RoutableConnectors::Nuvei => Self::Nuvei,
             RoutableConnectors::Opennode => Self::Opennode,
@@ -779,7 +780,7 @@ impl TryFrom<Connector> for RoutableConnectors {
             Connector::Nmi => Ok(Self::Nmi),
             Connector::Nomupay => Ok(Self::Nomupay),
             Connector::Noon => Ok(Self::Noon),
-            // Connector::Nordea => Ok(Self::Nordea),
+            Connector::Nordea => Ok(Self::Nordea),
             Connector::Novalnet => Ok(Self::Novalnet),
             Connector::Nuvei => Ok(Self::Nuvei),
             Connector::Opennode => Ok(Self::Opennode),
diff --git a/crates/common_utils/src/lib.rs b/crates/common_utils/src/lib.rs
index 3f491d3e9a6..d6a9475b179 100644
--- a/crates/common_utils/src/lib.rs
+++ b/crates/common_utils/src/lib.rs
@@ -110,6 +110,17 @@ pub mod date_time {
         now().assume_utc().format(&Iso8601::<ISO_CONFIG>)
     }
 
+    /// Return the current date and time in UTC formatted as "ddd, DD MMM YYYY HH:mm:ss GMT".
+    pub fn now_rfc7231_http_date() -> Result<String, time::error::Format> {
+        let now_utc = OffsetDateTime::now_utc();
+        // Desired format: ddd, DD MMM YYYY HH:mm:ss GMT
+        // Example: Fri, 23 May 2025 06:19:35 GMT
+        let format = time::macros::format_description!(
+            "[weekday repr:short], [day padding:zero] [month repr:short] [year repr:full] [hour padding:zero repr:24]:[minute padding:zero]:[second padding:zero] GMT"
+        );
+        now_utc.format(&format)
+    }
+
     impl From<DateFormat> for &[BorrowedFormatItem<'_>] {
         fn from(format: DateFormat) -> Self {
             match format {
diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs
index 7289e6d4a98..9a5c7edb2ca 100644
--- a/crates/connector_configs/src/connector.rs
+++ b/crates/connector_configs/src/connector.rs
@@ -460,6 +460,7 @@ impl ConnectorConfig {
             Connector::Nexixpay => Ok(connector_data.nexixpay),
             Connector::Prophetpay => Ok(connector_data.prophetpay),
             Connector::Nmi => Ok(connector_data.nmi),
+            Connector::Nordea => Ok(connector_data.nordea),
             Connector::Nomupay => Err("Use get_payout_connector_config".to_string()),
             Connector::Novalnet => Ok(connector_data.novalnet),
             Connector::Noon => Ok(connector_data.noon),
diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml
index 5f38b42d4a1..4646e73f71c 100644
--- a/crates/connector_configs/toml/development.toml
+++ b/crates/connector_configs/toml/development.toml
@@ -6355,7 +6355,31 @@ placeholder = "Enter Acquirer Merchant ID"
 required = false
 type = "Text"
 
-
+[nordea]
+[[nordea.bank_debit]]
+  payment_method_type = "sepa"
+[nordea.connector_auth.SignatureKey]
+  api_key="Client Secret"
+  key1="Client ID"
+  api_secret="eIDAS Private Key"
+[nordea.metadata.creditor_account_type]
+  name="creditor_account_type"
+  label="Creditor Account Type"
+  placeholder="Enter Beneficiary Account Type e.g. IBAN"
+  required=true
+  type="Text"
+[nordea.metadata.creditor_account_value]
+  name="creditor_account_value"
+  label="Creditor Account Type"
+  placeholder="Enter Beneficiary Account Number"
+  required=true
+  type="Text"
+[nordea.metadata.creditor_beneficiary_name]
+  name="creditor_beneficiary_name"
+  label="Creditor Account Beneficiary Name"
+  placeholder="Enter Beneficiary Name"
+  required=true
+  type="Text"
 
 [worldpayxml]
 [[worldpayxml.credit]]
diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml
index 4bb725ed128..6bb5497957a 100644
--- a/crates/connector_configs/toml/production.toml
+++ b/crates/connector_configs/toml/production.toml
@@ -4923,6 +4923,33 @@ placeholder = "Enter Acquirer Merchant ID"
 required = false
 type = "Text"
 
+[nordea]
+[[nordea.bank_debit]]
+  payment_method_type = "sepa"
+[nordea.connector_auth.SignatureKey]
+  api_key="Client Secret"
+  key1="Client ID"
+  api_secret="eIDAS Private Key"
+[nordea.metadata.creditor_account_type]
+  name="creditor_account_type"
+  label="Creditor Account Type"
+  placeholder="Enter Beneficiary Account Type e.g. IBAN"
+  required=true
+  type="Text"
+[nordea.metadata.creditor_account_value]
+  name="creditor_account_value"
+  label="Creditor Account Type"
+  placeholder="Enter Beneficiary Account Number"
+  required=true
+  type="Text"
+[nordea.metadata.creditor_beneficiary_name]
+  name="creditor_beneficiary_name"
+  label="Creditor Account Beneficiary Name"
+  placeholder="Enter Beneficiary Name"
+  required=true
+  type="Text"
+
+
 [worldpayxml]
 [[worldpayxml.credit]]
 payment_method_type = "Mastercard"
diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml
index 3b17bfca44e..37b63f84066 100644
--- a/crates/connector_configs/toml/sandbox.toml
+++ b/crates/connector_configs/toml/sandbox.toml
@@ -6335,6 +6335,32 @@ placeholder = "Enter Acquirer Merchant ID"
 required = false
 type = "Text"
 
+[nordea]
+[[nordea.bank_debit]]
+  payment_method_type = "sepa"
+[nordea.connector_auth.SignatureKey]
+  api_key="Client Secret"
+  key1="Client ID"
+  api_secret="eIDAS Private Key"
+[nordea.metadata.creditor_account_type]
+  name="creditor_account_type"
+  label="Creditor Account Type"
+  placeholder="Enter Beneficiary Account Type e.g. IBAN"
+  required=true
+  type="Text"
+[nordea.metadata.creditor_account_value]
+  name="creditor_account_value"
+  label="Creditor Account Type"
+  placeholder="Enter Beneficiary Account Number"
+  required=true
+  type="Text"
+[nordea.metadata.creditor_beneficiary_name]
+  name="creditor_beneficiary_name"
+  label="Creditor Account Beneficiary Name"
+  placeholder="Enter Beneficiary Name"
+  required=true
+  type="Text"
+
 
 [worldpayxml]
 [[worldpayxml.credit]]
diff --git a/crates/hyperswitch_connectors/Cargo.toml b/crates/hyperswitch_connectors/Cargo.toml
index 63e98299c39..d06d6f299d6 100644
--- a/crates/hyperswitch_connectors/Cargo.toml
+++ b/crates/hyperswitch_connectors/Cargo.toml
@@ -37,6 +37,7 @@ lazy_static = "1.5.0"
 mime = "0.3.17"
 num-traits = "0.2.19"
 openssl = {version = "0.10.70"}
+pem = "3.0.5"
 qrcode = "0.14.1"
 quick-xml = { version = "0.31.0", features = ["serialize"] }
 rand = "0.8.5"
diff --git a/crates/hyperswitch_connectors/src/connectors/nordea.rs b/crates/hyperswitch_connectors/src/connectors/nordea.rs
index 9230d856f8d..fb0d9e0f625 100644
--- a/crates/hyperswitch_connectors/src/connectors/nordea.rs
+++ b/crates/hyperswitch_connectors/src/connectors/nordea.rs
@@ -1,28 +1,39 @@
+mod requests;
+mod responses;
 pub mod transformers;
 
+use base64::Engine;
+use common_enums::enums;
 use common_utils::{
+    consts, date_time,
     errors::CustomResult,
     ext_traits::BytesExt,
     request::{Method, Request, RequestBuilder, RequestContent},
-    types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector},
+    types::{AmountConvertor, StringMajorUnit, StringMajorUnitForConnector},
 };
 use error_stack::{report, ResultExt};
 use hyperswitch_domain_models::{
-    router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
+    router_data::{AccessToken, AccessTokenAuthenticationResponse, ErrorResponse, RouterData},
     router_flow_types::{
         access_token_auth::AccessTokenAuth,
         payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
         refunds::{Execute, RSync},
+        AccessTokenAuthentication, PreProcessing,
     },
     router_request_types::{
-        AccessTokenRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData,
-        PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData,
+        AccessTokenAuthenticationRequestData, AccessTokenRequestData,
+        PaymentMethodTokenizationData, PaymentsAuthorizeData, PaymentsCancelData,
+        PaymentsCaptureData, PaymentsPreProcessingData, PaymentsSessionData, PaymentsSyncData,
         RefundsData, SetupMandateRequestData,
     },
-    router_response_types::{PaymentsResponseData, RefundsResponseData},
+    router_response_types::{
+        ConnectorInfo, PaymentMethodDetails, PaymentsResponseData, RefundsResponseData,
+        SupportedPaymentMethods, SupportedPaymentMethodsExt,
+    },
     types::{
-        PaymentsAuthorizeRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData,
-        RefundSyncRouterData, RefundsRouterData,
+        AccessTokenAuthenticationRouterData, PaymentsAuthorizeRouterData,
+        PaymentsPreProcessingRouterData, PaymentsSyncRouterData, RefreshTokenRouterData,
+        RefundsRouterData,
     },
 };
 use hyperswitch_interfaces::{
@@ -31,31 +42,204 @@ use hyperswitch_interfaces::{
         ConnectorValidation,
     },
     configs::Connectors,
+    consts::{NO_ERROR_CODE, NO_ERROR_MESSAGE},
     errors,
     events::connector_api_logs::ConnectorEvent,
-    types::{self, Response},
+    types::{self, AuthenticationTokenType, RefreshTokenType, Response},
     webhooks,
 };
-use masking::{ExposeInterface, Mask};
-use transformers as nordea;
+use lazy_static::lazy_static;
+use masking::{ExposeInterface, Mask, PeekInterface, Secret};
+use ring::{
+    digest,
+    signature::{RsaKeyPair, RSA_PKCS1_SHA256},
+};
+use transformers::{get_error_data, NordeaAuthType};
+use url::Url;
 
-use crate::{constants::headers, types::ResponseRouterData, utils};
+use crate::{
+    connectors::nordea::{
+        requests::{
+            NordeaOAuthExchangeRequest, NordeaOAuthRequest, NordeaPaymentsConfirmRequest,
+            NordeaPaymentsRequest, NordeaRouterData,
+        },
+        responses::{
+            NordeaOAuthExchangeResponse, NordeaPaymentsConfirmResponse,
+            NordeaPaymentsInitiateResponse,
+        },
+    },
+    constants::headers,
+    types::ResponseRouterData,
+    utils::{self, RouterData as OtherRouterData},
+};
 
 #[derive(Clone)]
 pub struct Nordea {
-    amount_converter: &'static (dyn AmountConvertor<Output = StringMinorUnit> + Sync),
+    amount_converter: &'static (dyn AmountConvertor<Output = StringMajorUnit> + Sync),
+}
+
+struct SignatureParams<'a> {
+    content_type: &'a str,
+    host: &'a str,
+    path: &'a str,
+    payload_digest: Option<&'a str>,
+    date: &'a str,
+    http_method: Method,
 }
 
 impl Nordea {
     pub fn new() -> &'static Self {
         &Self {
-            amount_converter: &StringMinorUnitForConnector,
+            amount_converter: &StringMajorUnitForConnector,
         }
     }
+
+    pub fn generate_digest(&self, payload: &[u8]) -> String {
+        let payload_digest = digest::digest(&digest::SHA256, payload);
+        format!("sha-256={}", consts::BASE64_ENGINE.encode(payload_digest))
+    }
+
+    pub fn generate_digest_from_request(&self, payload: &RequestContent) -> String {
+        let payload_bytes = match payload {
+            RequestContent::RawBytes(bytes) => bytes.clone(),
+            _ => payload.get_inner_value().expose().as_bytes().to_vec(),
+        };
+
+        self.generate_digest(&payload_bytes)
+    }
+
+    fn format_private_key(
+        &self,
+        private_key_str: &str,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let key = private_key_str.to_string();
+
+        // Check if it already has PEM headers
+        let pem_data =
+            if key.contains("BEGIN") && key.contains("END") && key.contains("PRIVATE KEY") {
+                key
+            } else {
+                // Remove whitespace and format with 64-char lines
+                let cleaned_key = key
+                    .chars()
+                    .filter(|c| !c.is_whitespace())
+                    .collect::<String>();
+
+                let formatted_key = cleaned_key
+                    .chars()
+                    .collect::<Vec<char>>()
+                    .chunks(64)
+                    .map(|chunk| chunk.iter().collect::<String>())
+                    .collect::<Vec<String>>()
+                    .join("\n");
+
+                format!(
+                "-----BEGIN RSA PRIVATE KEY-----\n{formatted_key}\n-----END RSA PRIVATE KEY-----",
+            )
+            };
+
+        Ok(pem_data)
+    }
+
+    // For non-production environments, signature generation can be skipped and instead `SKIP_SIGNATURE_VALIDATION_FOR_SANDBOX` can be passed.
+    fn generate_signature(
+        &self,
+        auth: &NordeaAuthType,
+        signature_params: SignatureParams<'_>,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        const REQUEST_WITHOUT_CONTENT_HEADERS: &str =
+            "(request-target) x-nordea-originating-host x-nordea-originating-date";
+        const REQUEST_WITH_CONTENT_HEADERS: &str = "(request-target) x-nordea-originating-host x-nordea-originating-date content-type digest";
+
+        let method_string = signature_params.http_method.to_string().to_lowercase();
+        let mut normalized_string = format!(
+            "(request-target): {} {}\nx-nordea-originating-host: {}\nx-nordea-originating-date: {}",
+            method_string, signature_params.path, signature_params.host, signature_params.date
+        );
+
+        let headers = if matches!(
+            signature_params.http_method,
+            Method::Post | Method::Put | Method::Patch
+        ) {
+            let digest = signature_params.payload_digest.unwrap_or("");
+            normalized_string.push_str(&format!(
+                "\ncontent-type: {}\ndigest: {}",
+                signature_params.content_type, digest
+            ));
+            REQUEST_WITH_CONTENT_HEADERS
+        } else {
+            REQUEST_WITHOUT_CONTENT_HEADERS
+        };
+
+        let signature_base64 = {
+            let private_key_pem =
+                self.format_private_key(&auth.eidas_private_key.clone().expose())?;
+
+            let private_key_der = pem::parse(&private_key_pem).change_context(
+                errors::ConnectorError::InvalidConnectorConfig {
+                    config: "eIDAS Private Key",
+                },
+            )?;
+            let private_key_der_contents = private_key_der.contents();
+            let key_pair = RsaKeyPair::from_der(private_key_der_contents).change_context(
+                errors::ConnectorError::InvalidConnectorConfig {
+                    config: "eIDAS Private Key",
+                },
+            )?;
+
+            let mut signature = vec![0u8; key_pair.public().modulus_len()];
+            key_pair
+                .sign(
+                    &RSA_PKCS1_SHA256,
+                    &ring::rand::SystemRandom::new(),
+                    normalized_string.as_bytes(),
+                    &mut signature,
+                )
+                .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+
+            consts::BASE64_ENGINE.encode(signature)
+        };
+
+        Ok(format!(
+            r#"keyId="{}",algorithm="rsa-sha256",headers="{}",signature="{}""#,
+            auth.client_id.peek(),
+            headers,
+            signature_base64
+        ))
+    }
+
+    // This helper function correctly serializes a struct into the required
+    // non-percent-encoded form URL string.
+    fn get_form_urlencoded_payload<T: serde::Serialize>(
+        &self,
+        form_data: &T,
+    ) -> Result<Vec<u8>, error_stack::Report<errors::ConnectorError>> {
+        let json_value = serde_json::to_value(form_data)
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+
+        let btree_map: std::collections::BTreeMap<String, serde_json::Value> =
+            serde_json::from_value(json_value)
+                .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+
+        Ok(btree_map
+            .iter()
+            .map(|(k, v)| {
+                // Remove quotes from string values for proper form encoding
+                let value = match v {
+                    serde_json::Value::String(s) => s.clone(),
+                    _ => v.to_string(),
+                };
+                format!("{k}={value}")
+            })
+            .collect::<Vec<_>>()
+            .join("&")
+            .into_bytes())
+    }
 }
 
 impl api::Payment for Nordea {}
 impl api::PaymentSession for Nordea {}
+impl api::ConnectorAuthenticationToken for Nordea {}
 impl api::ConnectorAccessToken for Nordea {}
 impl api::MandateSetup for Nordea {}
 impl api::PaymentAuthorize for Nordea {}
@@ -66,13 +250,15 @@ impl api::Refund for Nordea {}
 impl api::RefundExecute for Nordea {}
 impl api::RefundSync for Nordea {}
 impl api::PaymentToken for Nordea {}
+impl api::PaymentsPreProcessing for Nordea {}
 
 impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
     for Nordea
 {
-    // Not Implemented (R)
 }
 
+impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Nordea {}
+
 impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Nordea
 where
     Self: ConnectorIntegration<Flow, Request, Response>,
@@ -80,15 +266,105 @@ where
     fn build_headers(
         &self,
         req: &RouterData<Flow, Request, Response>,
-        _connectors: &Connectors,
+        connectors: &Connectors,
     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
-        let mut header = vec![(
-            headers::CONTENT_TYPE.to_string(),
-            self.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)
+        let access_token = req
+            .access_token
+            .clone()
+            .ok_or(errors::ConnectorError::FailedToObtainAuthType)?;
+        let auth = NordeaAuthType::try_from(&req.connector_auth_type)?;
+        let content_type = self.get_content_type().to_string();
+        let http_method = self.get_http_method();
+
+        // Extract host from base URL
+        let nordea_host = Url::parse(self.base_url(connectors))
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?
+            .host_str()
+            .ok_or(errors::ConnectorError::RequestEncodingFailed)?
+            .to_string();
+
+        let nordea_origin_date = date_time::now_rfc7231_http_date()
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+
+        let full_url = self.get_url(req, connectors)?;
+        let url_parsed =
+            Url::parse(&full_url).change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        let path = url_parsed.path();
+        let path_with_query = if let Some(query) = url_parsed.query() {
+            format!("{path}?{query}")
+        } else {
+            path.to_string()
+        };
+
+        let mut required_headers = vec![
+            (
+                headers::CONTENT_TYPE.to_string(),
+                content_type.clone().into(),
+            ),
+            (
+                headers::AUTHORIZATION.to_string(),
+                format!("Bearer {}", access_token.token.peek()).into_masked(),
+            ),
+            (
+                "X-IBM-Client-ID".to_string(),
+                auth.client_id.clone().expose().into_masked(),
+            ),
+            (
+                "X-IBM-Client-Secret".to_string(),
+                auth.client_secret.clone().expose().into_masked(),
+            ),
+            (
+                "X-Nordea-Originating-Date".to_string(),
+                nordea_origin_date.clone().into_masked(),
+            ),
+            (
+                "X-Nordea-Originating-Host".to_string(),
+                nordea_host.clone().into_masked(),
+            ),
+        ];
+
+        if matches!(http_method, Method::Post | Method::Put | Method::Patch) {
+            let nordea_request = self.get_request_body(req, connectors)?;
+
+            let sha256_digest = self.generate_digest_from_request(&nordea_request);
+
+            // Add Digest header
+            required_headers.push((
+                "Digest".to_string(),
+                sha256_digest.to_string().into_masked(),
+            ));
+
+            let signature = self.generate_signature(
+                &auth,
+                SignatureParams {
+                    content_type: &content_type,
+                    host: &nordea_host,
+                    path,
+                    payload_digest: Some(&sha256_digest),
+                    date: &nordea_origin_date,
+                    http_method,
+                },
+            )?;
+
+            required_headers.push(("Signature".to_string(), signature.into_masked()));
+        } else {
+            // Generate signature without digest for GET requests
+            let signature = self.generate_signature(
+                &auth,
+                SignatureParams {
+                    content_type: &content_type,
+                    host: &nordea_host,
+                    path: &path_with_query,
+                    payload_digest: None,
+                    date: &nordea_origin_date,
+                    http_method,
+                },
+            )?;
+
+            required_headers.push(("Signature".to_string(), signature.into_masked()));
+        }
+
+        Ok(required_headers)
     }
 }
 
@@ -109,24 +385,12 @@ impl ConnectorCommon for Nordea {
         connectors.nordea.base_url.as_ref()
     }
 
-    fn get_auth_header(
-        &self,
-        auth_type: &ConnectorAuthType,
-    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
-        let auth = nordea::NordeaAuthType::try_from(auth_type)
-            .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
-        Ok(vec![(
-            headers::AUTHORIZATION.to_string(),
-            auth.api_key.expose().into_masked(),
-        )])
-    }
-
     fn build_error_response(
         &self,
         res: Response,
         event_builder: Option<&mut ConnectorEvent>,
     ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
-        let response: nordea::NordeaErrorResponse = res
+        let response: responses::NordeaErrorResponse = res
             .response
             .parse_struct("NordeaErrorResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
@@ -136,9 +400,14 @@ impl ConnectorCommon for Nordea {
 
         Ok(ErrorResponse {
             status_code: res.status_code,
-            code: response.code,
-            message: response.message,
-            reason: response.reason,
+            code: get_error_data(response.error.as_ref())
+                .and_then(|failure| failure.code.clone())
+                .unwrap_or(NO_ERROR_CODE.to_string()),
+            message: get_error_data(response.error.as_ref())
+                .and_then(|failure| failure.description.clone())
+                .unwrap_or(NO_ERROR_MESSAGE.to_string()),
+            reason: get_error_data(response.error.as_ref())
+                .and_then(|failure| failure.failure_type.clone()),
             attempt_status: None,
             connector_transaction_id: None,
             network_decline_code: None,
@@ -148,94 +417,167 @@ impl ConnectorCommon for Nordea {
     }
 }
 
-impl ConnectorValidation for Nordea {
-    //TODO: implement functions when support enabled
-}
+impl ConnectorValidation for Nordea {}
 
-impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Nordea {
-    //TODO: implement sessions flow
-}
-
-impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken> for Nordea {}
-
-impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData> for Nordea {}
-
-impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Nordea {
-    fn get_headers(
+impl
+    ConnectorIntegration<
+        AccessTokenAuthentication,
+        AccessTokenAuthenticationRequestData,
+        AccessTokenAuthenticationResponse,
+    > for Nordea
+{
+    fn get_url(
         &self,
-        req: &PaymentsAuthorizeRouterData,
+        _req: &AccessTokenAuthenticationRouterData,
         connectors: &Connectors,
-    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
-        self.build_headers(req, connectors)
+    ) -> CustomResult<String, errors::ConnectorError> {
+        Ok(format!(
+            "{}/personal/v5/authorize",
+            self.base_url(connectors)
+        ))
     }
 
     fn get_content_type(&self) -> &'static str {
-        self.common_get_content_type()
-    }
-
-    fn get_url(
-        &self,
-        _req: &PaymentsAuthorizeRouterData,
-        _connectors: &Connectors,
-    ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        "application/json"
     }
 
     fn get_request_body(
         &self,
-        req: &PaymentsAuthorizeRouterData,
+        req: &AccessTokenAuthenticationRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        let amount = utils::convert_amount(
-            self.amount_converter,
-            req.request.minor_amount,
-            req.request.currency,
-        )?;
-
-        let connector_router_data = nordea::NordeaRouterData::from((amount, req));
-        let connector_req = nordea::NordeaPaymentsRequest::try_from(&connector_router_data)?;
+        let connector_req = NordeaOAuthRequest::try_from(req)?;
         Ok(RequestContent::Json(Box::new(connector_req)))
     }
 
     fn build_request(
         &self,
-        req: &PaymentsAuthorizeRouterData,
+        req: &AccessTokenAuthenticationRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Option<Request>, errors::ConnectorError> {
-        Ok(Some(
+        let auth = NordeaAuthType::try_from(&req.connector_auth_type)?;
+        let content_type = self.common_get_content_type().to_string();
+        let http_method = Method::Post;
+
+        // Extract host from base URL
+        let nordea_host = Url::parse(self.base_url(connectors))
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?
+            .host_str()
+            .ok_or(errors::ConnectorError::RequestEncodingFailed)?
+            .to_string();
+
+        let nordea_origin_date = date_time::now_rfc7231_http_date()
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+
+        let full_url = self.get_url(req, connectors)?;
+        let url_parsed =
+            Url::parse(&full_url).change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        let path = url_parsed.path();
+
+        let request_body = self.get_request_body(req, connectors)?;
+
+        let mut required_headers = vec![
+            (
+                headers::CONTENT_TYPE.to_string(),
+                content_type.clone().into(),
+            ),
+            (
+                "X-IBM-Client-ID".to_string(),
+                auth.client_id.clone().expose().into_masked(),
+            ),
+            (
+                "X-IBM-Client-Secret".to_string(),
+                auth.client_secret.clone().expose().into_masked(),
+            ),
+            (
+                "X-Nordea-Originating-Date".to_string(),
+                nordea_origin_date.clone().into_masked(),
+            ),
+            (
+                "X-Nordea-Originating-Host".to_string(),
+                nordea_host.clone().into_masked(),
+            ),
+        ];
+
+        let sha256_digest = self.generate_digest_from_request(&request_body);
+
+        // Add Digest header
+        required_headers.push((
+            "Digest".to_string(),
+            sha256_digest.to_string().into_masked(),
+        ));
+
+        let signature = self.generate_signature(
+            &auth,
+            SignatureParams {
+                content_type: &content_type,
+                host: &nordea_host,
+                path,
+                payload_digest: Some(&sha256_digest),
+                date: &nordea_origin_date,
+                http_method,
+            },
+        )?;
+
+        required_headers.push(("Signature".to_string(), signature.into_masked()));
+
+        let request = Some(
             RequestBuilder::new()
-                .method(Method::Post)
-                .url(&types::PaymentsAuthorizeType::get_url(
-                    self, req, connectors,
-                )?)
+                .method(http_method)
                 .attach_default_headers()
-                .headers(types::PaymentsAuthorizeType::get_headers(
-                    self, req, connectors,
-                )?)
-                .set_body(types::PaymentsAuthorizeType::get_request_body(
-                    self, req, connectors,
-                )?)
+                .headers(required_headers)
+                .url(&AuthenticationTokenType::get_url(self, req, connectors)?)
+                .set_body(request_body)
                 .build(),
-        ))
+        );
+        Ok(request)
     }
 
     fn handle_response(
         &self,
-        data: &PaymentsAuthorizeRouterData,
-        event_builder: Option<&mut ConnectorEvent>,
+        data: &AccessTokenAuthenticationRouterData,
+        _event_builder: Option<&mut ConnectorEvent>,
         res: Response,
-    ) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> {
-        let response: nordea::NordeaPaymentsResponse = res
-            .response
-            .parse_struct("Nordea PaymentsAuthorizeResponse")
-            .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,
-        })
+    ) -> CustomResult<AccessTokenAuthenticationRouterData, errors::ConnectorError> {
+        // Handle 302 redirect response
+        if res.status_code == 302 {
+            // Extract Location header
+            let headers =
+                res.headers
+                    .as_ref()
+                    .ok_or(errors::ConnectorError::MissingRequiredField {
+                        field_name: "headers",
+                    })?;
+            let location_header = headers
+                .get("Location")
+                .map(|value| value.to_str())
+                .and_then(|location_value| location_value.ok())
+                .ok_or(errors::ConnectorError::ParsingFailed)?;
+
+            // Parse auth code from query params
+            let url = Url::parse(location_header)
+                .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+
+            let code = url
+                .query_pairs()
+                .find(|(key, _)| key == "code")
+                .map(|(_, value)| value.to_string())
+                .ok_or(errors::ConnectorError::MissingRequiredField { field_name: "code" })?;
+
+            // Return auth code as "token" with short expiry
+            Ok(RouterData {
+                response: Ok(AccessTokenAuthenticationResponse {
+                    code: Secret::new(code),
+                    expires: 60, // 60 seconds - auth code validity
+                }),
+                ..data.clone()
+            })
+        } else {
+            Err(
+                errors::ConnectorError::UnexpectedResponseError("Expected 302 redirect".into())
+                    .into(),
+            )
+        }
     }
 
     fn get_error_response(
@@ -247,54 +589,127 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
     }
 }
 
-impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Nordea {
-    fn get_headers(
+impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken> for Nordea {
+    fn get_url(
         &self,
-        req: &PaymentsSyncRouterData,
+        _req: &RefreshTokenRouterData,
         connectors: &Connectors,
-    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
-        self.build_headers(req, connectors)
-    }
-
-    fn get_content_type(&self) -> &'static str {
-        self.common_get_content_type()
+    ) -> CustomResult<String, errors::ConnectorError> {
+        Ok(format!(
+            "{}/personal/v5/authorize/token",
+            self.base_url(connectors)
+        ))
     }
 
-    fn get_url(
+    fn get_request_body(
         &self,
-        _req: &PaymentsSyncRouterData,
+        req: &RefreshTokenRouterData,
         _connectors: &Connectors,
-    ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let connector_req = NordeaOAuthExchangeRequest::try_from(req)?;
+        let body_bytes = self.get_form_urlencoded_payload(&Box::new(connector_req))?;
+        Ok(RequestContent::RawBytes(body_bytes))
     }
 
     fn build_request(
         &self,
-        req: &PaymentsSyncRouterData,
+        req: &RefreshTokenRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Option<Request>, errors::ConnectorError> {
-        Ok(Some(
+        // For the OAuth token exchange request, we don't have a bearer token yet
+        // We're exchanging the auth code for an access token
+        let auth = NordeaAuthType::try_from(&req.connector_auth_type)?;
+        let content_type = "application/x-www-form-urlencoded".to_string();
+        let http_method = Method::Post;
+
+        // Extract host from base URL
+        let nordea_host = Url::parse(self.base_url(connectors))
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?
+            .host_str()
+            .ok_or(errors::ConnectorError::RequestEncodingFailed)?
+            .to_string();
+
+        let nordea_origin_date = date_time::now_rfc7231_http_date()
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+
+        let full_url = self.get_url(req, connectors)?;
+        let url_parsed =
+            Url::parse(&full_url).change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        let path = url_parsed.path();
+
+        let request_body = self.get_request_body(req, connectors)?;
+
+        let mut required_headers = vec![
+            (
+                headers::CONTENT_TYPE.to_string(),
+                content_type.clone().into(),
+            ),
+            (
+                "X-IBM-Client-ID".to_string(),
+                auth.client_id.clone().expose().into_masked(),
+            ),
+            (
+                "X-IBM-Client-Secret".to_string(),
+                auth.client_secret.clone().expose().into_masked(),
+            ),
+            (
+                "X-Nordea-Originating-Date".to_string(),
+                nordea_origin_date.clone().into_masked(),
+            ),
+            (
+                "X-Nordea-Originating-Host".to_string(),
+                nordea_host.clone().into_masked(),
+            ),
+        ];
+
+        let sha256_digest = self.generate_digest_from_request(&request_body);
+
+        // Add Digest header
+        required_headers.push((
+            "Digest".to_string(),
+            sha256_digest.to_string().into_masked(),
+        ));
+
+        let signature = self.generate_signature(
+            &auth,
+            SignatureParams {
+                content_type: &content_type,
+                host: &nordea_host,
+                path,
+                payload_digest: Some(&sha256_digest),
+                date: &nordea_origin_date,
+                http_method,
+            },
+        )?;
+
+        required_headers.push(("Signature".to_string(), signature.into_masked()));
+
+        let request = Some(
             RequestBuilder::new()
-                .method(Method::Get)
-                .url(&types::PaymentsSyncType::get_url(self, req, connectors)?)
+                .method(http_method)
                 .attach_default_headers()
-                .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?)
+                .headers(required_headers)
+                .url(&RefreshTokenType::get_url(self, req, connectors)?)
+                .set_body(request_body)
                 .build(),
-        ))
+        );
+        Ok(request)
     }
 
     fn handle_response(
         &self,
-        data: &PaymentsSyncRouterData,
+        data: &RefreshTokenRouterData,
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
-    ) -> CustomResult<PaymentsSyncRouterData, errors::ConnectorError> {
-        let response: nordea::NordeaPaymentsResponse = res
+    ) -> CustomResult<RefreshTokenRouterData, errors::ConnectorError> {
+        let response: NordeaOAuthExchangeResponse = res
             .response
-            .parse_struct("nordea PaymentsSyncResponse")
+            .parse_struct("NordeaOAuthExchangeResponse")
             .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(),
@@ -311,10 +726,25 @@ impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Nor
     }
 }
 
-impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> for Nordea {
+impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData> for Nordea {
+    fn build_request(
+        &self,
+        _req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(
+            errors::ConnectorError::NotImplemented("Setup Mandate flow for Nordea".to_string())
+                .into(),
+        )
+    }
+}
+
+impl ConnectorIntegration<PreProcessing, PaymentsPreProcessingData, PaymentsResponseData>
+    for Nordea
+{
     fn get_headers(
         &self,
-        req: &PaymentsCaptureRouterData,
+        req: &PaymentsPreProcessingRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
         self.build_headers(req, connectors)
@@ -326,34 +756,85 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
 
     fn get_url(
         &self,
-        _req: &PaymentsCaptureRouterData,
-        _connectors: &Connectors,
+        req: &PaymentsPreProcessingRouterData,
+        connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        // Determine the payment endpoint based on country and currency
+        let country = req.get_billing_country()?;
+
+        let currency =
+            req.request
+                .currency
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "currency",
+                })?;
+
+        let endpoint = match (country, currency) {
+            (api_models::enums::CountryAlpha2::FI, api_models::enums::Currency::EUR) => {
+                "/personal/v5/payments/sepa-credit-transfers"
+            }
+            (api_models::enums::CountryAlpha2::DK, api_models::enums::Currency::DKK) => {
+                "/personal/v5/payments/domestic-credit-transfers"
+            }
+            (
+                api_models::enums::CountryAlpha2::FI
+                | api_models::enums::CountryAlpha2::DK
+                | api_models::enums::CountryAlpha2::SE
+                | api_models::enums::CountryAlpha2::NO,
+                _,
+            ) => "/personal/v5/payments/cross-border-credit-transfers",
+            _ => {
+                return Err(errors::ConnectorError::NotSupported {
+                    message: format!("Country {country:?} is not supported by Nordea"),
+                    connector: "Nordea",
+                }
+                .into())
+            }
+        };
+
+        Ok(format!("{}{}", self.base_url(connectors), endpoint))
     }
 
     fn get_request_body(
         &self,
-        _req: &PaymentsCaptureRouterData,
+        req: &PaymentsPreProcessingRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into())
+        let minor_amount =
+            req.request
+                .minor_amount
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "minor_amount",
+                })?;
+        let currency =
+            req.request
+                .currency
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "currency",
+                })?;
+
+        let amount = utils::convert_amount(self.amount_converter, minor_amount, currency)?;
+        let connector_router_data = NordeaRouterData::from((amount, req));
+        let connector_req = NordeaPaymentsRequest::try_from(&connector_router_data)?;
+        Ok(RequestContent::Json(Box::new(connector_req)))
     }
 
     fn build_request(
         &self,
-        req: &PaymentsCaptureRouterData,
+        req: &PaymentsPreProcessingRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Option<Request>, errors::ConnectorError> {
         Ok(Some(
             RequestBuilder::new()
                 .method(Method::Post)
-                .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?)
+                .url(&types::PaymentsPreProcessingType::get_url(
+                    self, req, connectors,
+                )?)
                 .attach_default_headers()
-                .headers(types::PaymentsCaptureType::get_headers(
+                .headers(types::PaymentsPreProcessingType::get_headers(
                     self, req, connectors,
                 )?)
-                .set_body(types::PaymentsCaptureType::get_request_body(
+                .set_body(types::PaymentsPreProcessingType::get_request_body(
                     self, req, connectors,
                 )?)
                 .build(),
@@ -362,16 +843,18 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
 
     fn handle_response(
         &self,
-        data: &PaymentsCaptureRouterData,
+        data: &PaymentsPreProcessingRouterData,
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
-    ) -> CustomResult<PaymentsCaptureRouterData, errors::ConnectorError> {
-        let response: nordea::NordeaPaymentsResponse = res
+    ) -> CustomResult<PaymentsPreProcessingRouterData, errors::ConnectorError> {
+        let response: NordeaPaymentsInitiateResponse = res
             .response
-            .parse_struct("Nordea PaymentsCaptureResponse")
+            .parse_struct("NordeaPaymentsInitiateResponse")
             .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(),
@@ -388,12 +871,10 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
     }
 }
 
-impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Nordea {}
-
-impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Nordea {
+impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Nordea {
     fn get_headers(
         &self,
-        req: &RefundsRouterData<Execute>,
+        req: &PaymentsAuthorizeRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
         self.build_headers(req, connectors)
@@ -403,61 +884,74 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Nordea
         self.common_get_content_type()
     }
 
+    fn get_http_method(&self) -> Method {
+        Method::Put
+    }
+
     fn get_url(
         &self,
-        _req: &RefundsRouterData<Execute>,
+        _req: &PaymentsAuthorizeRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!(
+            "{}{}",
+            self.base_url(_connectors),
+            "/personal/v5/payments"
+        ))
     }
 
     fn get_request_body(
         &self,
-        req: &RefundsRouterData<Execute>,
+        req: &PaymentsAuthorizeRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        let refund_amount = utils::convert_amount(
+        let amount = utils::convert_amount(
             self.amount_converter,
-            req.request.minor_refund_amount,
+            req.request.minor_amount,
             req.request.currency,
         )?;
 
-        let connector_router_data = nordea::NordeaRouterData::from((refund_amount, req));
-        let connector_req = nordea::NordeaRefundRequest::try_from(&connector_router_data)?;
+        let connector_router_data = NordeaRouterData::from((amount, req));
+        let connector_req = NordeaPaymentsConfirmRequest::try_from(&connector_router_data)?;
         Ok(RequestContent::Json(Box::new(connector_req)))
     }
 
     fn build_request(
         &self,
-        req: &RefundsRouterData<Execute>,
+        req: &PaymentsAuthorizeRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Option<Request>, errors::ConnectorError> {
-        let request = RequestBuilder::new()
-            .method(Method::Post)
-            .url(&types::RefundExecuteType::get_url(self, req, connectors)?)
-            .attach_default_headers()
-            .headers(types::RefundExecuteType::get_headers(
-                self, req, connectors,
-            )?)
-            .set_body(types::RefundExecuteType::get_request_body(
-                self, req, connectors,
-            )?)
-            .build();
-        Ok(Some(request))
+        Ok(Some(
+            RequestBuilder::new()
+                .method(types::PaymentsAuthorizeType::get_http_method(self))
+                .url(&types::PaymentsAuthorizeType::get_url(
+                    self, req, connectors,
+                )?)
+                .attach_default_headers()
+                .headers(types::PaymentsAuthorizeType::get_headers(
+                    self, req, connectors,
+                )?)
+                .set_body(types::PaymentsAuthorizeType::get_request_body(
+                    self, req, connectors,
+                )?)
+                .build(),
+        ))
     }
 
     fn handle_response(
         &self,
-        data: &RefundsRouterData<Execute>,
+        data: &PaymentsAuthorizeRouterData,
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
-    ) -> CustomResult<RefundsRouterData<Execute>, errors::ConnectorError> {
-        let response: nordea::RefundResponse =
-            res.response
-                .parse_struct("nordea RefundResponse")
-                .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+    ) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> {
+        let response: NordeaPaymentsConfirmResponse = res
+            .response
+            .parse_struct("NordeaPaymentsConfirmResponse")
+            .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(),
@@ -474,10 +968,10 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Nordea
     }
 }
 
-impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Nordea {
+impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Nordea {
     fn get_headers(
         &self,
-        req: &RefundSyncRouterData,
+        req: &PaymentsSyncRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
         self.build_headers(req, connectors)
@@ -487,41 +981,52 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Nordea {
         self.common_get_content_type()
     }
 
+    fn get_http_method(&self) -> Method {
+        Method::Get
+    }
+
     fn get_url(
         &self,
-        _req: &RefundSyncRouterData,
+        req: &PaymentsSyncRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let id = req.request.connector_transaction_id.clone();
+        let connector_transaction_id = id
+            .get_connector_transaction_id()
+            .change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
+
+        Ok(format!(
+            "{}{}{}",
+            self.base_url(_connectors),
+            "/personal/v5/payments/",
+            connector_transaction_id
+        ))
     }
 
     fn build_request(
         &self,
-        req: &RefundSyncRouterData,
+        req: &PaymentsSyncRouterData,
         connectors: &Connectors,
     ) -> CustomResult<Option<Request>, errors::ConnectorError> {
         Ok(Some(
             RequestBuilder::new()
-                .method(Method::Get)
-                .url(&types::RefundSyncType::get_url(self, req, connectors)?)
+                .method(types::PaymentsSyncType::get_http_method(self))
+                .url(&types::PaymentsSyncType::get_url(self, req, connectors)?)
                 .attach_default_headers()
-                .headers(types::RefundSyncType::get_headers(self, req, connectors)?)
-                .set_body(types::RefundSyncType::get_request_body(
-                    self, req, connectors,
-                )?)
+                .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?)
                 .build(),
         ))
     }
 
     fn handle_response(
         &self,
-        data: &RefundSyncRouterData,
+        data: &PaymentsSyncRouterData,
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
-    ) -> CustomResult<RefundSyncRouterData, errors::ConnectorError> {
-        let response: nordea::RefundResponse = res
+    ) -> CustomResult<PaymentsSyncRouterData, errors::ConnectorError> {
+        let response: NordeaPaymentsInitiateResponse = res
             .response
-            .parse_struct("nordea RefundSyncResponse")
+            .parse_struct("NordeaPaymentsSyncResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
@@ -541,6 +1046,52 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Nordea {
     }
 }
 
+impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> for Nordea {
+    fn build_request(
+        &self,
+        _req: &RouterData<Capture, PaymentsCaptureData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(errors::ConnectorError::FlowNotSupported {
+            flow: "Capture".to_string(),
+            connector: "Nordea".to_string(),
+        }
+        .into())
+    }
+}
+
+impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Nordea {
+    fn build_request(
+        &self,
+        _req: &RouterData<Void, PaymentsCancelData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(errors::ConnectorError::FlowNotSupported {
+            flow: "Payments Cancel".to_string(),
+            connector: "Nordea".to_string(),
+        }
+        .into())
+    }
+}
+
+impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Nordea {
+    fn build_request(
+        &self,
+        _req: &RefundsRouterData<Execute>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(errors::ConnectorError::FlowNotSupported {
+            flow: "Personal API Refunds".to_string(),
+            connector: "Nordea".to_string(),
+        }
+        .into())
+    }
+}
+
+impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Nordea {
+    // Default impl gets executed
+}
+
 #[async_trait::async_trait]
 impl webhooks::IncomingWebhook for Nordea {
     fn get_webhook_object_reference_id(
@@ -565,4 +1116,54 @@ impl webhooks::IncomingWebhook for Nordea {
     }
 }
 
-impl ConnectorSpecifications for Nordea {}
+lazy_static! {
+    static ref NORDEA_CONNECTOR_INFO: ConnectorInfo = ConnectorInfo {
+        display_name:
+            "Nordea",
+        description:
+            "Nordea is one of the leading financial services group in the Nordics and the preferred choice for millions across the region.",
+        connector_type: enums::PaymentConnectorCategory::PaymentGateway,
+    };
+    static ref NORDEA_SUPPORTED_PAYMENT_METHODS: SupportedPaymentMethods = {
+        let nordea_supported_capture_methods = vec![
+            enums::CaptureMethod::Automatic,
+            enums::CaptureMethod::SequentialAutomatic,
+        ];
+
+        let mut nordea_supported_payment_methods = SupportedPaymentMethods::new();
+
+        nordea_supported_payment_methods.add(
+            enums::PaymentMethod::BankDebit,
+            enums::PaymentMethodType::Sepa,
+            PaymentMethodDetails {
+                mandates: common_enums::FeatureStatus::NotSupported,
+                // Supported only in corporate API (corporate accounts)
+                refunds: common_enums::FeatureStatus::NotSupported,
+                supported_capture_methods: nordea_supported_capture_methods.clone(),
+                specific_features: None,
+            },
+        );
+
+        nordea_supported_payment_methods
+    };
+    static ref NORDEA_SUPPORTED_WEBHOOK_FLOWS: Vec<enums::EventClass> = Vec::new();
+}
+
+impl ConnectorSpecifications for Nordea {
+    fn get_connector_about(&self) -> Option<&'static ConnectorInfo> {
+        Some(&*NORDEA_CONNECTOR_INFO)
+    }
+
+    fn get_supported_payment_methods(&self) -> Option<&'static SupportedPaymentMethods> {
+        Some(&*NORDEA_SUPPORTED_PAYMENT_METHODS)
+    }
+
+    fn get_supported_webhook_flows(&self) -> Option<&'static [enums::EventClass]> {
+        Some(&*NORDEA_SUPPORTED_WEBHOOK_FLOWS)
+    }
+
+    fn authentication_token_for_token_creation(&self) -> bool {
+        // Nordea requires authentication token for access token creation
+        true
+    }
+}
diff --git a/crates/hyperswitch_connectors/src/connectors/nordea/requests.rs b/crates/hyperswitch_connectors/src/connectors/nordea/requests.rs
new file mode 100644
index 00000000000..a30a12ce407
--- /dev/null
+++ b/crates/hyperswitch_connectors/src/connectors/nordea/requests.rs
@@ -0,0 +1,381 @@
+use common_utils::types::StringMajorUnit;
+use masking::Secret;
+use serde::{Deserialize, Serialize};
+
+pub struct NordeaRouterData<T> {
+    pub amount: StringMajorUnit,
+    pub router_data: T,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct NordeaOAuthRequest {
+    /// Country is a mandatory parameter with possible values FI, DK, NO or SE
+    pub country: api_models::enums::CountryAlpha2,
+    /// Duration of access authorization in minutes. range: 1 to 259200 minutes (180 days).
+    /// Duration should be left empty if the request includes PAYMENTS_SINGLE_SCA scope.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub duration: Option<i32>,
+    /// Maximum transaction history in months. Optional if ACCOUNTS_TRANSACTIONS scope is requested. Default=2 months. range: 1 to 18 months
+    #[serde(rename = "max_tx_history")]
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub maximum_transaction_history: Option<i32>,
+    /// Redirect URI you used when this application was registered with Nordea.
+    pub redirect_uri: String,
+    pub scope: Vec<AccessScope>,
+    /// The OAuth2 state parameter. This is a nonce and should be used to prevent CSRF attacks.
+    pub state: Secret<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(rename_all = "snake_case")]
+pub enum GrantType {
+    AuthorizationCode,
+    RefreshToken,
+}
+
+// To be passed in query parameters for OAuth scopes
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum AccessScope {
+    AccountsBasic,
+    AccountsBalances,
+    AccountsDetails,
+    AccountsTransactions,
+    PaymentsMultiple,
+    PaymentsSingleSca,
+    CardsInformation,
+    CardsTransactions,
+}
+
+#[derive(Debug, Clone, Serialize)]
+pub struct NordeaOAuthExchangeRequest {
+    /// authorization_code flow
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub code: Option<Secret<String>>,
+    pub grant_type: GrantType,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub redirect_uri: Option<String>,
+    /// refresh_token flow
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub refresh_token: Option<Secret<String>>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum AccountType {
+    /// International bank account number
+    Iban,
+    /// National bank account number of Sweden
+    BbanSe,
+    /// National bank account number of Denmark
+    BbanDk,
+    /// National bank account number of Norway
+    BbanNo,
+    /// Bankgiro number
+    Bgnr,
+    /// Plusgiro number
+    Pgnr,
+    /// Creditor number (Giro) Denmark
+    GiroDk,
+    /// Any bank account number without any check-digit validations
+    BbanOther,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct AccountNumber {
+    /// Type of account number
+    #[serde(rename = "_type")]
+    pub account_type: AccountType,
+    /// Currency of the account (Mandatory for debtor, Optional for creditor)
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub currency: Option<api_models::enums::Currency>,
+    /// Actual account number
+    pub value: Secret<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct CreditorAccountReference {
+    /// RF or Invoice for FI Sepa payments, OCR for NO Kid payments and 01, 04, 15, 71, 73 or 75 for Danish Transfer Form payments.
+    #[serde(rename = "_type")]
+    pub creditor_reference_type: String,
+    /// Actual reference number
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub value: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaAddress {
+    /// First line of the address. e.g. Street address
+    pub line1: Option<Secret<String>>,
+    /// Second line of the address (optional). e.g. Postal address
+    pub line2: Option<Secret<String>>,
+    /// Third line of the address (optional). e.g. Country
+    pub line3: Option<Secret<String>>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct CreditorBank {
+    /// Address
+    pub address: Option<NordeaAddress>,
+    /// Bank code
+    pub bank_code: Option<String>,
+    /// Business identifier code (BIC) of the creditor bank.
+    /// This information is required, if the creditor account number is not in IBAN format.
+    #[serde(rename = "bic")]
+    pub business_identifier_code: Option<Secret<String>>,
+    /// Country of the creditor bank. Only ISO 3166 alpha-2 codes are used.
+    pub country: api_models::enums::CountryAlpha2,
+    /// Name of the creditor bank.
+    #[serde(rename = "name")]
+    pub bank_name: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct CreditorAccount {
+    /// Account number
+    pub account: AccountNumber,
+    /// Creditor bank information.
+    pub bank: Option<CreditorBank>,
+    /// Country of the creditor
+    pub country: Option<api_models::enums::CountryAlpha2>,
+    /// Address
+    pub creditor_address: Option<NordeaAddress>,
+    /// Message for the creditor to appear on their transaction.
+    /// Max length: FI SEPA:140; SE:12; PGNR:25; BGNR:150; DK: 40 (Instant/Express: 140); NO: 140
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub message: Option<String>,
+    /// Name of the creditor.
+    /// Max length: FI SEPA: 30; SE: 35; DK: Not use (Mandatory for Instant/Express payments: 70);
+    /// NO: 30 (mandatory for Straksbetaling/Express payments).
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub name: Option<Secret<String>>,
+    /// Creditor reference number.
+    /// Either Reference or Message has to be passed in the Request
+    pub reference: Option<CreditorAccountReference>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct DebitorAccount {
+    /// Account number
+    pub account: AccountNumber,
+    /// Own message to be on the debtor's transaction.
+    /// Max length 20. NB: This field is not supported for SEPA and Norwegian payments and will be ignored.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub message: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct InstructedAmount {
+    /// Monetary amount of the payment. Max (digits+decimals): FI SEPA: (9+2); SE:(11+2); DK:(7+2); NO:(7+2)
+    pub amount: StringMajorUnit,
+    /// Currency code according to ISO 4217.
+    /// NB: Possible value depends on the type of the payment.
+    /// For domestic payment it should be same as debtor local currency,
+    /// for SEPA it must be EUR,
+    /// for cross border it can be Currency code according to ISO 4217.
+    pub currency: api_models::enums::Currency,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum RecurrenceType {
+    Daily,
+    Weekly,
+    Biweekly,
+    MonthlySameDay,
+    MonthlyEom,
+    QuartelySameDay,
+    QuartelyEom,
+    SemiAnnuallySameDay,
+    SemiAnnuallyEom,
+    TriAnnuallySameDay,
+    YearlySameDay,
+    YearlyEom,
+    EveryMinuteSandboxOnly,
+}
+
+#[derive(Debug, Serialize, PartialEq)]
+#[serde(rename_all = "snake_case")]
+#[allow(dead_code)] // This is an optional field and not having it is fine
+pub enum FundsAvailabilityRequest {
+    True,
+    False,
+}
+
+#[derive(Debug, Serialize, PartialEq, Clone)]
+pub enum PaymentsUrgency {
+    Standard,
+    Express,
+    Sameday,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct RecurringInformation {
+    /// Number of occurrences. Not applicable for NO (use end_date instead). Format: int32.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub count: Option<i32>,
+    /// Date on which the recurrence will end. Format: YYYY-MM-DD. Applicable only for Norway. Format: date
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub end_date: Option<String>,
+    /// Repeats every interval
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub recurrence_type: Option<RecurrenceType>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum TppCategory {
+    Error,
+    Warning,
+    Info,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum TppCode {
+    Ds0a,
+    Narr,
+    Am21,
+    Am04,
+    Tm01,
+    Am12,
+    Rc06,
+    Rc07,
+    Rc04,
+    Ag06,
+    Bg06,
+    Be22,
+    Be20,
+    Ff06,
+    Be19,
+    Am03,
+    Am11,
+    Ch04,
+    Dt01,
+    Ch03,
+    Ff08,
+    Ac10,
+    Ac02,
+    Ag08,
+    Rr09,
+    Rc11,
+    Ff10,
+    Rr10,
+    Ff05,
+    Ch15,
+    Ff04,
+    Ac11,
+    Ac03,
+    Ac13,
+    Ac14,
+    Ac05,
+    Ac06,
+    Rr07,
+    Dt03,
+    Am13,
+    Ds24,
+    Fr01,
+    Am02,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct ThirdPartyMessages {
+    /// Category of the TPP message, INFO is further information, WARNING is something can be fixed, ERROR possibly non fixable issue
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub category: Option<TppCategory>,
+    /// Additional code that is combined with the text
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub code: Option<TppCode>,
+    /// Additional explaining text to the TPP
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub text: Option<String>,
+}
+
+#[derive(Debug, Serialize, PartialEq)]
+pub struct NordeaPaymentsRequest {
+    /// Creditor of the payment
+    #[serde(rename = "creditor")]
+    pub creditor_account: CreditorAccount,
+    /// Debtor of the payment
+    #[serde(rename = "debtor")]
+    pub debitor_account: DebitorAccount,
+    /// Free text reference that can be provided by the PSU.
+    /// This identification is passed on throughout the entire end-to-end chain.
+    /// Only in scope for Nordea Business DK.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub end_to_end_identification: Option<String>,
+    /// Unique identification as assigned by a partner to identify the payment.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub external_id: Option<String>,
+    /// Monetary amount
+    pub instructed_amount: InstructedAmount,
+    /// Recurring information
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub recurring: Option<RecurringInformation>,
+    /// Use as an indicator that the supplied payment (amount, currency and debtor account)
+    /// should be used to check whether the funds are available for further processing - at this moment.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub request_availability_of_funds: Option<FundsAvailabilityRequest>,
+    /// Choose a preferred execution date (or leave blank for today's date).
+    /// This should be a valid bank day, and depending on the country the date will either be
+    /// pushed to the next valid bank day, or return an error if a non-banking day date was
+    /// supplied (all dates accepted in sandbox). SEPA: max +5 years from yesterday,
+    /// Domestic: max. +1 year from yesterday. NB: Not supported for Own transfer Non-Recurring Norway.
+    /// Format:date.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub requested_execution_date: Option<String>,
+    /// Additional messages for third parties
+    #[serde(rename = "tpp_messages")]
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub tpp_messages: Option<Vec<ThirdPartyMessages>>,
+    /// Urgency of the payment. NB: This field is supported for
+    /// DK Domestic ('standard' and 'express')
+    /// NO Domestic bank transfer payments ('standard'). Use 'express' for Straksbetaling (Instant payment).
+    /// FI Sepa ('standard' and 'express') All other payment types ignore this input.
+    /// For further details on urgencies and cut-offs, refer to the Nordea website. Value 'sameday' is marked as deprecated and will be removed in the future.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub urgency: Option<PaymentsUrgency>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum NordeaAuthenticationMethod {
+    Mta,
+    #[serde(rename = "CCALC (Deprecated)")]
+    Ccalc,
+    Qrt,
+    CardRdr,
+    BankidSe,
+    QrtSe,
+    BankidNo,
+    BankidmNo,
+    MtaNo,
+    #[serde(rename = "NEMID_2F")]
+    Nemid2f,
+    Mitid,
+    MtaDk,
+    QrtDk,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
+#[serde(rename_all = "snake_case")]
+pub enum NordeaConfirmLanguage {
+    Fi,
+    Da,
+    Sv,
+    En,
+    No,
+}
+
+#[derive(Debug, Serialize, PartialEq)]
+pub struct NordeaPaymentsConfirmRequest {
+    /// Authentication method to use for the signing of payment.
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub authentication_method: Option<NordeaAuthenticationMethod>,
+    /// Language of the signing page that will be displayed to client, ISO639-1 and 639-2, default=en
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub language: Option<NordeaConfirmLanguage>,
+    pub payments_ids: Vec<String>,
+    pub redirect_url: Option<String>,
+    pub state: Option<String>,
+}
diff --git a/crates/hyperswitch_connectors/src/connectors/nordea/responses.rs b/crates/hyperswitch_connectors/src/connectors/nordea/responses.rs
new file mode 100644
index 00000000000..10693c9b43a
--- /dev/null
+++ b/crates/hyperswitch_connectors/src/connectors/nordea/responses.rs
@@ -0,0 +1,261 @@
+use common_enums::CountryAlpha2;
+use common_utils::types::StringMajorUnit;
+use masking::Secret;
+use serde::{Deserialize, Serialize};
+
+use super::requests::{
+    CreditorAccount, DebitorAccount, InstructedAmount, PaymentsUrgency, RecurringInformation,
+    ThirdPartyMessages,
+};
+
+// OAuth token response structure
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct NordeaOAuthExchangeResponse {
+    pub access_token: Option<Secret<String>>,
+    pub expires_in: Option<i64>,
+    pub refresh_token: Option<Secret<String>>,
+    pub token_type: Option<String>,
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub enum NordeaPaymentStatus {
+    #[default]
+    PendingConfirmation,
+    PendingSecondConfirmation,
+    PendingUserApproval,
+    OnHold,
+    Confirmed,
+    Rejected,
+    Paid,
+    InsufficientFunds,
+    LimitExceeded,
+    UserApprovalFailed,
+    UserApprovalTimeout,
+    UserApprovalCancelled,
+    Unknown,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaGroupHeader {
+    /// Response creation time. Format: date-time.
+    pub creation_date_time: Option<String>,
+    /// HTTP code for response. Format: int32.
+    pub http_code: Option<i32>,
+    /// Original request id for correlation purposes
+    pub message_identification: Option<String>,
+    /// Details of paginated response
+    pub message_pagination: Option<MessagePagination>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaResponseLinks {
+    /// Describes the nature of the link, e.g. 'details' for a link to the detailed information of a listed resource.
+    pub rel: Option<String>,
+    /// Relative path to the linked resource
+    pub href: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum FeesType {
+    Additional,
+    Standard,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct TransactionFee {
+    /// Monetary amount
+    pub amount: InstructedAmount,
+    pub description: Option<String>,
+    pub excluded_from_total_fee: Option<bool>,
+    pub percentage: Option<bool>,
+    #[serde(rename = "type")]
+    pub fees_type: Option<FeesType>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct BankFee {
+    /// Example 'domestic_transaction' only for DK domestic payments
+    #[serde(rename = "_type")]
+    pub bank_fee_type: Option<String>,
+    /// Country code according to ISO Alpha-2
+    pub country_code: Option<CountryAlpha2>,
+    /// Currency code according to ISO 4217
+    pub currency_code: Option<api_models::enums::Currency>,
+    /// Value of the fee.
+    pub value: Option<StringMajorUnit>,
+    pub fees: Option<Vec<TransactionFee>>,
+    /// Monetary amount
+    pub total_fee_amount: InstructedAmount,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "lowercase")]
+pub enum ChargeBearer {
+    Shar,
+    Debt,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct ExchangeRate {
+    pub base_currency: Option<api_models::enums::Currency>,
+    pub exchange_currency: Option<api_models::enums::Currency>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct MessagePagination {
+    /// Resource listing may return a continuationKey if there's more results available.
+    /// Request may be retried with the continuationKey, but otherwise same parameters, in order to get more results.
+    pub continuation_key: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaPaymentsInitiateResponseData {
+    /// Unique payment identifier assigned for new payment
+    #[serde(rename = "_id")]
+    pub payment_id: String,
+    /// HATEOAS inspired links: 'rel' and 'href'. Context specific link (only GET supported)
+    #[serde(rename = "_links")]
+    pub links: Option<Vec<NordeaResponseLinks>>,
+    /// Marked as required field in the docs, but connector does not send amount in payment_response.amount
+    pub amount: Option<StringMajorUnit>,
+    /// Bearer of charges. shar = The Debtor (sender of the payment) will pay all fees charged by the sending bank.
+    /// The Creditor (recipient of the payment) will pay all fees charged by the receiving bank.
+    /// debt = The Debtor (sender of the payment) will bear all of the payment transaction fees.
+    /// The creditor (beneficiary) will receive the full amount of the payment.
+    pub charge_bearer: Option<ChargeBearer>,
+    /// Creditor of the payment
+    #[serde(rename = "creditor")]
+    pub creditor_account: CreditorAccount,
+    pub currency: Option<api_models::enums::Currency>,
+    /// Debtor of the payment
+    #[serde(rename = "debtor")]
+    pub debitor_account: Option<DebitorAccount>,
+    /// Timestamp of payment creation. ISO 8601 format yyyy-mm-ddThh:mm:ss.fffZ. Format:date-time.
+    pub entry_date_time: Option<String>,
+    /// Unique identification as assigned by a partner to identify the payment.
+    pub external_id: Option<String>,
+    /// An amount the bank will charge for executing the payment
+    pub fee: Option<BankFee>,
+    pub indicative_exchange_rate: Option<ExchangeRate>,
+    /// It is mentioned as `number`. It can be an integer or a decimal number.
+    pub rate: Option<f32>,
+    /// Monetary amount
+    pub instructed_amount: Option<InstructedAmount>,
+    /// Indication of cross border payment to own account
+    pub is_own_account_transfer: Option<bool>,
+    /// OTP Challenge
+    pub otp_challenge: Option<String>,
+    /// Status of the payment
+    pub payment_status: NordeaPaymentStatus,
+    /// Planned execution date will indicate the day the payment will be finalized. If the payment has been pushed due to cut-off, it will be indicated in planned execution date. Format:date.
+    pub planned_execution_date: Option<String>,
+    /// Recurring information
+    pub recurring: Option<RecurringInformation>,
+    /// Choose a preferred execution date (or leave blank for today's date).
+    /// This should be a valid bank day, and depending on the country the date will either be pushed to the next valid bank day,
+    /// or return an error if a non-banking day date was supplied (all dates accepted in sandbox).
+    /// SEPA: max +5 years from yesterday, Domestic: max. +1 year from yesterday. NB: Not supported for Own transfer Non-Recurring Norway.
+    /// Format:date.
+    pub requested_execution_date: Option<String>,
+    /// Timestamp of payment creation. ISO 8601 format yyyy-mm-ddThh:mm:ss.fffZ Format:date-time.
+    pub timestamp: Option<String>,
+    /// Additional messages for third parties
+    pub tpp_messages: Option<Vec<ThirdPartyMessages>>,
+    pub transaction_fee: Option<Vec<BankFee>>,
+    /// Currency that the cross border payment will be transferred in.
+    /// This field is only supported for cross border payments for DK.
+    /// If this field is not supplied then the payment will use the currency specified for the currency field of instructed_amount.
+    pub transfer_currency: Option<api_models::enums::Currency>,
+    /// Urgency of the payment. NB: This field is supported for DK Domestic ('standard' and 'express') and NO Domestic bank transfer payments ('standard' and 'express').
+    /// Use 'express' for Straksbetaling (Instant payment).
+    /// All other payment types ignore this input.
+    /// For further details on urgencies and cut-offs, refer to the Nordea website.
+    /// Value 'sameday' is marked as deprecated and will be removed in the future.
+    pub urgency: Option<PaymentsUrgency>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaPaymentsInitiateResponse {
+    /// Payment information
+    #[serde(rename = "response")]
+    pub payments_response: Option<NordeaPaymentsInitiateResponseData>,
+    /// External response header
+    pub group_header: Option<NordeaGroupHeader>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaPaymentsConfirmErrorObject {
+    /// Error message
+    pub error: Option<String>,
+    /// Description of the error
+    pub error_description: Option<String>,
+    /// Payment id of the payment, the error is associated with
+    pub payment_id: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaPaymentsResponseWrapper {
+    pub payments: Vec<NordeaPaymentsInitiateResponseData>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaPaymentsConfirmResponse {
+    /// HATEOAS inspired links: 'rel' and 'href'
+    #[serde(rename = "_links")]
+    pub links: Option<Vec<NordeaResponseLinks>>,
+    /// Error description
+    pub errors: Option<Vec<NordeaPaymentsConfirmErrorObject>>,
+    /// External response header
+    pub group_header: Option<NordeaGroupHeader>,
+    /// OTP Challenge
+    pub otp_challenge: Option<String>,
+    #[serde(rename = "response")]
+    pub nordea_payments_response: Option<NordeaPaymentsResponseWrapper>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaOriginalRequest {
+    /// Original request url
+    #[serde(rename = "url")]
+    pub nordea_url: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaFailures {
+    /// Failure code
+    pub code: Option<String>,
+    /// Failure description
+    pub description: Option<String>,
+    /// JSON path of the failing element if applicable
+    pub path: Option<String>,
+    /// Type of the validation error, e.g. NotNull
+    #[serde(rename = "type")]
+    pub failure_type: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaErrorBody {
+    // Serde JSON because connector returns an `(item)` object in failures array object
+    /// More details on the occurred error: Validation error
+    #[serde(rename = "failures")]
+    pub nordea_failures: Option<Vec<NordeaFailures>>,
+    /// Original request information
+    #[serde(rename = "request")]
+    pub nordea_request: Option<NordeaOriginalRequest>,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct NordeaErrorResponse {
+    /// Error response body
+    pub error: Option<NordeaErrorBody>,
+    /// External response header
+    pub group_header: Option<NordeaGroupHeader>,
+    #[serde(rename = "httpCode")]
+    pub http_code: Option<String>,
+    #[serde(rename = "moreInformation")]
+    pub more_information: Option<String>,
+}
+
+// Nordea does not support refunds in Private APIs. Only Corporate APIs support Refunds
diff --git a/crates/hyperswitch_connectors/src/connectors/nordea/transformers.rs b/crates/hyperswitch_connectors/src/connectors/nordea/transformers.rs
index bea06d53e39..6e781e7de9a 100644
--- a/crates/hyperswitch_connectors/src/connectors/nordea/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/nordea/transformers.rs
@@ -1,31 +1,43 @@
-use common_enums::enums;
-use common_utils::types::StringMinorUnit;
+use std::collections::HashMap;
+
+use common_utils::{pii, request::Method, types::StringMajorUnit};
+use error_stack::ResultExt;
 use hyperswitch_domain_models::{
-    payment_method_data::PaymentMethodData,
-    router_data::{ConnectorAuthType, RouterData},
-    router_flow_types::refunds::{Execute, RSync},
-    router_request_types::ResponseId,
-    router_response_types::{PaymentsResponseData, RefundsResponseData},
-    types::{PaymentsAuthorizeRouterData, RefundsRouterData},
+    payment_method_data::{BankDebitData, PaymentMethodData},
+    router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
+    router_flow_types::{Authorize, PreProcessing},
+    router_request_types::{PaymentsAuthorizeData, PaymentsPreProcessingData, ResponseId},
+    router_response_types::{PaymentsResponseData, RedirectForm},
+    types::{
+        self, AccessTokenAuthenticationRouterData, PaymentsAuthorizeRouterData,
+        PaymentsPreProcessingRouterData, PaymentsSyncRouterData,
+    },
 };
 use hyperswitch_interfaces::errors;
 use masking::Secret;
-use serde::{Deserialize, Serialize};
+use rand::distributions::DistString;
+use serde::{Deserialize, Deserializer, Serialize};
 
 use crate::{
-    types::{RefundsResponseRouterData, ResponseRouterData},
-    utils::PaymentsAuthorizeRequestData,
+    connectors::nordea::{
+        requests::{
+            AccessScope, AccountNumber, AccountType, CreditorAccount, CreditorBank, DebitorAccount,
+            GrantType, NordeaOAuthExchangeRequest, NordeaOAuthRequest,
+            NordeaPaymentsConfirmRequest, NordeaPaymentsRequest, NordeaRouterData, PaymentsUrgency,
+        },
+        responses::{
+            NordeaErrorBody, NordeaFailures, NordeaOAuthExchangeResponse, NordeaPaymentStatus,
+            NordeaPaymentsConfirmResponse, NordeaPaymentsInitiateResponse,
+        },
+    },
+    types::{PaymentsSyncResponseRouterData, ResponseRouterData},
+    utils::{self, get_unimplemented_payment_method_error_message, RouterData as _},
 };
 
-//TODO: Fill the struct with respective fields
-pub struct NordeaRouterData<T> {
-    pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
-    pub router_data: T,
-}
+type Error = error_stack::Report<errors::ConnectorError>;
 
-impl<T> From<(StringMinorUnit, T)> for NordeaRouterData<T> {
-    fn from((amount, item): (StringMinorUnit, T)) -> Self {
-        //Todo :  use utils to convert the amount to the type of amount that a connector accepts
+impl<T> From<(StringMajorUnit, T)> for NordeaRouterData<T> {
+    fn from((amount, item): (StringMajorUnit, T)) -> Self {
         Self {
             amount,
             router_data: item,
@@ -33,196 +45,528 @@ impl<T> From<(StringMinorUnit, T)> for NordeaRouterData<T> {
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, PartialEq)]
-pub struct NordeaPaymentsRequest {
-    amount: StringMinorUnit,
-    card: NordeaCard,
-}
-
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
-pub struct NordeaCard {
-    number: cards::CardNumber,
-    expiry_month: Secret<String>,
-    expiry_year: Secret<String>,
-    cvc: Secret<String>,
-    complete: bool,
-}
-
-impl TryFrom<&NordeaRouterData<&PaymentsAuthorizeRouterData>> for NordeaPaymentsRequest {
-    type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(
-        item: &NordeaRouterData<&PaymentsAuthorizeRouterData>,
-    ) -> Result<Self, Self::Error> {
-        match item.router_data.request.payment_method_data.clone() {
-            PaymentMethodData::Card(req_card) => {
-                let card = NordeaCard {
-                    number: req_card.card_number,
-                    expiry_month: req_card.card_exp_month,
-                    expiry_year: req_card.card_exp_year,
-                    cvc: req_card.card_cvc,
-                    complete: item.router_data.request.is_auto_capture()?,
-                };
-                Ok(Self {
-                    amount: item.amount.clone(),
-                    card,
-                })
-            }
-            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
-        }
-    }
-}
-
-//TODO: Fill the struct with respective fields
 // Auth Struct
+#[derive(Debug)]
 pub struct NordeaAuthType {
-    pub(super) api_key: Secret<String>,
+    pub(super) client_id: Secret<String>,
+    pub(super) client_secret: Secret<String>,
+    /// PEM format private key for eIDAS signing
+    /// Should be base64 encoded
+    pub(super) eidas_private_key: Secret<String>,
 }
 
 impl TryFrom<&ConnectorAuthType> for NordeaAuthType {
-    type Error = error_stack::Report<errors::ConnectorError>;
+    type Error = Error;
     fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
         match auth_type {
-            ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
-                api_key: api_key.to_owned(),
+            ConnectorAuthType::SignatureKey {
+                api_key,
+                key1,
+                api_secret,
+            } => Ok(Self {
+                client_id: key1.to_owned(),
+                client_secret: api_key.to_owned(),
+                eidas_private_key: api_secret.to_owned(),
             }),
             _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
         }
     }
 }
-// PaymentsResponse
-//TODO: Append the remaining status flags
-#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "lowercase")]
-pub enum NordeaPaymentStatus {
-    Succeeded,
-    Failed,
-    #[default]
-    Processing,
+
+#[derive(Debug, Default, Serialize, Deserialize)]
+pub struct NordeaConnectorMetadataObject {
+    pub creditor_account_value: Secret<String>,
+    pub creditor_account_type: String,
+    pub creditor_beneficiary_name: Secret<String>,
 }
 
-impl From<NordeaPaymentStatus> for common_enums::AttemptStatus {
-    fn from(item: NordeaPaymentStatus) -> Self {
-        match item {
-            NordeaPaymentStatus::Succeeded => Self::Charged,
-            NordeaPaymentStatus::Failed => Self::Failure,
-            NordeaPaymentStatus::Processing => Self::Authorizing,
-        }
+impl TryFrom<&Option<pii::SecretSerdeValue>> for NordeaConnectorMetadataObject {
+    type Error = Error;
+    fn try_from(meta_data: &Option<pii::SecretSerdeValue>) -> Result<Self, Self::Error> {
+        let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
+            .change_context(errors::ConnectorError::InvalidConnectorConfig {
+                config: "merchant_connector_account.metadata",
+            })?;
+        Ok(metadata)
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct NordeaPaymentsResponse {
-    status: NordeaPaymentStatus,
-    id: String,
+impl TryFrom<&AccessTokenAuthenticationRouterData> for NordeaOAuthRequest {
+    type Error = Error;
+    fn try_from(item: &AccessTokenAuthenticationRouterData) -> Result<Self, Self::Error> {
+        let country = item.get_billing_country()?;
+
+        // Set refresh_token maximum expiry duration to 180 days (259200 / 60 = 180)
+        // Minimum is 1 minute
+        let duration = Some(259200);
+        let maximum_transaction_history = Some(18);
+        let redirect_uri = "https://hyperswitch.io".to_string();
+        let scope = [
+            AccessScope::AccountsBasic,
+            AccessScope::AccountsDetails,
+            AccessScope::AccountsBalances,
+            AccessScope::AccountsTransactions,
+            AccessScope::PaymentsMultiple,
+        ]
+        .to_vec();
+        let state = rand::distributions::Alphanumeric.sample_string(&mut rand::thread_rng(), 15);
+
+        Ok(Self {
+            country,
+            duration,
+            maximum_transaction_history,
+            redirect_uri,
+            scope,
+            state: state.into(),
+        })
+    }
+}
+
+impl TryFrom<&types::RefreshTokenRouterData> for NordeaOAuthExchangeRequest {
+    type Error = Error;
+    fn try_from(item: &types::RefreshTokenRouterData) -> Result<Self, Self::Error> {
+        let code = item
+            .request
+            .authentication_token
+            .as_ref()
+            .ok_or(errors::ConnectorError::MissingRequiredField {
+                field_name: "authorization_code",
+            })?
+            .code
+            .clone();
+        let grant_type = GrantType::AuthorizationCode;
+        let redirect_uri = Some("https://hyperswitch.io".to_string());
+
+        Ok(Self {
+            code: Some(code),
+            grant_type,
+            redirect_uri,
+            refresh_token: None, // We're not using refresh_token to generate new access_token
+        })
+    }
 }
 
-impl<F, T> TryFrom<ResponseRouterData<F, NordeaPaymentsResponse, T, PaymentsResponseData>>
-    for RouterData<F, T, PaymentsResponseData>
+impl<F, T> TryFrom<ResponseRouterData<F, NordeaOAuthExchangeResponse, T, AccessToken>>
+    for RouterData<F, T, AccessToken>
 {
-    type Error = error_stack::Report<errors::ConnectorError>;
+    type Error = Error;
     fn try_from(
-        item: ResponseRouterData<F, NordeaPaymentsResponse, T, PaymentsResponseData>,
+        item: ResponseRouterData<F, NordeaOAuthExchangeResponse, T, AccessToken>,
     ) -> Result<Self, Self::Error> {
+        let access_token =
+            item.response
+                .access_token
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "access_token",
+                })?;
+
+        let expires_in = item.response.expires_in.unwrap_or(3600); // Default to 1 hour if not provided
+
         Ok(Self {
-            status: common_enums::AttemptStatus::from(item.response.status),
-            response: Ok(PaymentsResponseData::TransactionResponse {
-                resource_id: ResponseId::ConnectorTransactionId(item.response.id),
-                redirection_data: Box::new(None),
-                mandate_reference: Box::new(None),
-                connector_metadata: None,
-                network_txn_id: None,
-                connector_response_reference_id: None,
-                incremental_authorization_allowed: None,
-                charges: None,
+            status: common_enums::AttemptStatus::AuthenticationSuccessful,
+            response: Ok(AccessToken {
+                token: access_token.clone(),
+                expires: expires_in,
             }),
             ..item.data
         })
     }
 }
 
-//TODO: Fill the struct with respective fields
-// REFUND :
-// Type definition for RefundRequest
-#[derive(Default, Debug, Serialize)]
-pub struct NordeaRefundRequest {
-    pub amount: StringMinorUnit,
+impl TryFrom<&str> for AccountType {
+    type Error = Error;
+
+    fn try_from(value: &str) -> Result<Self, Self::Error> {
+        match value.to_uppercase().as_str() {
+            "IBAN" => Ok(Self::Iban),
+            "BBAN_SE" => Ok(Self::BbanSe),
+            "BBAN_DK" => Ok(Self::BbanDk),
+            "BBAN_NO" => Ok(Self::BbanNo),
+            "BGNR" => Ok(Self::Bgnr),
+            "PGNR" => Ok(Self::Pgnr),
+            "GIRO_DK" => Ok(Self::GiroDk),
+            "BBAN_OTHER" => Ok(Self::BbanOther),
+            _ => Err(errors::ConnectorError::InvalidConnectorConfig {
+                config: "account_type",
+            }
+            .into()),
+        }
+    }
 }
 
-impl<F> TryFrom<&NordeaRouterData<&RefundsRouterData<F>>> for NordeaRefundRequest {
-    type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(item: &NordeaRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
-        Ok(Self {
-            amount: item.amount.to_owned(),
-        })
+impl<'de> Deserialize<'de> for PaymentsUrgency {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let s = String::deserialize(deserializer)?.to_lowercase();
+        match s.as_str() {
+            "standard" => Ok(Self::Standard),
+            "express" => Ok(Self::Express),
+            "sameday" => Ok(Self::Sameday),
+            _ => Err(serde::de::Error::unknown_variant(
+                &s,
+                &["standard", "express", "sameday"],
+            )),
+        }
+    }
+}
+
+fn get_creditor_account_from_metadata(
+    router_data: &PaymentsPreProcessingRouterData,
+) -> Result<CreditorAccount, Error> {
+    let metadata: NordeaConnectorMetadataObject =
+        utils::to_connector_meta_from_secret(router_data.connector_meta_data.clone())
+            .change_context(errors::ConnectorError::InvalidConnectorConfig {
+                config: "merchant_connector_account.metadata",
+            })?;
+    let creditor_account = CreditorAccount {
+        account: AccountNumber {
+            account_type: AccountType::try_from(metadata.creditor_account_type.as_str())
+                .unwrap_or(AccountType::Iban),
+            currency: router_data.request.currency,
+            value: metadata.creditor_account_value,
+        },
+        country: router_data.get_optional_billing_country(),
+        // Merchant is the beneficiary in this case
+        name: Some(metadata.creditor_beneficiary_name),
+        message: router_data
+            .description
+            .as_ref()
+            .map(|desc| desc.chars().take(20).collect::<String>()),
+        bank: Some(CreditorBank {
+            address: None,
+            bank_code: None,
+            bank_name: None,
+            business_identifier_code: None,
+            country: router_data.get_billing_country()?,
+        }),
+        creditor_address: None,
+        // Either Reference or Message must be supplied in the request
+        reference: None,
+    };
+    Ok(creditor_account)
+}
+
+impl TryFrom<&NordeaRouterData<&PaymentsPreProcessingRouterData>> for NordeaPaymentsRequest {
+    type Error = Error;
+    fn try_from(
+        item: &NordeaRouterData<&PaymentsPreProcessingRouterData>,
+    ) -> Result<Self, Self::Error> {
+        match item.router_data.request.payment_method_data.clone() {
+            Some(PaymentMethodData::BankDebit(bank_debit_data)) => match bank_debit_data {
+                BankDebitData::SepaBankDebit { iban, .. } => {
+                    let creditor_account = get_creditor_account_from_metadata(item.router_data)?;
+                    let debitor_account = DebitorAccount {
+                        account: AccountNumber {
+                            account_type: AccountType::Iban,
+                            currency: item.router_data.request.currency,
+                            value: iban,
+                        },
+                        message: item
+                            .router_data
+                            .description
+                            .as_ref()
+                            .map(|desc| desc.chars().take(20).collect::<String>()),
+                    };
+
+                    let instructed_amount = super::requests::InstructedAmount {
+                        amount: item.amount.clone(),
+                        currency: item.router_data.request.currency.ok_or(
+                            errors::ConnectorError::MissingRequiredField {
+                                field_name: "amount",
+                            },
+                        )?,
+                    };
+
+                    Ok(Self {
+                        creditor_account,
+                        debitor_account,
+                        end_to_end_identification: None,
+                        external_id: Some(item.router_data.connector_request_reference_id.clone()),
+                        instructed_amount,
+                        recurring: None,
+                        request_availability_of_funds: None,
+                        requested_execution_date: None,
+                        tpp_messages: None,
+                        urgency: None,
+                    })
+                }
+                BankDebitData::AchBankDebit { .. }
+                | BankDebitData::BacsBankDebit { .. }
+                | BankDebitData::BecsBankDebit { .. } => {
+                    Err(errors::ConnectorError::NotImplemented(
+                        get_unimplemented_payment_method_error_message("Nordea"),
+                    )
+                    .into())
+                }
+            },
+            Some(PaymentMethodData::CardRedirect(_))
+            | Some(PaymentMethodData::CardDetailsForNetworkTransactionId(_))
+            | Some(PaymentMethodData::Wallet(_))
+            | Some(PaymentMethodData::PayLater(_))
+            | Some(PaymentMethodData::BankRedirect(_))
+            | Some(PaymentMethodData::BankTransfer(_))
+            | Some(PaymentMethodData::Crypto(_))
+            | Some(PaymentMethodData::MandatePayment)
+            | Some(PaymentMethodData::Reward)
+            | Some(PaymentMethodData::RealTimePayment(_))
+            | Some(PaymentMethodData::MobilePayment(_))
+            | Some(PaymentMethodData::Upi(_))
+            | Some(PaymentMethodData::Voucher(_))
+            | Some(PaymentMethodData::GiftCard(_))
+            | Some(PaymentMethodData::OpenBanking(_))
+            | Some(PaymentMethodData::CardToken(_))
+            | Some(PaymentMethodData::NetworkToken(_))
+            | Some(PaymentMethodData::Card(_))
+            | None => {
+                Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into())
+            }
+        }
     }
 }
 
-// Type definition for Refund Response
+impl TryFrom<&NordeaRouterData<&PaymentsAuthorizeRouterData>> for NordeaPaymentsConfirmRequest {
+    type Error = Error;
+    fn try_from(
+        item: &NordeaRouterData<&PaymentsAuthorizeRouterData>,
+    ) -> Result<Self, Self::Error> {
+        let payment_ids = match &item.router_data.response {
+            Ok(response_data) => response_data
+                .get_connector_transaction_id()
+                .map_err(|_| errors::ConnectorError::MissingConnectorTransactionID)?,
+            Err(_) => return Err(errors::ConnectorError::ResponseDeserializationFailed.into()),
+        };
 
-#[allow(dead_code)]
-#[derive(Debug, Serialize, Default, Deserialize, Clone)]
-pub enum RefundStatus {
-    Succeeded,
-    Failed,
-    #[default]
-    Processing,
+        Ok(Self {
+            authentication_method: None,
+            language: None,
+            payments_ids: vec![payment_ids],
+            redirect_url: None,
+            state: None,
+        })
+    }
 }
 
-impl From<RefundStatus> for enums::RefundStatus {
-    fn from(item: RefundStatus) -> Self {
+impl From<NordeaPaymentStatus> for common_enums::AttemptStatus {
+    fn from(item: NordeaPaymentStatus) -> Self {
         match item {
-            RefundStatus::Succeeded => Self::Success,
-            RefundStatus::Failed => Self::Failure,
-            RefundStatus::Processing => Self::Pending,
-            //TODO: Review mapping
+            NordeaPaymentStatus::Confirmed | NordeaPaymentStatus::Paid => Self::Charged,
+
+            NordeaPaymentStatus::PendingConfirmation
+            | NordeaPaymentStatus::PendingSecondConfirmation => Self::ConfirmationAwaited,
+            NordeaPaymentStatus::PendingUserApproval => Self::AuthenticationPending,
+
+            NordeaPaymentStatus::OnHold | NordeaPaymentStatus::Unknown => Self::Pending,
+
+            NordeaPaymentStatus::Rejected
+            | NordeaPaymentStatus::InsufficientFunds
+            | NordeaPaymentStatus::LimitExceeded
+            | NordeaPaymentStatus::UserApprovalFailed
+            | NordeaPaymentStatus::UserApprovalTimeout
+            | NordeaPaymentStatus::UserApprovalCancelled => Self::Failure,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize)]
-pub struct RefundResponse {
-    id: String,
-    status: RefundStatus,
+pub fn get_error_data(error_response: Option<&NordeaErrorBody>) -> Option<&NordeaFailures> {
+    error_response
+        .and_then(|error| error.nordea_failures.as_ref())
+        .and_then(|failures| failures.first())
+}
+
+// Helper function to convert NordeaPaymentsInitiateResponse to common response data
+fn convert_nordea_payment_response(
+    response: &NordeaPaymentsInitiateResponse,
+) -> Result<(PaymentsResponseData, common_enums::AttemptStatus), Error> {
+    let payment_response = response
+        .payments_response
+        .as_ref()
+        .ok_or(errors::ConnectorError::ResponseHandlingFailed)?;
+
+    let resource_id = ResponseId::ConnectorTransactionId(payment_response.payment_id.clone());
+
+    let response_data = PaymentsResponseData::TransactionResponse {
+        resource_id,
+        redirection_data: Box::new(None),
+        mandate_reference: Box::new(None),
+        connector_metadata: None,
+        network_txn_id: None,
+        connector_response_reference_id: payment_response.external_id.clone(),
+        incremental_authorization_allowed: None,
+        charges: None,
+    };
+
+    let status = common_enums::AttemptStatus::from(payment_response.payment_status.clone());
+
+    Ok((response_data, status))
 }
 
-impl TryFrom<RefundsResponseRouterData<Execute, RefundResponse>> for RefundsRouterData<Execute> {
-    type Error = error_stack::Report<errors::ConnectorError>;
+impl
+    TryFrom<
+        ResponseRouterData<
+            PreProcessing,
+            NordeaPaymentsInitiateResponse,
+            PaymentsPreProcessingData,
+            PaymentsResponseData,
+        >,
+    > for RouterData<PreProcessing, PaymentsPreProcessingData, PaymentsResponseData>
+{
+    type Error = Error;
     fn try_from(
-        item: RefundsResponseRouterData<Execute, RefundResponse>,
+        item: ResponseRouterData<
+            PreProcessing,
+            NordeaPaymentsInitiateResponse,
+            PaymentsPreProcessingData,
+            PaymentsResponseData,
+        >,
     ) -> Result<Self, Self::Error> {
+        let (response, status) = convert_nordea_payment_response(&item.response)?;
         Ok(Self {
-            response: Ok(RefundsResponseData {
-                connector_refund_id: item.response.id.to_string(),
-                refund_status: enums::RefundStatus::from(item.response.status),
-            }),
+            status,
+            response: Ok(response),
             ..item.data
         })
     }
 }
 
-impl TryFrom<RefundsResponseRouterData<RSync, RefundResponse>> for RefundsRouterData<RSync> {
-    type Error = error_stack::Report<errors::ConnectorError>;
+impl
+    TryFrom<
+        ResponseRouterData<
+            Authorize,
+            NordeaPaymentsConfirmResponse,
+            PaymentsAuthorizeData,
+            PaymentsResponseData,
+        >,
+    > for RouterData<Authorize, PaymentsAuthorizeData, PaymentsResponseData>
+{
+    type Error = Error;
     fn try_from(
-        item: RefundsResponseRouterData<RSync, RefundResponse>,
+        item: ResponseRouterData<
+            Authorize,
+            NordeaPaymentsConfirmResponse,
+            PaymentsAuthorizeData,
+            PaymentsResponseData,
+        >,
     ) -> Result<Self, Self::Error> {
+        // First check if there are any errors in the response
+        if let Some(errors) = &item.response.errors {
+            if !errors.is_empty() {
+                // Get the first error for the error response
+                let first_error = errors
+                    .first()
+                    .ok_or(errors::ConnectorError::ResponseHandlingFailed)?;
+
+                return Ok(Self {
+                    status: common_enums::AttemptStatus::Failure,
+                    response: Err(ErrorResponse {
+                        code: first_error
+                            .error
+                            .clone()
+                            .unwrap_or_else(|| "UNKNOWN_ERROR".to_string()),
+                        message: first_error
+                            .error_description
+                            .clone()
+                            .unwrap_or_else(|| "Payment confirmation failed".to_string()),
+                        reason: first_error.error_description.clone(),
+                        status_code: item.http_code,
+                        attempt_status: Some(common_enums::AttemptStatus::Failure),
+                        connector_transaction_id: first_error.payment_id.clone(),
+                        network_advice_code: None,
+                        network_decline_code: None,
+                        network_error_message: None,
+                    }),
+                    ..item.data
+                });
+            }
+        }
+
+        // If no errors, proceed with normal response handling
+        // Check if there's a redirect link at the top level only
+        let redirection_data = item
+            .response
+            .links
+            .as_ref()
+            .and_then(|links| {
+                links.iter().find(|link| {
+                    link.rel
+                        .as_ref()
+                        .map(|rel| rel == "signing")
+                        .unwrap_or(false)
+                })
+            })
+            .and_then(|link| link.href.clone())
+            .map(|redirect_url| RedirectForm::Form {
+                endpoint: redirect_url,
+                method: Method::Get,
+                form_fields: HashMap::new(),
+            });
+
+        let (response, status) = match &item.response.nordea_payments_response {
+            Some(payment_response_wrapper) => {
+                // Get the first payment from the payments array
+                let payment = payment_response_wrapper
+                    .payments
+                    .first()
+                    .ok_or(errors::ConnectorError::ResponseHandlingFailed)?;
+
+                let resource_id = ResponseId::ConnectorTransactionId(payment.payment_id.clone());
+
+                let response = Ok(PaymentsResponseData::TransactionResponse {
+                    resource_id,
+                    redirection_data: Box::new(redirection_data),
+                    mandate_reference: Box::new(None),
+                    connector_metadata: None,
+                    network_txn_id: None,
+                    connector_response_reference_id: payment.external_id.clone(),
+                    incremental_authorization_allowed: None,
+                    charges: None,
+                });
+
+                let status = common_enums::AttemptStatus::from(payment.payment_status.clone());
+
+                (response, status)
+            }
+            None => {
+                // No payment response, but we might still have a redirect link
+                if let Some(redirect) = redirection_data {
+                    let response = Ok(PaymentsResponseData::TransactionResponse {
+                        resource_id: ResponseId::NoResponseId,
+                        redirection_data: Box::new(Some(redirect)),
+                        mandate_reference: Box::new(None),
+                        connector_metadata: None,
+                        network_txn_id: None,
+                        connector_response_reference_id: None,
+                        incremental_authorization_allowed: None,
+                        charges: None,
+                    });
+                    (response, common_enums::AttemptStatus::AuthenticationPending)
+                } else {
+                    return Err(errors::ConnectorError::ResponseHandlingFailed.into());
+                }
+            }
+        };
+
         Ok(Self {
-            response: Ok(RefundsResponseData {
-                connector_refund_id: item.response.id.to_string(),
-                refund_status: enums::RefundStatus::from(item.response.status),
-            }),
+            status,
+            response,
             ..item.data
         })
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
-pub struct NordeaErrorResponse {
-    pub status_code: u16,
-    pub code: String,
-    pub message: String,
-    pub reason: Option<String>,
+impl TryFrom<PaymentsSyncResponseRouterData<NordeaPaymentsInitiateResponse>>
+    for PaymentsSyncRouterData
+{
+    type Error = Error;
+    fn try_from(
+        item: PaymentsSyncResponseRouterData<NordeaPaymentsInitiateResponse>,
+    ) -> Result<Self, Self::Error> {
+        let (response, status) = convert_nordea_payment_response(&item.response)?;
+        Ok(Self {
+            status,
+            response: Ok(response),
+            ..item.data
+        })
+    }
 }
diff --git a/crates/hyperswitch_connectors/src/default_implementations.rs b/crates/hyperswitch_connectors/src/default_implementations.rs
index 7df691d95ab..484f20cf8df 100644
--- a/crates/hyperswitch_connectors/src/default_implementations.rs
+++ b/crates/hyperswitch_connectors/src/default_implementations.rs
@@ -24,25 +24,8 @@ use hyperswitch_domain_models::router_response_types::revenue_recovery::{
     BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
     RevenueRecoveryRecordBackResponse,
 };
-#[cfg(feature = "frm")]
-use hyperswitch_domain_models::{
-    router_flow_types::fraud_check::{Checkout, Fulfillment, RecordReturn, Sale, Transaction},
-    router_request_types::fraud_check::{
-        FraudCheckCheckoutData, FraudCheckFulfillmentData, FraudCheckRecordReturnData,
-        FraudCheckSaleData, FraudCheckTransactionData,
-    },
-    router_response_types::fraud_check::FraudCheckResponseData,
-};
-#[cfg(feature = "payouts")]
-use hyperswitch_domain_models::{
-    router_flow_types::payouts::{
-        PoCancel, PoCreate, PoEligibility, PoFulfill, PoQuote, PoRecipient, PoRecipientAccount,
-        PoSync,
-    },
-    router_request_types::PayoutsData,
-    router_response_types::PayoutsResponseData,
-};
 use hyperswitch_domain_models::{
+    router_data::AccessTokenAuthenticationResponse,
     router_flow_types::{
         authentication::{
             Authentication, PostAuthentication, PreAuthentication, PreAuthenticationVersionCall,
@@ -57,8 +40,9 @@ use hyperswitch_domain_models::{
             UpdateMetadata,
         },
         webhooks::VerifyWebhookSource,
-        Authenticate, AuthenticationConfirmation, ExternalVaultCreateFlow, ExternalVaultDeleteFlow,
-        ExternalVaultInsertFlow, ExternalVaultRetrieveFlow, PostAuthenticate, PreAuthenticate,
+        AccessTokenAuthentication, Authenticate, AuthenticationConfirmation,
+        ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow,
+        ExternalVaultRetrieveFlow, PostAuthenticate, PreAuthenticate,
     },
     router_request_types::{
         authentication,
@@ -67,14 +51,15 @@ use hyperswitch_domain_models::{
             UasConfirmationRequestData, UasPostAuthenticationRequestData,
             UasPreAuthenticationRequestData,
         },
-        AcceptDisputeRequestData, AuthorizeSessionTokenData, CompleteAuthorizeData,
-        ConnectorCustomerData, CreateOrderRequestData, DefendDisputeRequestData, DisputeSyncData,
-        FetchDisputesRequestData, MandateRevokeRequestData, PaymentsApproveData,
-        PaymentsCancelPostCaptureData, PaymentsIncrementalAuthorizationData,
-        PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreProcessingData,
-        PaymentsRejectData, PaymentsTaxCalculationData, PaymentsUpdateMetadataData,
-        RetrieveFileRequestData, SdkPaymentsSessionUpdateData, SubmitEvidenceRequestData,
-        UploadFileRequestData, VaultRequestData, VerifyWebhookSourceRequestData,
+        AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AuthorizeSessionTokenData,
+        CompleteAuthorizeData, ConnectorCustomerData, CreateOrderRequestData,
+        DefendDisputeRequestData, DisputeSyncData, FetchDisputesRequestData,
+        MandateRevokeRequestData, PaymentsApproveData, PaymentsCancelPostCaptureData,
+        PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
+        PaymentsPostSessionTokensData, PaymentsPreProcessingData, PaymentsRejectData,
+        PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RetrieveFileRequestData,
+        SdkPaymentsSessionUpdateData, SubmitEvidenceRequestData, UploadFileRequestData,
+        VaultRequestData, VerifyWebhookSourceRequestData,
     },
     router_response_types::{
         AcceptDisputeResponse, AuthenticationResponseData, DefendDisputeResponse,
@@ -85,6 +70,24 @@ use hyperswitch_domain_models::{
     },
 };
 #[cfg(feature = "frm")]
+use hyperswitch_domain_models::{
+    router_flow_types::fraud_check::{Checkout, Fulfillment, RecordReturn, Sale, Transaction},
+    router_request_types::fraud_check::{
+        FraudCheckCheckoutData, FraudCheckFulfillmentData, FraudCheckRecordReturnData,
+        FraudCheckSaleData, FraudCheckTransactionData,
+    },
+    router_response_types::fraud_check::FraudCheckResponseData,
+};
+#[cfg(feature = "payouts")]
+use hyperswitch_domain_models::{
+    router_flow_types::payouts::{
+        PoCancel, PoCreate, PoEligibility, PoFulfill, PoQuote, PoRecipient, PoRecipientAccount,
+        PoSync,
+    },
+    router_request_types::PayoutsData,
+    router_response_types::PayoutsResponseData,
+};
+#[cfg(feature = "frm")]
 use hyperswitch_interfaces::api::fraud_check::{
     FraudCheck, FraudCheckCheckout, FraudCheckFulfillment, FraudCheckRecordReturn, FraudCheckSale,
     FraudCheckTransaction,
@@ -124,9 +127,10 @@ use hyperswitch_interfaces::{
             ExternalVault, ExternalVaultCreate, ExternalVaultDelete, ExternalVaultInsert,
             ExternalVaultRetrieve,
         },
-        ConnectorIntegration, ConnectorMandateRevoke, ConnectorRedirectResponse,
-        ConnectorTransactionId, UasAuthentication, UasAuthenticationConfirmation,
-        UasPostAuthentication, UasPreAuthentication, UnifiedAuthenticationService,
+        ConnectorAuthenticationToken, ConnectorIntegration, ConnectorMandateRevoke,
+        ConnectorRedirectResponse, ConnectorTransactionId, UasAuthentication,
+        UasAuthenticationConfirmation, UasPostAuthentication, UasPreAuthentication,
+        UnifiedAuthenticationService,
     },
     errors::ConnectorError,
 };
@@ -1703,7 +1707,6 @@ default_imp_for_pre_processing_steps!(
     connectors::Netcetera,
     connectors::Nomupay,
     connectors::Noon,
-    connectors::Nordea,
     connectors::Novalnet,
     connectors::Nexinets,
     connectors::Opayo,
@@ -7499,6 +7502,146 @@ default_imp_for_external_vault_create!(
     connectors::Zsl
 );
 
+macro_rules! default_imp_for_connector_authentication_token {
+    ($($path:ident::$connector:ident),*) => {
+        $(
+            impl ConnectorAuthenticationToken for $path::$connector {}
+            impl
+            ConnectorIntegration<
+            AccessTokenAuthentication,
+            AccessTokenAuthenticationRequestData,
+            AccessTokenAuthenticationResponse,
+        > for $path::$connector
+        {}
+    )*
+    };
+}
+
+default_imp_for_connector_authentication_token!(
+    connectors::Aci,
+    connectors::Adyen,
+    connectors::Adyenplatform,
+    connectors::Affirm,
+    connectors::Airwallex,
+    connectors::Amazonpay,
+    connectors::Archipel,
+    connectors::Authipay,
+    connectors::Authorizedotnet,
+    connectors::Barclaycard,
+    connectors::Bambora,
+    connectors::Bamboraapac,
+    connectors::Bankofamerica,
+    connectors::Billwerk,
+    connectors::Bitpay,
+    connectors::Bluecode,
+    connectors::Bluesnap,
+    connectors::Blackhawknetwork,
+    connectors::Boku,
+    connectors::Braintree,
+    connectors::Breadpay,
+    connectors::Cashtocode,
+    connectors::Celero,
+    connectors::Chargebee,
+    connectors::Checkbook,
+    connectors::Checkout,
+    connectors::Coinbase,
+    connectors::Coingate,
+    connectors::Cryptopay,
+    connectors::CtpMastercard,
+    connectors::Custombilling,
+    connectors::Cybersource,
+    connectors::Datatrans,
+    connectors::Deutschebank,
+    connectors::Digitalvirgo,
+    connectors::Dlocal,
+    connectors::Dwolla,
+    connectors::Ebanx,
+    connectors::Elavon,
+    connectors::Facilitapay,
+    connectors::Fiserv,
+    connectors::Fiservemea,
+    connectors::Fiuu,
+    connectors::Flexiti,
+    connectors::Forte,
+    connectors::Getnet,
+    connectors::Globalpay,
+    connectors::Globepay,
+    connectors::Gocardless,
+    connectors::Gpayments,
+    connectors::Helcim,
+    connectors::Hipay,
+    connectors::HyperswitchVault,
+    connectors::Iatapay,
+    connectors::Inespay,
+    connectors::Itaubank,
+    connectors::Juspaythreedsserver,
+    connectors::Jpmorgan,
+    connectors::Katapult,
+    connectors::Klarna,
+    connectors::Mpgs,
+    connectors::Netcetera,
+    connectors::Nomupay,
+    connectors::Nmi,
+    connectors::Noon,
+    connectors::Novalnet,
+    connectors::Nexinets,
+    connectors::Nexixpay,
+    connectors::Nuvei,
+    connectors::Opayo,
+    connectors::Opennode,
+    connectors::Payeezy,
+    connectors::Payload,
+    connectors::Paystack,
+    connectors::Paytm,
+    connectors::Payu,
+    connectors::Phonepe,
+    connectors::Paypal,
+    connectors::Plaid,
+    connectors::Powertranz,
+    connectors::Prophetpay,
+    connectors::Mifinity,
+    connectors::Mollie,
+    connectors::Moneris,
+    connectors::Multisafepay,
+    connectors::Paybox,
+    connectors::Payme,
+    connectors::Payone,
+    connectors::Placetopay,
+    connectors::Rapyd,
+    connectors::Razorpay,
+    connectors::Recurly,
+    connectors::Redsys,
+    connectors::Riskified,
+    connectors::Santander,
+    connectors::Sift,
+    connectors::Signifyd,
+    connectors::Shift4,
+    connectors::Silverflow,
+    connectors::Stax,
+    connectors::Stripe,
+    connectors::Stripebilling,
+    connectors::Square,
+    connectors::Taxjar,
+    connectors::Threedsecureio,
+    connectors::Thunes,
+    connectors::Tokenio,
+    connectors::Trustpay,
+    connectors::Trustpayments,
+    connectors::Tsys,
+    connectors::UnifiedAuthenticationService,
+    connectors::Wise,
+    connectors::Worldline,
+    connectors::Worldpay,
+    connectors::Worldpayvantiv,
+    connectors::Worldpayxml,
+    connectors::Wellsfargo,
+    connectors::Vgs,
+    connectors::Volt,
+    connectors::Xendit,
+    connectors::Zen,
+    connectors::Zsl
+);
+
 #[cfg(feature = "dummy_connector")]
 impl<const T: u8> PaymentsCompleteAuthorize for connectors::DummyConnector<T> {}
 #[cfg(feature = "dummy_connector")]
@@ -8026,3 +8169,15 @@ impl<const T: u8> ConnectorIntegration<ExternalVaultCreateFlow, VaultRequestData
     for connectors::DummyConnector<T>
 {
 }
+
+#[cfg(feature = "dummy_connector")]
+impl<const T: u8> ConnectorAuthenticationToken for connectors::DummyConnector<T> {}
+#[cfg(feature = "dummy_connector")]
+impl<const T: u8>
+    ConnectorIntegration<
+        AccessTokenAuthentication,
+        AccessTokenAuthenticationRequestData,
+        AccessTokenAuthenticationResponse,
+    > for connectors::DummyConnector<T>
+{
+}
diff --git a/crates/hyperswitch_connectors/src/default_implementations_v2.rs b/crates/hyperswitch_connectors/src/default_implementations_v2.rs
index 69166f3e01f..046aba87b0a 100644
--- a/crates/hyperswitch_connectors/src/default_implementations_v2.rs
+++ b/crates/hyperswitch_connectors/src/default_implementations_v2.rs
@@ -1,12 +1,13 @@
 use hyperswitch_domain_models::{
-    router_data::AccessToken,
+    router_data::{AccessToken, AccessTokenAuthenticationResponse},
     router_data_v2::{
         flow_common_types::{
             BillingConnectorInvoiceSyncFlowData, BillingConnectorPaymentsSyncFlowData,
             DisputesFlowData, MandateRevokeFlowData, PaymentFlowData, RefundFlowData,
             RevenueRecoveryRecordBackData, WebhookSourceVerifyData,
         },
-        AccessTokenFlowData, ExternalAuthenticationFlowData, FilesFlowData, VaultConnectorFlowData,
+        AccessTokenFlowData, AuthenticationTokenFlowData, ExternalAuthenticationFlowData,
+        FilesFlowData, VaultConnectorFlowData,
     },
     router_flow_types::{
         authentication::{
@@ -26,8 +27,8 @@ use hyperswitch_domain_models::{
             BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, RecoveryRecordBack,
         },
         webhooks::VerifyWebhookSource,
-        AccessTokenAuth, ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow,
-        ExternalVaultRetrieveFlow,
+        AccessTokenAuth, AccessTokenAuthentication, ExternalVaultCreateFlow,
+        ExternalVaultDeleteFlow, ExternalVaultInsertFlow, ExternalVaultRetrieveFlow,
     },
     router_request_types::{
         authentication,
@@ -35,14 +36,14 @@ use hyperswitch_domain_models::{
             BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
             RevenueRecoveryRecordBackRequest,
         },
-        AcceptDisputeRequestData, AccessTokenRequestData, AuthorizeSessionTokenData,
-        CompleteAuthorizeData, ConnectorCustomerData, CreateOrderRequestData,
-        DefendDisputeRequestData, DisputeSyncData, FetchDisputesRequestData,
-        MandateRevokeRequestData, PaymentMethodTokenizationData, PaymentsApproveData,
-        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
-        PaymentsCaptureData, PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
-        PaymentsPostSessionTokensData, PaymentsPreProcessingData, PaymentsRejectData,
-        PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
+        AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AccessTokenRequestData,
+        AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
+        CreateOrderRequestData, DefendDisputeRequestData, DisputeSyncData,
+        FetchDisputesRequestData, MandateRevokeRequestData, PaymentMethodTokenizationData,
+        PaymentsApproveData, PaymentsAuthorizeData, PaymentsCancelData,
+        PaymentsCancelPostCaptureData, PaymentsCaptureData, PaymentsIncrementalAuthorizationData,
+        PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreProcessingData,
+        PaymentsRejectData, PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
         PaymentsUpdateMetadataData, RefundsData, RetrieveFileRequestData,
         SdkPaymentsSessionUpdateData, SetupMandateRequestData, SubmitEvidenceRequestData,
         UploadFileRequestData, VaultRequestData, VerifyWebhookSourceRequestData,
@@ -118,7 +119,8 @@ use hyperswitch_interfaces::{
             ExternalVaultCreateV2, ExternalVaultDeleteV2, ExternalVaultInsertV2,
             ExternalVaultRetrieveV2, ExternalVaultV2,
         },
-        ConnectorAccessTokenV2, ConnectorMandateRevokeV2, ConnectorVerifyWebhookSourceV2,
+        ConnectorAccessTokenV2, ConnectorAuthenticationTokenV2, ConnectorMandateRevokeV2,
+        ConnectorVerifyWebhookSourceV2,
     },
     connector_integration_v2::ConnectorIntegrationV2,
 };
@@ -524,6 +526,136 @@ default_imp_for_new_connector_integration_refund!(
     connectors::Zsl
 );
 
+macro_rules! default_imp_for_new_connector_integration_connector_authentication_token {
+    ($($path:ident::$connector:ident),*) => {
+        $(
+            impl ConnectorAuthenticationTokenV2 for $path::$connector{}
+            impl
+            ConnectorIntegrationV2<AccessTokenAuthentication, AuthenticationTokenFlowData, AccessTokenAuthenticationRequestData, AccessTokenAuthenticationResponse,>
+            for $path::$connector{}
+    )*
+    };
+}
+
+default_imp_for_new_connector_integration_connector_authentication_token!(
+    connectors::Vgs,
+    connectors::Aci,
+    connectors::Adyen,
+    connectors::Adyenplatform,
+    connectors::Affirm,
+    connectors::Airwallex,
+    connectors::Amazonpay,
+    connectors::Authipay,
+    connectors::Authorizedotnet,
+    connectors::Bambora,
+    connectors::Bamboraapac,
+    connectors::Bankofamerica,
+    connectors::Barclaycard,
+    connectors::Billwerk,
+    connectors::Bitpay,
+    connectors::Blackhawknetwork,
+    connectors::Bluesnap,
+    connectors::Boku,
+    connectors::Braintree,
+    connectors::Breadpay,
+    connectors::Cashtocode,
+    connectors::Celero,
+    connectors::Chargebee,
+    connectors::Checkbook,
+    connectors::Checkout,
+    connectors::Coinbase,
+    connectors::Coingate,
+    connectors::Cryptopay,
+    connectors::CtpMastercard,
+    connectors::Custombilling,
+    connectors::Cybersource,
+    connectors::Datatrans,
+    connectors::Deutschebank,
+    connectors::Digitalvirgo,
+    connectors::Dlocal,
+    connectors::Dwolla,
+    connectors::Ebanx,
+    connectors::Elavon,
+    connectors::Facilitapay,
+    connectors::Fiserv,
+    connectors::Fiservemea,
+    connectors::Fiuu,
+    connectors::Forte,
+    connectors::Getnet,
+    connectors::Globalpay,
+    connectors::Globepay,
+    connectors::Gocardless,
+    connectors::Gpayments,
+    connectors::Hipay,
+    connectors::Helcim,
+    connectors::HyperswitchVault,
+    connectors::Iatapay,
+    connectors::Inespay,
+    connectors::Itaubank,
+    connectors::Jpmorgan,
+    connectors::Juspaythreedsserver,
+    connectors::Klarna,
+    connectors::Nomupay,
+    connectors::Noon,
+    connectors::Nordea,
+    connectors::Novalnet,
+    connectors::Netcetera,
+    connectors::Nexinets,
+    connectors::Nexixpay,
+    connectors::Nmi,
+    connectors::Payone,
+    connectors::Opayo,
+    connectors::Opennode,
+    connectors::Nuvei,
+    connectors::Paybox,
+    connectors::Payeezy,
+    connectors::Payload,
+    connectors::Payme,
+    connectors::Paypal,
+    connectors::Paystack,
+    connectors::Payu,
+    connectors::Placetopay,
+    connectors::Plaid,
+    connectors::Powertranz,
+    connectors::Prophetpay,
+    connectors::Mifinity,
+    connectors::Mollie,
+    connectors::Moneris,
+    connectors::Multisafepay,
+    connectors::Rapyd,
+    connectors::Razorpay,
+    connectors::Recurly,
+    connectors::Redsys,
+    connectors::Riskified,
+    connectors::Santander,
+    connectors::Shift4,
+    connectors::Sift,
+    connectors::Silverflow,
+    connectors::Signifyd,
+    connectors::Stax,
+    connectors::Stripe,
+    connectors::Square,
+    connectors::Stripebilling,
+    connectors::Taxjar,
+    connectors::Threedsecureio,
+    connectors::Thunes,
+    connectors::Tokenio,
+    connectors::Trustpay,
+    connectors::Tsys,
+    connectors::UnifiedAuthenticationService,
+    connectors::Wise,
+    connectors::Worldline,
+    connectors::Volt,
+    connectors::Worldpay,
+    connectors::Worldpayvantiv,
+    connectors::Worldpayxml,
+    connectors::Wellsfargo,
+    connectors::Wellsfargopayout,
+    connectors::Xendit,
+    connectors::Zen,
+    connectors::Zsl
+);
+
 macro_rules! default_imp_for_new_connector_integration_connector_access_token {
     ($($path:ident::$connector:ident),*) => {
         $(
diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs
index 13998ed6612..743c04aad72 100644
--- a/crates/hyperswitch_connectors/src/utils.rs
+++ b/crates/hyperswitch_connectors/src/utils.rs
@@ -1696,6 +1696,7 @@ pub trait PaymentsAuthorizeRequestData {
     fn get_connector_mandate_id(&self) -> Result<String, Error>;
     fn get_complete_authorize_url(&self) -> Result<String, Error>;
     fn get_ip_address_as_optional(&self) -> Option<Secret<String, IpAddress>>;
+    fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error>;
     fn get_optional_user_agent(&self) -> Option<String>;
     fn get_original_amount(&self) -> i64;
     fn get_surcharge_amount(&self) -> Option<i64>;
@@ -1818,6 +1819,16 @@ impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData {
                 .map(|ip| Secret::new(ip.to_string()))
         })
     }
+    fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error> {
+        let ip_address = self
+            .browser_info
+            .clone()
+            .and_then(|browser_info| browser_info.ip_address);
+
+        let val = ip_address.ok_or_else(missing_field_err("browser_info.ip_address"))?;
+
+        Ok(Secret::new(val.to_string()))
+    }
     fn get_optional_user_agent(&self) -> Option<String> {
         self.browser_info
             .clone()
diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs
index f8613275034..d3b6883571e 100644
--- a/crates/hyperswitch_domain_models/src/router_data.rs
+++ b/crates/hyperswitch_domain_models/src/router_data.rs
@@ -258,6 +258,12 @@ impl ConnectorAuthType {
     }
 }
 
+#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
+pub struct AccessTokenAuthenticationResponse {
+    pub code: Secret<String>,
+    pub expires: i64,
+}
+
 #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
 pub struct AccessToken {
     pub token: Secret<String>,
diff --git a/crates/hyperswitch_domain_models/src/router_data_v2.rs b/crates/hyperswitch_domain_models/src/router_data_v2.rs
index d6498c962ef..60b6070da0d 100644
--- a/crates/hyperswitch_domain_models/src/router_data_v2.rs
+++ b/crates/hyperswitch_domain_models/src/router_data_v2.rs
@@ -8,9 +8,9 @@ pub use flow_common_types::FrmFlowData;
 #[cfg(feature = "payouts")]
 pub use flow_common_types::PayoutFlowData;
 pub use flow_common_types::{
-    AccessTokenFlowData, DisputesFlowData, ExternalAuthenticationFlowData, FilesFlowData,
-    MandateRevokeFlowData, PaymentFlowData, RefundFlowData, UasFlowData, VaultConnectorFlowData,
-    WebhookSourceVerifyData,
+    AccessTokenFlowData, AuthenticationTokenFlowData, DisputesFlowData,
+    ExternalAuthenticationFlowData, FilesFlowData, MandateRevokeFlowData, PaymentFlowData,
+    RefundFlowData, UasFlowData, VaultConnectorFlowData, WebhookSourceVerifyData,
 };
 
 use crate::router_data::{ConnectorAuthType, ErrorResponse};
diff --git a/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs b/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs
index 5bc18dc8af2..3fe6e85bdab 100644
--- a/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs
@@ -132,6 +132,9 @@ pub struct WebhookSourceVerifyData {
     pub merchant_id: common_utils::id_type::MerchantId,
 }
 
+#[derive(Debug, Clone)]
+pub struct AuthenticationTokenFlowData {}
+
 #[derive(Debug, Clone)]
 pub struct AccessTokenFlowData {}
 
diff --git a/crates/hyperswitch_domain_models/src/router_flow_types/access_token_auth.rs b/crates/hyperswitch_domain_models/src/router_flow_types/access_token_auth.rs
index dd45ca9ca37..66c940e5ec2 100644
--- a/crates/hyperswitch_domain_models/src/router_flow_types/access_token_auth.rs
+++ b/crates/hyperswitch_domain_models/src/router_flow_types/access_token_auth.rs
@@ -1,2 +1,5 @@
+#[derive(Clone, Debug)]
+pub struct AccessTokenAuthentication;
+
 #[derive(Clone, Debug)]
 pub struct AccessTokenAuth;
diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs
index 8d1bf9ffaa5..142d2633fcc 100644
--- a/crates/hyperswitch_domain_models/src/router_request_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_request_types.rs
@@ -16,7 +16,7 @@ use crate::{
     address,
     errors::api_error_response::ApiErrorResponse,
     mandates, payments,
-    router_data::{self, RouterData},
+    router_data::{self, AccessTokenAuthenticationResponse, RouterData},
     router_flow_types as flows, router_response_types as response_types,
     vault::PaymentMethodVaultingData,
 };
@@ -813,13 +813,29 @@ pub struct DestinationChargeRefund {
     pub revert_transfer: bool,
 }
 
+#[derive(Debug, Clone)]
+pub struct AccessTokenAuthenticationRequestData {
+    pub auth_creds: router_data::ConnectorAuthType,
+}
+
+impl TryFrom<router_data::ConnectorAuthType> for AccessTokenAuthenticationRequestData {
+    type Error = ApiErrorResponse;
+    fn try_from(connector_auth: router_data::ConnectorAuthType) -> Result<Self, Self::Error> {
+        Ok(Self {
+            auth_creds: connector_auth,
+        })
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct AccessTokenRequestData {
     pub app_id: Secret<String>,
     pub id: Option<Secret<String>>,
+    pub authentication_token: Option<AccessTokenAuthenticationResponse>,
     // Add more keys if required
 }
 
+// This is for backward compatibility
 impl TryFrom<router_data::ConnectorAuthType> for AccessTokenRequestData {
     type Error = ApiErrorResponse;
     fn try_from(connector_auth: router_data::ConnectorAuthType) -> Result<Self, Self::Error> {
@@ -827,18 +843,22 @@ impl TryFrom<router_data::ConnectorAuthType> for AccessTokenRequestData {
             router_data::ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
                 app_id: api_key,
                 id: None,
+                authentication_token: None,
             }),
             router_data::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
                 app_id: api_key,
                 id: Some(key1),
+                authentication_token: None,
             }),
             router_data::ConnectorAuthType::SignatureKey { api_key, key1, .. } => Ok(Self {
                 app_id: api_key,
                 id: Some(key1),
+                authentication_token: None,
             }),
             router_data::ConnectorAuthType::MultiAuthKey { api_key, key1, .. } => Ok(Self {
                 app_id: api_key,
                 id: Some(key1),
+                authentication_token: None,
             }),
 
             _ => Err(ApiErrorResponse::InvalidDataValue {
@@ -848,6 +868,25 @@ impl TryFrom<router_data::ConnectorAuthType> for AccessTokenRequestData {
     }
 }
 
+impl
+    TryFrom<(
+        router_data::ConnectorAuthType,
+        Option<AccessTokenAuthenticationResponse>,
+    )> for AccessTokenRequestData
+{
+    type Error = ApiErrorResponse;
+    fn try_from(
+        (connector_auth, authentication_token): (
+            router_data::ConnectorAuthType,
+            Option<AccessTokenAuthenticationResponse>,
+        ),
+    ) -> Result<Self, Self::Error> {
+        let mut access_token_request_data = Self::try_from(connector_auth)?;
+        access_token_request_data.authentication_token = authentication_token;
+        Ok(access_token_request_data)
+    }
+}
+
 #[derive(Default, Debug, Clone)]
 pub struct AcceptDisputeRequestData {
     pub dispute_id: String,
diff --git a/crates/hyperswitch_domain_models/src/types.rs b/crates/hyperswitch_domain_models/src/types.rs
index 2dc507cf200..6036bdcca58 100644
--- a/crates/hyperswitch_domain_models/src/types.rs
+++ b/crates/hyperswitch_domain_models/src/types.rs
@@ -1,16 +1,16 @@
 pub use diesel_models::types::OrderDetailsWithAmount;
 
 use crate::{
-    router_data::{AccessToken, RouterData},
+    router_data::{AccessToken, AccessTokenAuthenticationResponse, RouterData},
     router_data_v2::{self, RouterDataV2},
     router_flow_types::{
         mandate_revoke::MandateRevoke, revenue_recovery::RecoveryRecordBack, AccessTokenAuth,
-        Authenticate, AuthenticationConfirmation, Authorize, AuthorizeSessionToken,
-        BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, CalculateTax, Capture,
-        CompleteAuthorize, CreateConnectorCustomer, CreateOrder, Execute, IncrementalAuthorization,
-        PSync, PaymentMethodToken, PostAuthenticate, PostCaptureVoid, PostSessionTokens,
-        PreAuthenticate, PreProcessing, RSync, SdkSessionUpdate, Session, SetupMandate,
-        UpdateMetadata, VerifyWebhookSource, Void,
+        AccessTokenAuthentication, Authenticate, AuthenticationConfirmation, Authorize,
+        AuthorizeSessionToken, BillingConnectorInvoiceSync, BillingConnectorPaymentsSync,
+        CalculateTax, Capture, CompleteAuthorize, CreateConnectorCustomer, CreateOrder, Execute,
+        IncrementalAuthorization, PSync, PaymentMethodToken, PostAuthenticate, PostCaptureVoid,
+        PostSessionTokens, PreAuthenticate, PreProcessing, RSync, SdkSessionUpdate, Session,
+        SetupMandate, UpdateMetadata, VerifyWebhookSource, Void,
     },
     router_request_types::{
         revenue_recovery::{
@@ -22,12 +22,13 @@ use crate::{
             UasConfirmationRequestData, UasPostAuthenticationRequestData,
             UasPreAuthenticationRequestData,
         },
-        AccessTokenRequestData, AuthorizeSessionTokenData, CompleteAuthorizeData,
-        ConnectorCustomerData, CreateOrderRequestData, MandateRevokeRequestData,
-        PaymentMethodTokenizationData, PaymentsAuthorizeData, PaymentsCancelData,
-        PaymentsCancelPostCaptureData, PaymentsCaptureData, PaymentsIncrementalAuthorizationData,
-        PaymentsPostSessionTokensData, PaymentsPreProcessingData, PaymentsSessionData,
-        PaymentsSyncData, PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData,
+        AccessTokenAuthenticationRequestData, AccessTokenRequestData, AuthorizeSessionTokenData,
+        CompleteAuthorizeData, ConnectorCustomerData, CreateOrderRequestData,
+        MandateRevokeRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData,
+        PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
+        PaymentsIncrementalAuthorizationData, PaymentsPostSessionTokensData,
+        PaymentsPreProcessingData, PaymentsSessionData, PaymentsSyncData,
+        PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData,
         SdkPaymentsSessionUpdateData, SetupMandateRequestData, VaultRequestData,
         VerifyWebhookSourceRequestData,
     },
@@ -67,6 +68,11 @@ pub type PaymentsCompleteAuthorizeRouterData =
     RouterData<CompleteAuthorize, CompleteAuthorizeData, PaymentsResponseData>;
 pub type PaymentsTaxCalculationRouterData =
     RouterData<CalculateTax, PaymentsTaxCalculationData, TaxCalculationResponseData>;
+pub type AccessTokenAuthenticationRouterData = RouterData<
+    AccessTokenAuthentication,
+    AccessTokenAuthenticationRequestData,
+    AccessTokenAuthenticationResponse,
+>;
 pub type RefreshTokenRouterData = RouterData<AccessTokenAuth, AccessTokenRequestData, AccessToken>;
 pub type PaymentsPostSessionTokensRouterData =
     RouterData<PostSessionTokens, PaymentsPostSessionTokensData, PaymentsResponseData>;
diff --git a/crates/hyperswitch_interfaces/src/api.rs b/crates/hyperswitch_interfaces/src/api.rs
index 70d1bc2c1b6..6efc23c3c3d 100644
--- a/crates/hyperswitch_interfaces/src/api.rs
+++ b/crates/hyperswitch_interfaces/src/api.rs
@@ -40,14 +40,17 @@ use hyperswitch_domain_models::{
     connector_endpoints::Connectors,
     errors::api_error_response::ApiErrorResponse,
     payment_method_data::PaymentMethodData,
-    router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
+    router_data::{
+        AccessToken, AccessTokenAuthenticationResponse, ConnectorAuthType, ErrorResponse,
+        RouterData,
+    },
     router_data_v2::{
-        flow_common_types::WebhookSourceVerifyData, AccessTokenFlowData, MandateRevokeFlowData,
-        UasFlowData,
+        flow_common_types::{AuthenticationTokenFlowData, WebhookSourceVerifyData},
+        AccessTokenFlowData, MandateRevokeFlowData, UasFlowData,
     },
     router_flow_types::{
-        mandate_revoke::MandateRevoke, AccessTokenAuth, Authenticate, AuthenticationConfirmation,
-        PostAuthenticate, PreAuthenticate, VerifyWebhookSource,
+        mandate_revoke::MandateRevoke, AccessTokenAuth, AccessTokenAuthentication, Authenticate,
+        AuthenticationConfirmation, PostAuthenticate, PreAuthenticate, VerifyWebhookSource,
     },
     router_request_types::{
         unified_authentication_service::{
@@ -55,7 +58,8 @@ use hyperswitch_domain_models::{
             UasConfirmationRequestData, UasPostAuthenticationRequestData,
             UasPreAuthenticationRequestData,
         },
-        AccessTokenRequestData, MandateRevokeRequestData, VerifyWebhookSourceRequestData,
+        AccessTokenAuthenticationRequestData, AccessTokenRequestData, MandateRevokeRequestData,
+        VerifyWebhookSourceRequestData,
     },
     router_response_types::{
         ConnectorInfo, MandateRevokeResponseData, PaymentMethodDetails, SupportedPaymentMethods,
@@ -87,6 +91,7 @@ pub trait Connector:
     + ConnectorRedirectResponse
     + webhooks::IncomingWebhook
     + ConnectorAccessToken
+    + ConnectorAuthenticationToken
     + disputes::Dispute
     + files::FileUpload
     + ConnectorTransactionId
@@ -109,6 +114,7 @@ impl<
             + Send
             + webhooks::IncomingWebhook
             + ConnectorAccessToken
+            + ConnectorAuthenticationToken
             + disputes::Dispute
             + files::FileUpload
             + ConnectorTransactionId
@@ -383,6 +389,12 @@ pub trait ConnectorSpecifications {
         None
     }
 
+    /// Check if connector should make another request to create an access token
+    /// Connectors should override this method if they require an authentication token to create a new access token
+    fn authentication_token_for_token_creation(&self) -> bool {
+        false
+    }
+
     #[cfg(not(feature = "v2"))]
     /// Generate connector request reference ID
     fn generate_connector_request_reference_id(
@@ -445,6 +457,27 @@ pub trait ConnectorMandateRevokeV2:
 {
 }
 
+/// trait ConnectorAuthenticationToken
+pub trait ConnectorAuthenticationToken:
+    ConnectorIntegration<
+    AccessTokenAuthentication,
+    AccessTokenAuthenticationRequestData,
+    AccessTokenAuthenticationResponse,
+>
+{
+}
+
+/// trait ConnectorAuthenticationTokenV2
+pub trait ConnectorAuthenticationTokenV2:
+    ConnectorIntegrationV2<
+    AccessTokenAuthentication,
+    AuthenticationTokenFlowData,
+    AccessTokenAuthenticationRequestData,
+    AccessTokenAuthenticationResponse,
+>
+{
+}
+
 /// trait ConnectorAccessToken
 pub trait ConnectorAccessToken:
     ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken>
diff --git a/crates/hyperswitch_interfaces/src/connector_integration_interface.rs b/crates/hyperswitch_interfaces/src/connector_integration_interface.rs
index c40c65ac5f7..66a1e291756 100644
--- a/crates/hyperswitch_interfaces/src/connector_integration_interface.rs
+++ b/crates/hyperswitch_interfaces/src/connector_integration_interface.rs
@@ -519,6 +519,14 @@ impl ConnectorSpecifications for ConnectorEnum {
         }
     }
 
+    /// Check if connector supports authentication token
+    fn authentication_token_for_token_creation(&self) -> bool {
+        match self {
+            Self::Old(connector) => connector.authentication_token_for_token_creation(),
+            Self::New(connector) => connector.authentication_token_for_token_creation(),
+        }
+    }
+
     #[cfg(feature = "v1")]
     fn generate_connector_request_reference_id(
         &self,
diff --git a/crates/hyperswitch_interfaces/src/connector_integration_v2.rs b/crates/hyperswitch_interfaces/src/connector_integration_v2.rs
index d51320ebbff..999770b65cb 100644
--- a/crates/hyperswitch_interfaces/src/connector_integration_v2.rs
+++ b/crates/hyperswitch_interfaces/src/connector_integration_v2.rs
@@ -22,6 +22,7 @@ pub trait ConnectorV2:
     + api::payments_v2::PaymentV2
     + api::ConnectorRedirectResponse
     + webhooks::IncomingWebhook
+    + api::ConnectorAuthenticationTokenV2
     + api::ConnectorAccessTokenV2
     + api::disputes_v2::DisputeV2
     + api::files_v2::FileUploadV2
@@ -42,6 +43,7 @@ impl<
             + api::ConnectorRedirectResponse
             + Send
             + webhooks::IncomingWebhook
+            + api::ConnectorAuthenticationTokenV2
             + api::ConnectorAccessTokenV2
             + api::disputes_v2::DisputeV2
             + api::files_v2::FileUploadV2
diff --git a/crates/hyperswitch_interfaces/src/conversion_impls.rs b/crates/hyperswitch_interfaces/src/conversion_impls.rs
index 633a7172be2..d70b8e882af 100644
--- a/crates/hyperswitch_interfaces/src/conversion_impls.rs
+++ b/crates/hyperswitch_interfaces/src/conversion_impls.rs
@@ -9,7 +9,7 @@ use hyperswitch_domain_models::{
     router_data::{self, RouterData},
     router_data_v2::{
         flow_common_types::{
-            AccessTokenFlowData, BillingConnectorInvoiceSyncFlowData,
+            AccessTokenFlowData, AuthenticationTokenFlowData, BillingConnectorInvoiceSyncFlowData,
             BillingConnectorPaymentsSyncFlowData, DisputesFlowData, ExternalAuthenticationFlowData,
             FilesFlowData, MandateRevokeFlowData, PaymentFlowData, RefundFlowData,
             RevenueRecoveryRecordBackData, UasFlowData, VaultConnectorFlowData,
@@ -91,6 +91,45 @@ fn get_default_router_data<F, Req, Resp>(
     }
 }
 
+impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
+    for AuthenticationTokenFlowData
+{
+    fn from_old_router_data(
+        old_router_data: &RouterData<T, Req, Resp>,
+    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
+    where
+        Self: Sized,
+    {
+        let resource_common_data = Self {};
+        Ok(RouterDataV2 {
+            flow: std::marker::PhantomData,
+            tenant_id: old_router_data.tenant_id.clone(),
+            resource_common_data,
+            connector_auth_type: old_router_data.connector_auth_type.clone(),
+            request: old_router_data.request.clone(),
+            response: old_router_data.response.clone(),
+        })
+    }
+
+    fn to_old_router_data(
+        new_router_data: RouterDataV2<T, Self, Req, Resp>,
+    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
+    where
+        Self: Sized,
+    {
+        let Self {} = new_router_data.resource_common_data;
+        let request = new_router_data.request.clone();
+        let response = new_router_data.response.clone();
+        let router_data = get_default_router_data(
+            new_router_data.tenant_id.clone(),
+            "authentication token",
+            request,
+            response,
+        );
+        Ok(router_data)
+    }
+}
+
 impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for AccessTokenFlowData {
     fn from_old_router_data(
         old_router_data: &RouterData<T, Req, Resp>,
diff --git a/crates/hyperswitch_interfaces/src/types.rs b/crates/hyperswitch_interfaces/src/types.rs
index 04053546c93..eed89fe00ba 100644
--- a/crates/hyperswitch_interfaces/src/types.rs
+++ b/crates/hyperswitch_interfaces/src/types.rs
@@ -1,7 +1,7 @@
 //! Types interface
 
 use hyperswitch_domain_models::{
-    router_data::AccessToken,
+    router_data::{AccessToken, AccessTokenAuthenticationResponse},
     router_data_v2::flow_common_types,
     router_flow_types::{
         access_token_auth::AccessTokenAuth,
@@ -24,7 +24,7 @@ use hyperswitch_domain_models::{
             ExternalVaultRetrieveFlow,
         },
         webhooks::VerifyWebhookSource,
-        BillingConnectorInvoiceSync,
+        AccessTokenAuthentication, BillingConnectorInvoiceSync,
     },
     router_request_types::{
         revenue_recovery::{
@@ -36,12 +36,12 @@ use hyperswitch_domain_models::{
             UasConfirmationRequestData, UasPostAuthenticationRequestData,
             UasPreAuthenticationRequestData,
         },
-        AcceptDisputeRequestData, AccessTokenRequestData, AuthorizeSessionTokenData,
-        CompleteAuthorizeData, ConnectorCustomerData, CreateOrderRequestData,
-        DefendDisputeRequestData, DisputeSyncData, FetchDisputesRequestData,
-        MandateRevokeRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData,
-        PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
-        PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
+        AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AccessTokenRequestData,
+        AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
+        CreateOrderRequestData, DefendDisputeRequestData, DisputeSyncData,
+        FetchDisputesRequestData, MandateRevokeRequestData, PaymentMethodTokenizationData,
+        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
+        PaymentsCaptureData, PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
         PaymentsPostSessionTokensData, PaymentsPreProcessingData, PaymentsSessionData,
         PaymentsSyncData, PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData,
         RetrieveFileRequestData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
@@ -193,6 +193,12 @@ pub type PayoutQuoteType = dyn ConnectorIntegration<PoQuote, PayoutsData, Payout
 /// Type alias for `ConnectorIntegration<PoSync, PayoutsData, PayoutsResponseData>`
 #[cfg(feature = "payouts")]
 pub type PayoutSyncType = dyn ConnectorIntegration<PoSync, PayoutsData, PayoutsResponseData>;
+/// Type alias for `ConnectorIntegration<AccessTokenAuthentication, AccessTokenAuthenticationRequestData, AccessTokenAuthenticationResponse>`
+pub type AuthenticationTokenType = dyn ConnectorIntegration<
+    AccessTokenAuthentication,
+    AccessTokenAuthenticationRequestData,
+    AccessTokenAuthenticationResponse,
+>;
 /// Type alias for `ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken>`
 pub type RefreshTokenType =
     dyn ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken>;
diff --git a/crates/payment_methods/src/configs/payment_connector_required_fields.rs b/crates/payment_methods/src/configs/payment_connector_required_fields.rs
index 8e67724d68d..57b6e94cbba 100644
--- a/crates/payment_methods/src/configs/payment_connector_required_fields.rs
+++ b/crates/payment_methods/src/configs/payment_connector_required_fields.rs
@@ -3210,6 +3210,19 @@ fn get_bank_debit_required_fields() -> HashMap<enums::PaymentMethodType, Connect
                     Connector::Inespay,
                     fields(vec![], vec![], vec![RequiredField::SepaBankDebitIban]),
                 ),
+                (
+                    Connector::Nordea,
+                    RequiredFieldFinal {
+                        mandate: HashMap::new(),
+
+                        non_mandate: HashMap::new(),
+
+                        common: HashMap::from([
+                            RequiredField::BillingAddressCountries(vec!["DK,FI,NO,SE"]).to_tuple(),
+                            RequiredField::SepaBankDebitIban.to_tuple(),
+                        ]),
+                    },
+                ),
             ]),
         ),
         (
diff --git a/crates/router/src/core/connector_validation.rs b/crates/router/src/core/connector_validation.rs
index b9019d9cf3d..874f778017b 100644
--- a/crates/router/src/core/connector_validation.rs
+++ b/crates/router/src/core/connector_validation.rs
@@ -349,10 +349,10 @@ impl ConnectorAuthTypeAndMetadataValidation<'_> {
                 noon::transformers::NoonAuthType::try_from(self.auth_type)?;
                 Ok(())
             }
-            // api_enums::Connector::Nordea => {
-            //     nordea::transformers::NordeaAuthType::try_from(self.auth_type)?;
-            //     Ok(())
-            // }
+            api_enums::Connector::Nordea => {
+                nordea::transformers::NordeaAuthType::try_from(self.auth_type)?;
+                Ok(())
+            }
             api_enums::Connector::Novalnet => {
                 novalnet::transformers::NovalnetAuthType::try_from(self.auth_type)?;
                 Ok(())
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index ee7aa40496b..e5604e5afbc 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -6113,7 +6113,9 @@ where
             }
         }
         Some(domain::PaymentMethodData::BankDebit(_)) => {
-            if connector.connector_name == router_types::Connector::Gocardless {
+            if connector.connector_name == router_types::Connector::Gocardless
+                || connector.connector_name == router_types::Connector::Nordea
+            {
                 router_data = router_data.preprocessing_steps(state, connector).await?;
                 let is_error_in_response = router_data.response.is_err();
                 // If is_error_in_response is true, should_continue_payment should be false, we should throw the error
diff --git a/crates/router/src/core/payments/access_token.rs b/crates/router/src/core/payments/access_token.rs
index f2f75964914..cf49d65b138 100644
--- a/crates/router/src/core/payments/access_token.rs
+++ b/crates/router/src/core/payments/access_token.rs
@@ -2,6 +2,7 @@ use std::fmt::Debug;
 
 use common_utils::ext_traits::AsyncExt;
 use error_stack::ResultExt;
+use hyperswitch_interfaces::api::ConnectorSpecifications;
 
 use crate::{
     consts,
@@ -112,10 +113,15 @@ pub async fn add_access_token<
                     )),
                 );
 
+                let authentication_token =
+                    execute_authentication_token(state, connector, router_data).await?;
+
                 let cloned_router_data = router_data.clone();
-                let refresh_token_request_data = types::AccessTokenRequestData::try_from(
+
+                let refresh_token_request_data = types::AccessTokenRequestData::try_from((
                     router_data.connector_auth_type.clone(),
-                )
+                    authentication_token,
+                ))
                 .attach_printable(
                     "Could not create access token request, invalid connector account credentials",
                 )?;
@@ -254,3 +260,93 @@ pub async fn refresh_connector_auth(
     );
     Ok(access_token_router_data)
 }
+
+pub async fn execute_authentication_token<
+    F: Clone + 'static,
+    Req: Debug + Clone + 'static,
+    Res: Debug + Clone + 'static,
+>(
+    state: &SessionState,
+    connector: &api_types::ConnectorData,
+    router_data: &types::RouterData<F, Req, Res>,
+) -> RouterResult<Option<types::AccessTokenAuthenticationResponse>> {
+    let should_create_authentication_token = connector
+        .connector
+        .authentication_token_for_token_creation();
+
+    if !should_create_authentication_token {
+        return Ok(None);
+    }
+
+    let authentication_token_request_data = types::AccessTokenAuthenticationRequestData::try_from(
+        router_data.connector_auth_type.clone(),
+    )
+    .attach_printable(
+        "Could not create authentication token request, invalid connector account credentials",
+    )?;
+
+    let authentication_token_response_data: Result<
+        types::AccessTokenAuthenticationResponse,
+        types::ErrorResponse,
+    > = Err(types::ErrorResponse::default());
+
+    let auth_token_router_data = payments::helpers::router_data_type_conversion::<
+        _,
+        api_types::AccessTokenAuthentication,
+        _,
+        _,
+        _,
+        _,
+    >(
+        router_data.clone(),
+        authentication_token_request_data,
+        authentication_token_response_data,
+    );
+
+    let connector_integration: services::BoxedAuthenticationTokenConnectorIntegrationInterface<
+        api_types::AccessTokenAuthentication,
+        types::AccessTokenAuthenticationRequestData,
+        types::AccessTokenAuthenticationResponse,
+    > = connector.connector.get_connector_integration();
+
+    let auth_token_router_data_result = services::execute_connector_processing_step(
+        state,
+        connector_integration,
+        &auth_token_router_data,
+        payments::CallConnectorAction::Trigger,
+        None,
+        None,
+    )
+    .await;
+
+    let auth_token_result = match auth_token_router_data_result {
+        Ok(router_data) => router_data.response,
+        Err(connector_error) => {
+            // Handle timeout errors
+            if connector_error.current_context().is_connector_timeout() {
+                let error_response = types::ErrorResponse {
+                    code: consts::REQUEST_TIMEOUT_ERROR_CODE.to_string(),
+                    message: consts::REQUEST_TIMEOUT_ERROR_MESSAGE.to_string(),
+                    reason: Some(consts::REQUEST_TIMEOUT_ERROR_MESSAGE.to_string()),
+                    status_code: 504,
+                    attempt_status: None,
+                    connector_transaction_id: None,
+                    network_advice_code: None,
+                    network_decline_code: None,
+                    network_error_message: None,
+                };
+                Err(error_response)
+            } else {
+                return Err(connector_error
+                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .attach_printable("Could not get authentication token"));
+            }
+        }
+    };
+
+    let authentication_token = auth_token_result
+        .map_err(|_error| errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to get authentication token")?;
+
+    Ok(Some(authentication_token))
+}
diff --git a/crates/router/src/core/payments/flows/approve_flow.rs b/crates/router/src/core/payments/flows/approve_flow.rs
index 296b081db6a..4008e0debe5 100644
--- a/crates/router/src/core/payments/flows/approve_flow.rs
+++ b/crates/router/src/core/payments/flows/approve_flow.rs
@@ -85,8 +85,14 @@ impl Feature<api::Approve, types::PaymentsApproveData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs
index 2aa69e6a36b..a51912e5662 100644
--- a/crates/router/src/core/payments/flows/authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/authorize_flow.rs
@@ -248,8 +248,14 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn add_session_token<'a>(
diff --git a/crates/router/src/core/payments/flows/cancel_flow.rs b/crates/router/src/core/payments/flows/cancel_flow.rs
index 7f025f81c85..a452a165c7d 100644
--- a/crates/router/src/core/payments/flows/cancel_flow.rs
+++ b/crates/router/src/core/payments/flows/cancel_flow.rs
@@ -103,8 +103,14 @@ impl Feature<api::Void, types::PaymentsCancelData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/cancel_post_capture_flow.rs b/crates/router/src/core/payments/flows/cancel_post_capture_flow.rs
index 67ccd612a9d..5b4625c8478 100644
--- a/crates/router/src/core/payments/flows/cancel_post_capture_flow.rs
+++ b/crates/router/src/core/payments/flows/cancel_post_capture_flow.rs
@@ -111,8 +111,14 @@ impl Feature<api::PostCaptureVoid, types::PaymentsCancelPostCaptureData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/capture_flow.rs b/crates/router/src/core/payments/flows/capture_flow.rs
index 3f2dafc0cb7..61f54eb3d50 100644
--- a/crates/router/src/core/payments/flows/capture_flow.rs
+++ b/crates/router/src/core/payments/flows/capture_flow.rs
@@ -124,8 +124,14 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/complete_authorize_flow.rs b/crates/router/src/core/payments/flows/complete_authorize_flow.rs
index 1d7a7772fbe..30ed3477150 100644
--- a/crates/router/src/core/payments/flows/complete_authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/complete_authorize_flow.rs
@@ -142,8 +142,14 @@ impl Feature<api::CompleteAuthorize, types::CompleteAuthorizeData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn add_payment_method_token<'a>(
diff --git a/crates/router/src/core/payments/flows/incremental_authorization_flow.rs b/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
index ef04b0354da..23a4c788e8a 100644
--- a/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
+++ b/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
@@ -106,8 +106,14 @@ impl Feature<api::IncrementalAuthorization, types::PaymentsIncrementalAuthorizat
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/post_session_tokens_flow.rs b/crates/router/src/core/payments/flows/post_session_tokens_flow.rs
index b356b695131..68ecc97e8a0 100644
--- a/crates/router/src/core/payments/flows/post_session_tokens_flow.rs
+++ b/crates/router/src/core/payments/flows/post_session_tokens_flow.rs
@@ -105,8 +105,14 @@ impl Feature<api::PostSessionTokens, types::PaymentsPostSessionTokensData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/psync_flow.rs b/crates/router/src/core/payments/flows/psync_flow.rs
index 641af1d397e..93a2c1ecd48 100644
--- a/crates/router/src/core/payments/flows/psync_flow.rs
+++ b/crates/router/src/core/payments/flows/psync_flow.rs
@@ -168,8 +168,14 @@ impl Feature<api::PSync, types::PaymentsSyncData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/reject_flow.rs b/crates/router/src/core/payments/flows/reject_flow.rs
index 2c7a9878ed2..0bf9f091f33 100644
--- a/crates/router/src/core/payments/flows/reject_flow.rs
+++ b/crates/router/src/core/payments/flows/reject_flow.rs
@@ -84,8 +84,14 @@ impl Feature<api::Reject, types::PaymentsRejectData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs
index 06441f24662..1f67fd4c003 100644
--- a/crates/router/src/core/payments/flows/session_flow.rs
+++ b/crates/router/src/core/payments/flows/session_flow.rs
@@ -125,8 +125,14 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn create_connector_customer<'a>(
diff --git a/crates/router/src/core/payments/flows/session_update_flow.rs b/crates/router/src/core/payments/flows/session_update_flow.rs
index 24b51ce1ca1..a52eef0b1d0 100644
--- a/crates/router/src/core/payments/flows/session_update_flow.rs
+++ b/crates/router/src/core/payments/flows/session_update_flow.rs
@@ -105,8 +105,14 @@ impl Feature<api::SdkSessionUpdate, types::SdkPaymentsSessionUpdateData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/payments/flows/setup_mandate_flow.rs b/crates/router/src/core/payments/flows/setup_mandate_flow.rs
index c89f04aa69a..4c1b1a445df 100644
--- a/crates/router/src/core/payments/flows/setup_mandate_flow.rs
+++ b/crates/router/src/core/payments/flows/setup_mandate_flow.rs
@@ -145,8 +145,14 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn add_payment_method_token<'a>(
diff --git a/crates/router/src/core/payments/flows/update_metadata_flow.rs b/crates/router/src/core/payments/flows/update_metadata_flow.rs
index a57b6acb751..538ed55d11f 100644
--- a/crates/router/src/core/payments/flows/update_metadata_flow.rs
+++ b/crates/router/src/core/payments/flows/update_metadata_flow.rs
@@ -104,8 +104,14 @@ impl Feature<api::UpdateMetadata, types::PaymentsUpdateMetadataData>
         merchant_context: &domain::MerchantContext,
         creds_identifier: Option<&str>,
     ) -> RouterResult<types::AddAccessTokenResult> {
-        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
-            .await
+        Box::pin(access_token::add_access_token(
+            state,
+            connector,
+            merchant_context,
+            self,
+            creds_identifier,
+        ))
+        .await
     }
 
     async fn build_flow_specific_connector_request(
diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs
index 0894297b747..ed44f61b4da 100644
--- a/crates/router/src/core/refunds.rs
+++ b/crates/router/src/core/refunds.rs
@@ -183,13 +183,13 @@ pub async fn trigger_refund_to_gateway(
     )
     .await?;
 
-    let add_access_token_result = access_token::add_access_token(
+    let add_access_token_result = Box::pin(access_token::add_access_token(
         state,
         &connector,
         merchant_context,
         &router_data,
         creds_identifier.as_deref(),
-    )
+    ))
     .await?;
 
     logger::debug!(refund_router_data=?router_data);
@@ -617,13 +617,13 @@ pub async fn sync_refund_with_gateway(
     )
     .await?;
 
-    let add_access_token_result = access_token::add_access_token(
+    let add_access_token_result = Box::pin(access_token::add_access_token(
         state,
         &connector,
         merchant_context,
         &router_data,
         creds_identifier.as_deref(),
-    )
+    ))
     .await?;
 
     logger::debug!(refund_retrieve_router_data=?router_data);
diff --git a/crates/router/src/core/refunds_v2.rs b/crates/router/src/core/refunds_v2.rs
index ceab569885d..bb4f2535ee7 100644
--- a/crates/router/src/core/refunds_v2.rs
+++ b/crates/router/src/core/refunds_v2.rs
@@ -169,9 +169,14 @@ pub async fn trigger_refund_to_gateway(
     )
     .await?;
 
-    let add_access_token_result =
-        access_token::add_access_token(state, &connector, merchant_context, &router_data, None)
-            .await?;
+    let add_access_token_result = Box::pin(access_token::add_access_token(
+        state,
+        &connector,
+        merchant_context,
+        &router_data,
+        None,
+    ))
+    .await?;
 
     logger::debug!(refund_router_data=?router_data);
 
@@ -271,9 +276,14 @@ pub async fn internal_trigger_refund_to_gateway(
     )
     .await?;
 
-    let add_access_token_result =
-        access_token::add_access_token(state, &connector, merchant_context, &router_data, None)
-            .await?;
+    let add_access_token_result = Box::pin(access_token::add_access_token(
+        state,
+        &connector,
+        merchant_context,
+        &router_data,
+        None,
+    ))
+    .await?;
 
     access_token::update_router_data_with_access_token_result(
         &add_access_token_result,
@@ -805,9 +815,14 @@ pub async fn sync_refund_with_gateway(
     )
     .await?;
 
-    let add_access_token_result =
-        access_token::add_access_token(state, &connector, merchant_context, &router_data, None)
-            .await?;
+    let add_access_token_result = Box::pin(access_token::add_access_token(
+        state,
+        &connector,
+        merchant_context,
+        &router_data,
+        None,
+    ))
+    .await?;
 
     logger::debug!(refund_retrieve_router_data=?router_data);
 
@@ -886,9 +901,14 @@ pub async fn internal_sync_refund_with_gateway(
     )
     .await?;
 
-    let add_access_token_result =
-        access_token::add_access_token(state, &connector, merchant_context, &router_data, None)
-            .await?;
+    let add_access_token_result = Box::pin(access_token::add_access_token(
+        state,
+        &connector,
+        merchant_context,
+        &router_data,
+        None,
+    ))
+    .await?;
 
     access_token::update_router_data_with_access_token_result(
         &add_access_token_result,
diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs
index d36cacd1a5c..005f41f91c8 100644
--- a/crates/router/src/services/api.rs
+++ b/crates/router/src/services/api.rs
@@ -98,6 +98,8 @@ pub type BoxedWebhookSourceVerificationConnectorIntegrationInterface<T, Req, Res
     BoxedConnectorIntegrationInterface<T, common_types::WebhookSourceVerifyData, Req, Resp>;
 pub type BoxedExternalAuthenticationConnectorIntegrationInterface<T, Req, Resp> =
     BoxedConnectorIntegrationInterface<T, common_types::ExternalAuthenticationFlowData, Req, Resp>;
+pub type BoxedAuthenticationTokenConnectorIntegrationInterface<T, Req, Resp> =
+    BoxedConnectorIntegrationInterface<T, common_types::AuthenticationTokenFlowData, Req, Resp>;
 pub type BoxedAccessTokenConnectorIntegrationInterface<T, Req, Resp> =
     BoxedConnectorIntegrationInterface<T, common_types::AccessTokenFlowData, Req, Resp>;
 pub type BoxedFilesConnectorIntegrationInterface<T, Req, Resp> =
diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs
index 41254507c23..f735c0e5863 100644
--- a/crates/router/src/types.rs
+++ b/crates/router/src/types.rs
@@ -47,15 +47,15 @@ use hyperswitch_domain_models::router_flow_types::{
 pub use hyperswitch_domain_models::{
     payment_address::PaymentAddress,
     router_data::{
-        AccessToken, AdditionalPaymentMethodConnectorResponse, ConnectorAuthType,
-        ConnectorResponseData, ErrorResponse, GooglePayPaymentMethodDetails,
+        AccessToken, AccessTokenAuthenticationResponse, AdditionalPaymentMethodConnectorResponse,
+        ConnectorAuthType, ConnectorResponseData, ErrorResponse, GooglePayPaymentMethodDetails,
         GooglePayPredecryptDataInternal, L2L3Data, PaymentMethodBalance, PaymentMethodToken,
         RecurringMandatePaymentData, RouterData,
     },
     router_data_v2::{
-        AccessTokenFlowData, DisputesFlowData, ExternalAuthenticationFlowData, FilesFlowData,
-        MandateRevokeFlowData, PaymentFlowData, RefundFlowData, RouterDataV2, UasFlowData,
-        WebhookSourceVerifyData,
+        AccessTokenFlowData, AuthenticationTokenFlowData, DisputesFlowData,
+        ExternalAuthenticationFlowData, FilesFlowData, MandateRevokeFlowData, PaymentFlowData,
+        RefundFlowData, RouterDataV2, UasFlowData, WebhookSourceVerifyData,
     },
     router_request_types::{
         revenue_recovery::{
@@ -67,14 +67,14 @@ pub use hyperswitch_domain_models::{
             UasConfirmationRequestData, UasPostAuthenticationRequestData,
             UasPreAuthenticationRequestData,
         },
-        AcceptDisputeRequestData, AccessTokenRequestData, AuthorizeSessionTokenData,
-        BrowserInformation, ChargeRefunds, ChargeRefundsOptions, CompleteAuthorizeData,
-        CompleteAuthorizeRedirectResponse, ConnectorCustomerData, CreateOrderRequestData,
-        DefendDisputeRequestData, DestinationChargeRefund, DirectChargeRefund, DisputeSyncData,
-        FetchDisputesRequestData, MandateRevokeRequestData, MultipleCaptureRequestData,
-        PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthorizeData,
-        PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
-        PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
+        AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AccessTokenRequestData,
+        AuthorizeSessionTokenData, BrowserInformation, ChargeRefunds, ChargeRefundsOptions,
+        CompleteAuthorizeData, CompleteAuthorizeRedirectResponse, ConnectorCustomerData,
+        CreateOrderRequestData, DefendDisputeRequestData, DestinationChargeRefund,
+        DirectChargeRefund, DisputeSyncData, FetchDisputesRequestData, MandateRevokeRequestData,
+        MultipleCaptureRequestData, PaymentMethodTokenizationData, PaymentsApproveData,
+        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
+        PaymentsCaptureData, PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
         PaymentsPostSessionTokensData, PaymentsPreProcessingData, PaymentsRejectData,
         PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
         PaymentsUpdateMetadataData, RefundsData, ResponseId, RetrieveFileRequestData,
@@ -118,15 +118,14 @@ pub use hyperswitch_interfaces::{
     },
 };
 
+#[cfg(feature = "v2")]
+use crate::core::errors;
 pub use crate::core::payments::CustomerDetails;
 #[cfg(feature = "payouts")]
 use crate::core::utils::IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_PAYOUTS_FLOW;
 use crate::{
     consts,
-    core::{
-        errors::{self},
-        payments::{OperationSessionGetters, PaymentData},
-    },
+    core::payments::{OperationSessionGetters, PaymentData},
     services,
     types::transformers::{ForeignFrom, ForeignTryFrom},
 };
@@ -1133,34 +1132,6 @@ pub struct ConnectorsList {
     pub connectors: Vec<String>,
 }
 
-impl ForeignTryFrom<ConnectorAuthType> for AccessTokenRequestData {
-    type Error = errors::ApiErrorResponse;
-    fn foreign_try_from(connector_auth: ConnectorAuthType) -> Result<Self, Self::Error> {
-        match connector_auth {
-            ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
-                app_id: api_key,
-                id: None,
-            }),
-            ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
-                app_id: api_key,
-                id: Some(key1),
-            }),
-            ConnectorAuthType::SignatureKey { api_key, key1, .. } => Ok(Self {
-                app_id: api_key,
-                id: Some(key1),
-            }),
-            ConnectorAuthType::MultiAuthKey { api_key, key1, .. } => Ok(Self {
-                app_id: api_key,
-                id: Some(key1),
-            }),
-
-            _ => Err(errors::ApiErrorResponse::InvalidDataValue {
-                field_name: "connector_account_details",
-            }),
-        }
-    }
-}
-
 impl ForeignFrom<&PaymentsAuthorizeRouterData> for AuthorizeSessionTokenData {
     fn foreign_from(data: &PaymentsAuthorizeRouterData) -> Self {
         Self {
diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs
index 156bb21d0b8..01f872e6f3a 100644
--- a/crates/router/src/types/api.rs
+++ b/crates/router/src/types/api.rs
@@ -43,7 +43,8 @@ use api_models::routing::{self as api_routing, RoutableConnectorChoice};
 use common_enums::RoutableConnectors;
 use error_stack::ResultExt;
 pub use hyperswitch_domain_models::router_flow_types::{
-    access_token_auth::AccessTokenAuth, mandate_revoke::MandateRevoke,
+    access_token_auth::{AccessTokenAuth, AccessTokenAuthentication},
+    mandate_revoke::MandateRevoke,
     webhooks::VerifyWebhookSource,
 };
 pub use hyperswitch_interfaces::{
@@ -62,7 +63,8 @@ pub use hyperswitch_interfaces::{
             RevenueRecovery, RevenueRecoveryRecordBack,
         },
         revenue_recovery_v2::RevenueRecoveryV2,
-        BoxedConnector, Connector, ConnectorAccessToken, ConnectorAccessTokenV2, ConnectorCommon,
+        BoxedConnector, Connector, ConnectorAccessToken, ConnectorAccessTokenV2,
+        ConnectorAuthenticationToken, ConnectorAuthenticationTokenV2, ConnectorCommon,
         ConnectorCommonExt, ConnectorMandateRevoke, ConnectorMandateRevokeV2,
         ConnectorTransactionId, ConnectorVerifyWebhookSource, ConnectorVerifyWebhookSourceV2,
         CurrencyUnit,
diff --git a/crates/router/src/types/api/connector_mapping.rs b/crates/router/src/types/api/connector_mapping.rs
index 2bd3bf33141..580ac62062c 100644
--- a/crates/router/src/types/api/connector_mapping.rs
+++ b/crates/router/src/types/api/connector_mapping.rs
@@ -312,7 +312,9 @@ impl ConnectorData {
                     Ok(ConnectorEnum::Old(Box::new(connector::Nomupay::new())))
                 }
                 enums::Connector::Noon => Ok(ConnectorEnum::Old(Box::new(connector::Noon::new()))),
-                // enums::Connector::Nordea => Ok(ConnectorEnum::Old(Box::new(connector::Nordea::new()))),
+                enums::Connector::Nordea => {
+                    Ok(ConnectorEnum::Old(Box::new(connector::Nordea::new())))
+                }
                 enums::Connector::Novalnet => {
                     Ok(ConnectorEnum::Old(Box::new(connector::Novalnet::new())))
                 }
diff --git a/crates/router/src/types/connector_transformers.rs b/crates/router/src/types/connector_transformers.rs
index ddb8fc333ca..4cf4bad8086 100644
--- a/crates/router/src/types/connector_transformers.rs
+++ b/crates/router/src/types/connector_transformers.rs
@@ -99,7 +99,7 @@ impl ForeignTryFrom<api_enums::Connector> for common_enums::RoutableConnectors {
             api_enums::Connector::Nmi => Self::Nmi,
             api_enums::Connector::Nomupay => Self::Nomupay,
             api_enums::Connector::Noon => Self::Noon,
-            // api_enums::Connector::Nordea => Self::Nordea,
+            api_enums::Connector::Nordea => Self::Nordea,
             api_enums::Connector::Novalnet => Self::Novalnet,
             api_enums::Connector::Nuvei => Self::Nuvei,
             api_enums::Connector::Opennode => Self::Opennode,
diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml
index 625cdb50176..00784b49c15 100644
--- a/crates/router/tests/connectors/sample_auth.toml
+++ b/crates/router/tests/connectors/sample_auth.toml
@@ -289,6 +289,7 @@ api_key = "API Key"
 [nordea]
 api_key = "Client Secret"
 key1 = "Client ID"
+api_secret = "eIDAS Private Key"
 
 [novalnet]
 api_key="API Key"
diff --git a/crates/test_utils/src/connector_auth.rs b/crates/test_utils/src/connector_auth.rs
index 3829fc17eba..22a44919f83 100644
--- a/crates/test_utils/src/connector_auth.rs
+++ b/crates/test_utils/src/connector_auth.rs
@@ -81,7 +81,7 @@ pub struct ConnectorAuthentication {
     pub nexixpay: Option<HeaderKey>,
     pub nomupay: Option<BodyKey>,
     pub noon: Option<SignatureKey>,
-    pub nordea: Option<BodyKey>,
+    pub nordea: Option<SignatureKey>,
     pub novalnet: Option<HeaderKey>,
     pub nmi: Option<HeaderKey>,
     pub nuvei: Option<SignatureKey>,
diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml
index adb2d4a2491..41954a9f8b8 100644
--- a/loadtest/config/development.toml
+++ b/loadtest/config/development.toml
@@ -591,6 +591,9 @@ paypal = { currency = "AUD,BRL,CAD,CHF,CNY,CZK,DKK,EUR,GBP,HKD,HUF,ILS,JPY,MXN,M
 credit = { country = "US, CA", currency = "CAD,USD" }
 debit = { country = "US, CA", currency = "CAD,USD" }
 
+[pm_filters.nordea]
+sepa = { country = "DK,FI,NO,SE", currency = "DKK,EUR,NOK,SEK" }
+
 [pm_filters.fiuu]
 duit_now = { country = "MY", currency = "MYR" }
 apple_pay = { country = "MY", currency = "MYR" }

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

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

## Description
<!-- Describe your changes in detail -->

### Summary

This PR introduces Nordea as a new payment connector with support for SEPA bank debit payments. It also implements a new **Authentication Token Flow** mechanism that enables two-step OAuth authentication, which is required by certain connectors like Nordea.

### Problem Statement

Some payment connectors require a more complex authentication process that involves:
1. **Step 1**: Obtaining an authentication token (authorization code) using client credentials
2. **Step 2**: Exchanging that authentication token for an access token using OAuth 2.0 flow

The existing access token flow in Hyperswitch only supported direct access token generation, making it incompatible with connectors that require this two-step OAuth authentication process.

### Solution

This PR introduces:
1. **Authentication Token Flow**: A new connector flow that handles the two-step OAuth authentication process
2. **Nordea Connector Integration**: The first connector to utilize this new authentication flow  
3. **SEPA Bank Debit Support**: Implementation of SEPA payment method through Nordea

### Implementation Details

#### Authentication Token Flow Architecture

The new authentication flow works as follows:

```mermaid
flowchart TD
    A[Payment Flow Initiated] --> B{Connector Supports<br/>Access Token?}
    B -->|No| Z[Continue with Payment<br/>No Access Token]
    B -->|Yes| C[Check Access Token Cache]
    
    C --> D{Access Token<br/>in Cache?}
    D -->|Yes| E[Use Cached Access Token]
    D -->|No| F{Connector Needs<br/>Authentication Token?}
    
    F -->|No| G[Create AccessTokenRequestData<br/>with ConnectorAuthType only]
    F -->|Yes| H[Authentication Token Flow]
    
    H --> I[Create AccessTokenAuthenticationRequestData<br/>from ConnectorAuthType]
    I --> J[Call execute_authentication_token]
    J --> K[POST /oauth/authorize<br/>with client credentials]
    K --> L{Authentication<br/>Successful?}
    
    L -->|No| M[Return Error]
    L -->|Yes| N[Receive AccessTokenAuthenticationResponse<br/>authorization code]
    
    N --> O[Create AccessTokenRequestData<br/>with ConnectorAuthType + AuthenticationToken]
    O --> P[Access Token Flow]
    G --> P
    
    P --> Q[Call refresh_connector_auth]
    Q --> R[POST /oauth/token<br/>exchange auth code for access token]
    R --> S{Access Token<br/>Successful?}
    
    S -->|No| T[Return Error]
    S -->|Yes| U[Receive AccessToken<br/>bearer token + expiry]
    
    U --> V[Cache Access Token<br/>with reduced expiry]
    V --> W[Return Access Token]
    E --> W
    W --> X[Use Access Token<br/>for Payment Requests]
    
    M --> Y[Payment Flow Fails]
    T --> Y
    X --> AA[Payment Flow Continues]
    Z --> AA
    
    style H fill:#e1f5fe
    style P fill:#f3e5f5
    style I fill:#e8f5e8
    style O fill:#e8f5e8
    style K fill:#fff3e0
    style R fill:#fff3e0
    style V fill:#e8eaf6
```

#### Key Components

- __AccessTokenAuthenticationRequestData__: Contains connector auth credentials for the first OAuth step
- __AccessTokenAuthenticationResponse__: Contains the authorization code received from the authentication endpoint
- __Enhanced AccessTokenRequestData__: Now supports both direct access token creation and token exchange flows
- __Automatic Flow Detection__: The system automatically detects if a connector needs authentication tokens via `authentication_token_for_token_creation()`

#### Nordea Connector Integration

- __Authentication__: Implements OAuth 2.0 with eIDAS signature validation

- __Payment Methods__: SEPA Credit Transfers (bank debit)

- __Supported Operations__:

  - Payment authorization (automatic capture only)
  - Payment synchronization (PSync)
  - Two-step OAuth authentication flow

- __Not Supported__:

  - Manual capture
  - Refunds (only available in Corporate APIs)
  - Void/cancellation

#### Technical Implementation

- __Signature Generation__: Implements eIDAS signature generation using RSA-SHA256 for API request signing

- __Auth Configuration__: Uses `SignatureKey` auth type with:

  - `api_key`: Client Secret
  - `key1`: Client ID
  - `api_secret`: eIDAS Private Key (base64 encoded)

- __Request Signing__: All requests include:

  - X-Nordea-Originating-Host
  - X-Nordea-Originating-Date
  - Signature header (following HTTP Signature spec)
  - Digest header for POST/PUT requests

- __Payment Flow__:

  1. Authentication token creation (authorization)
  2. Access token exchange
  3. Payment initiation (PreProcessing)
  4. Payment confirmation (Authorize)

### Changes Made

1. __Core Authentication Infrastructure__:

   - Added `AccessTokenAuthenticationRequestData` struct for auth token requests
   - Added `AccessTokenAuthenticationResponse` struct for auth token responses
   - Enhanced `AccessTokenRequestData` to support both direct and exchange flows
   - Added `execute_authentication_token` function for OAuth step 1
   - Modified access token flow to check for authentication token support
   - Added backward-compatible authentication token detection

2. __Connector Implementation__:

   - Added Nordea connector module with request/response structures
   - Implemented eIDAS signature generation
   - Added SEPA payment method support
   - Implemented OAuth 2.0 authentication flow

3. __Configuration__:

   - Added Nordea to connector configs (development, sandbox, production)
   - Added payment method required fields configuration
   - Updated WASM bindings for frontend integration

### Testing

- Tested SEPA bank debit payments through complete flow
- Verified eIDAS signature generation
- Confirmed OAuth authentication flow works correctly
- Validated payment status synchronization
- Tested backward compatibility with existing connectors

### Unsupported features by Nordea

- Webhooks
- Manual Capture
- Refunds (only supported through Corporate API and is behind a paywall)

### Breaking Changes

None - The authentication token flow is backward compatible and only activates for connectors that explicitly support it through the `authentication_token_for_token_creation()` method.

### Additional Changes

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

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

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


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

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

New connector Nordea SEPA integration. Closes #8134.

## 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>MCA</summary>

```curl
curl --location 'http://localhost:8080/account/postman_merchant_GHAction_1752842696/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_DL49cxo4k5VbOYIabte7WgRsu9xTmB6in77WVBxdN8nPRWMqzFb5ISd3mGocJC0I' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "nordea",
    "business_country": "US",
    "business_label": "default",
    "connector_account_details": {
        "auth_type": "SignatureKey",
        "api_key": "client_secret",
        "key1": "client_id",
        "api_secret": "decrypted_certificate"
    },
    "test_mode": false,
    "disabled": false,
    "metadata": {
        "creditor_account_type": "IBAN",
        "creditor_account_value": "{{creditor_account_number}}",
        "creditor_beneficiary_name": "Test Merchant"
    },
    "payment_methods_enabled": [
        {
            "payment_method": "bank_debit",
            "payment_method_types": [
                {
                    "payment_method_type": "sepa",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ]
}'
```
```json
{
    "connector_type": "payment_processor",
    "connector_name": "nordea",
    "connector_label": "nordea_US_default",
    "merchant_connector_id": "mca_UWrnV7EnGkfVapwuHOAM",
    "profile_id": "pro_892QTRQ3W6mWykBeSXDQ",
    "connector_account_details": {
        "auth_type": "SignatureKey",
        "api_key": "client_secret",
        "key1": "client_id",
        "api_secret": "decrypted_certificate"
    },
    "payment_methods_enabled": [
        {
            "payment_method": "bank_debit",
            "payment_method_types": [
                {
                    "payment_method_type": "sepa",
                    "payment_experience": null,
                    "card_networks": null,
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "connector_webhook_details": null,
    "metadata": {
        "creditor_account_type": "IBAN",
        "creditor_account_value": "FI7473834510057469",
        "creditor_beneficiary_name": "Test Merchant"
    },
    "test_mode": false,
    "disabled": false,
    "frm_configs": null,
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "applepay_verified_domains": null,
    "pm_auth_config": null,
    "status": "active",
    "additional_merchant_data": null,
    "connector_wallets_details": null
}
```

</details>

<details>

<summary>Payment Create</summary>

```curl
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Accept-Language: ja' \
--header 'api-key: dev_DL49cxo4k5VbOYIabte7WgRsu9xTmB6in77WVBxdN8nPRWMqzFb5ISd3mGocJC0I' \
--data-raw '{
    "amount": 10400,
    "currency": "EUR",
    "confirm": false,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 10400,
    "customer_id": "customer",
    "email": "guesjhvghht@example.com",
    
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "three_ds",
    "return_url": "https://duck.com",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "FI"
            ,
            "first_name": "PiX"
            ,
            "last_name": "THE"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "FI",
            "first_name": "PiX"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "browser_info": {
        "color_depth": 24,
        "java_enabled": true,
        "java_script_enabled": true,
        "language": "en-GB",
        "screen_height": 720,
        "screen_width": 1280,
        "time_zone": -330,
        "ip_address": "208.127.127.193",
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0"
    }
    
}'
```
```json
{
    "payment_id": "pay_GJDKAKdDxM4bQ8xX0anw",
    "merchant_id": "postman_merchant_GHAction_1752842696",
    "status": "requires_payment_method",
    "amount": 10400,
    "net_amount": 10400,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": null,
    "client_secret": "pay_GJDKAKdDxM4bQ8xX0anw_secret_TL3I7uzVd7IA4uvwkPqh",
    "created": "2025-07-18T12:45:03.009Z",
    "currency": "EUR",
    "customer_id": "customer",
    "customer": {
        "id": "customer",
        "name": null,
        "email": "guesjhvghht@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": null,
    "payment_method_data": null,
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "FI",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "FI",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": "THE"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guesjhvghht@example.com",
    "name": null,
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": null,
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "customer",
        "created_at": 1752842702,
        "expires": 1752846302,
        "secret": "epk_d55a0599354449ebafda40a1f4989778"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_892QTRQ3W6mWykBeSXDQ",
    "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-07-18T13:00:03.008Z",
    "fingerprint": null,
    "browser_info": {
        "language": "en-GB",
        "time_zone": -330,
        "ip_address": "208.127.127.193",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1280,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 720,
        "java_script_enabled": true
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-07-18T12:45:03.075Z",
    "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
}
```

</details>

<details>

<summary>Payment Confirm</summary>

```curl
curl --location 'http://localhost:8080/payments/pay_GJDKAKdDxM4bQ8xX0anw/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: pk_dev_b6513b5899694eaeb7d76adfe1d29708' \
--data '{
    "payment_method": "bank_debit",
    "payment_method_type": "sepa",
    "payment_method_data": {
        "bank_debit": {
            "sepa_bank_debit": {
                "iban": "FI6593857450293470"
            }
        }
    },
    "client_secret": "pay_GJDKAKdDxM4bQ8xX0anw_secret_TL3I7uzVd7IA4uvwkPqh"
}'
```
```json
{
    "payment_id": "pay_GJDKAKdDxM4bQ8xX0anw",
    "merchant_id": "postman_merchant_GHAction_1752842696",
    "status": "requires_customer_action",
    "amount": 10400,
    "net_amount": 10400,
    "shipping_cost": null,
    "amount_capturable": 10400,
    "amount_received": null,
    "connector": "nordea",
    "client_secret": "pay_GJDKAKdDxM4bQ8xX0anw_secret_TL3I7uzVd7IA4uvwkPqh",
    "created": "2025-07-18T12:45:03.009Z",
    "currency": "EUR",
    "customer_id": "customer",
    "customer": {
        "id": "customer",
        "name": null,
        "email": "guesjhvghht@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "bank_debit",
    "payment_method_data": {
        "bank_debit": {
            "sepa": {
                "iban": "FI659********93470",
                "bank_account_holder_name": null
            }
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "FI",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "FI",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": "THE"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guesjhvghht@example.com",
    "name": null,
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_GJDKAKdDxM4bQ8xX0anw/postman_merchant_GHAction_1752842696/pay_GJDKAKdDxM4bQ8xX0anw_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "sepa",
    "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": "c14b226e-dfc1-4458-a477-a7b3ee4387fd",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_GJDKAKdDxM4bQ8xX0anw_1",
    "payment_link": null,
    "profile_id": "pro_892QTRQ3W6mWykBeSXDQ",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_UWrnV7EnGkfVapwuHOAM",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-07-18T13:00:03.008Z",
    "fingerprint": null,
    "browser_info": {
        "os_type": null,
        "language": null,
        "time_zone": null,
        "ip_address": "::1",
        "os_version": null,
        "user_agent": null,
        "color_depth": null,
        "device_model": null,
        "java_enabled": null,
        "screen_width": null,
        "accept_header": null,
        "screen_height": null,
        "accept_language": "en",
        "java_script_enabled": null
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-07-18T12:45:06.878Z",
    "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
}
```

</details>

<details>

<summary>Redirection</summary>

<img width="249" height="120" alt="image" src="https://github.com/user-attachments/assets/c66f3ea7-e779-4702-8190-1d7925bfa7fc" />

</details>

<details>

<summary>Retrieve</summary>

```curl
curl --location 'http://localhost:8080/payments/pay_GJDKAKdDxM4bQ8xX0anw?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_DL49cxo4k5VbOYIabte7WgRsu9xTmB6in77WVBxdN8nPRWMqzFb5ISd3mGocJC0I'
```
```json
{
    "payment_id": "pay_GJDKAKdDxM4bQ8xX0anw",
    "merchant_id": "postman_merchant_GHAction_1752842696",
    "status": "succeeded",
    "amount": 10400,
    "net_amount": 10400,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 10400,
    "connector": "nordea",
    "client_secret": "pay_GJDKAKdDxM4bQ8xX0anw_secret_TL3I7uzVd7IA4uvwkPqh",
    "created": "2025-07-18T12:45:03.009Z",
    "currency": "EUR",
    "customer_id": "customer",
    "customer": {
        "id": "customer",
        "name": null,
        "email": "guesjhvghht@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "bank_debit",
    "payment_method_data": {
        "bank_debit": {
            "sepa": {
                "iban": "FI659********93470",
                "bank_account_holder_name": null
            }
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "FI",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "FI",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": "THE"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guesjhvghht@example.com",
    "name": null,
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "sepa",
    "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": "c14b226e-dfc1-4458-a477-a7b3ee4387fd",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_GJDKAKdDxM4bQ8xX0anw_1",
    "payment_link": null,
    "profile_id": "pro_892QTRQ3W6mWykBeSXDQ",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_UWrnV7EnGkfVapwuHOAM",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-07-18T13:00:03.008Z",
    "fingerprint": null,
    "browser_info": {
        "os_type": null,
        "language": null,
        "time_zone": null,
        "ip_address": "::1",
        "os_version": null,
        "user_agent": null,
        "color_depth": null,
        "device_model": null,
        "java_enabled": null,
        "screen_width": null,
        "accept_header": null,
        "screen_height": null,
        "accept_language": "en",
        "java_script_enabled": null
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-07-18T12:45:16.869Z",
    "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
}
```

</details>


<details>

<summary>Cypress</summary>

WILL INTRODUCE IN NEXT PR.

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

<!-- @coderabbitai ignore -->