Bug: [FEATURE] Add support for Bank Debits payment method



### Feature Description

### Problem statement
Bank Debits enables merchants to directly pull funds from the customers' bank accounts once the customers provide authorization for the same. It is primarily used for recurring transactions/mandates and for large ticket transactions like rent, fees, etc.
Hyperswitch will need to support the following popular Bank Debits from US and EU:

- ACH Direct Debit
- BECS Direct Debit
- BACS Direct Debit
- SEPA Direct Debit


### Possible Implementation

_No response_

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

- [X] I checked and didn't find 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
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index f7985c1fc42..43c341dcd67 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -409,11 +409,14 @@ pub enum PaymentExperience {
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
 pub enum PaymentMethodType {
+    Ach,
     Affirm,
     AfterpayClearpay,
     AliPay,
     ApplePay,
+    Bacs,
     BancontactCard,
+    Becs,
     Blik,
     Credit,
     CryptoCurrency,
@@ -432,6 +435,7 @@ pub enum PaymentMethodType {
     PayBright,
     Paypal,
     Przelewy24,
+    Sepa,
     Sofort,
     Swish,
     Trustly,
@@ -463,6 +467,7 @@ pub enum PaymentMethod {
     Wallet,
     BankRedirect,
     Crypto,
+    BankDebit,
 }
 
 #[derive(
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index d0165aa1f13..a73faf42775 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -462,13 +462,57 @@ pub enum PayLaterData {
     Walley {},
 }
 
-#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
+#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, ToSchema, Eq, PartialEq)]
+#[serde(rename_all = "snake_case")]
+pub enum BankDebitData {
+    /// Payment Method data for Ach bank debit
+    AchBankDebit {
+        /// Billing details for bank debit
+        billing_details: BankDebitBilling,
+        /// Account number for ach bank debit payment
+        #[schema(value_type = String, example = "000123456789")]
+        account_number: Secret<String>,
+        /// Routing number for ach bank debit payment
+        #[schema(value_type = String, example = "110000000")]
+        routing_number: Secret<String>,
+    },
+    SepaBankDebit {
+        /// Billing details for bank debit
+        billing_details: BankDebitBilling,
+        /// International bank account number (iban) for SEPA
+        #[schema(value_type = String, example = "DE89370400440532013000")]
+        iban: Secret<String>,
+    },
+    BecsBankDebit {
+        /// Billing details for bank debit
+        billing_details: BankDebitBilling,
+        /// Account number for Becs payment method
+        #[schema(value_type = String, example = "000123456")]
+        account_number: Secret<String>,
+        /// Bank-State-Branch (bsb) number
+        #[schema(value_type = String, example = "000000")]
+        bsb_number: Secret<String>,
+    },
+    BacsBankDebit {
+        /// Billing details for bank debit
+        billing_details: BankDebitBilling,
+        /// Account number for Bacs payment method
+        #[schema(value_type = String, example = "00012345")]
+        account_number: Secret<String>,
+        /// Sort code for Bacs payment method
+        #[schema(value_type = String, example = "108800")]
+        sort_code: Secret<String>,
+    },
+}
+
+#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
 #[serde(rename_all = "snake_case")]
 pub enum PaymentMethodData {
     Card(Card),
     Wallet(WalletData),
     PayLater(PayLaterData),
     BankRedirect(BankRedirectData),
+    BankDebit(BankDebitData),
     Crypto(CryptoData),
 }
 
@@ -485,6 +529,7 @@ pub enum AdditionalPaymentData {
     Wallet {},
     PayLater {},
     Crypto {},
+    BankDebit {},
 }
 
 impl From<&PaymentMethodData> for AdditionalPaymentData {
@@ -509,6 +554,7 @@ impl From<&PaymentMethodData> for AdditionalPaymentData {
             PaymentMethodData::Wallet(_) => Self::Wallet {},
             PaymentMethodData::PayLater(_) => Self::PayLater {},
             PaymentMethodData::Crypto(_) => Self::Crypto {},
+            PaymentMethodData::BankDebit(_) => Self::BankDebit {},
         }
     }
 }
@@ -607,6 +653,18 @@ pub struct BankRedirectBilling {
     pub billing_name: Secret<String>,
 }
 
+#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, ToSchema, Eq, PartialEq)]
+pub struct BankDebitBilling {
+    /// The billing name for bank debits
+    #[schema(value_type = String, example = "John Doe")]
+    pub name: Secret<String>,
+    /// The billing email for bank debits
+    #[schema(value_type = String, example = "example@example.com")]
+    pub email: Secret<String, pii::Email>,
+    /// The billing address for bank debits
+    pub address: Option<AddressDetails>,
+}
+
 #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
 #[serde(rename_all = "snake_case")]
 pub enum WalletData {
@@ -720,6 +778,7 @@ pub enum PaymentMethodDataResponse {
     Paypal,
     BankRedirect(BankRedirectData),
     Crypto(CryptoData),
+    BankDebit(BankDebitData),
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, ToSchema)]
@@ -1135,7 +1194,7 @@ pub struct PaymentListResponse {
     pub data: Vec<PaymentsResponse>,
 }
 
-#[derive(Setter, Clone, Default, Debug, Eq, PartialEq, serde::Serialize)]
+#[derive(Setter, Clone, Default, Debug, serde::Serialize)]
 pub struct VerifyResponse {
     pub verify_id: Option<String>,
     pub merchant_id: Option<String>,
@@ -1260,6 +1319,7 @@ impl From<PaymentMethodData> for PaymentMethodDataResponse {
                 Self::BankRedirect(bank_redirect_data)
             }
             PaymentMethodData::Crypto(crpto_data) => Self::Crypto(crpto_data),
+            PaymentMethodData::BankDebit(bank_debit_data) => Self::BankDebit(bank_debit_data),
         }
     }
 }
diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs
index 644d148b34f..010de4d91a5 100644
--- a/crates/router/src/connector/aci/transformers.rs
+++ b/crates/router/src/connector/aci/transformers.rs
@@ -111,11 +111,14 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AciPaymentsRequest {
             api::PaymentMethodData::PayLater(_) => PaymentDetails::Klarna,
             api::PaymentMethodData::Wallet(_) => PaymentDetails::Wallet,
             api::PaymentMethodData::BankRedirect(_) => PaymentDetails::BankRedirect,
-            api::PaymentMethodData::Crypto(_) => Err(errors::ConnectorError::NotSupported {
-                payment_method: format!("{:?}", item.payment_method),
-                connector: "Aci",
-                payment_experience: api_models::enums::PaymentExperience::RedirectToUrl.to_string(),
-            })?,
+            api::PaymentMethodData::Crypto(_) | api::PaymentMethodData::BankDebit(_) => {
+                Err(errors::ConnectorError::NotSupported {
+                    payment_method: format!("{:?}", item.payment_method),
+                    connector: "Aci",
+                    payment_experience: api_models::enums::PaymentExperience::RedirectToUrl
+                        .to_string(),
+                })?
+            }
         };
 
         let auth = AciAuthType::try_from(&item.connector_auth_type)?;
diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs
index e8da467c383..f9992431838 100644
--- a/crates/router/src/connector/authorizedotnet/transformers.rs
+++ b/crates/router/src/connector/authorizedotnet/transformers.rs
@@ -87,11 +87,14 @@ impl TryFrom<api_models::payments::PaymentMethodData> for PaymentDetails {
             api::PaymentMethodData::PayLater(_) => Ok(Self::Klarna),
             api::PaymentMethodData::Wallet(_) => Ok(Self::Wallet),
             api::PaymentMethodData::BankRedirect(_) => Ok(Self::BankRedirect),
-            api::PaymentMethodData::Crypto(_) => Err(errors::ConnectorError::NotSupported {
-                payment_method: format!("{value:?}"),
-                connector: "AuthorizeDotNet",
-                payment_experience: api_models::enums::PaymentExperience::RedirectToUrl.to_string(),
-            })?,
+            api::PaymentMethodData::Crypto(_) | api::PaymentMethodData::BankDebit(_) => {
+                Err(errors::ConnectorError::NotSupported {
+                    payment_method: format!("{value:?}"),
+                    connector: "AuthorizeDotNet",
+                    payment_experience: api_models::enums::PaymentExperience::RedirectToUrl
+                        .to_string(),
+                })?
+            }
         }
     }
 }
diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs
index d5e00464fc4..267a577325c 100644
--- a/crates/router/src/connector/stripe/transformers.rs
+++ b/crates/router/src/connector/stripe/transformers.rs
@@ -1,8 +1,8 @@
 use api_models::{self, enums as api_enums, payments};
 use base64::Engine;
-use common_utils::{fp_utils, pii::Email};
+use common_utils::{fp_utils, pii};
 use error_stack::{IntoReport, ResultExt};
-use masking::ExposeInterface;
+use masking::{ExposeInterface, ExposeOptionInterface, Secret};
 use serde::{Deserialize, Serialize};
 use url::Url;
 use uuid::Uuid;
@@ -10,7 +10,6 @@ use uuid::Uuid;
 use crate::{
     consts,
     core::errors,
-    pii::{self, ExposeOptionInterface, Secret},
     services,
     types::{self, api, storage::enums},
     utils::OptionExt,
@@ -63,6 +62,22 @@ pub enum Auth3ds {
     Any,
 }
 
+#[derive(Debug, Eq, PartialEq, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum StripeMandateType {
+    Online,
+}
+
+#[derive(Debug, Eq, PartialEq, Serialize)]
+pub struct StripeMandateRequest {
+    #[serde(rename = "mandate_data[customer_acceptance][type]")]
+    pub mandate_type: StripeMandateType,
+    #[serde(rename = "mandate_data[customer_acceptance][online][ip_address]")]
+    pub ip_address: Secret<String, pii::IpAddress>,
+    #[serde(rename = "mandate_data[customer_acceptance][online][user_agent]")]
+    pub user_agent: String,
+}
+
 #[derive(Debug, Eq, PartialEq, Serialize)]
 pub struct PaymentIntentRequest {
     pub amount: i64, //amount in cents, hence passed as integer
@@ -78,6 +93,8 @@ pub struct PaymentIntentRequest {
     pub return_url: String,
     pub confirm: bool,
     pub mandate: Option<String>,
+    #[serde(flatten)]
+    pub setup_mandate_details: Option<StripeMandateRequest>,
     pub description: Option<String>,
     #[serde(flatten)]
     pub shipping: StripeShippingAddress,
@@ -198,6 +215,47 @@ pub struct StripeBankRedirectData {
     pub bank_specific_data: Option<BankSpecificData>,
 }
 
+#[derive(Debug, Eq, PartialEq, Serialize)]
+#[serde(tag = "payment_method_data[type]")]
+pub enum BankDebitData {
+    #[serde(rename = "us_bank_account")]
+    Ach {
+        #[serde(rename = "payment_method_data[us_bank_account][account_holder_type]")]
+        account_holder_type: String,
+        #[serde(rename = "payment_method_data[us_bank_account][account_number]")]
+        account_number: Secret<String>,
+        #[serde(rename = "payment_method_data[us_bank_account][routing_number]")]
+        routing_number: Secret<String>,
+    },
+    #[serde(rename = "sepa_debit")]
+    Sepa {
+        #[serde(rename = "payment_method_data[sepa_debit][iban]")]
+        iban: Secret<String>,
+    },
+    #[serde(rename = "au_becs_debit")]
+    Becs {
+        #[serde(rename = "payment_method_data[au_becs_debit][account_number]")]
+        account_number: Secret<String>,
+        #[serde(rename = "payment_method_data[au_becs_debit][bsb_number]")]
+        bsb_number: Secret<String>,
+    },
+    #[serde(rename = "bacs_debit")]
+    Bacs {
+        #[serde(rename = "payment_method_data[bacs_debit][account_number]")]
+        account_number: Secret<String>,
+        #[serde(rename = "payment_method_data[bacs_debit][sort_code]")]
+        sort_code: Secret<String>,
+    },
+}
+
+#[derive(Debug, Eq, PartialEq, Serialize)]
+pub struct StripeBankDebitData {
+    #[serde(rename = "payment_method_types[]")]
+    pub payment_method_types: StripePaymentMethodType,
+    #[serde(flatten)]
+    pub bank_specific_data: BankDebitData,
+}
+
 #[derive(Debug, Eq, PartialEq, Serialize)]
 #[serde(untagged)]
 pub enum StripePaymentMethodData {
@@ -205,6 +263,7 @@ pub enum StripePaymentMethodData {
     PayLater(StripePayLaterData),
     Wallet(StripeWallet),
     BankRedirect(StripeBankRedirectData),
+    BankDebit(StripeBankDebitData),
 }
 
 #[derive(Debug, Eq, PartialEq, Serialize)]
@@ -230,7 +289,7 @@ pub struct ApplepayPayment {
     pub payment_method_types: StripePaymentMethodType,
 }
 
-#[derive(Debug, Eq, PartialEq, Serialize, Clone)]
+#[derive(Debug, Eq, PartialEq, Serialize, Clone, Copy)]
 #[serde(rename_all = "snake_case")]
 pub enum StripePaymentMethodType {
     Card,
@@ -242,6 +301,14 @@ pub enum StripePaymentMethodType {
     Ideal,
     Sofort,
     ApplePay,
+    #[serde(rename = "us_bank_account")]
+    Ach,
+    #[serde(rename = "sepa_debit")]
+    Sepa,
+    #[serde(rename = "au_becs_debit")]
+    Becs,
+    #[serde(rename = "bacs_debit")]
+    Bacs,
 }
 
 #[derive(Debug, Eq, PartialEq, Serialize, Clone)]
@@ -472,6 +539,35 @@ impl TryFrom<(&api_models::payments::PayLaterData, StripePaymentMethodType)>
     }
 }
 
+impl From<&payments::BankDebitBilling> for StripeBillingAddress {
+    fn from(item: &payments::BankDebitBilling) -> Self {
+        Self {
+            email: Some(item.email.to_owned()),
+            country: item
+                .address
+                .as_ref()
+                .and_then(|address| address.country.to_owned()),
+            name: Some(item.name.to_owned()),
+            city: item
+                .address
+                .as_ref()
+                .and_then(|address| address.city.to_owned()),
+            address_line1: item
+                .address
+                .as_ref()
+                .and_then(|address| address.line1.to_owned()),
+            address_line2: item
+                .address
+                .as_ref()
+                .and_then(|address| address.line2.to_owned()),
+            zip_code: item
+                .address
+                .as_ref()
+                .and_then(|address| address.zip.to_owned()),
+        }
+    }
+}
+
 impl TryFrom<&payments::BankRedirectData> for StripeBillingAddress {
     type Error = errors::ConnectorError;
 
@@ -514,6 +610,64 @@ fn get_bank_specific_data(
     }
 }
 
+fn get_bank_debit_data(
+    bank_debit_data: &payments::BankDebitData,
+) -> (StripePaymentMethodType, BankDebitData, StripeBillingAddress) {
+    match bank_debit_data {
+        payments::BankDebitData::AchBankDebit {
+            billing_details,
+            account_number,
+            routing_number,
+        } => {
+            let ach_data = BankDebitData::Ach {
+                account_holder_type: "individual".to_string(),
+                account_number: account_number.to_owned(),
+                routing_number: routing_number.to_owned(),
+            };
+
+            let billing_data = StripeBillingAddress::from(billing_details);
+            (StripePaymentMethodType::Ach, ach_data, billing_data)
+        }
+        payments::BankDebitData::SepaBankDebit {
+            billing_details,
+            iban,
+        } => {
+            let sepa_data = BankDebitData::Sepa {
+                iban: iban.to_owned(),
+            };
+
+            let billing_data = StripeBillingAddress::from(billing_details);
+            (StripePaymentMethodType::Sepa, sepa_data, billing_data)
+        }
+        payments::BankDebitData::BecsBankDebit {
+            billing_details,
+            account_number,
+            bsb_number,
+        } => {
+            let becs_data = BankDebitData::Becs {
+                account_number: account_number.to_owned(),
+                bsb_number: bsb_number.to_owned(),
+            };
+
+            let billing_data = StripeBillingAddress::from(billing_details);
+            (StripePaymentMethodType::Becs, becs_data, billing_data)
+        }
+        payments::BankDebitData::BacsBankDebit {
+            billing_details,
+            account_number,
+            sort_code,
+        } => {
+            let bacs_data = BankDebitData::Bacs {
+                account_number: account_number.to_owned(),
+                sort_code: sort_code.to_owned(),
+            };
+
+            let billing_data = StripeBillingAddress::from(billing_details);
+            (StripePaymentMethodType::Bacs, bacs_data, billing_data)
+        }
+    }
+}
+
 fn create_stripe_payment_method(
     pm_type: Option<&enums::PaymentMethodType>,
     experience: Option<&enums::PaymentExperience>,
@@ -558,13 +712,12 @@ fn create_stripe_payment_method(
 
             let stripe_pm_type = infer_stripe_pay_later_type(pm_type, pm_experience)?;
 
-            let billing_address =
-                StripeBillingAddress::try_from((pay_later_data, stripe_pm_type.clone()))?;
+            let billing_address = StripeBillingAddress::try_from((pay_later_data, stripe_pm_type))?;
 
             Ok((
                 StripePaymentMethodData::PayLater(StripePayLaterData {
-                    payment_method_types: stripe_pm_type.clone(),
-                    payment_method_data_type: stripe_pm_type.clone(),
+                    payment_method_types: stripe_pm_type,
+                    payment_method_data_type: stripe_pm_type,
                 }),
                 stripe_pm_type,
                 billing_address,
@@ -577,8 +730,8 @@ fn create_stripe_payment_method(
             let bank_name = get_bank_name(&pm_type, bank_redirect_data)?;
             Ok((
                 StripePaymentMethodData::BankRedirect(StripeBankRedirectData {
-                    payment_method_types: pm_type.clone(),
-                    payment_method_data_type: pm_type.clone(),
+                    payment_method_types: pm_type,
+                    payment_method_data_type: pm_type,
                     bank_name,
                     bank_specific_data,
                 }),
@@ -609,6 +762,16 @@ fn create_stripe_payment_method(
             )
             .into()),
         },
+        payments::PaymentMethodData::BankDebit(bank_debit_data) => {
+            let (pm_type, bank_debit_data, billing_address) = get_bank_debit_data(bank_debit_data);
+
+            let pm_data = StripePaymentMethodData::BankDebit(StripeBankDebitData {
+                payment_method_types: pm_type,
+                bank_specific_data: bank_debit_data,
+            });
+
+            Ok((pm_data, pm_type, billing_address))
+        }
         _ => Err(errors::ConnectorError::NotImplemented(
             "stripe does not support this payment method".to_string(),
         )
@@ -694,6 +857,22 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
             _ => payment_data,
         };
 
+        let setup_mandate_details =
+            item.request
+                .setup_mandate_details
+                .as_ref()
+                .and_then(|mandate_details| {
+                    mandate_details
+                        .customer_acceptance
+                        .online
+                        .as_ref()
+                        .map(|online_details| StripeMandateRequest {
+                            mandate_type: StripeMandateType::Online,
+                            ip_address: online_details.ip_address.to_owned(),
+                            user_agent: online_details.user_agent.to_owned(),
+                        })
+                });
+
         Ok(Self {
             amount: item.request.amount, //hopefully we don't loose some cents here
             currency: item.request.currency.to_string(), //we need to copy the value and not transfer ownership
@@ -715,6 +894,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
             capture_method: StripeCaptureMethod::from(item.request.capture_method),
             payment_data,
             mandate,
+            setup_mandate_details,
         })
     }
 }
@@ -881,12 +1061,9 @@ impl<F, T>
     fn try_from(
         item: types::ResponseRouterData<F, PaymentIntentResponse, T, types::PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
-        let redirection_data =
-            item.response
-                .next_action
-                .map(|StripeNextActionResponse::RedirectToUrl(response)| {
-                    services::RedirectForm::from((response.url, services::Method::Get))
-                });
+        let redirection_data = item.response.next_action.map(|next_action_response| {
+            services::RedirectForm::from((next_action_response.get_url(), services::Method::Get))
+        });
 
         let mandate_reference =
             item.response
@@ -929,11 +1106,16 @@ impl<F, T>
             types::PaymentsResponseData,
         >,
     ) -> Result<Self, Self::Error> {
-        let redirection_data = item.response.next_action.as_ref().map(
-            |StripeNextActionResponse::RedirectToUrl(response)| {
-                services::RedirectForm::from((response.url.clone(), services::Method::Get))
-            },
-        );
+        let redirection_data = item
+            .response
+            .next_action
+            .as_ref()
+            .map(|next_action_response| {
+                services::RedirectForm::from((
+                    next_action_response.get_url(),
+                    services::Method::Get,
+                ))
+            });
 
         let mandate_reference =
             item.response
@@ -949,7 +1131,11 @@ impl<F, T>
                     | StripePaymentMethodOptions::Eps {}
                     | StripePaymentMethodOptions::Giropay {}
                     | StripePaymentMethodOptions::Ideal {}
-                    | StripePaymentMethodOptions::Sofort {} => None,
+                    | StripePaymentMethodOptions::Sofort {}
+                    | StripePaymentMethodOptions::Ach {}
+                    | StripePaymentMethodOptions::Bacs {}
+                    | StripePaymentMethodOptions::Becs {}
+                    | StripePaymentMethodOptions::Sepa {} => None,
                 });
 
         let error_res =
@@ -990,12 +1176,9 @@ impl<F, T>
     fn try_from(
         item: types::ResponseRouterData<F, SetupIntentResponse, T, types::PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
-        let redirection_data =
-            item.response
-                .next_action
-                .map(|StripeNextActionResponse::RedirectToUrl(response)| {
-                    services::RedirectForm::from((response.url, services::Method::Get))
-                });
+        let redirection_data = item.response.next_action.map(|next_action_response| {
+            services::RedirectForm::from((next_action_response.get_url(), services::Method::Get))
+        });
 
         let mandate_reference =
             item.response
@@ -1024,6 +1207,18 @@ impl<F, T>
 #[serde(rename_all = "snake_case", remote = "Self")]
 pub enum StripeNextActionResponse {
     RedirectToUrl(StripeRedirectToUrlResponse),
+    VerifyWithMicrodeposits(StripeVerifyWithMicroDepositsResponse),
+}
+
+impl StripeNextActionResponse {
+    fn get_url(&self) -> Url {
+        match self {
+            Self::RedirectToUrl(redirect_to_url) => redirect_to_url.url.to_owned(),
+            Self::VerifyWithMicrodeposits(verify_with_microdeposits) => {
+                verify_with_microdeposits.hosted_verification_url.to_owned()
+            }
+        }
+    }
 }
 
 // This impl is required because Stripe's response is of the below format, which is externally
@@ -1052,6 +1247,11 @@ pub struct StripeRedirectToUrlResponse {
     url: Url,
 }
 
+#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
+pub struct StripeVerifyWithMicroDepositsResponse {
+    hosted_verification_url: Url,
+}
+
 // REFUND :
 // Type definition for Stripe RefundRequest
 
@@ -1189,11 +1389,19 @@ pub struct StripeShippingAddress {
 #[derive(Debug, Default, Eq, PartialEq, Serialize)]
 pub struct StripeBillingAddress {
     #[serde(rename = "payment_method_data[billing_details][email]")]
-    pub email: Option<Secret<String, Email>>,
+    pub email: Option<Secret<String, pii::Email>>,
     #[serde(rename = "payment_method_data[billing_details][address][country]")]
     pub country: Option<api_enums::CountryCode>,
     #[serde(rename = "payment_method_data[billing_details][name]")]
     pub name: Option<Secret<String>>,
+    #[serde(rename = "payment_method_data[billing_details][address][city]")]
+    pub city: Option<String>,
+    #[serde(rename = "payment_method_data[billing_details][address][line1]")]
+    pub address_line1: Option<Secret<String>>,
+    #[serde(rename = "payment_method_data[billing_details][address][line2]")]
+    pub address_line2: Option<Secret<String>>,
+    #[serde(rename = "payment_method_data[billing_details][address][postal_code]")]
+    pub zip_code: Option<Secret<String>>,
 }
 
 #[derive(Debug, Clone, serde::Deserialize, Eq, PartialEq)]
@@ -1233,6 +1441,14 @@ pub enum StripePaymentMethodOptions {
     Giropay {},
     Ideal {},
     Sofort {},
+    #[serde(rename = "us_bank_account")]
+    Ach {},
+    #[serde(rename = "sepa_debit")]
+    Sepa {},
+    #[serde(rename = "au_becs_debit")]
+    Becs {},
+    #[serde(rename = "bacs_debit")]
+    Bacs {},
 }
 // #[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
 // pub struct Card
@@ -1373,12 +1589,12 @@ impl
                 }
             })),
             api::PaymentMethodData::PayLater(_) => Ok(Self::PayLater(StripePayLaterData {
-                payment_method_types: pm_type.clone(),
+                payment_method_types: pm_type,
                 payment_method_data_type: pm_type,
             })),
             api::PaymentMethodData::BankRedirect(_) => {
                 Ok(Self::BankRedirect(StripeBankRedirectData {
-                    payment_method_types: pm_type.clone(),
+                    payment_method_types: pm_type,
                     payment_method_data_type: pm_type,
                     bank_name: None,
                     bank_specific_data: None,
@@ -1403,6 +1619,14 @@ impl
                 }
                 _ => Err(errors::ConnectorError::InvalidWallet.into()),
             },
+            api::PaymentMethodData::BankDebit(bank_debit_data) => {
+                let (pm_type, bank_data, _) = get_bank_debit_data(&bank_debit_data);
+
+                Ok(Self::BankDebit(StripeBankDebitData {
+                    payment_method_types: pm_type,
+                    bank_specific_data: bank_data,
+                }))
+            }
             api::PaymentMethodData::Crypto(_) => Err(errors::ConnectorError::NotSupported {
                 payment_method: format!("{pm_type:?}"),
                 connector: "Stripe",
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index f6e21648305..4c7a76765cb 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -802,6 +802,7 @@ pub async fn make_pm_data<'a, F: Clone, R>(
         (pm @ Some(api::PaymentMethodData::PayLater(_)), _) => Ok(pm.to_owned()),
         (pm @ Some(api::PaymentMethodData::BankRedirect(_)), _) => Ok(pm.to_owned()),
         (pm @ Some(api::PaymentMethodData::Crypto(_)), _) => Ok(pm.to_owned()),
+        (pm @ Some(api::PaymentMethodData::BankDebit(_)), _) => Ok(pm.to_owned()),
         (pm_opt @ Some(pm @ api::PaymentMethodData::Wallet(_)), _) => {
             let token = vault::Vault::store_payment_method_data_in_locker(
                 state,
diff --git a/crates/router/src/openapi.rs b/crates/router/src/openapi.rs
index d16e2ef5972..e5aeac89567 100644
--- a/crates/router/src/openapi.rs
+++ b/crates/router/src/openapi.rs
@@ -155,6 +155,7 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::payments::Address,
         api_models::payments::BankRedirectData,
         api_models::payments::BankRedirectBilling,
+        api_models::payments::BankRedirectBilling,
         api_models::payments::OrderDetails,
         api_models::payments::NextActionType,
         api_models::payments::Metadata,
diff --git a/crates/storage_models/src/enums.rs b/crates/storage_models/src/enums.rs
index 21bb28561e8..c858ea25939 100644
--- a/crates/storage_models/src/enums.rs
+++ b/crates/storage_models/src/enums.rs
@@ -456,6 +456,7 @@ pub enum PaymentMethod {
     Wallet,
     BankRedirect,
     Crypto,
+    BankDebit,
 }
 
 #[derive(
@@ -612,11 +613,14 @@ pub enum MandateStatus {
 #[strum(serialize_all = "snake_case")]
 #[serde(rename_all = "snake_case")]
 pub enum PaymentMethodType {
+    Ach,
     Affirm,
     AfterpayClearpay,
     AliPay,
     ApplePay,
+    Bacs,
     BancontactCard,
+    Becs,
     Blik,
     Credit,
     CryptoCurrency,
@@ -635,6 +639,7 @@ pub enum PaymentMethodType {
     PayBright,
     Paypal,
     Przelewy24,
+    Sepa,
     Sofort,
     Swish,
     Trustly,

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

- [x] New feature

## Description
<!-- Describe your changes in detail -->
This PR will add support for creating payments using `bank_debits` payment method. This has been implemented for stripe.
Mandate details have to passed for all the payment methods.
- Sample mandate data
```json
{
"mandate_data": {
        "customer_acceptance": {
            "acceptance_type": "online",
            "accepted_at": "2022-09-10T10:11:12Z",
            "online": {
                "ip_address": "123.32.25.123",
                "user_agent": "Mozilla/5.0 (Linux; Android 12; SM-S906N Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36"
            }
        },
        "mandate_type": {
            "single_use": {
                "amount": 6540,
                "currency": "USD"
            }
        }
    },
}
```
- Ach Bank debit in US. Create a `merchant_connector_account` with `business_country` as `US`.
```json
{
"currency":"USD",
"business_country": "US",
"payment_method": "bank_debit",
    "payment_method_type": "ach",
    "payment_method_data": {
        "bank_debit": {
            "ach_bank_debit": {
                "billing_details": {
                    "name": "John Doe",
                    "email": "johndoe@example.com"
                },
                "account_number": "000123456789",
                "routing_number": "110000000"
            }
        }
    }
}
```

- Sepa. Create a `merchant_connector_account` in any country of the EU region, example "FR".
```json
{
"currency":"EUR",
"business_country":"FR",
"payment_method": "bank_debit",
    "payment_method_type": "sepa",
    "payment_method_data": {
        "bank_debit": {
            "sepa_bank_debit": {
                "billing_details": {
                    "name": "John Doe",
                    "email": "johndoe@example.com"
                },
                "iban": "DE89370400440532013000"
            }
        }
    }
}
```

- Becs. Create a `merchant_connector_account` in `AU` region.
```json
{
"currency":"AUD",
"payment_method": "bank_debit",
    "payment_method_type": "becs",
    "payment_method_data": {
        "bank_debit": {
            "becs_bank_debit": {
                "billing_details": {
                    "name": "John Doe",
                    "email": "johndoe@example.com"
                },
                "account_number": "000123456",
                "bsb_number": "000000"
            }
        }
    }
}
```
- Bacs
```json
{
"payment_method_type": "bacs",
    "payment_method_data": {
        "bank_debit": {
            "bacs_bank_debit": {
                "billing_details": {
                    "name": "John Doe",
                    "email": "johndoe@example.com",
                    "address": {
                        "line1": "Street",
                        "line2": "Area",
                        "city": "LDN",
                        "zip": "SW1A",
                        "country": "GB"
                    }
                },
                "account_number": "00012345",
                "sort_code": "108800"
            }
        }
    }
}
```

## 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 its an obvious bug or documentation fix
that will have little conversation).
-->
To support `bank_debits` payment method for anyone to use. Closes #838 

## 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)?
-->
- ACH bank debit
<img width="844" alt="Screenshot 2023-04-18 at 12 43 41 PM" src="https://user-images.githubusercontent.com/48803246/232700078-0e6670df-810e-4aa0-ad50-c9988f676714.png">
- Microdeposit verification for ACH
<img alt="Screenshot 2023-04-18 at 12 45 26 PM" src = "https://user-images.githubusercontent.com/48803246/232700520-a9980e9e-d21b-4ea3-ad62-fcc13e72f305.png">

- Sepa bank debit
<img width="829" alt="Screenshot 2023-04-18 at 12 56 24 PM" src="https://user-images.githubusercontent.com/48803246/232703129-ac241075-dcc2-40b9-b376-cabb05733a26.png">

- Bacs bank debit
The payment goes to `requires_action`. This requires some options to be enabled in stripe account.

- Becs bank debit
<img width="824" alt="Screenshot 2023-04-19 at 12 50 14 PM" src="https://user-images.githubusercontent.com/48803246/232998656-02007ecb-e713-41a7-a541-bc9782dd8e28.png">


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

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