Bug: [REFACTOR] : [Stripe] fix Mandate flow



### Feature Description

Earlier the connector_mandate_id was not being populated as expected, instead it was being populated in a separate field as payment_method_id in mandate_reference data. In this PR the flow has been refactored and fixed to send the Response from connector such that it is mapped to the connector_mandate_id in the core.


### 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/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs
index 4673cce4d81..18776bcba43 100644
--- a/crates/router/src/connector/stripe/transformers.rs
+++ b/crates/router/src/connector/stripe/transformers.rs
@@ -124,7 +124,6 @@ pub struct PaymentIntentRequest {
     pub meta_data: HashMap<String, String>,
     pub return_url: String,
     pub confirm: bool,
-    pub mandate: Option<Secret<String>>,
     pub payment_method: Option<String>,
     pub customer: Option<Secret<String>>,
     #[serde(flatten)]
@@ -1800,7 +1799,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
         };
         let mut payment_method_options = None;
 
-        let (mut payment_data, payment_method, mandate, billing_address, payment_method_types) = {
+        let (mut payment_data, payment_method, billing_address, payment_method_types) = {
             match item
                 .request
                 .mandate_id
@@ -1811,7 +1810,6 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
                     connector_mandate_ids,
                 )) => (
                     None,
-                    connector_mandate_ids.payment_method_id,
                     connector_mandate_ids.connector_mandate_id,
                     StripeBillingAddress::default(),
                     get_payment_method_type_for_saved_payment_method_payment(item)?,
@@ -1826,7 +1824,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
                             network_transaction_id: Secret::new(network_transaction_id),
                         }),
                     });
-                    (None, None, None, StripeBillingAddress::default(), None)
+                    (None, None, StripeBillingAddress::default(), None)
                 }
                 _ => {
                     let (payment_method_data, payment_method_type, billing_address) =
@@ -1848,7 +1846,6 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
                     (
                         Some(payment_method_data),
                         None,
-                        None,
                         billing_address,
                         payment_method_type,
                     )
@@ -1965,7 +1962,6 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
             billing: billing_address,
             capture_method: StripeCaptureMethod::from(item.request.capture_method),
             payment_data,
-            mandate: mandate.map(Secret::new),
             payment_method_options,
             payment_method,
             customer: item.connector_customer.to_owned().map(Secret::new),
@@ -2416,40 +2412,6 @@ fn extract_payment_method_connector_response_from_latest_attempt(
     .map(types::ConnectorResponseData::with_additional_payment_method_data)
 }
 
-impl ForeignFrom<(Option<StripePaymentMethodOptions>, String)> for types::MandateReference {
-    fn foreign_from(
-        (payment_method_options, payment_method_id): (Option<StripePaymentMethodOptions>, String),
-    ) -> Self {
-        Self {
-            connector_mandate_id: payment_method_options.and_then(|options| match options {
-                StripePaymentMethodOptions::Card {
-                    mandate_options, ..
-                } => mandate_options.map(|mandate_options| mandate_options.reference.expose()),
-                StripePaymentMethodOptions::Klarna {}
-                | StripePaymentMethodOptions::Affirm {}
-                | StripePaymentMethodOptions::AfterpayClearpay {}
-                | StripePaymentMethodOptions::Eps {}
-                | StripePaymentMethodOptions::Giropay {}
-                | StripePaymentMethodOptions::Ideal {}
-                | StripePaymentMethodOptions::Sofort {}
-                | StripePaymentMethodOptions::Ach {}
-                | StripePaymentMethodOptions::Bacs {}
-                | StripePaymentMethodOptions::Becs {}
-                | StripePaymentMethodOptions::WechatPay {}
-                | StripePaymentMethodOptions::Alipay {}
-                | StripePaymentMethodOptions::Sepa {}
-                | StripePaymentMethodOptions::Bancontact {}
-                | StripePaymentMethodOptions::Przelewy24 {}
-                | StripePaymentMethodOptions::CustomerBalance {}
-                | StripePaymentMethodOptions::Blik {}
-                | StripePaymentMethodOptions::Multibanco {}
-                | StripePaymentMethodOptions::Cashapp {} => None,
-            }),
-            payment_method_id: Some(payment_method_id),
-        }
-    }
-}
-
 impl<F, T>
     TryFrom<types::ResponseRouterData<F, PaymentIntentResponse, T, types::PaymentsResponseData>>
     for types::RouterData<F, T, types::PaymentsResponseData>
@@ -2465,11 +2427,16 @@ impl<F, T>
                 services::RedirectForm::from((redirection_url, services::Method::Get))
             });
 
