Bug: [FEATURE] filter out payment_methods which doesn't support mandates during list api call



### Feature Description

When a mandate payment is created, sdk makes a payment_method_list api call which lists all the payment_methods. But not all of them support mandate payments. 
Filter the payment_methods which doesn't support mandates and list only those which supports during payment_method_list api call.

### Possible Implementation

Create an hashmap indicating which payment_methods through which connector, supports mandates. And while listing payment methods, validate between the merchant configured payment_methods and the supported payment_methods.

### 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 I am willing to submit a PR!
diff --git a/config/config.example.toml b/config/config.example.toml
index 4f54a4a6c28..06ff14b9818 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -290,6 +290,10 @@ refund_tolerance = 100           # Fake delay tolerance for dummy connector refu
 refund_retrieve_duration = 500   # Fake delay duration for dummy connector refund sync
 refund_retrieve_tolerance = 100  # Fake delay tolerance for dummy connector refund sync
 
+[mandates.supported_payment_methods]
+card.credit = {connector_list = "stripe,adyen"}     # Mandate supported payment method type and connector for card
+pay_later.klarna = {connector_list = "adyen"}       # Mandate supported payment method type and connector for pay_later
+
 # Required fields info used while listing the payment_method_data
 [required_fields.pay_later] # payment_method = "pay_later"
 afterpay_clearpay = {fields = {stripe = [  # payment_method_type = afterpay_clearpay, connector = "stripe"
diff --git a/config/development.toml b/config/development.toml
index ce57de8ec9c..05450f51454 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -307,5 +307,12 @@ refund_retrieve_tolerance = 100
 [delayed_session_response]
 connectors_with_delayed_session_response = "trustpay"
 
+[mandates.supported_payment_methods]
+pay_later.klarna = {connector_list = "adyen"}
+wallet.google_pay = {connector_list = "stripe,adyen"}
+wallet.apple_pay = {connector_list = "stripe,adyen"}
+card.credit = {connector_list = "stripe,adyen,authorizedotnet,globalpay,worldpay,multisafepay,nmi,nexinets,noon"}
+card.debit = {connector_list = "stripe,adyen,authorizedotnet,globalpay,worldpay,multisafepay,nmi,nexinets,noon"}
+
 [connector_request_reference_id_config]
 merchant_ids_send_payment_id_as_connector_request_id = []
diff --git a/crates/router/src/configs/defaults.rs b/crates/router/src/configs/defaults.rs
index b6c63c49505..2b566d2664e 100644
--- a/crates/router/src/configs/defaults.rs
+++ b/crates/router/src/configs/defaults.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
 
 use api_models::{enums, payment_methods::RequiredFieldInfo};
 
@@ -143,6 +143,89 @@ impl Default for super::settings::DrainerSettings {
     }
 }
 
+use super::settings::{
+    Mandates, SupportedConnectorsForMandate, SupportedPaymentMethodTypesForMandate,
+    SupportedPaymentMethodsForMandate,
+};
+
+impl Default for Mandates {
+    fn default() -> Self {
+        Self {
+            supported_payment_methods: SupportedPaymentMethodsForMandate(HashMap::from([
+                (
+                    enums::PaymentMethod::PayLater,
+                    SupportedPaymentMethodTypesForMandate(HashMap::from([(
+                        enums::PaymentMethodType::Klarna,
+                        SupportedConnectorsForMandate {
+                            connector_list: HashSet::from([enums::Connector::Adyen]),
+                        },
+                    )])),
+                ),
+                (
+                    enums::PaymentMethod::Wallet,
+                    SupportedPaymentMethodTypesForMandate(HashMap::from([
+                        (
+                            enums::PaymentMethodType::GooglePay,
+                            SupportedConnectorsForMandate {
+                                connector_list: HashSet::from([
+                                    enums::Connector::Stripe,
+                                    enums::Connector::Adyen,
+                                ]),
+                            },
+                        ),
+                        (
+                            enums::PaymentMethodType::ApplePay,
+                            SupportedConnectorsForMandate {
+                                connector_list: HashSet::from([
+                                    enums::Connector::Stripe,
+                                    enums::Connector::Adyen,
+                                ]),
+                            },
+                        ),
+                    ])),
+                ),
+                (
+                    enums::PaymentMethod::Card,
+                    SupportedPaymentMethodTypesForMandate(HashMap::from([
+                        (
+                            enums::PaymentMethodType::Credit,
+                            SupportedConnectorsForMandate {
+                                connector_list: HashSet::from([
+                                    enums::Connector::Stripe,
+                                    enums::Connector::Adyen,
+                                    enums::Connector::Authorizedotnet,
+                                    enums::Connector::Globalpay,
+                                    enums::Connector::Worldpay,
+                                    enums::Connector::Multisafepay,
+                                    enums::Connector::Nmi,
+                                    enums::Connector::Nexinets,
+                                    enums::Connector::Noon,
+                                ]),
+                            },
+                        ),
+                        (
+                            enums::PaymentMethodType::Debit,
+                            SupportedConnectorsForMandate {
+                                connector_list: HashSet::from([
+                                    enums::Connector::Stripe,
+                                    enums::Connector::Adyen,
+                                    enums::Connector::Authorizedotnet,
+                                    enums::Connector::Globalpay,
+                                    enums::Connector::Worldpay,
+                                    enums::Connector::Multisafepay,
+                                    enums::Connector::Nmi,
+                                    enums::Connector::Nexinets,
+                                    enums::Connector::Noon,
+                                ]),
+                            },
+                        ),
+                    ])),
+                ),
+            ])),
+        }
+    }
+}
+
 impl Default for super::settings::RequiredFields {
     fn default() -> Self {
         Self(HashMap::from([
diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs
index a0b2f62c793..f629ab4283c 100644
--- a/crates/router/src/configs/settings.rs
+++ b/crates/router/src/configs/settings.rs
@@ -83,6 +83,7 @@ pub struct Settings {
     pub dummy_connector: DummyConnector,
     #[cfg(feature = "email")]
     pub email: EmailSettings,
+    pub mandates: Mandates,
     pub required_fields: RequiredFields,
     pub delayed_session_response: DelayedSessionConfig,
     pub connector_request_reference_id_config: ConnectorRequestReferenceIdConfig,
@@ -127,6 +128,27 @@ pub struct DummyConnector {
     pub refund_retrieve_tolerance: u64,
 }
 
+#[derive(Debug, Deserialize, Clone)]
+pub struct Mandates {
+    pub supported_payment_methods: SupportedPaymentMethodsForMandate,
+}
+
+#[derive(Debug, Deserialize, Clone)]
+pub struct SupportedPaymentMethodsForMandate(
+    pub HashMap<enums::PaymentMethod, SupportedPaymentMethodTypesForMandate>,
+);
+
+#[derive(Debug, Deserialize, Clone)]
+pub struct SupportedPaymentMethodTypesForMandate(
+    pub HashMap<enums::PaymentMethodType, SupportedConnectorsForMandate>,
+);
+
+#[derive(Debug, Deserialize, Clone)]
+pub struct SupportedConnectorsForMandate {
+    #[serde(deserialize_with = "connector_deser")]
+    pub connector_list: HashSet<api_models::enums::Connector>,
+}
+
 #[derive(Debug, Deserialize, Clone, Default)]
 pub struct PaymentMethodTokenFilter {
     #[serde(deserialize_with = "pm_deser")]
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 499b8d24190..3b1cff71aaa 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -861,6 +861,7 @@ pub async fn list_payment_methods(
             address.as_ref(),
             mca.connector_name,
             pm_config_mapping,
+            &state.conf.mandates.supported_payment_methods,
         )
         .await?;
     }
@@ -1224,6 +1225,7 @@ pub async fn filter_payment_methods(
     address: Option<&domain::Address>,
     connector: String,
     config: &settings::ConnectorFilters,
+    supported_payment_methods_for_mandate: &settings::SupportedPaymentMethodsForMandate,
 ) -> errors::CustomResult<(), errors::ApiErrorResponse> {
     for payment_method in payment_methods.into_iter() {
         let parse_result = serde_json::from_value::<PaymentMethodsEnabled>(payment_method);
@@ -1305,6 +1307,27 @@ pub async fn filter_payment_methods(
                         &payment_method_object.payment_method_type,
                     );
 
+                    let connector_variant = api_enums::Connector::from_str(connector.as_str())
+                        .into_report()
+                        .change_context(errors::ConnectorError::InvalidConnectorName)
+                        .change_context(errors::ApiErrorResponse::InvalidDataValue {
+                            field_name: "connector",
+                        })
+                        .attach_printable_lazy(|| {
+                            format!("unable to parse connector name {connector:?}")
+                        })?;
+                    let filter7 = payment_attempt
+                        .and_then(|attempt| attempt.mandate_details.as_ref())
+                        .map(|_mandate_details| {
+                            filter_pm_based_on_supported_payments_for_mandate(
+                                supported_payment_methods_for_mandate,
+                                &payment_method,
+                                &payment_method_object.payment_method_type,
+                                connector_variant,
+                            )
+                        })
+                        .unwrap_or(true);
+
                     let connector = connector.clone();
 
                     let response_pm_type = ResponsePaymentMethodIntermediate::new(
@@ -1313,7 +1336,7 @@ pub async fn filter_payment_methods(
                         payment_method,
                     );
 
-                    if filter && filter2 && filter3 && filter4 && filter5 && filter6 {
+                    if filter && filter2 && filter3 && filter4 && filter5 && filter6 && filter7 {
                         resp.push(response_pm_type);
                     }
                 }
@@ -1323,6 +1346,20 @@ pub async fn filter_payment_methods(
     Ok(())
 }
 
+fn filter_pm_based_on_supported_payments_for_mandate(
+    supported_payment_methods_for_mandate: &settings::SupportedPaymentMethodsForMandate,
+    payment_method: &api_enums::PaymentMethod,
+    payment_method_type: &api_enums::PaymentMethodType,
+    connector: api_enums::Connector,
+) -> bool {
+    supported_payment_methods_for_mandate
+        .0
+        .get(payment_method)
+        .and_then(|payment_method_type_hm| payment_method_type_hm.0.get(payment_method_type))
+        .map(|supported_connectors| supported_connectors.connector_list.contains(&connector))
+        .unwrap_or(false)
+}
+
 fn filter_pm_based_on_config<'a>(
     config: &'a crate::configs::settings::ConnectorFilters,
     connector: &'a str,

## 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 -->
When a mandate payment is created, sdk makes a payment_method_list api call which lists all the payment_methods. But not all of them support mandate payments.
Added a filter for payment_methods which filters payment methods that doesn't support mandates and list only those which supports, during payment_method_list api call.
Created an hashmap containing info about which payment_methods through which connector, supports mandates. And while listing payment methods, validate between the merchant configured payment_methods and the supported payment_methods.

### Additional Changes

- [ ] 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`
-->
crates/router/src/configs/settings.rs

## 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).
-->
List the payment_methods which support mandates filtering out others.

## 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)?
-->
Postman
Configured payment methods - 
![Screenshot 2023-05-30 at 4 08 41 PM](https://github.com/juspay/hyperswitch/assets/70657455/b8ab7be2-79e5-44ce-91b8-dc6e7eeab15a)
![Screenshot 2023-05-30 at 4 09 01 PM](https://github.com/juspay/hyperswitch/assets/70657455/7439ff38-f47c-4106-b6e1-92c28b0d8a41)

Filtered payment methods - 
![Screenshot 2023-05-30 at 4 10 07 PM](https://github.com/juspay/hyperswitch/assets/70657455/a6104323-ac3d-4fd7-bafe-71b68236e4d4)



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

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