Bug: Fix(mandates): handle the connector_mandate creation once and only if the payment is charged



Earlier we used to store the connector mandate id irrespective of the payments status being charged or not for 3DS flows, now we would handle the connector_mandate_id updation in payment_method once and only if the payment has a status as charged.


diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 8306deeb258..e36a6d74994 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -3356,3 +3356,16 @@ pub enum SurchargeCalculationOverride {
     /// Calculate surcharge
     Calculate,
 }
+
+/// Connector Mandate Status
+#[derive(
+    Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, strum::Display,
+)]
+#[strum(serialize_all = "snake_case")]
+#[serde(rename_all = "snake_case")]
+pub enum ConnectorMandateStatus {
+    /// Indicates that the connector mandate is active and can be used for payments.
+    Active,
+    /// Indicates that the connector mandate  is not active and hence cannot be used for payments.
+    Inactive,
+}
diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs
index 277061c78aa..ae98b8a0481 100644
--- a/crates/diesel_models/src/payment_attempt.rs
+++ b/crates/diesel_models/src/payment_attempt.rs
@@ -12,6 +12,16 @@ use crate::schema::payment_attempt;
 #[cfg(feature = "v2")]
 use crate::schema_v2::payment_attempt;
 
+common_utils::impl_to_sql_from_sql_json!(ConnectorMandateReferenceId);
+#[derive(
+    Clone, Debug, serde::Deserialize, serde::Serialize, Eq, PartialEq, diesel::AsExpression,
+)]
+#[diesel(sql_type = diesel::sql_types::Jsonb)]
+pub struct ConnectorMandateReferenceId {
+    pub connector_mandate_id: Option<String>,
+    pub payment_method_id: Option<String>,
+    pub mandate_metadata: Option<serde_json::Value>,
+}
 #[cfg(feature = "v2")]
 #[derive(
     Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize, Selectable,