-        let mandate_reference = item.response.payment_method.map(|pm| {
-            types::MandateReference::foreign_from((
-                item.response.payment_method_options,
-                pm.expose(),
-            ))
+        let mandate_reference = item.response.payment_method.map(|paymet_method_id| {
+            // Implemented Save and re-use payment information for recurring charges
+            // For more info: https://docs.stripe.com/recurring-payments#accept-recurring-payments
+            // For backward compataibility payment_method_id & connector_mandate_id is being populated with the same value
+            let connector_mandate_id = Some(paymet_method_id.clone().expose());
+            let payment_method_id = Some(paymet_method_id.expose());
+            types::MandateReference {
+                connector_mandate_id,
+                payment_method_id,
+            }
         });
 
         //Note: we might have to call retrieve_setup_intent to get the network_transaction_id in case its not sent in PaymentIntentResponse
@@ -2588,26 +2555,32 @@ impl<F, T>
                 services::RedirectForm::from((redirection_url, services::Method::Get))
             });
 
-        let mandate_reference = item.response.payment_method.clone().map(|pm| {
-            types::MandateReference::foreign_from((
-                item.response.payment_method_options.clone(),
-                match item.response.latest_charge.clone() {
+        let mandate_reference = item
+            .response
+            .payment_method
+            .clone()
+            .map(|paymet_method_id| {
+                // Implemented Save and re-use payment information for recurring charges
+                // For more info: https://docs.stripe.com/recurring-payments#accept-recurring-payments
+                // For backward compataibility payment_method_id & connector_mandate_id is being populated with the same value
+                let connector_mandate_id = Some(paymet_method_id.clone().expose());
+                let payment_method_id = match item.response.latest_charge.clone() {
                     Some(StripeChargeEnum::ChargeObject(charge)) => {
                         match charge.payment_method_details {
                             Some(StripePaymentMethodDetailsResponse::Bancontact { bancontact }) => {
                                 bancontact
                                     .attached_payment_method
                                     .map(|attached_payment_method| attached_payment_method.expose())
-                                    .unwrap_or(pm.expose())
+                                    .unwrap_or(paymet_method_id.expose())
                             }
                             Some(StripePaymentMethodDetailsResponse::Ideal { ideal }) => ideal
                                 .attached_payment_method
                                 .map(|attached_payment_method| attached_payment_method.expose())
-                                .unwrap_or(pm.expose()),
+                                .unwrap_or(paymet_method_id.expose()),
                             Some(StripePaymentMethodDetailsResponse::Sofort { sofort }) => sofort
                                 .attached_payment_method
                                 .map(|attached_payment_method| attached_payment_method.expose())
-                                .unwrap_or(pm.expose()),
+                                .unwrap_or(paymet_method_id.expose()),
                             Some(StripePaymentMethodDetailsResponse::Blik)
                             | Some(StripePaymentMethodDetailsResponse::Eps)
                             | Some(StripePaymentMethodDetailsResponse::Fpx)
@@ -2625,13 +2598,16 @@ impl<F, T>
                             | Some(StripePaymentMethodDetailsResponse::Wechatpay)
                             | Some(StripePaymentMethodDetailsResponse::Alipay)
                             | Some(StripePaymentMethodDetailsResponse::CustomerBalance)
-                            | None => pm.expose(),
+                            | None => paymet_method_id.expose(),
                         }
                     }
-                    Some(StripeChargeEnum::ChargeId(_)) | None => pm.expose(),
-                },
-            ))
-        });
+                    Some(StripeChargeEnum::ChargeId(_)) | None => paymet_method_id.expose(),
+                };
+                types::MandateReference {
+                    connector_mandate_id,
+                    payment_method_id: Some(payment_method_id),
+                }
+            });
 
         let connector_metadata =
             get_connector_metadata(item.response.next_action.as_ref(), item.response.amount)?;
@@ -2687,8 +2663,16 @@ impl<F, T>
                 services::RedirectForm::from((redirection_url, services::Method::Get))
             });
 
