Bug: [FEATURE] Make PM auth service generic across Payment Method types



### Feature Description

Currently, PM auth only supports ACH, need to make it generic across SEPA, BACS as well.

### Possible Implementation

Will probably need some kind of parent structure to differentiate between types

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

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

### Have you read the Contributing Guidelines?

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

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs
index 35193b958f2..9873f62bfe1 100644
--- a/crates/api_models/src/payment_methods.rs
+++ b/crates/api_models/src/payment_methods.rs
@@ -222,17 +222,24 @@ pub struct PaymentMethodDataBankCreds {
     pub connector_details: Vec<BankAccountConnectorDetails>,
 }
 
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+pub struct BankAccountTokenData {
+    pub payment_method_type: api_enums::PaymentMethodType,
+    pub payment_method: api_enums::PaymentMethod,
+    pub connector_details: BankAccountConnectorDetails,
+}
+
 #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
 pub struct BankAccountConnectorDetails {
     pub connector: String,
-    pub account_id: String,
+    pub account_id: masking::Secret<String>,
     pub mca_id: String,
     pub access_token: BankAccountAccessCreds,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
 pub enum BankAccountAccessCreds {
-    AccessToken(String),
+    AccessToken(masking::Secret<String>),
 }
 #[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
 pub struct CardDetailFromLocker {
diff --git a/crates/pm_auth/src/connector/plaid/transformers.rs b/crates/pm_auth/src/connector/plaid/transformers.rs
index 5e1ad67aead..f163875958e 100644
--- a/crates/pm_auth/src/connector/plaid/transformers.rs
+++ b/crates/pm_auth/src/connector/plaid/transformers.rs
@@ -1,7 +1,7 @@
 use std::collections::HashMap;
 
-use common_enums::PaymentMethodType;
-use masking::Secret;
+use common_enums::{PaymentMethod, PaymentMethodType};
+use masking::{PeekInterface, Secret};
 use serde::{Deserialize, Serialize};
 
 use crate::{core::errors, types};
@@ -200,13 +200,19 @@ pub struct PlaidBankAccountCredentialsBacs {
 impl TryFrom<&types::BankDetailsRouterData> for PlaidBankAccountCredentialsRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::BankDetailsRouterData) -> Result<Self, Self::Error> {
+        let options = item.request.optional_ids.as_ref().map(|bank_account_ids| {
+            let ids = bank_account_ids
+                .ids
+                .iter()
+                .map(|id| id.peek().to_string())
+                .collect::<Vec<_>>();
+
+            BankAccountCredentialsOptions { account_ids: ids }
+        });
+
         Ok(Self {
-            access_token: item.request.access_token.clone(),
-            options: item.request.optional_ids.as_ref().map(|bank_account_ids| {
-                BankAccountCredentialsOptions {
-                    account_ids: bank_account_ids.ids.clone(),
-                }
-            }),
+            access_token: item.request.access_token.peek().to_string(),
+            options,
         })
     }
 }
@@ -232,26 +238,84 @@ impl<F, T>
     ) -> Result<Self, Self::Error> {
         let (account_numbers, accounts_info) = (item.response.numbers, item.response.accounts);
         let mut bank_account_vec = Vec::new();
-        let mut id_to_suptype = HashMap::new();
+        let mut id_to_subtype = HashMap::new();
 
         accounts_info.into_iter().for_each(|acc| {
-            id_to_suptype.insert(acc.account_id, (acc.subtype, acc.name));
+            id_to_subtype.insert(acc.account_id, (acc.subtype, acc.name));
         });
 
         account_numbers.ach.into_iter().for_each(|ach| {
             let (acc_type, acc_name) =
-                if let Some((_type, name)) = id_to_suptype.get(&ach.account_id) {
+                if let Some((_type, name)) = id_to_subtype.get(&ach.account_id) {
                     (_type.to_owned(), Some(name.clone()))
                 } else {
                     (None, None)
                 };
 
+            let account_details =
+                types::PaymentMethodTypeDetails::Ach(types::BankAccountDetailsAch {
+                    account_number: Secret::new(ach.account),
+                    routing_number: Secret::new(ach.routing),
+                });
+
             let bank_details_new = types::BankAccountDetails {
                 account_name: acc_name,
-                account_number: ach.account,
-                routing_number: ach.routing,
+                account_details,
                 payment_method_type: PaymentMethodType::Ach,
-                account_id: ach.account_id,
+                payment_method: PaymentMethod::BankDebit,
+                account_id: ach.account_id.into(),
+                account_type: acc_type,
+            };
+
+            bank_account_vec.push(bank_details_new);
+        });
+
+        account_numbers.bacs.into_iter().for_each(|bacs| {
+            let (acc_type, acc_name) =
+                if let Some((_type, name)) = id_to_subtype.get(&bacs.account_id) {
+                    (_type.to_owned(), Some(name.clone()))
+                } else {
+                    (None, None)
+                };
+
+            let account_details =
+                types::PaymentMethodTypeDetails::Bacs(types::BankAccountDetailsBacs {
+                    account_number: Secret::new(bacs.account),
+                    sort_code: Secret::new(bacs.sort_code),
+                });
+
+            let bank_details_new = types::BankAccountDetails {
+                account_name: acc_name,
+                account_details,
+                payment_method_type: PaymentMethodType::Bacs,
+                payment_method: PaymentMethod::BankDebit,
+                account_id: bacs.account_id.into(),
+                account_type: acc_type,
+            };
+
+            bank_account_vec.push(bank_details_new);
+        });
+
+        account_numbers.international.into_iter().for_each(|sepa| {
+            let (acc_type, acc_name) =
+                if let Some((_type, name)) = id_to_subtype.get(&sepa.account_id) {
+                    (_type.to_owned(), Some(name.clone()))
+                } else {
+                    (None, None)
+                };
+
+            let account_details =
+                types::PaymentMethodTypeDetails::Sepa(types::BankAccountDetailsSepa {
+                    iban: Secret::new(sepa.iban),
+                    bic: Secret::new(sepa.bic),
+                });
+
+            let bank_details_new = types::BankAccountDetails {
+                account_name: acc_name,
+                account_details,
+                payment_method_type: PaymentMethodType::Sepa,
+                payment_method: PaymentMethod::BankDebit,
+                account_id: sepa.account_id.into(),
                 account_type: acc_type,
             };
 
diff --git a/crates/pm_auth/src/types.rs b/crates/pm_auth/src/types.rs
index 6f5875247f1..51fd796072b 100644
--- a/crates/pm_auth/src/types.rs
+++ b/crates/pm_auth/src/types.rs
@@ -3,7 +3,7 @@ pub mod api;
 use std::marker::PhantomData;
 
 use api::auth_service::{BankAccountCredentials, ExchangeToken, LinkToken};
-use common_enums::PaymentMethodType;
+use common_enums::{PaymentMethod, PaymentMethodType};
 use masking::Secret;
 #[derive(Debug, Clone)]
 pub struct PaymentAuthRouterData<F, Request, Response> {
@@ -55,13 +55,13 @@ pub type ExchangeTokenRouterData =
 
 #[derive(Debug, Clone)]
 pub struct BankAccountCredentialsRequest {
-    pub access_token: String,
+    pub access_token: Secret<String>,
     pub optional_ids: Option<BankAccountOptionalIDs>,
 }
 
 #[derive(Debug, Clone)]
 pub struct BankAccountOptionalIDs {
-    pub ids: Vec<String>,
+    pub ids: Vec<Secret<String>>,
 }
 
 #[derive(Debug, Clone)]
@@ -72,13 +72,37 @@ pub struct BankAccountCredentialsResponse {
 #[derive(Debug, Clone)]
 pub struct BankAccountDetails {
     pub account_name: Option<String>,
-    pub account_number: String,
-    pub routing_number: String,
+    pub account_details: PaymentMethodTypeDetails,
     pub payment_method_type: PaymentMethodType,
-    pub account_id: String,
+    pub payment_method: PaymentMethod,
+    pub account_id: Secret<String>,
     pub account_type: Option<String>,
 }
 
+#[derive(Debug, Clone)]
+pub enum PaymentMethodTypeDetails {
+    Ach(BankAccountDetailsAch),
+    Bacs(BankAccountDetailsBacs),
+    Sepa(BankAccountDetailsSepa),
+}
+#[derive(Debug, Clone)]
+pub struct BankAccountDetailsAch {
+    pub account_number: Secret<String>,
+    pub routing_number: Secret<String>,
+}
+
+#[derive(Debug, Clone)]
+pub struct BankAccountDetailsBacs {
+    pub account_number: Secret<String>,
+    pub sort_code: Secret<String>,
+}
+
+#[derive(Debug, Clone)]
+pub struct BankAccountDetailsSepa {
+    pub iban: Secret<String>,
+    pub bic: Secret<String>,
+}
+
 pub type BankDetailsRouterData = PaymentAuthRouterData<
     BankAccountCredentials,
     BankAccountCredentialsRequest,
diff --git a/crates/router/src/configs/defaults.rs b/crates/router/src/configs/defaults.rs
index f9d98647d1b..7ade016856c 100644
--- a/crates/router/src/configs/defaults.rs
+++ b/crates/router/src/configs/defaults.rs
@@ -6453,7 +6453,15 @@ impl Default for super::settings::RequiredFields {
                                     RequiredFieldFinal {
                                         mandate: HashMap::new(),
                                         non_mandate: HashMap::new(),
-                                        common: HashMap::new(),
+                                        common: HashMap::from([ (
+                                            "billing.address.first_name".to_string(),
+                                            RequiredFieldInfo {
+                                                required_field: "billing.address.first_name".to_string(),
+                                                display_name: "billing_first_name".to_string(),
+                                                field_type: enums::FieldType::UserBillingName,
+                                                value: None,
+                                            }
+                                        )]),
                                     })]
                                 )}
                     ),
@@ -6466,7 +6474,15 @@ impl Default for super::settings::RequiredFields {
                                     RequiredFieldFinal {
                                         mandate: HashMap::new(),
                                         non_mandate: HashMap::new(),
-                                        common: HashMap::new(),
+                                        common: HashMap::from([ (
+                                            "billing.address.first_name".to_string(),
+                                            RequiredFieldInfo {
+                                                required_field: "billing.address.first_name".to_string(),
+                                                display_name: "billing_first_name".to_string(),
+                                                field_type: enums::FieldType::UserBillingName,
+                                                value: None,
+                                            }
+                                        )]),
                                     }
                                 ),
                                ]),