@@ -76,6 +86,7 @@ pub struct PaymentAttempt {
     pub id: String,
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -153,6 +164,7 @@ pub struct PaymentAttempt {
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
     pub connector_transaction_data: Option<String>,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -256,6 +268,7 @@ pub struct PaymentAttemptNew {
     pub card_network: Option<String>,
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -328,6 +341,7 @@ pub struct PaymentAttemptNew {
     pub card_network: Option<String>,
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -442,6 +456,7 @@ pub enum PaymentAttemptUpdate {
         unified_message: Option<Option<String>>,
         payment_method_data: Option<serde_json::Value>,
         charge_id: Option<String>,
+        connector_mandate_detail: Option<ConnectorMandateReferenceId>,
     },
     UnresolvedResponseUpdate {
         status: storage_enums::AttemptStatus,
@@ -757,6 +772,7 @@ pub struct PaymentAttemptUpdateInternal {
     customer_acceptance: Option<pii::SecretSerdeValue>,
     card_network: Option<String>,
     connector_payment_data: Option<String>,
+    connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -813,6 +829,7 @@ pub struct PaymentAttemptUpdateInternal {
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
     pub connector_transaction_data: Option<String>,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v2")]
@@ -1002,6 +1019,7 @@ impl PaymentAttemptUpdate {
             shipping_cost,
             order_tax_amount,
             connector_transaction_data,
+            connector_mandate_detail,
         } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source);
         PaymentAttempt {
             amount: amount.unwrap_or(source.amount),
@@ -1059,6 +1077,7 @@ impl PaymentAttemptUpdate {
             order_tax_amount: order_tax_amount.or(source.order_tax_amount),
             connector_transaction_data: connector_transaction_data
                 .or(source.connector_transaction_data),
+            connector_mandate_detail: connector_mandate_detail.or(source.connector_mandate_detail),
             ..source
         }
     }
@@ -2054,6 +2073,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::AuthenticationTypeUpdate {
                 authentication_type,
@@ -2109,6 +2129,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::ConfirmUpdate {
                 amount,
@@ -2194,6 +2215,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost,
                 order_tax_amount,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::VoidUpdate {
                 status,
@@ -2250,6 +2272,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::RejectUpdate {
                 status,
@@ -2307,6 +2330,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::BlocklistUpdate {
                 status,
@@ -2364,6 +2388,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::PaymentMethodDetailsUpdate {
                 payment_method_id,
@@ -2419,6 +2444,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::ResponseUpdate {
                 status,
@@ -2441,6 +2467,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 unified_message,
                 payment_method_data,
                 charge_id,
+                connector_mandate_detail,
             } => {
                 let (connector_transaction_id, connector_transaction_data) =
                     connector_transaction_id
@@ -2498,6 +2525,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                     card_network: None,
                     shipping_cost: None,
                     order_tax_amount: None,
+                    connector_mandate_detail,
                 }
             }
             PaymentAttemptUpdate::ErrorUpdate {
@@ -2570,6 +2598,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                     card_network: None,
                     shipping_cost: None,
                     order_tax_amount: None,
+                    connector_mandate_detail: None,
                 }
             }
             PaymentAttemptUpdate::StatusUpdate { status, updated_by } => Self {
@@ -2623,6 +2652,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::UpdateTrackers {
                 payment_token,
@@ -2684,6 +2714,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::UnresolvedResponseUpdate {
                 status,
@@ -2752,6 +2783,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                     card_network: None,
                     shipping_cost: None,
                     order_tax_amount: None,
+                    connector_mandate_detail: None,
                 }
             }
             PaymentAttemptUpdate::PreprocessingUpdate {
@@ -2819,6 +2851,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                     card_network: None,
                     shipping_cost: None,
                     order_tax_amount: None,
+                    connector_mandate_detail: None,
                 }
             }
             PaymentAttemptUpdate::CaptureUpdate {
@@ -2876,6 +2909,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::AmountToCaptureUpdate {
                 status,
@@ -2932,6 +2966,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::ConnectorResponse {
                 authentication_data,
@@ -2997,6 +3032,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                     card_network: None,
                     shipping_cost: None,
                     order_tax_amount: None,
+                    connector_mandate_detail: None,
                 }
             }
             PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate {
@@ -3053,6 +3089,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::AuthenticationUpdate {
                 status,
@@ -3111,6 +3148,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
             PaymentAttemptUpdate::ManualUpdate {
                 status,
@@ -3178,6 +3216,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                     card_network: None,
                     shipping_cost: None,
                     order_tax_amount: None,
+                    connector_mandate_detail: None,
                 }
             }
             PaymentAttemptUpdate::PostSessionTokensUpdate {
@@ -3234,6 +3273,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 shipping_cost: None,
                 order_tax_amount: None,
                 connector_transaction_data: None,
+                connector_mandate_detail: None,
             },
         }
     }
@@ -3319,7 +3359,6 @@ mod tests {
             "user_agent": "amet irure esse"
         }
     },
-    "mandate_type": {
         "single_use": {
             "amount": 6540,
             "currency": "USD"
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 5cd2abd3599..8d2dfc47b62 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -850,6 +850,7 @@ diesel::table! {
         order_tax_amount -> Nullable<Int8>,
         #[max_length = 512]
         connector_transaction_data -> Nullable<Varchar>,
+        connector_mandate_detail -> Nullable<Jsonb>,
     }
 }
 
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index d662603981b..45a4ce03e55 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -821,6 +821,7 @@ diesel::table! {
         id -> Varchar,
         shipping_cost -> Nullable<Int8>,
         order_tax_amount -> Nullable<Int8>,
+        connector_mandate_detail -> Nullable<Jsonb>,
     }
 }
 
diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs
index db30d02bd7c..88617afb392 100644
--- a/crates/diesel_models/src/user/sample_data.rs
+++ b/crates/diesel_models/src/user/sample_data.rs
@@ -12,7 +12,7 @@ use crate::schema::payment_attempt;
 use crate::schema_v2::payment_attempt;
 use crate::{
     enums::{MandateDataType, MandateDetails},
-    PaymentAttemptNew,
+    ConnectorMandateReferenceId, PaymentAttemptNew,
 };
 
 #[cfg(feature = "v2")]
@@ -204,6 +204,7 @@ pub struct PaymentAttemptBatchNew {
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
     pub connector_transaction_data: Option<String>,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -282,6 +283,7 @@ impl PaymentAttemptBatchNew {
             organization_id: self.organization_id,
             shipping_cost: self.shipping_cost,
             order_tax_amount: self.order_tax_amount,
+            connector_mandate_detail: self.connector_mandate_detail,
         }
     }
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
index 691037c2824..8ecac77e54e 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
@@ -10,7 +10,8 @@ use common_utils::{
     },
 };
 use diesel_models::{
-    PaymentAttempt as DieselPaymentAttempt, PaymentAttemptNew as DieselPaymentAttemptNew,
+    ConnectorMandateReferenceId, PaymentAttempt as DieselPaymentAttempt,
+    PaymentAttemptNew as DieselPaymentAttemptNew,
     PaymentAttemptUpdate as DieselPaymentAttemptUpdate,
 };
 use error_stack::ResultExt;
@@ -222,6 +223,7 @@ pub struct PaymentAttempt {
     pub shipping_cost: Option<MinorUnit>,
     pub order_tax_amount: Option<MinorUnit>,
     pub id: String,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 impl PaymentAttempt {
@@ -331,6 +333,7 @@ pub struct PaymentAttempt {
     pub customer_acceptance: Option<pii::SecretSerdeValue>,
     pub profile_id: id_type::ProfileId,
     pub organization_id: id_type::OrganizationId,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default)]
@@ -624,6 +627,7 @@ pub struct PaymentAttemptNew {
     pub customer_acceptance: Option<pii::SecretSerdeValue>,
     pub profile_id: id_type::ProfileId,
     pub organization_id: id_type::OrganizationId,
+    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
 }
 
 #[cfg(feature = "v1")]
@@ -732,6 +736,7 @@ pub enum PaymentAttemptUpdate {
         unified_message: Option<Option<String>>,
         payment_method_data: Option<serde_json::Value>,
         charge_id: Option<String>,
+        connector_mandate_detail: Option<ConnectorMandateReferenceId>,
     },
     UnresolvedResponseUpdate {
         status: storage_enums::AttemptStatus,
@@ -992,6 +997,7 @@ impl PaymentAttemptUpdate {
                 unified_message,
                 payment_method_data,
                 charge_id,
+                connector_mandate_detail,
             } => DieselPaymentAttemptUpdate::ResponseUpdate {
                 status,
                 connector,
@@ -1013,6 +1019,7 @@ impl PaymentAttemptUpdate {
                 unified_message,
                 payment_method_data,
                 charge_id,
+                connector_mandate_detail,
             },
             Self::UnresolvedResponseUpdate {
                 status,
@@ -1281,6 +1288,7 @@ impl behaviour::Conversion for PaymentAttempt {
             connector_transaction_data,
             order_tax_amount: self.net_amount.get_order_tax_amount(),
             shipping_cost: self.net_amount.get_shipping_cost(),
+            connector_mandate_detail: self.connector_mandate_detail,
         })
     }
 
@@ -1361,6 +1369,7 @@ impl behaviour::Conversion for PaymentAttempt {
                 customer_acceptance: storage_model.customer_acceptance,
                 profile_id: storage_model.profile_id,
                 organization_id: storage_model.organization_id,
+                connector_mandate_detail: storage_model.connector_mandate_detail,
             })
         }
         .await
@@ -1442,6 +1451,7 @@ impl behaviour::Conversion for PaymentAttempt {
             card_network,
             order_tax_amount: self.net_amount.get_order_tax_amount(),
             shipping_cost: self.net_amount.get_shipping_cost(),
+            connector_mandate_detail: self.connector_mandate_detail,
         })
     }
 }
@@ -1517,6 +1527,7 @@ impl behaviour::Conversion for PaymentAttempt {
             shipping_cost,
             order_tax_amount,
             connector,
+            connector_mandate_detail,
         } = self;
 
         let (connector_payment_id, connector_payment_data) = connector_payment_id
@@ -1580,6 +1591,7 @@ impl behaviour::Conversion for PaymentAttempt {
             external_reference_id,
             connector,
             connector_payment_data,
+            connector_mandate_detail,
         })
     }
 
@@ -1651,6 +1663,7 @@ impl behaviour::Conversion for PaymentAttempt {
                 authentication_applied: storage_model.authentication_applied,
                 external_reference_id: storage_model.external_reference_id,
                 connector: storage_model.connector,
+                connector_mandate_detail: storage_model.connector_mandate_detail,
             })
         }
         .await
@@ -1718,6 +1731,7 @@ impl behaviour::Conversion for PaymentAttempt {
             order_tax_amount: self.order_tax_amount,
             shipping_cost: self.shipping_cost,
             amount_to_capture: self.amount_to_capture,
+            connector_mandate_detail: self.connector_mandate_detail,
         })
     }
 }
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 7c97516192e..27d73d0df46 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -4071,6 +4071,7 @@ impl AttemptType {
             customer_acceptance: old_payment_attempt.customer_acceptance,
             organization_id: old_payment_attempt.organization_id,
             profile_id: old_payment_attempt.profile_id,
+            connector_mandate_detail: None,
         }
     }
 
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index 9ec2438ddb3..ca32be35e55 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -614,7 +614,6 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         } else {
             (None, payment_method_info)
         };
-
         // The operation merges mandate data from both request and payment_attempt
         let setup_mandate = mandate_data.map(|mut sm| {
             sm.mandate_type = payment_attempt.mandate_details.clone().or(sm.mandate_type);
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 779b2d29c06..fc1f71c2085 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -1206,8 +1206,10 @@ impl PaymentCreate {
                     .map(Secret::new),
                 organization_id: organization_id.clone(),
                 profile_id,
+                connector_mandate_detail: None,
             },
             additional_pm_data,
+
         ))
     }
 
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index 6ead0523020..3bb6647b527 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -1,11 +1,12 @@
 use std::collections::HashMap;
 
+use api_models::payments::{ConnectorMandateReferenceId, MandateReferenceId};
 #[cfg(all(feature = "v1", feature = "dynamic_routing"))]
 use api_models::routing::RoutableConnectorChoice;
 use async_trait::async_trait;
 use common_enums::{AuthorizationStatus, SessionUpdateStatus};
 use common_utils::{
-    ext_traits::{AsyncExt, Encode},
+    ext_traits::{AsyncExt, Encode, ValueExt},
     types::{keymanager::KeyManagerState, ConnectorTransactionId, MinorUnit},
 };
 use error_stack::{report, ResultExt};