-        let mandate_reference = item.response.payment_method.map(|pm| {
-            types::MandateReference::foreign_from((item.response.payment_method_options, pm))
+        let mandate_reference = item.response.payment_method.map(|paymet_method_id| {
+            // Implemented Save and re-use payment information for recurring charges
+            // For more info: https://docs.stripe.com/recurring-payments#accept-recurring-payments
+            // For backward compataibility payment_method_id & connector_mandate_id is being populated with the same value
+            let connector_mandate_id = Some(paymet_method_id.clone());
+            let payment_method_id = Some(paymet_method_id);
+            types::MandateReference {
+                connector_mandate_id,
+                payment_method_id,
+            }
         });
         let status = enums::AttemptStatus::from(item.response.status);
         let connector_response_data = item

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

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

## Description
Earlier the connector_mandate_id was not being populated as expected, instead it was being populated in a separate field as `payment_method_id` in mandate_reference data. And earlier if we try to do MIT payment using `payment_method_id` it was not working.  In this PR the flow has been refactored and fixed to send the  Response from connector such that it is mapped to the `connector_mandate_id` in the core.

### 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?
1. Create a CIT Card payment via Stripe Connector. 
```{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "SWANGI123",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },

"setup_future_usage" : "off_session",
"customer_acceptance": {
            "acceptance_type": "offline",
            "accepted_at": "1963-05-03T04:07:52.723Z",
            "online": {
                "ip_address": "in sit",
                "user_agent": "amet irure esse"
            }
        }
}
```
Response
```
{
    "payment_id": "pay_W8etDYfDKWRbDIn09D4U",
    "merchant_id": "postman_merchant_GHAction_d77decd1-f90c-4746-acbf-ab8dd9d535a7",
    "status": "succeeded",
    "amount": 6540,
    "net_amount": 6540,
    "amount_capturable": 0,
    "amount_received": 6540,
    "connector": "stripe",
    "client_secret": "pay_W8etDYfDKWRbDIn09D4U_secret_lGSLQbpiCobpLFr17nCb",
    "created": "2024-04-03T05:50:06.402Z",
    "currency": "USD",
    "customer_id": "SWANGI123",
    "customer": {
        "id": "SWANGI123",
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": "off_session",
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "4242",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "424242",
            "card_extended_bin": "42424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "payment_checks": {
                "address_line1_check": null,
                "address_postal_code_check": null,
                "cvc_check": "pass"
            },
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": null,
    "billing": null,
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": "https://duck.com/",
    "authentication_type": "no_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": "SWANGI123",
        "created_at": 1712123406,
        "expires": 1712127006,
        "secret": "epk_c17fa3fa8a6046349669f9ad4a6c0ac8"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "pi_3P1Mi3D5R7gDAGff1hkHBS5N",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pi_3P1Mi3D5R7gDAGff1hkHBS5N",
    "payment_link": null,
    "profile_id": "pro_7kS7x2eFLd119TxUPlRq",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_dWmQ6lhUUo9rUXfB5vbF",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-04-03T06:05:06.402Z",
    "fingerprint": null,
    "payment_method_id": null,
    "payment_method_status": null
}
```
hit List Payment methods for a Customer 
Response:
```
{
    "customer_payment_methods": [
        {
            "payment_token": "token_FwaoCK5rxMkaapn3GQuu",
            "payment_method_id": "pm_aV6lBMNaXPHFCzujobVL",
            "customer_id": "SWANGI123",
            "payment_method": "card",
            "payment_method_type": null,
            "payment_method_issuer": null,
            "payment_method_issuer_code": null,
            "recurring_enabled": false,
            "installment_payment_enabled": false,
            "payment_experience": [
                "redirect_to_url"
            ],
            "card": {
                "scheme": null,
                "issuer_country": null,
                "last4_digits": "4242",
                "expiry_month": "10",
                "expiry_year": "25",
                "card_token": null,
                "card_holder_name": "joseph Doe",
                "card_fingerprint": null,
                "nick_name": null,
                "card_network": null,
                "card_isin": "424242",
                "card_issuer": null,
                "card_type": null,
                "saved_to_locker": true
            },
            "metadata": null,
            "created": "2024-04-03T05:50:08.940Z",
            "bank": null,
            "surcharge_details": null,
            "requires_cvv": true,
            "last_used_at": "2024-04-03T05:50:08.940Z",
            "default_payment_method_set": false
        },
        {
            "payment_token": "token_ZH3KUgh1tBQMm3yj2FaI",
            "payment_method_id": "pm_QfcwtyKLOS7ROJKB3mhV",
            "customer_id": "SWANGI123",
            "payment_method": "card",
            "payment_method_type": null,
            "payment_method_issuer": null,
            "payment_method_issuer_code": null,
            "recurring_enabled": false,
            "installment_payment_enabled": false,
            "payment_experience": [
                "redirect_to_url"
            ],
            "card": {
                "scheme": null,
                "issuer_country": null,
                "last4_digits": "4242",
                "expiry_month": "10",
                "expiry_year": "25",
                "card_token": null,
                "card_holder_name": "joseph Doe",
                "card_fingerprint": null,
                "nick_name": null,
                "card_network": null,
                "card_isin": "424242",
                "card_issuer": null,
                "card_type": null,
                "saved_to_locker": true
            },
            "metadata": null,
            "created": "2024-04-02T13:50:05.528Z",
            "bank": null,
            "surcharge_details": null,
            "requires_cvv": true,
            "last_used_at": "2024-04-02T13:50:05.528Z",
            "default_payment_method_set": true
        }
    ],
    "is_guest_customer": null
}
```
In Response we will get `payment_method_id` . 

Using this payment_method_id we will create MIT 
```
{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "SWANGI123",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },

"off_session": true,
        "recurring_details":{
    "type":"payment_method_id",
    "data":"{{payment_method_id}}"
}
}
```

## 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