@@ -6481,7 +6497,15 @@ impl Default for super::settings::RequiredFields {
                                     RequiredFieldFinal {
                                         mandate: HashMap::new(),
                                         non_mandate: HashMap::new(),
-                                        common: HashMap::new(),
+                                        common: HashMap::from([ (
+                                            "billing.address.first_name".to_string(),
+                                            RequiredFieldInfo {
+                                                required_field: "billing.address.first_name".to_string(),
+                                                display_name: "billing_first_name".to_string(),
+                                                field_type: enums::FieldType::UserBillingName,
+                                                value: None,
+                                            }
+                                        )]),
                                     }
                                 ),
                                 ]),
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 60abf0701a5..41efea14942 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -7,7 +7,7 @@ use api_models::{
     admin::{self, PaymentMethodsEnabled},
     enums::{self as api_enums},
     payment_methods::{
-        BankAccountConnectorDetails, CardDetailsPaymentMethod, CardNetworkTypes,
+        BankAccountTokenData, CardDetailsPaymentMethod, CardNetworkTypes,
         CustomerDefaultPaymentMethodResponse, MaskedBankDetails, PaymentExperienceTypes,
         PaymentMethodsData, RequestPaymentMethodTypes, RequiredFieldInfo,
         ResponsePaymentMethodIntermediate, ResponsePaymentMethodTypes,
@@ -2824,14 +2824,14 @@ pub async fn list_customer_payment_method(
 
             enums::PaymentMethod::BankDebit => {
                 // Retrieve the pm_auth connector details so that it can be tokenized
-                let bank_account_connector_details = get_bank_account_connector_details(&pm, key)
+                let bank_account_token_data = get_bank_account_connector_details(&pm, key)
                     .await
                     .unwrap_or_else(|err| {
                         logger::error!(error=?err);
                         None
                     });
-                if let Some(connector_details) = bank_account_connector_details {
-                    let token_data = PaymentTokenData::AuthBankDebit(connector_details);
+                if let Some(data) = bank_account_token_data {
+                    let token_data = PaymentTokenData::AuthBankDebit(data);
                     (None, None, token_data)
                 } else {
                     continue;
@@ -3133,7 +3133,7 @@ async fn get_masked_bank_details(
 async fn get_bank_account_connector_details(
     pm: &payment_method::PaymentMethod,
     key: &[u8],
-) -> errors::RouterResult<Option<BankAccountConnectorDetails>> {
+) -> errors::RouterResult<Option<BankAccountTokenData>> {
     let payment_method_data =
         decrypt::<serde_json::Value, masking::WithType>(pm.payment_method_data.clone(), key)
             .await
@@ -3162,12 +3162,19 @@ async fn get_bank_account_connector_details(
                     .connector_details
                     .first()
                     .ok_or(errors::ApiErrorResponse::InternalServerError)?;
-                Ok(Some(BankAccountConnectorDetails {
-                    connector: connector_details.connector.clone(),
-                    account_id: connector_details.account_id.clone(),
-                    mca_id: connector_details.mca_id.clone(),
-                    access_token: connector_details.access_token.clone(),
-                }))
+
+                let pm_type = pm
+                    .payment_method_type
+                    .get_required_value("payment_method_type")
+                    .attach_printable("PaymentMethodType not found")?;
+
+                let token_data = BankAccountTokenData {
+                    payment_method_type: pm_type,
+                    payment_method: pm.payment_method,
+                    connector_details: connector_details.clone(),
+                };
+
+                Ok(Some(token_data))
             }
         },
         None => Ok(None),
diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs
index 21ba27eac17..20db03a26a6 100644
--- a/crates/router/src/core/pm_auth.rs
+++ b/crates/router/src/core/pm_auth.rs
@@ -5,6 +5,7 @@ use api_models::{
     payment_methods::{self, BankAccountAccessCreds},
     payments::{AddressDetails, BankDebitBilling, BankDebitData, PaymentMethodData},
 };
+use common_enums::PaymentMethodType;
 use hex;
 pub mod helpers;
 pub mod transformers;
@@ -18,7 +19,7 @@ use common_utils::{
 use data_models::payments::PaymentIntent;
 use error_stack::{IntoReport, ResultExt};
 use helpers::PaymentAuthConnectorDataExt;
-use masking::{ExposeInterface, PeekInterface};
+use masking::{ExposeInterface, PeekInterface, Secret};
 use pm_auth::{
     connector::plaid::transformers::PlaidAuthType,
     types::{
@@ -273,7 +274,7 @@ async fn store_bank_details_in_payment_methods(
     merchant_account: domain::MerchantAccount,
     state: AppState,
     bank_account_details_resp: pm_auth_types::BankAccountCredentialsResponse,
-    connector_details: (&str, String),
+    connector_details: (&str, Secret<String>),
     mca_id: String,
 ) -> RouterResult<()> {
     let key = key_store.key.get_inner().peek();
@@ -357,7 +358,31 @@ async fn store_bank_details_in_payment_methods(
     let mut new_entries: Vec<storage::PaymentMethodNew> = Vec::new();
 
     for creds in bank_account_details_resp.credentials {
-        let hash_string = format!("{}-{}", creds.account_number, creds.routing_number);
+        let (account_number, hash_string) = match creds.account_details {
+            pm_auth_types::PaymentMethodTypeDetails::Ach(ach) => (
+                ach.account_number.clone(),
+                format!(
+                    "{}-{}-{}",
+                    ach.account_number.peek(),
+                    ach.routing_number.peek(),
+                    PaymentMethodType::Ach,
+                ),
+            ),
+            pm_auth_types::PaymentMethodTypeDetails::Bacs(bacs) => (
+                bacs.account_number.clone(),
+                format!(
+                    "{}-{}-{}",
+                    bacs.account_number.peek(),
+                    bacs.sort_code.peek(),
+                    PaymentMethodType::Bacs
+                ),
+            ),
+            pm_auth_types::PaymentMethodTypeDetails::Sepa(sepa) => (
+                sepa.iban.clone(),
+                format!("{}-{}", sepa.iban.expose(), PaymentMethodType::Sepa),
+            ),
+        };
+
         let generated_hash = hex::encode(
             HmacSha256::sign_message(&HmacSha256, pm_auth_key.as_bytes(), hash_string.as_bytes())
                 .change_context(ApiErrorResponse::InternalServerError)
@@ -366,8 +391,8 @@ async fn store_bank_details_in_payment_methods(
 
         let contains_account = hash_to_payment_method.get(&generated_hash);
         let mut pmd = payment_methods::PaymentMethodDataBankCreds {
-            mask: creds
-                .account_number
+            mask: account_number
+                .peek()
                 .chars()
                 .rev()
                 .take(4)
@@ -472,10 +497,10 @@ pub async fn get_bank_account_creds(
     connector: PaymentAuthConnectorData,
     merchant_account: &domain::MerchantAccount,
     connector_name: &str,
-    access_token: &str,
+    access_token: &Secret<String>,
     auth_type: pm_auth_types::ConnectorAuthType,
     state: &AppState,
-    bank_account_id: Option<String>,
+    bank_account_id: Option<Secret<String>>,
 ) -> RouterResult<pm_auth_types::BankAccountCredentialsResponse> {
     let connector_integration_bank_details: BoxedConnectorIntegration<
         '_,
@@ -489,7 +514,7 @@ pub async fn get_bank_account_creds(
         merchant_id: Some(merchant_account.merchant_id.clone()),
         connector: Some(connector_name.to_string()),
         request: pm_auth_types::BankAccountCredentialsRequest {
-            access_token: access_token.to_string(),
+            access_token: access_token.clone(),
             optional_ids: bank_account_id
                 .map(|id| pm_auth_types::BankAccountOptionalIDs { ids: vec![id] }),
         },
@@ -530,7 +555,7 @@ async fn get_access_token_from_exchange_api(
     payload: &api_models::pm_auth::ExchangeTokenCreateRequest,
     auth_type: &pm_auth_types::ConnectorAuthType,
     state: &AppState,
-) -> RouterResult<String> {
+) -> RouterResult<Secret<String>> {
     let connector_integration: BoxedConnectorIntegration<
         '_,
         ExchangeToken,
@@ -573,7 +598,7 @@ async fn get_access_token_from_exchange_api(
             })?;
 
     let access_token = exchange_token_resp.access_token;
-    Ok(access_token)
+    Ok(Secret::new(access_token))
 }
 
 async fn get_selected_config_from_redis(
@@ -593,7 +618,9 @@ async fn get_selected_config_from_redis(
             "Vec<PaymentMethodAuthConnectorChoice>",
         )
         .await
-        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .change_context(errors::ApiErrorResponse::GenericNotFoundError {
+            message: "payment method auth connector name not found".to_string(),
+        })
         .attach_printable("Failed to get payment method auth choices from redis")?;
 
     let selected_config = pm_auth_configs
@@ -603,7 +630,7 @@ async fn get_selected_config_from_redis(
                 && conf.payment_method_type == payload.payment_method_type
         })
         .ok_or(ApiErrorResponse::GenericNotFoundError {
-            message: "connector name not found".to_string(),
+            message: "payment method auth connector name not found".to_string(),
         })
         .into_report()?
         .clone();
@@ -614,14 +641,14 @@ async fn get_selected_config_from_redis(
 pub async fn retrieve_payment_method_from_auth_service(
     state: &AppState,
     key_store: &domain::MerchantKeyStore,
-    auth_token: &payment_methods::BankAccountConnectorDetails,
+    auth_token: &payment_methods::BankAccountTokenData,
     payment_intent: &PaymentIntent,
     customer: &Option<domain::Customer>,
 ) -> RouterResult<Option<(PaymentMethodData, enums::PaymentMethod)>> {
     let db = state.store.as_ref();
 
     let connector = pm_auth_types::api::PaymentAuthConnectorData::get_connector_by_name(
-        auth_token.connector.as_str(),
+        auth_token.connector_details.connector.as_str(),
     )?;
 
     let merchant_account = db
@@ -632,12 +659,12 @@ pub async fn retrieve_payment_method_from_auth_service(
     let mca = db
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
             &payment_intent.merchant_id,
-            &auth_token.mca_id,
+            &auth_token.connector_details.mca_id,
             key_store,
         )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound {
-            id: auth_token.mca_id.clone(),
+            id: auth_token.connector_details.mca_id.clone(),
         })
         .attach_printable(
             "error while fetching merchant_connector_account from merchant_id and connector name",
@@ -645,24 +672,27 @@ pub async fn retrieve_payment_method_from_auth_service(
 
     let auth_type = pm_auth_helpers::get_connector_auth_type(mca)?;
 
-    let BankAccountAccessCreds::AccessToken(access_token) = &auth_token.access_token;
+    let BankAccountAccessCreds::AccessToken(access_token) =
+        &auth_token.connector_details.access_token;
 
     let bank_account_creds = get_bank_account_creds(
         connector,
         &merchant_account,
-        &auth_token.connector,
+        &auth_token.connector_details.connector,
         access_token,
         auth_type,
         state,
-        Some(auth_token.account_id.clone()),
+        Some(auth_token.connector_details.account_id.clone()),
     )
     .await?;
 
-    logger::debug!("bank_creds: {:?}", bank_account_creds);
-
     let bank_account = bank_account_creds
         .credentials
-        .first()
+        .iter()
+        .find(|acc| {
+            acc.payment_method_type == auth_token.payment_method_type
+                && acc.payment_method == auth_token.payment_method
+        })
         .ok_or(errors::ApiErrorResponse::InternalServerError)
         .into_report()
         .attach_printable("Bank account details not found")?;
@@ -686,7 +716,12 @@ pub async fn retrieve_payment_method_from_auth_service(
 
     let name = address
         .as_ref()
-        .and_then(|addr| addr.first_name.clone().map(|name| name.into_inner()));
+        .and_then(|addr| addr.first_name.clone().map(|name| name.into_inner()))
+        .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
+            message: "billing_first_name not found".to_string(),
+        })
+        .into_report()
+        .attach_printable("billing_first_name not found")?;
 
     let address_details = address.clone().map(|addr| {
         let line1 = addr.line1.map(|line1| line1.into_inner());
@@ -716,20 +751,41 @@ pub async fn retrieve_payment_method_from_auth_service(
         .map(common_utils::pii::Email::from)
         .get_required_value("email")?;
 
-    let payment_method_data = PaymentMethodData::BankDebit(BankDebitData::AchBankDebit {
-        billing_details: BankDebitBilling {
-            name: name.unwrap_or_default(),
-            email,
-            address: address_details,
-        },
-        account_number: masking::Secret::new(bank_account.account_number.clone()),
-        routing_number: masking::Secret::new(bank_account.routing_number.clone()),
-        card_holder_name: None,
-        bank_account_holder_name: None,
-        bank_name: None,
-        bank_type,
-        bank_holder_type: None,
-    });
+    let billing_details = BankDebitBilling {
+        name,
+        email,
+        address: address_details,
+    };
+
+    let payment_method_data = match &bank_account.account_details {
+        pm_auth_types::PaymentMethodTypeDetails::Ach(ach) => {
+            PaymentMethodData::BankDebit(BankDebitData::AchBankDebit {
+                billing_details,
+                account_number: ach.account_number.clone(),
+                routing_number: ach.routing_number.clone(),
+                card_holder_name: None,
+                bank_account_holder_name: None,
+                bank_name: None,
+                bank_type,
+                bank_holder_type: None,
+            })
+        }
+        pm_auth_types::PaymentMethodTypeDetails::Bacs(bacs) => {
+            PaymentMethodData::BankDebit(BankDebitData::BacsBankDebit {
+                billing_details,
+                account_number: bacs.account_number.clone(),
+                sort_code: bacs.sort_code.clone(),
+                bank_account_holder_name: None,
+            })
+        }
+        pm_auth_types::PaymentMethodTypeDetails::Sepa(sepa) => {
+            PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit {
+                billing_details,
+                iban: sepa.iban.clone(),
+                bank_account_holder_name: None,
+            })
+        }
+    };
 
     Ok(Some((payment_method_data, enums::PaymentMethod::BankDebit)))
 }
diff --git a/crates/router/src/types/storage/payment_method.rs b/crates/router/src/types/storage/payment_method.rs
index d3339b7c4be..e1d74c70089 100644
--- a/crates/router/src/types/storage/payment_method.rs
+++ b/crates/router/src/types/storage/payment_method.rs
@@ -52,7 +52,7 @@ pub enum PaymentTokenData {
     TemporaryGeneric(GenericTokenData),
     Permanent(CardTokenData),
     PermanentCard(CardTokenData),
-    AuthBankDebit(payment_methods::BankAccountConnectorDetails),
+    AuthBankDebit(payment_methods::BankAccountTokenData),
     WalletToken(WalletTokenData),
 }
 

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

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

## Description
<!-- Describe your changes in detail -->
Support for SEPA and BACS in direct debit PM auth.
Earlier we only supported ACH based response from pm auth connector in PM auth, now have added support for BACS and SEPA based responses as well.



### Additional Changes

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

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

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


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

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


## 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)?
-->
Have tested locally by hardcoding response from connector. This cannot be tested as it is in sandbox because Plaid always sends a basic ACH based response in sandbox which won't trigger the response structure for BACS and SEPA (the implementation of this PR).
A simple sanity testing however can be done for the feature, refer to this for testing instructions - https://github.com/juspay/hyperswitch/pull/3047

<img width="1512" alt="image" src="https://github.com/juspay/hyperswitch/assets/76486416/2ec82cb1-8a1e-4d6f-b4ad-913bc082db54">
<img width="1512" alt="image" src="https://github.com/juspay/hyperswitch/assets/76486416/aafcaa7a-fdca-4344-9ed1-8d3e19b91006">



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

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