@@ -184,14 +185,11 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
         let save_payment_call_future = Box::pin(tokenization::save_payment_method(
             state,
             connector_name.clone(),
-            merchant_connector_id.clone(),
             save_payment_data,
             customer_id.clone(),
             merchant_account,
             resp.request.payment_method_type,
             key_store,
-            Some(resp.request.amount),
-            Some(resp.request.currency),
             billing_name.clone(),
             payment_method_billing_address,
             business_profile,
@@ -208,7 +206,7 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
                 resp.request.setup_future_usage,
                 Some(enums::FutureUsage::OffSession)
             );
-
+        let storage_scheme = merchant_account.storage_scheme;
         if is_legacy_mandate {
             // Mandate is created on the application side and at the connector.
             let tokenization::SavePaymentMethodDataResponse {
@@ -233,15 +231,46 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
             // The mandate is created on connector's end.
             let tokenization::SavePaymentMethodDataResponse {
                 payment_method_id,
-                mandate_reference_id,
+                connector_mandate_reference_id,
                 ..
             } = save_payment_call_future.await?;
-
+            payment_data.payment_method_info = if let Some(payment_method_id) = &payment_method_id {
+                match state
+                    .store
+                    .find_payment_method(
+                        &(state.into()),
+                        key_store,
+                        payment_method_id,
+                        storage_scheme,
+                    )
+                    .await
+                {
+                    Ok(payment_method) => Some(payment_method),
+                    Err(error) => {
+                        if error.current_context().is_db_not_found() {
+                            logger::info!("Payment Method not found in db {:?}", error);
+                            None
+                        } else {
+                            Err(error)
+                                .change_context(errors::ApiErrorResponse::InternalServerError)
+                                .attach_printable("Error retrieving payment method from db")
+                                .map_err(|err| logger::error!(payment_method_retrieve=?err))
+                                .ok()
+                        }
+                    }
+                }
+            } else {
+                None
+            };
             payment_data.payment_attempt.payment_method_id = payment_method_id;
-
+            payment_data.payment_attempt.connector_mandate_detail = connector_mandate_reference_id
+                .clone()
+                .map(ForeignFrom::foreign_from);
             payment_data.set_mandate_id(api_models::payments::MandateIds {
                 mandate_id: None,
-                mandate_reference_id,
+                mandate_reference_id: connector_mandate_reference_id.map(|connector_mandate_id| {
+                    MandateReferenceId::ConnectorMandateId(connector_mandate_id)
+                }),
             });
             Ok(())
         } else if should_avoid_saving {
@@ -256,16 +285,10 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
             let key_store = key_store.clone();
             let state = state.clone();
             let customer_id = payment_data.payment_intent.customer_id.clone();
-
-            let merchant_connector_id = payment_data.payment_attempt.merchant_connector_id.clone();
             let payment_attempt = payment_data.payment_attempt.clone();
 
             let business_profile = business_profile.clone();
-
-            let amount = resp.request.amount;
-            let currency = resp.request.currency;
             let payment_method_type = resp.request.payment_method_type;
-            let storage_scheme = merchant_account.clone().storage_scheme;
             let payment_method_billing_address = payment_method_billing_address.cloned();
 
             logger::info!("Call to save_payment_method in locker");
@@ -276,14 +299,11 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
                     let result = Box::pin(tokenization::save_payment_method(
                         &state,
                         connector_name,
-                        merchant_connector_id,
                         save_payment_data,
                         customer_id,
                         &merchant_account,
                         payment_method_type,
                         &key_store,
-                        Some(amount),
-                        Some(currency),
                         billing_name,
                         payment_method_billing_address.as_ref(),
                         &business_profile,
@@ -554,6 +574,33 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsSyncData> for
     where
         F: 'b + Clone + Send + Sync,
     {
+        let (connector_mandate_id, mandate_metadata) = resp
+            .response
+            .clone()
+            .ok()
+            .and_then(|resp| {
+                if let types::PaymentsResponseData::TransactionResponse {
+                    mandate_reference, ..
+                } = resp
+                {
+                    mandate_reference.map(|mandate_ref| {
+                        (
+                            mandate_ref.connector_mandate_id.clone(),
+                            mandate_ref.mandate_metadata.clone(),
+                        )
+                    })
+                } else {
+                    None
+                }
+            })
+            .unwrap_or((None, None));
+
+        update_connector_mandate_details_for_the_flow(
+            connector_mandate_id,
+            mandate_metadata,
+            payment_data,
+        )?;
+
         update_payment_method_status_and_ntid(
             state,
             key_store,
@@ -1038,19 +1085,16 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::SetupMandateRequestDa
         let merchant_connector_id = payment_data.payment_attempt.merchant_connector_id.clone();
         let tokenization::SavePaymentMethodDataResponse {
             payment_method_id,
-            mandate_reference_id,
+            connector_mandate_reference_id,
             ..
         } = Box::pin(tokenization::save_payment_method(
             state,
             connector_name,
-            merchant_connector_id.clone(),
             save_payment_data,
             customer_id.clone(),
             merchant_account,
             resp.request.payment_method_type,
             key_store,
-            resp.request.amount,
-            Some(resp.request.currency),
             billing_name,
             None,
             business_profile,
@@ -1069,9 +1113,14 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::SetupMandateRequestDa
         .await?;
         payment_data.payment_attempt.payment_method_id = payment_method_id;
         payment_data.payment_attempt.mandate_id = mandate_id;
+        payment_data.payment_attempt.connector_mandate_detail = connector_mandate_reference_id
+            .clone()
+            .map(ForeignFrom::foreign_from);
         payment_data.set_mandate_id(api_models::payments::MandateIds {
             mandate_id: None,
-            mandate_reference_id,
+            mandate_reference_id: connector_mandate_reference_id.map(|connector_mandate_id| {
+                MandateReferenceId::ConnectorMandateId(connector_mandate_id)
+            }),
         });
         Ok(())
     }
@@ -1127,6 +1176,32 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::CompleteAuthorizeData
     where
         F: 'b + Clone + Send + Sync,
     {
+        let (connector_mandate_id, mandate_metadata) = resp
+            .response
+            .clone()
+            .ok()
+            .and_then(|resp| {
+                if let types::PaymentsResponseData::TransactionResponse {
+                    mandate_reference, ..
+                } = resp
+                {
+                    mandate_reference.map(|mandate_ref| {
+                        (
+                            mandate_ref.connector_mandate_id.clone(),
+                            mandate_ref.mandate_metadata.clone(),
+                        )
+                    })
+                } else {
+                    None
+                }
+            })
+            .unwrap_or((None, None));
+        update_connector_mandate_details_for_the_flow(
+            connector_mandate_id,
+            mandate_metadata,
+            payment_data,
+        )?;
+
         update_payment_method_status_and_ntid(
             state,
             key_store,
@@ -1487,6 +1562,78 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
                                     .payment_intent
                                     .fingerprint_id
                                     .clone_from(&payment_data.payment_attempt.fingerprint_id);
+
+                                if let Some(payment_method) =
+                                    payment_data.payment_method_info.clone()
+                                {
+                                    // Parse value to check for mandates' existence
+                                    let mandate_details = payment_method
+                                        .connector_mandate_details
+                                        .clone()
+                                        .map(|val| {
+                                            val.parse_value::<storage::PaymentsMandateReference>(
+                                                "PaymentsMandateReference",
+                                            )
+                                        })
+                                        .transpose()
+                                        .change_context(
+                                            errors::ApiErrorResponse::InternalServerError,
+                                        )
+                                        .attach_printable(
+                                            "Failed to deserialize to Payment Mandate Reference ",
+                                        )?;
+
+                                    if let Some(mca_id) =
+                                        payment_data.payment_attempt.merchant_connector_id.clone()
+                                    {
+                                        // check if the mandate has not already been set to active
+                                        if !mandate_details
+                                        .as_ref()
+                                        .map(|payment_mandate_reference| {
+
+                                                payment_mandate_reference.0.get(&mca_id)
+                                                    .map(|payment_mandate_reference_record| payment_mandate_reference_record.connector_mandate_status == Some(common_enums::ConnectorMandateStatus::Active))
+                                                    .unwrap_or(false)
+                                        })
+                                        .unwrap_or(false)
+                                    {
+                                        let (connector_mandate_id, mandate_metadata) = payment_data.payment_attempt.connector_mandate_detail.clone()
+                                        .map(|cmr| (cmr.connector_mandate_id, cmr.mandate_metadata))
+                                        .unwrap_or((None, None));
+
+                                        // Update the connector mandate details with the payment attempt connector mandate id
+                                        let connector_mandate_details =
+                                                    tokenization::update_connector_mandate_details(
+                                                        mandate_details,
+                                                        payment_data.payment_attempt.payment_method_type,
+                                                        Some(
+                                                            payment_data
+                                                                .payment_attempt
+                                                                .net_amount
+                                                                .get_total_amount()
+                                                                .get_amount_as_i64(),
+                                                        ),
+                                                        payment_data.payment_attempt.currency,
+                                                        payment_data.payment_attempt.merchant_connector_id.clone(),
+                                                        connector_mandate_id,
+                                                        mandate_metadata,
+                                                    )?;
+                                        // Update the payment method table with the active mandate record
+                                        payment_methods::cards::update_payment_method_connector_mandate_details(
+                                                        state,
+                                                        key_store,
+                                                        &*state.store,
+                                                        payment_method,
+                                                        connector_mandate_details,
+                                                        storage_scheme,
+                                                    )
+                                                    .await
+                                                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                                                    .attach_printable("Failed to update payment method in db")?;
+                                    }
+                                    }
+                                }
+
                                 metrics::SUCCESSFUL_PAYMENT.add(&metrics::CONTEXT, 1, &[]);
                             }
 
@@ -1561,6 +1708,10 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
                                         encoded_data,
                                         payment_method_data: additional_payment_method_data,
                                         charge_id,
+                                        connector_mandate_detail: payment_data
+                                            .payment_attempt
+                                            .connector_mandate_detail
+                                            .clone(),
                                     }),
                                 ),
                             };
@@ -1760,59 +1911,6 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
         .in_current_span(),
     );
 
-    // When connector requires redirection for mandate creation it can update the connector mandate_id in payment_methods during Psync and CompleteAuthorize
-
-    let flow_name = core_utils::get_flow_name::<F>()?;
-    if flow_name == "PSync" || flow_name == "CompleteAuthorize" {
-        let (connector_mandate_id, mandate_metadata) = match router_data.response.clone() {
-            Ok(resp) => match resp {
-                types::PaymentsResponseData::TransactionResponse {
-                    ref mandate_reference,
-                    ..
-                } => {
-                    if let Some(mandate_ref) = mandate_reference {
-                        (
-                            mandate_ref.connector_mandate_id.clone(),
-                            mandate_ref.mandate_metadata.clone(),
-                        )
-                    } else {
-                        (None, None)
-                    }
-                }
-                _ => (None, None),
-            },
-            Err(_) => (None, None),
-        };
-        if let Some(payment_method) = payment_data.payment_method_info.clone() {
-            let connector_mandate_details =
-                tokenization::update_connector_mandate_details_in_payment_method(
-                    payment_method.clone(),
-                    payment_method.payment_method_type,
-                    Some(
-                        payment_data
-                            .payment_attempt
-                            .net_amount
-                            .get_total_amount()
-                            .get_amount_as_i64(),
-                    ),
-                    payment_data.payment_attempt.currency,
-                    payment_data.payment_attempt.merchant_connector_id.clone(),
-                    connector_mandate_id,
-                    mandate_metadata,
-                )?;
-            payment_methods::cards::update_payment_method_connector_mandate_details(
-                state,
-                key_store,
-                &*state.store,
-                payment_method.clone(),
-                connector_mandate_details,
-                storage_scheme,
-            )
-            .await
-            .change_context(errors::ApiErrorResponse::InternalServerError)
-            .attach_printable("Failed to update payment method in db")?
-        }
-    }
     // When connector requires redirection for mandate creation it can update the connector mandate_id during Psync and CompleteAuthorize
     let m_db = state.clone().store;
     let m_router_data_merchant_id = router_data.merchant_id.clone();
@@ -2032,6 +2130,35 @@ async fn update_payment_method_status_and_ntid<F: Clone>(
     Ok(())
 }
 
+fn update_connector_mandate_details_for_the_flow<F: Clone>(
+    connector_mandate_id: Option<String>,
+    mandate_metadata: Option<serde_json::Value>,
+    payment_data: &mut PaymentData<F>,
+) -> RouterResult<()> {
+    let connector_mandate_reference_id = if connector_mandate_id.is_some() {
+        Some(ConnectorMandateReferenceId {
+            connector_mandate_id: connector_mandate_id.clone(),
+            payment_method_id: None,
+            update_history: None,
+            mandate_metadata: mandate_metadata.clone(),
+        })
+    } else {
+        None
+    };
+
+    payment_data.payment_attempt.connector_mandate_detail = connector_mandate_reference_id
+        .clone()
+        .map(ForeignFrom::foreign_from);
+
+    payment_data.set_mandate_id(api_models::payments::MandateIds {
+        mandate_id: None,
+        mandate_reference_id: connector_mandate_reference_id.map(|connector_mandate_id| {
+            MandateReferenceId::ConnectorMandateId(connector_mandate_id)
+        }),
+    });
+    Ok(())
+}
+
 fn response_to_capture_update(
     multiple_capture_data: &MultipleCaptureData,
     response_list: HashMap<String, CaptureSyncResponse>,
diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs
index 374c5680685..e4b6d0e287c 100644
--- a/crates/router/src/core/payments/retry.rs
+++ b/crates/router/src/core/payments/retry.rs
@@ -456,6 +456,7 @@ where
                 unified_message: None,
                 payment_method_data: additional_payment_method_data,
                 charge_id,
+                connector_mandate_detail: None,
             };
 
             #[cfg(feature = "v1")]
@@ -642,6 +643,7 @@ pub fn make_new_payment_attempt(
         fingerprint_id: Default::default(),
         charge_id: Default::default(),
         customer_acceptance: Default::default(),
+        connector_mandate_detail: Default::default(),
     }
 }
 
diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs
index 213a9211c06..b4e5ade5698 100644
--- a/crates/router/src/core/payments/tokenization.rs
+++ b/crates/router/src/core/payments/tokenization.rs
@@ -5,8 +5,8 @@ use std::collections::HashMap;
     not(feature = "payment_methods_v2")
 ))]
 use api_models::payment_methods::PaymentMethodsData;
