Bug: Merchant Payment Method List changes for wallet restrictions



Since we are currently not getting any differentiators for multiple mandates set via a single wallet, we will be restricting setting up recurring payment for wallet only once.

- In Merchant Payment Method list, wallet types which are already saved and in active state for a customer should not be listed 
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index ce7f48405e2..8d54a6be408 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -1316,6 +1316,47 @@ pub async fn list_payment_methods(
         .await?;
     }
 
+    // Filter out applepay payment method from mca if customer has already saved it
+    response
+        .iter()
+        .position(|pm| {
+            pm.payment_method == enums::PaymentMethod::Wallet
+                && pm.payment_method_type == enums::PaymentMethodType::ApplePay
+        })
+        .as_ref()
+        .zip(customer.as_ref())
+        .async_map(|(index, customer)| async {
+            match db
+                .find_payment_method_by_customer_id_merchant_id_list(
+                    &customer.customer_id,
+                    &merchant_account.merchant_id,
+                    None,
+                )
+                .await
+            {
+                Ok(customer_payment_methods) => {
+                    if customer_payment_methods.iter().any(|pm| {
+                        pm.payment_method == enums::PaymentMethod::Wallet
+                            && pm.payment_method_type == Some(enums::PaymentMethodType::ApplePay)
+                    }) {
+                        response.remove(*index);
+                    }
+                    Ok(())
+                }
+                Err(error) => {
+                    if error.current_context().is_db_not_found() {
+                        Ok(())
+                    } else {
+                        Err(error)
+                            .change_context(errors::ApiErrorResponse::InternalServerError)
+                            .attach_printable("failed to find payment methods for a customer")
+                    }
+                }
+            }
+        })
+        .await
+        .transpose()?;
+
     let mut pmt_to_auth_connector = HashMap::new();
 
     if let Some((payment_attempt, payment_intent)) =

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

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

## Description
<!-- Describe your changes in detail -->
Since we are currently not getting any differentiators for multiple mandates set via a single wallet, we will be restricting setting up recurring payment for wallet only once.

- In Merchant Payment Method list, wallet types which are already saved and in active state for a customer should not be listed 

### 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)?
-->
1. Create mca
```
curl --location 'http://localhost:8080/account/merchant_1709561576/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "fiz_operations",
    "connector_name": "stripe",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "abc"
    },
    "test_mode": false,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "bank_debit",
            "payment_method_types": [
                {
                    "payment_method_type": "ach",
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "minimum_amount": 0,
                    "maximum_amount": 10000
                }
            ]
        },
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "apple_pay",
                    "payment_experience": "invoke_sdk_client",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "google_pay",
                    "payment_experience": "invoke_sdk_client",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "metadata": {
        "apple_pay_combined": {
            "manual": {
                "session_token_data": {
                    "initiative": "web",
                    "certificate": "certificate",
                    "display_name": "applepay",
                    "certificate_keys": "keys",
                    "initiative_context": "sdk-test-app.netlify.app",
                    "merchant_identifier": "xyz"
                },
                "payment_request_data": {
                    "label": "applepay",
                    "supported_networks": [
                        "visa",
                        "masterCard",
                        "amex",
                        "discover"
                    ],
                    "merchant_capabilities": [
                        "supports3DS"
                    ]
                }
            }
        },
        "google_pay": {
            "merchant_info": {
                "merchant_name": "Stripe"
            },
            "allowed_payment_methods": [
                {
                    "type": "CARD",
                    "parameters": {
                        "allowed_auth_methods": [
                            "PAN_ONLY",
                            "CRYPTOGRAM_3DS"
                        ],
                        "allowed_card_networks": [
                            "AMEX",
                            "DISCOVER",
                            "INTERAC",
                            "JCB",
                            "MASTERCARD",
                            "VISA"
                        ]
                    },
                    "tokenization_specification": {
                        "type": "PAYMENT_GATEWAY",
                        "parameters": {
                            "gateway": "stripe",
                            "stripe:version": "2018-10-31",
                            "stripe:publishableKey": "abc"
                        }
                    }
                }
            ]
        }
    },
    "connector_webhook_details": {
        "merchant_secret": "MyWebhookSecret"
    },
    "business_country": "US",
    "business_label": "default"
}'
```

2. Create a applepay wallet payment so that wallet entry gets saved in `payment_methods` table
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_UyebBGu4SpiswmyxyM5ISeJO5BoAVQO8yWX20QFoKFBwB7q50t23zvH3xRqQ6auv' \
--data-raw '{
    "amount": 650,
    "currency": "USD",
    "confirm": true,
    "business_country": "US",
    "business_label": "default",
    "amount_to_capture": 650,
    "customer_id": "{{customer_id}}",
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "three_ds",
    "return_url": "https://google.com",
    "email": "something@gmail.com",
    "name": "Joseph Doe",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "statement_descriptor_name": "Juspay",
    "statement_descriptor_suffix": "Router",
    "payment_method": "wallet",
    "payment_method_type": "apple_pay",
    "setup_future_usage": "on_session",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "payment_method_data": {
        "wallet": {
            "apple_pay": {
                "payment_data": "xyz",
                "payment_method": {
                    "display_name": "Visa 0326",
                    "network": "Mastercard",
                    "type": "debit"
                },
                "transaction_identifier": "abc"
            }
        }
    },
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    }
}'
```

3. Do `list_customer_payment_method`. Find the wallet entry and get the `payment_method_id` from response
4. Now do a payment with any payment method with `confirm = false`
5. Do list MCA with `client_secret`
```
curl --location 'http://localhost:8080/account/payment_methods?client_secret=abc' \
--header 'Accept: application/json' \
--header 'api-key: abc' \
--data ''
```

6. Applepay shoudn't be listed in the result (Applepay is configured in merchant MCA and applepay payment method exists for customer, hence it has to be filtered)

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

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