-use api_models::payments::{ConnectorMandateReferenceId, MandateReferenceId};
-use common_enums::PaymentMethod;
+use api_models::payments::ConnectorMandateReferenceId;
+use common_enums::{ConnectorMandateStatus, PaymentMethod};
 use common_utils::{
     crypto::Encryptable,
     ext_traits::{AsyncExt, Encode, ValueExt},
@@ -61,7 +61,7 @@ impl<F, Req: Clone> From<&types::RouterData<F, Req, types::PaymentsResponseData>
 pub struct SavePaymentMethodDataResponse {
     pub payment_method_id: Option<String>,
     pub payment_method_status: Option<common_enums::PaymentMethodStatus>,
-    pub mandate_reference_id: Option<MandateReferenceId>,
+    pub connector_mandate_reference_id: Option<ConnectorMandateReferenceId>,
 }
 #[cfg(all(
     any(feature = "v1", feature = "v2"),
@@ -72,14 +72,11 @@ pub struct SavePaymentMethodDataResponse {
 pub async fn save_payment_method<FData>(
     state: &SessionState,
     connector_name: String,
-    merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
     save_payment_method_data: SavePaymentMethodData<FData>,
     customer_id: Option<id_type::CustomerId>,
     merchant_account: &domain::MerchantAccount,
     payment_method_type: Option<storage_enums::PaymentMethodType>,
     key_store: &domain::MerchantKeyStore,
-    amount: Option<i64>,
-    currency: Option<storage_enums::Currency>,
     billing_name: Option<Secret<String>>,
     payment_method_billing_address: Option<&api::Address>,
     business_profile: &domain::Profile,
@@ -174,32 +171,6 @@ where
                 }
                 _ => (None, None),
             };
-            let check_for_mit_mandates = save_payment_method_data
-                .request
-                .get_setup_mandate_details()
-                .is_none()
-                && save_payment_method_data
-                    .request
-                    .get_setup_future_usage()
-                    .map(|future_usage| future_usage == storage_enums::FutureUsage::OffSession)
-                    .unwrap_or(false);
-            // insert in PaymentMethods if its a off-session mit payment
-            let connector_mandate_details = if check_for_mit_mandates {
-                add_connector_mandate_details_in_payment_method(
-                    payment_method_type,
-                    amount,
-                    currency,
-                    merchant_connector_id.clone(),
-                    connector_mandate_id.clone(),
-                    mandate_metadata.clone(),
-                )
-            } else {
-                None
-            }
-            .map(|connector_mandate_data| connector_mandate_data.encode_to_value())
-            .transpose()
-            .change_context(errors::ApiErrorResponse::InternalServerError)
-            .attach_printable("Unable to serialize customer acceptance to value")?;
 
             let pm_id = if customer_acceptance.is_some() {
                 let payment_method_create_request =
@@ -384,24 +355,6 @@ where
                                     .await
                                     .change_context(errors::ApiErrorResponse::InternalServerError)
                                     .attach_printable("Failed to add payment method in db")?;
-                                    if check_for_mit_mandates {
-                                        let connector_mandate_details =
-                                            update_connector_mandate_details_in_payment_method(
-                                                pm.clone(),
-                                                payment_method_type,
-                                                amount,
-                                                currency,
-                                                merchant_connector_id.clone(),
-                                                connector_mandate_id.clone(),
-                                                mandate_metadata.clone(),
-                                            )?;
-
-                                        payment_methods::cards::update_payment_method_connector_mandate_details(state,
-                                        key_store,db, pm, connector_mandate_details, merchant_account.storage_scheme).await.change_context(
-                                        errors::ApiErrorResponse::InternalServerError,
-                                    )
-                                    .attach_printable("Failed to update payment method in db")?;
-                                    }
                                 }
                                 Err(err) => {
                                     if err.current_context().is_db_not_found() {
@@ -418,7 +371,7 @@ where
                                             customer_acceptance,
                                             pm_data_encrypted.map(Into::into),
                                             key_store,
-                                            connector_mandate_details,
+                                            None,
                                             pm_status,
                                             network_transaction_id,
                                             merchant_account.storage_scheme,
@@ -489,28 +442,7 @@ where
                                 resp.payment_method_id = payment_method_id;
 
                                 let existing_pm = match payment_method {
-                                    Ok(pm) => {
-                                        // update if its a off-session mit payment
-                                        if check_for_mit_mandates {
-                                            let connector_mandate_details =
-                                                update_connector_mandate_details_in_payment_method(
-                                                    pm.clone(),
-                                                    payment_method_type,
-                                                    amount,
-                                                    currency,
-                                                    merchant_connector_id.clone(),
-                                                    connector_mandate_id.clone(),
-                                                    mandate_metadata.clone(),
-                                                )?;
-
-                                            payment_methods::cards::update_payment_method_connector_mandate_details(  state,
-                                            key_store,db, pm.clone(), connector_mandate_details, merchant_account.storage_scheme).await.change_context(
-                                            errors::ApiErrorResponse::InternalServerError,
-                                        )
-                                        .attach_printable("Failed to update payment method in db")?;
-                                        }
-                                        Ok(pm)
-                                    }
+                                    Ok(pm) => Ok(pm),
                                     Err(err) => {
                                         if err.current_context().is_db_not_found() {
                                             payment_methods::cards::create_payment_method(
@@ -524,7 +456,7 @@ where
                                                 customer_acceptance,
                                                 pm_data_encrypted.map(Into::into),
                                                 key_store,
-                                                connector_mandate_details,
+                                                None,
                                                 pm_status,
                                                 network_transaction_id,
                                                 merchant_account.storage_scheme,
@@ -733,7 +665,7 @@ where
                                 customer_acceptance,
                                 pm_data_encrypted.map(Into::into),
                                 key_store,
-                                connector_mandate_details,
+                                None,
                                 pm_status,
                                 network_transaction_id,
                                 merchant_account.storage_scheme,
@@ -755,35 +687,28 @@ where
             } else {
                 None
             };
-            let cmid_config = db
-                .find_config_by_key_unwrap_or(
-                    format!("{}_should_show_connector_mandate_id_in_payments_response", merchant_account.get_id().get_string_repr().to_owned()).as_str(),
-                    Some("false".to_string()),
-                )
-                .await.map_err(|err| services::logger::error!(message="Failed to fetch the config", connector_mandate_details_population=?err)).ok();
-
-            let mandate_reference_id = match cmid_config {
-                Some(config) if config.config == "true" => Some(
-                    MandateReferenceId::ConnectorMandateId(ConnectorMandateReferenceId {
-                        connector_mandate_id: connector_mandate_id.clone(),
-                        payment_method_id: pm_id.clone(),
-                        update_history: None,
-                        mandate_metadata: mandate_metadata.clone(),
-                    }),
-                ),
-                _ => None,
+            // check if there needs to be a config if yes then remove it to a different place
+            let connector_mandate_reference_id = if connector_mandate_id.is_some() {
+                Some(ConnectorMandateReferenceId {
+                    connector_mandate_id: connector_mandate_id.clone(),
+                    payment_method_id: None,
+                    update_history: None,
+                    mandate_metadata: mandate_metadata.clone(),
+                })
+            } else {
+                None
             };
 
             Ok(SavePaymentMethodDataResponse {
                 payment_method_id: pm_id,
                 payment_method_status: pm_status,
-                mandate_reference_id,
+                connector_mandate_reference_id,
             })
         }
         Err(_) => Ok(SavePaymentMethodDataResponse {
             payment_method_id: None,
             payment_method_status: None,
-            mandate_reference_id: None,
+            connector_mandate_reference_id: None,
         }),
     }
 }
@@ -795,14 +720,11 @@ where
 pub async fn save_payment_method<FData>(
     _state: &SessionState,
     _connector_name: String,
-    _merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
     _save_payment_method_data: SavePaymentMethodData<FData>,
     _customer_id: Option<id_type::CustomerId>,
     _merchant_account: &domain::MerchantAccount,
     _payment_method_type: Option<storage_enums::PaymentMethodType>,
     _key_store: &domain::MerchantKeyStore,
-    _amount: Option<i64>,
-    _currency: Option<storage_enums::Currency>,
     _billing_name: Option<Secret<String>>,
     _payment_method_billing_address: Option<&api::Address>,
     _business_profile: &domain::Profile,
@@ -1226,6 +1148,7 @@ pub fn add_connector_mandate_details_in_payment_method(
                 original_payment_authorized_amount: authorized_amount,
                 original_payment_authorized_currency: authorized_currency,
                 mandate_metadata,
+                connector_mandate_status: Some(ConnectorMandateStatus::Active),
             },
         );
         Some(storage::PaymentsMandateReference(mandate_details))
@@ -1234,8 +1157,8 @@ pub fn add_connector_mandate_details_in_payment_method(
     }
 }
 
-pub fn update_connector_mandate_details_in_payment_method(
-    payment_method: domain::PaymentMethod,
+pub fn update_connector_mandate_details(
+    mandate_details: Option<storage::PaymentsMandateReference>,
     payment_method_type: Option<storage_enums::PaymentMethodType>,
     authorized_amount: Option<i64>,
     authorized_currency: Option<storage_enums::Currency>,
@@ -1243,17 +1166,8 @@ pub fn update_connector_mandate_details_in_payment_method(
     connector_mandate_id: Option<String>,
     mandate_metadata: Option<serde_json::Value>,
 ) -> RouterResult<Option<serde_json::Value>> {
-    let mandate_reference = match payment_method.connector_mandate_details {
-        Some(_) => {
-            let mandate_details = payment_method
-                .connector_mandate_details
-                .map(|val| {
-                    val.parse_value::<storage::PaymentsMandateReference>("PaymentsMandateReference")
-                })
-                .transpose()
-                .change_context(errors::ApiErrorResponse::InternalServerError)
-                .attach_printable("Failed to deserialize to Payment Mandate Reference ")?;
-
+    let mandate_reference = match mandate_details {
+        Some(mut payment_mandate_reference) => {
             if let Some((mca_id, connector_mandate_id)) =
                 merchant_connector_id.clone().zip(connector_mandate_id)
             {
@@ -1263,20 +1177,21 @@ pub fn update_connector_mandate_details_in_payment_method(
                     original_payment_authorized_amount: authorized_amount,
                     original_payment_authorized_currency: authorized_currency,
                     mandate_metadata: mandate_metadata.clone(),
+                    connector_mandate_status: Some(ConnectorMandateStatus::Active),
                 };
-                mandate_details.map(|mut payment_mandate_reference| {
-                    payment_mandate_reference
-                        .entry(mca_id)
-                        .and_modify(|pm| *pm = updated_record)
-                        .or_insert(storage::PaymentsMandateReferenceRecord {
-                            connector_mandate_id,
-                            payment_method_type,
-                            original_payment_authorized_amount: authorized_amount,
-                            original_payment_authorized_currency: authorized_currency,
-                            mandate_metadata: mandate_metadata.clone(),
-                        });
-                    payment_mandate_reference
-                })
+
+                payment_mandate_reference
+                    .entry(mca_id)
+                    .and_modify(|pm| *pm = updated_record)
+                    .or_insert(storage::PaymentsMandateReferenceRecord {
+                        connector_mandate_id,
+                        payment_method_type,
+                        original_payment_authorized_amount: authorized_amount,
+                        original_payment_authorized_currency: authorized_currency,
+                        mandate_metadata: mandate_metadata.clone(),
+                        connector_mandate_status: Some(ConnectorMandateStatus::Active),
+                    });
+                Some(payment_mandate_reference)
             } else {
                 None
             }
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index 36586fdb155..0d9d684cae8 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -1,8 +1,8 @@
 use std::{fmt::Debug, marker::PhantomData, str::FromStr};
 
 use api_models::payments::{
-    Address, CustomerDetails, CustomerDetailsResponse, FrmMessage, PaymentChargeRequest,
-    PaymentChargeResponse, RequestSurchargeDetails,
+    Address, ConnectorMandateReferenceId, CustomerDetails, CustomerDetailsResponse, FrmMessage,
+    PaymentChargeRequest, PaymentChargeResponse, RequestSurchargeDetails,
 };
 use common_enums::{Currency, RequestIncrementalAuthorization};
 use common_utils::{
@@ -11,7 +11,10 @@ use common_utils::{
     pii::Email,
     types::{self as common_utils_type, AmountConvertor, MinorUnit, StringMajorUnitForConnector},
 };
-use diesel_models::ephemeral_key;
+use diesel_models::{
+    ephemeral_key,
+    payment_attempt::ConnectorMandateReferenceId as DieselConnectorMandateReferenceId,
+};
 use error_stack::{report, ResultExt};
 use hyperswitch_domain_models::{payments::payment_intent::CustomerData, router_request_types};
 use masking::{ExposeInterface, Maskable, PeekInterface, Secret};
@@ -2849,3 +2852,23 @@ impl ForeignFrom<diesel_models::TransactionDetailsUiConfiguration>
         }
     }
 }
+
+impl ForeignFrom<DieselConnectorMandateReferenceId> for ConnectorMandateReferenceId {
+    fn foreign_from(value: DieselConnectorMandateReferenceId) -> Self {
+        Self {
+            connector_mandate_id: value.connector_mandate_id,
+            payment_method_id: value.payment_method_id,
+            update_history: None,
+            mandate_metadata: value.mandate_metadata,
+        }
+    }
+}
+impl ForeignFrom<ConnectorMandateReferenceId> for DieselConnectorMandateReferenceId {
+    fn foreign_from(value: ConnectorMandateReferenceId) -> Self {
+        Self {
+            connector_mandate_id: value.connector_mandate_id,
+            payment_method_id: value.payment_method_id,
+            mandate_metadata: value.mandate_metadata,
+        }
+    }
+}
diff --git a/crates/router/src/core/webhooks/incoming.rs b/crates/router/src/core/webhooks/incoming.rs
index 3942c395665..19670fc8ccb 100644
--- a/crates/router/src/core/webhooks/incoming.rs
+++ b/crates/router/src/core/webhooks/incoming.rs
@@ -259,13 +259,13 @@ async fn incoming_webhooks_core<W: types::OutgoingWebhookType>(
         let merchant_connector_account = match merchant_connector_account {
             Some(merchant_connector_account) => merchant_connector_account,
             None => {
-                helper_utils::get_mca_from_object_reference_id(
+                Box::pin(helper_utils::get_mca_from_object_reference_id(
                     &state,
                     object_ref_id.clone(),
                     &merchant_account,
                     &connector_name,
                     &key_store,
-                )
+                ))
                 .await?
             }
         };
diff --git a/crates/router/src/types/storage/payment_attempt.rs b/crates/router/src/types/storage/payment_attempt.rs
index 40335d5f2ab..502e03b7293 100644
--- a/crates/router/src/types/storage/payment_attempt.rs
+++ b/crates/router/src/types/storage/payment_attempt.rs
@@ -216,6 +216,7 @@ mod tests {
             customer_acceptance: Default::default(),
             profile_id: common_utils::generate_profile_id_of_default_length(),
             organization_id: Default::default(),
+            connector_mandate_detail: Default::default(),
         };
 
         let store = state
@@ -299,6 +300,7 @@ mod tests {
             customer_acceptance: Default::default(),
             profile_id: common_utils::generate_profile_id_of_default_length(),
             organization_id: Default::default(),
+            connector_mandate_detail: Default::default(),
         };
         let store = state
             .stores
@@ -395,6 +397,7 @@ mod tests {
             customer_acceptance: Default::default(),
             profile_id: common_utils::generate_profile_id_of_default_length(),
             organization_id: Default::default(),
+            connector_mandate_detail: Default::default(),
         };
         let store = state
             .stores
diff --git a/crates/router/src/types/storage/payment_method.rs b/crates/router/src/types/storage/payment_method.rs
index bb1b801edb6..20d0ee74b01 100644
--- a/crates/router/src/types/storage/payment_method.rs
+++ b/crates/router/src/types/storage/payment_method.rs
@@ -125,6 +125,7 @@ pub struct PaymentsMandateReferenceRecord {
     pub original_payment_authorized_amount: Option<i64>,
     pub original_payment_authorized_currency: Option<common_enums::Currency>,
     pub mandate_metadata: Option<serde_json::Value>,
+    pub connector_mandate_status: Option<common_enums::ConnectorMandateStatus>,
 }
 
 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs
index 122989a82cf..7faafb14ec1 100644
--- a/crates/router/src/utils/user/sample_data.rs
+++ b/crates/router/src/utils/user/sample_data.rs
@@ -339,6 +339,7 @@ pub async fn generate_sample_data(
             shipping_cost: None,
             order_tax_amount: None,
             connector_transaction_data,
+            connector_mandate_detail: None,
         };
 
         let refund = if refunds_count < number_of_refunds && !is_failed_payment {
diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs
index 59fb1155480..121397cdfb9 100644
--- a/crates/storage_impl/src/mock_db/payment_attempt.rs
+++ b/crates/storage_impl/src/mock_db/payment_attempt.rs
@@ -180,6 +180,7 @@ impl PaymentAttemptInterface for MockDb {
             customer_acceptance: payment_attempt.customer_acceptance,
             organization_id: payment_attempt.organization_id,
             profile_id: payment_attempt.profile_id,
+            connector_mandate_detail: payment_attempt.connector_mandate_detail,
         };
         payment_attempts.push(payment_attempt.clone());
         Ok(payment_attempt)
diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs
index 024ab9fd814..5087e28b854 100644
--- a/crates/storage_impl/src/payments/payment_attempt.rs
+++ b/crates/storage_impl/src/payments/payment_attempt.rs
@@ -531,6 +531,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
                     customer_acceptance: payment_attempt.customer_acceptance.clone(),
                     organization_id: payment_attempt.organization_id.clone(),
                     profile_id: payment_attempt.profile_id.clone(),
+                    connector_mandate_detail: payment_attempt.connector_mandate_detail.clone(),
                 };
 
                 let field = format!("pa_{}", created_attempt.attempt_id);
@@ -1453,6 +1454,7 @@ impl DataModelExt for PaymentAttempt {
             connector_transaction_data,
             shipping_cost: self.net_amount.get_shipping_cost(),
             order_tax_amount: self.net_amount.get_order_tax_amount(),
+            connector_mandate_detail: self.connector_mandate_detail,
         }
     }
 
@@ -1528,6 +1530,7 @@ impl DataModelExt for PaymentAttempt {
             customer_acceptance: storage_model.customer_acceptance,
             organization_id: storage_model.organization_id,
             profile_id: storage_model.profile_id,
+            connector_mandate_detail: storage_model.connector_mandate_detail,
         }
     }
 }
@@ -1610,6 +1613,7 @@ impl DataModelExt for PaymentAttemptNew {
             profile_id: self.profile_id,
             shipping_cost: self.net_amount.get_shipping_cost(),
             order_tax_amount: self.net_amount.get_order_tax_amount(),
+            connector_mandate_detail: self.connector_mandate_detail,
         }
     }
 
@@ -1681,6 +1685,7 @@ impl DataModelExt for PaymentAttemptNew {
             customer_acceptance: storage_model.customer_acceptance,
             organization_id: storage_model.organization_id,
             profile_id: storage_model.profile_id,
+            connector_mandate_detail: storage_model.connector_mandate_detail,
         }
     }
 }
diff --git a/migrations/2024-10-13-182546_add_connector_mandate_id_in_payment_attempt/down.sql b/migrations/2024-10-13-182546_add_connector_mandate_id_in_payment_attempt/down.sql
new file mode 100644
index 00000000000..f4e6f2e2e26
--- /dev/null
+++ b/migrations/2024-10-13-182546_add_connector_mandate_id_in_payment_attempt/down.sql
@@ -0,0 +1,3 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE
+    payment_attempt DROP COLUMN connector_mandate_detail;
\ No newline at end of file
diff --git a/migrations/2024-10-13-182546_add_connector_mandate_id_in_payment_attempt/up.sql b/migrations/2024-10-13-182546_add_connector_mandate_id_in_payment_attempt/up.sql
new file mode 100644
index 00000000000..bb592f623d4
--- /dev/null
+++ b/migrations/2024-10-13-182546_add_connector_mandate_id_in_payment_attempt/up.sql
@@ -0,0 +1,5 @@
+-- Your SQL goes here
+ALTER TABLE
+    payment_attempt
+ADD
+    COLUMN connector_mandate_detail JSONB DEFAULT NULL;
\ No newline at end of file

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

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

## Description
 Earlier we used to store the connector mandate id irrespective of the payments status being charged or not for 3DS flows, now we would handle the connector_mandate_id updation in payment_method once and only if the payment has a status as charged.


### Additional Changes

- [ ] This PR modifies the API contract
- [x] 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?

- Configure a MA and a MCA
- Make a 3ds mandate failed payment, it would be populated in the payment_attempt, but not in the payment_method table
```
Create
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-feature: router-custom' \
--header 'api-key: dev_5SpseUd7WAhIwgQeMpoCKwEeaPjmduquAv3Qu4VxdRkSBkilsq5arTZa6nXoPokw' \
--data-raw '{
    "amount": 8500,
    "currency": "USD",
    "confirm": false,
    
    "customer_id": "CustomerX777",
    "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",
    
"setup_future_usage":"off_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"
        }
    },
    


    "shipping": {
        "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"
        }
    },
    "connector_metadata": {
        "noon": {
            "order_category": "pay"
        }
    }
    
   
}'
```

```
Confirm

curl --location 'http://localhost:8080/payments/pay_v7bENZR0bgPe0g6ThobF/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-feature: router-custom' \
--header 'api-key: pk_dev_07feea3d36ed4f8da3cd844b07b8e3e9' \
--data '{
    "confirm": true,
    
    "client_secret":"pay_v7bENZR0bgPe0g6ThobF_secret_d792ajlpJ4z6XlS9esjK",
    "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"
        }
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "125.0.0.1"
    },
  
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    },
    
     
    "payment_method": "card",


     "payment_method_type": "debit",
    "payment_method_data": {
        "card": {

 
            
                 "card_number": "4000008400001629",
            "card_exp_month": "06",
            "card_exp_year": "2030",
            "card_holder_name": "John T",
            
            
            
            "card_cvc": "737"
        }
    }
}'
```

```
Response

{
    "payment_id": "pay_v7bENZR0bgPe0g6ThobF",
    "merchant_id": "merchant_1729155606",
    "status": "requires_customer_action",
    "amount": 8500,
    "net_amount": 8500,
    "amount_capturable": 8500,
    "amount_received": 0,
    "connector": "stripe",
    "client_secret": "pay_v7bENZR0bgPe0g6ThobF_secret_d792ajlpJ4z6XlS9esjK",
    "created": "2024-10-17T09:01:29.364Z",
    "currency": "USD",
    "customer_id": "CustomerX777",
    "customer": {
        "id": "CustomerX777",
        "name": "Joseph Doe",
        "email": "something@gmail.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "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": "1629",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "400000",
            "card_extended_bin": null,
            "card_exp_month": "06",
            "card_exp_year": "2030",
            "card_holder_name": null,
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": "something@gmail.com",
    "name": "Joseph Doe",
    "phone": "999999999",
    "return_url": "https://google.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_v7bENZR0bgPe0g6ThobF/merchant_1729155606/pay_v7bENZR0bgPe0g6ThobF_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "debit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": null,
    "connector_transaction_id": "pi_3QApaRD5R7gDAGff0khxOUA8",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": {
        "apple_pay": null,
        "airwallex": null,
        "noon": {
            "order_category": "pay"
        }
    },
    "feature_metadata": null,
    "reference_id": "pi_3QApaRD5R7gDAGff0khxOUA8",
    "payment_link": null,
    "profile_id": "pro_OYE7Iv9nauJb3HXYFB1u",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_LKJi6vdC2IEQwbEaVJQP",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-10-17T09:16:29.364Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "125.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_method_id": "pm_PxUXcAinbE62hBE1mAg2",
    "payment_method_status": "inactive",
    "updated": "2024-10-17T09:01:39.749Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": "pm_1QApaRD5R7gDAGffKM5cG6sU"
}
```
```
The payment_method_table won't have connectir_mandate_details
```
<img width="1725" alt="Screenshot 2024-10-17 at 2 48 01 PM" src="https://github.com/user-attachments/assets/c361f388-0c64-4b57-b5ff-ae8b4d5a3881">

- Make a 3ds payment successful, then only it will be populated in the payment_method
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-feature: router-custom' \
--header 'api-key: dev_5SpseUd7WAhIwgQeMpoCKwEeaPjmduquAv3Qu4VxdRkSBkilsq5arTZa6nXoPokw' \
--data-raw '{
    "amount": 8500,
    "currency": "USD",
    "confirm": false,
    
    "customer_id": "CustomerX777",
    "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",   
"setup_future_usage":"off_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"
        }
    },

    "shipping": {
        "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"
        }
    },
    "connector_metadata": {
        "noon": {
            "order_category": "pay"
        }
    }
    
   
}'
```
```
Confirm

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-feature: router-custom' \
--header 'api-key: dev_5SpseUd7WAhIwgQeMpoCKwEeaPjmduquAv3Qu4VxdRkSBkilsq5arTZa6nXoPokw' \
--data-raw '{
    "amount": 8500,
    "currency": "USD",
    "confirm": false,
    
    "customer_id": "CustomerX777",
    "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",
"setup_future_usage":"off_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"
        }
    },
    
    "shipping": {
        "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"
        }
    },
    "connector_metadata": {
        "noon": {
            "order_category": "pay"
        }
    }
    
   
}'
```
```
response
{
    "payment_id": "pay_m59xmko152RMgzTqgUeP",
    "merchant_id": "merchant_1729155606",
    "status": "succeeded",
    "amount": 8500,
    "net_amount": 8500,
    "amount_capturable": 0,
    "amount_received": 8500,
    "connector": "stripe",
    "client_secret": "pay_m59xmko152RMgzTqgUeP_secret_m8J1xt82aJYVaK4o4vNs",
    "created": "2024-10-17T09:18:18.049Z",
    "currency": "USD",
    "customer_id": "CustomerX777",
    "customer": {
        "id": "CustomerX777",
        "name": "Joseph Doe",
        "email": "something@gmail.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "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": "1111",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "411111",
            "card_extended_bin": null,
            "card_exp_month": "06",
            "card_exp_year": "2030",
            "card_holder_name": null,
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": "something@gmail.com",
    "name": "Joseph Doe",
    "phone": "999999999",
    "return_url": "https://google.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "debit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "pi_3QApqiD5R7gDAGff1ykvxYD0",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": {
        "apple_pay": null,
        "airwallex": null,
        "noon": {
            "order_category": "pay"
        }
    },
    "feature_metadata": null,
    "reference_id": "pi_3QApqiD5R7gDAGff1ykvxYD0",
    "payment_link": null,
    "profile_id": "pro_OYE7Iv9nauJb3HXYFB1u",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_LKJi6vdC2IEQwbEaVJQP",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-10-17T09:33:18.049Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "125.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_method_id": "pm_9ahIWQWjvWNTYCi1myPc",
    "payment_method_status": "active",
    "updated": "2024-10-17T09:18:35.865Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
```
The payment_method would have a connector_mandate_id with it 

<img width="1725" alt="Screenshot 2024-10-17 at 2 54 03 PM" src="https://github.com/user-attachments/assets/847ad97b-2cd0-4f48-a00f-8b833967df37">

- If another CIT mandate payment is made it wouldn't be populated anymore

- Make a complete authorise mandate payment , it should be saved in the payment_method, for that mca_id
 - Make a external 3ds mandate payment , it should be saved in the payment_method, for that mca_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`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
