Bug: [FEATURE] Add new column in PaymentAttempt for storing mandate_data 



### Feature Description

Add new column in PaymentAttempt for storing mandate_data to be future compatible 

### Possible Implementation

Add a column mandate_data which would be a struct , in order to store the mandate details for a mandate in Payment Attempt table

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

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/crates/data_models/src/mandates.rs b/crates/data_models/src/mandates.rs
index 319a78cf661..b4478f84ee9 100644
--- a/crates/data_models/src/mandates.rs
+++ b/crates/data_models/src/mandates.rs
@@ -13,7 +13,6 @@ use time::PrimitiveDateTime;
 #[serde(rename_all = "snake_case")]
 pub struct MandateDetails {
     pub update_mandate_id: Option<String>,
-    pub mandate_type: Option<MandateDataType>,
 }
 
 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
@@ -23,13 +22,6 @@ pub enum MandateDataType {
     MultiUse(Option<MandateAmountData>),
 }
 
-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
-#[serde(rename_all = "snake_case")]
-#[serde(untagged)]
-pub enum MandateTypeDetails {
-    MandateType(MandateDataType),
-    MandateDetails(MandateDetails),
-}
 #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
 pub struct MandateAmountData {
     pub amount: i64,
diff --git a/crates/data_models/src/payments/payment_attempt.rs b/crates/data_models/src/payments/payment_attempt.rs
index 2b5705c155b..084b0ef251e 100644
--- a/crates/data_models/src/payments/payment_attempt.rs
+++ b/crates/data_models/src/payments/payment_attempt.rs
@@ -4,7 +4,11 @@ use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
 use super::PaymentIntent;
-use crate::{errors, mandates::MandateTypeDetails, ForeignIDRef};
+use crate::{
+    errors,
+    mandates::{MandateDataType, MandateDetails},
+    ForeignIDRef,
+};
 
 #[async_trait::async_trait]
 pub trait PaymentAttemptInterface {
@@ -143,7 +147,7 @@ pub struct PaymentAttempt {
     pub straight_through_algorithm: Option<serde_json::Value>,
     pub preprocessing_step_id: Option<String>,
     // providing a location to store mandate details intermediately for transaction
-    pub mandate_details: Option<MandateTypeDetails>,
+    pub mandate_details: Option<MandateDataType>,
     pub error_reason: Option<String>,
     pub multiple_capture_count: Option<i16>,
     // reference to the payment at connector side
@@ -155,6 +159,7 @@ pub struct PaymentAttempt {
     pub merchant_connector_id: Option<String>,
     pub unified_code: Option<String>,
     pub unified_message: Option<String>,
+    pub mandate_data: Option<MandateDetails>,
 }
 
 impl PaymentAttempt {
@@ -221,7 +226,7 @@ pub struct PaymentAttemptNew {
     pub business_sub_label: Option<String>,
     pub straight_through_algorithm: Option<serde_json::Value>,
     pub preprocessing_step_id: Option<String>,
-    pub mandate_details: Option<MandateTypeDetails>,
+    pub mandate_details: Option<MandateDataType>,
     pub error_reason: Option<String>,
     pub connector_response_reference_id: Option<String>,
     pub multiple_capture_count: Option<i16>,
@@ -232,6 +237,7 @@ pub struct PaymentAttemptNew {
     pub merchant_connector_id: Option<String>,
     pub unified_code: Option<String>,
     pub unified_message: Option<String>,
+    pub mandate_data: Option<MandateDetails>,
 }
 
 impl PaymentAttemptNew {
diff --git a/crates/diesel_models/src/enums.rs b/crates/diesel_models/src/enums.rs
index babffdbc4a8..d65f6c5efa9 100644
--- a/crates/diesel_models/src/enums.rs
+++ b/crates/diesel_models/src/enums.rs
@@ -174,20 +174,8 @@ use diesel::{
 #[serde(rename_all = "snake_case")]
 pub struct MandateDetails {
     pub update_mandate_id: Option<String>,
-    pub mandate_type: Option<MandateDataType>,
 }
-
-#[derive(
-    serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression,
-)]
-#[diesel(sql_type = Jsonb)]
-#[serde(rename_all = "snake_case")]
-pub enum MandateDataType {
-    SingleUse(MandateAmountData),
-    MultiUse(Option<MandateAmountData>),
-}
-
-impl<DB: Backend> FromSql<Jsonb, DB> for MandateDataType
+impl<DB: Backend> FromSql<Jsonb, DB> for MandateDetails
 where
     serde_json::Value: FromSql<Jsonb, DB>,
 {
@@ -197,7 +185,7 @@ where
     }
 }
 
-impl ToSql<Jsonb, diesel::pg::Pg> for MandateDataType
+impl ToSql<Jsonb, diesel::pg::Pg> for MandateDetails
 where
     serde_json::Value: ToSql<Jsonb, diesel::pg::Pg>,
 {
@@ -210,19 +198,17 @@ where
         <serde_json::Value as ToSql<Jsonb, diesel::pg::Pg>>::to_sql(&value, &mut out.reborrow())
     }
 }
-
 #[derive(
     serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression,
 )]
 #[diesel(sql_type = Jsonb)]
-#[serde(untagged)]
 #[serde(rename_all = "snake_case")]
-pub enum MandateTypeDetails {
-    MandateType(MandateDataType),
-    MandateDetails(MandateDetails),
+pub enum MandateDataType {
+    SingleUse(MandateAmountData),
+    MultiUse(Option<MandateAmountData>),
 }
 
-impl<DB: Backend> FromSql<Jsonb, DB> for MandateTypeDetails
+impl<DB: Backend> FromSql<Jsonb, DB> for MandateDataType
 where
     serde_json::Value: FromSql<Jsonb, DB>,
 {
@@ -231,7 +217,8 @@ where
         Ok(serde_json::from_value(value)?)
     }
 }
-impl ToSql<Jsonb, diesel::pg::Pg> for MandateTypeDetails
+
+impl ToSql<Jsonb, diesel::pg::Pg> for MandateDataType
 where
     serde_json::Value: ToSql<Jsonb, diesel::pg::Pg>,
 {
diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs
index d286cc312bc..9af4595c9f4 100644
--- a/crates/diesel_models/src/payment_attempt.rs
+++ b/crates/diesel_models/src/payment_attempt.rs
@@ -51,7 +51,7 @@ pub struct PaymentAttempt {
     pub straight_through_algorithm: Option<serde_json::Value>,
     pub preprocessing_step_id: Option<String>,
     // providing a location to store mandate details intermediately for transaction
-    pub mandate_details: Option<storage_enums::MandateTypeDetails>,
+    pub mandate_details: Option<storage_enums::MandateDataType>,
     pub error_reason: Option<String>,
     pub multiple_capture_count: Option<i16>,
     // reference to the payment at connector side
@@ -64,6 +64,7 @@ pub struct PaymentAttempt {
     pub unified_code: Option<String>,
     pub unified_message: Option<String>,
     pub net_amount: Option<i64>,
+    pub mandate_data: Option<storage_enums::MandateDetails>,
 }
 
 impl PaymentAttempt {
@@ -126,7 +127,7 @@ pub struct PaymentAttemptNew {
     pub business_sub_label: Option<String>,
     pub straight_through_algorithm: Option<serde_json::Value>,
     pub preprocessing_step_id: Option<String>,
-    pub mandate_details: Option<storage_enums::MandateTypeDetails>,
+    pub mandate_details: Option<storage_enums::MandateDataType>,
     pub error_reason: Option<String>,
     pub connector_response_reference_id: Option<String>,
     pub multiple_capture_count: Option<i16>,
@@ -138,6 +139,7 @@ pub struct PaymentAttemptNew {
     pub unified_code: Option<String>,
     pub unified_message: Option<String>,
     pub net_amount: Option<i64>,
+    pub mandate_data: Option<storage_enums::MandateDetails>,
 }
 
 impl PaymentAttemptNew {
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index c9887e1770f..6c28677432b 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -688,6 +688,7 @@ diesel::table! {
         #[max_length = 1024]
         unified_message -> Nullable<Varchar>,
         net_amount -> Nullable<Int8>,
+        mandate_data -> Nullable<Jsonb>,
     }
 }
 
diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs
index 5a2226f0676..6a6d4c52c97 100644
--- a/crates/diesel_models/src/user/sample_data.rs
+++ b/crates/diesel_models/src/user/sample_data.rs
@@ -5,7 +5,11 @@ use common_enums::{
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
-use crate::{enums::MandateTypeDetails, schema::payment_attempt, PaymentAttemptNew};
+use crate::{
+    enums::{MandateDataType, MandateDetails},
+    schema::payment_attempt,
+    PaymentAttemptNew,
+};
 
 #[derive(
     Clone, Debug, Default, diesel::Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize,
@@ -50,7 +54,7 @@ pub struct PaymentAttemptBatchNew {
     pub business_sub_label: Option<String>,
     pub straight_through_algorithm: Option<serde_json::Value>,
     pub preprocessing_step_id: Option<String>,
-    pub mandate_details: Option<MandateTypeDetails>,
+    pub mandate_details: Option<MandateDataType>,
     pub error_reason: Option<String>,
     pub connector_response_reference_id: Option<String>,
     pub connector_transaction_id: Option<String>,
@@ -63,6 +67,7 @@ pub struct PaymentAttemptBatchNew {
     pub unified_code: Option<String>,
     pub unified_message: Option<String>,
     pub net_amount: Option<i64>,
+    pub mandate_data: Option<MandateDetails>,
 }
 
 #[allow(dead_code)]
@@ -116,6 +121,7 @@ impl PaymentAttemptBatchNew {
             unified_code: self.unified_code,
             unified_message: self.unified_message,
             net_amount: self.net_amount,
+            mandate_data: self.mandate_data,
         }
     }
 }
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 7b505e7c01c..5d287a89f62 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -1837,17 +1837,8 @@ pub async fn list_payment_methods(
             merchant_name: merchant_account.merchant_name,
             payment_type,
             payment_methods: payment_method_responses,
-            mandate_payment: payment_attempt
-                .and_then(|inner| inner.mandate_details)
-                .and_then(|man_type_details| match man_type_details {
-                    data_models::mandates::MandateTypeDetails::MandateType(mandate_type) => {
-                        Some(mandate_type)
-                    }
-                    data_models::mandates::MandateTypeDetails::MandateDetails(mandate_details) => {
-                        mandate_details.mandate_type
-                    }
-                })
-                .map(|d| match d {
+            mandate_payment: payment_attempt.and_then(|inner| inner.mandate_details).map(
+                |d| match d {
                     data_models::mandates::MandateDataType::SingleUse(i) => {
                         api::MandateType::SingleUse(api::MandateAmountData {
                             amount: i.amount,
@@ -1869,7 +1860,8 @@ pub async fn list_payment_methods(
                     data_models::mandates::MandateDataType::MultiUse(None) => {
                         api::MandateType::MultiUse(None)
                     }
-                }),
+                },
+            ),
             show_surcharge_breakup_screen: merchant_surcharge_configs
                 .show_surcharge_breakup_screen
                 .unwrap_or_default(),
@@ -2079,28 +2071,20 @@ pub async fn filter_payment_methods(
                         })?;
                     let filter7 = payment_attempt
                         .and_then(|attempt| attempt.mandate_details.as_ref())
-                        .map(|mandate_details| {
-                            let (mandate_type_present, update_mandate_id_present) =
-                                match mandate_details {
-                                    data_models::mandates::MandateTypeDetails::MandateType(_) => {
-                                        (true, false)
-                                    }
-                                    data_models::mandates::MandateTypeDetails::MandateDetails(
-                                        mand_details,
-                                    ) => (
-                                        mand_details.mandate_type.is_some(),
-                                        mand_details.update_mandate_id.is_some(),
-                                    ),
-                                };
-
-                            if mandate_type_present {
-                                filter_pm_based_on_supported_payments_for_mandate(
-                                    supported_payment_methods_for_mandate,
-                                    &payment_method,
-                                    &payment_method_object.payment_method_type,
-                                    connector_variant,
-                                )
-                            } else if update_mandate_id_present {
+                        .map(|_mandate_details| {
+                            filter_pm_based_on_supported_payments_for_mandate(
+                                supported_payment_methods_for_mandate,
+                                &payment_method,
+                                &payment_method_object.payment_method_type,
+                                connector_variant,
+                            )
+                        })
+                        .unwrap_or(true);
+
+                    let filter8 = payment_attempt
+                        .and_then(|attempt| attempt.mandate_data.as_ref())
+                        .map(|mandate_detail| {
+                            if mandate_detail.update_mandate_id.is_some() {
                                 filter_pm_based_on_update_mandate_support_for_connector(
                                     supported_payment_methods_for_update_mandate,
                                     &payment_method,
@@ -2121,7 +2105,15 @@ pub async fn filter_payment_methods(
                         payment_method,
                     );
 
-                    if filter && filter2 && filter3 && filter4 && filter5 && filter6 && filter7 {
+                    if filter
+                        && filter2
+                        && filter3
+                        && filter4
+                        && filter5
+                        && filter6
+                        && filter7
+                        && filter8
+                    {
                         resp.push(response_pm_type);
                     }
                 }
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 7ec1f5e9213..c6ba4a4e987 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -3201,6 +3201,7 @@ impl AttemptType {
             unified_code: None,
             unified_message: None,
             net_amount: old_payment_attempt.amount,
+            mandate_data: old_payment_attempt.mandate_data,
         }
     }
 
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index 54ec47ecea5..8349f050135 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -441,28 +441,11 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
 
         // The operation merges mandate data from both request and payment_attempt
         setup_mandate = setup_mandate.map(|mut sm| {
-            sm.mandate_type = payment_attempt
-                .mandate_details
-                .clone()
-                .and_then(|mandate| match mandate {
-                    data_models::mandates::MandateTypeDetails::MandateType(mandate_type) => {
-                        Some(mandate_type)
-                    }
-                    data_models::mandates::MandateTypeDetails::MandateDetails(mandate_details) => {
-                        mandate_details.mandate_type
-                    }
-                })
-                .or(sm.mandate_type);
+            sm.mandate_type = payment_attempt.mandate_details.clone().or(sm.mandate_type);
             sm.update_mandate_id = payment_attempt
-                .mandate_details
+                .mandate_data
                 .clone()
-                .and_then(|mandate| match mandate {
-                    data_models::mandates::MandateTypeDetails::MandateType(_) => None,
-                    data_models::mandates::MandateTypeDetails::MandateDetails(update_id) => {
-                        Some(update_id.update_mandate_id)
-                    }
-                })
-                .flatten()
+                .and_then(|mandate| mandate.update_mandate_id)
                 .or(sm.update_mandate_id);
             sm
         });
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 8d37fc486c5..0f581be3089 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -4,7 +4,7 @@ use api_models::enums::FrmSuggestion;
 use async_trait::async_trait;
 use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
 use data_models::{
-    mandates::{MandateData, MandateDetails, MandateTypeDetails},
+    mandates::{MandateData, MandateDetails},
     payments::payment_attempt::PaymentAttempt,
 };
 use diesel_models::ephemeral_key;
@@ -733,27 +733,17 @@ impl PaymentCreate {
             Err(errors::ApiErrorResponse::InvalidRequestData {message:"Only one field out of 'mandate_type' and 'update_mandate_id' was expected, found both".to_string()})?
         }
 
-        let mandate_details = if request.mandate_data.is_none() {
-            None
-        } else if let Some(update_id) = request
+        let mandate_data = if let Some(update_id) = request
             .mandate_data
             .as_ref()
             .and_then(|inner| inner.update_mandate_id.clone())
         {
-            let mandate_data = MandateDetails {
+            let mandate_details = MandateDetails {
                 update_mandate_id: Some(update_id),
-                mandate_type: None,
             };
-            Some(MandateTypeDetails::MandateDetails(mandate_data))
+            Some(mandate_details)
         } else {
-            let mandate_data = MandateDetails {
-                update_mandate_id: None,
-                mandate_type: request
-                    .mandate_data
-                    .as_ref()
-                    .and_then(|inner| inner.mandate_type.clone().map(Into::into)),
-            };
-            Some(MandateTypeDetails::MandateDetails(mandate_data))
+            None
         };
 
         Ok((
@@ -782,7 +772,11 @@ impl PaymentCreate {
                 business_sub_label: request.business_sub_label.clone(),
                 surcharge_amount,
                 tax_amount,
-                mandate_details,
+                mandate_details: request
+                    .mandate_data
+                    .as_ref()
+                    .and_then(|inner| inner.mandate_type.clone().map(Into::into)),
+                mandate_data,
                 ..storage::PaymentAttemptNew::default()
             },
             additional_pm_data,
diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs
index 24863ddc568..e60e32227d3 100644
--- a/crates/storage_impl/src/mock_db/payment_attempt.rs
+++ b/crates/storage_impl/src/mock_db/payment_attempt.rs
@@ -147,6 +147,7 @@ impl PaymentAttemptInterface for MockDb {
             merchant_connector_id: payment_attempt.merchant_connector_id,
             unified_code: payment_attempt.unified_code,
             unified_message: payment_attempt.unified_message,
+            mandate_data: payment_attempt.mandate_data,
         };
         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 6af136c1062..ec19e30c0ec 100644
--- a/crates/storage_impl/src/payments/payment_attempt.rs
+++ b/crates/storage_impl/src/payments/payment_attempt.rs
@@ -2,7 +2,7 @@ use api_models::enums::{AuthenticationType, Connector, PaymentMethod, PaymentMet
 use common_utils::{errors::CustomResult, fallback_reverse_lookup_not_found};
 use data_models::{
     errors,
-    mandates::{MandateAmountData, MandateDataType, MandateDetails, MandateTypeDetails},
+    mandates::{MandateAmountData, MandateDataType, MandateDetails},
     payments::{
         payment_attempt::{
             PaymentAttempt, PaymentAttemptInterface, PaymentAttemptNew, PaymentAttemptUpdate,
@@ -14,8 +14,7 @@ use data_models::{
 use diesel_models::{
     enums::{
         MandateAmountData as DieselMandateAmountData, MandateDataType as DieselMandateType,
-        MandateDetails as DieselMandateDetails, MandateTypeDetails as DieselMandateTypeOrDetails,
-        MerchantStorageScheme,
+        MandateDetails as DieselMandateDetails, MerchantStorageScheme,
     },
     kv,
     payment_attempt::{
@@ -391,6 +390,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
                     merchant_connector_id: payment_attempt.merchant_connector_id.clone(),
                     unified_code: payment_attempt.unified_code.clone(),
                     unified_message: payment_attempt.unified_message.clone(),
+                    mandate_data: payment_attempt.mandate_data.clone(),
                 };
 
                 let field = format!("pa_{}", created_attempt.attempt_id);
@@ -1016,42 +1016,11 @@ impl DataModelExt for MandateDetails {
     fn to_storage_model(self) -> Self::StorageModel {
         DieselMandateDetails {
             update_mandate_id: self.update_mandate_id,
-            mandate_type: self
-                .mandate_type
-                .map(|mand_type| mand_type.to_storage_model()),
         }
     }
     fn from_storage_model(storage_model: Self::StorageModel) -> Self {
         Self {
             update_mandate_id: storage_model.update_mandate_id,
-            mandate_type: storage_model
-                .mandate_type
-                .map(MandateDataType::from_storage_model),
-        }
-    }
-}
-impl DataModelExt for MandateTypeDetails {
-    type StorageModel = DieselMandateTypeOrDetails;
-
-    fn to_storage_model(self) -> Self::StorageModel {
-        match self {
-            Self::MandateType(mandate_type) => {
-                DieselMandateTypeOrDetails::MandateType(mandate_type.to_storage_model())
-            }
-            Self::MandateDetails(mandate_details) => {
-                DieselMandateTypeOrDetails::MandateDetails(mandate_details.to_storage_model())
-            }
-        }
-    }
-
-    fn from_storage_model(storage_model: Self::StorageModel) -> Self {
-        match storage_model {
-            DieselMandateTypeOrDetails::MandateType(data) => {
-                Self::MandateType(MandateDataType::from_storage_model(data))
-            }
-            DieselMandateTypeOrDetails::MandateDetails(data) => {
-                Self::MandateDetails(MandateDetails::from_storage_model(data))
-            }
         }
     }
 }
@@ -1124,7 +1093,7 @@ impl DataModelExt for PaymentAttempt {
             business_sub_label: self.business_sub_label,
             straight_through_algorithm: self.straight_through_algorithm,
             preprocessing_step_id: self.preprocessing_step_id,
-            mandate_details: self.mandate_details.map(|md| md.to_storage_model()),
+            mandate_details: self.mandate_details.map(|d| d.to_storage_model()),
             error_reason: self.error_reason,
             multiple_capture_count: self.multiple_capture_count,
             connector_response_reference_id: self.connector_response_reference_id,
@@ -1135,6 +1104,7 @@ impl DataModelExt for PaymentAttempt {
             merchant_connector_id: self.merchant_connector_id,
             unified_code: self.unified_code,
             unified_message: self.unified_message,
+            mandate_data: self.mandate_data.map(|d| d.to_storage_model()),
         }
     }
 
@@ -1179,7 +1149,7 @@ impl DataModelExt for PaymentAttempt {
             preprocessing_step_id: storage_model.preprocessing_step_id,
             mandate_details: storage_model
                 .mandate_details
-                .map(MandateTypeDetails::from_storage_model),
+                .map(MandateDataType::from_storage_model),
             error_reason: storage_model.error_reason,
             multiple_capture_count: storage_model.multiple_capture_count,
             connector_response_reference_id: storage_model.connector_response_reference_id,
@@ -1190,6 +1160,9 @@ impl DataModelExt for PaymentAttempt {
             merchant_connector_id: storage_model.merchant_connector_id,
             unified_code: storage_model.unified_code,
             unified_message: storage_model.unified_message,
+            mandate_data: storage_model
+                .mandate_data
+                .map(MandateDetails::from_storage_model),
         }
     }
 }
@@ -1245,6 +1218,7 @@ impl DataModelExt for PaymentAttemptNew {
             merchant_connector_id: self.merchant_connector_id,
             unified_code: self.unified_code,
             unified_message: self.unified_message,
+            mandate_data: self.mandate_data.map(|d| d.to_storage_model()),
         }
     }
 
@@ -1287,7 +1261,7 @@ impl DataModelExt for PaymentAttemptNew {
             preprocessing_step_id: storage_model.preprocessing_step_id,
             mandate_details: storage_model
                 .mandate_details
-                .map(MandateTypeDetails::from_storage_model),
+                .map(MandateDataType::from_storage_model),
             error_reason: storage_model.error_reason,
             connector_response_reference_id: storage_model.connector_response_reference_id,
             multiple_capture_count: storage_model.multiple_capture_count,
@@ -1298,6 +1272,9 @@ impl DataModelExt for PaymentAttemptNew {
             merchant_connector_id: storage_model.merchant_connector_id,
             unified_code: storage_model.unified_code,
             unified_message: storage_model.unified_message,
+            mandate_data: storage_model
+                .mandate_data
+                .map(MandateDetails::from_storage_model),
         }
     }
 }
diff --git a/migrations/2024-02-08-142804_add_mandate_data_payment_attempt/down.sql b/migrations/2024-02-08-142804_add_mandate_data_payment_attempt/down.sql
new file mode 100644
index 00000000000..9d2071f8dda
--- /dev/null
+++ b/migrations/2024-02-08-142804_add_mandate_data_payment_attempt/down.sql
@@ -0,0 +1,2 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE payment_attempt DROP COLUMN IF EXISTS mandate_data;
diff --git a/migrations/2024-02-08-142804_add_mandate_data_payment_attempt/up.sql b/migrations/2024-02-08-142804_add_mandate_data_payment_attempt/up.sql
new file mode 100644
index 00000000000..31ed6e88fea
--- /dev/null
+++ b/migrations/2024-02-08-142804_add_mandate_data_payment_attempt/up.sql
@@ -0,0 +1,3 @@
+-- Your SQL goes here
+ALTER TABLE payment_attempt
+ADD COLUMN IF NOT EXISTS mandate_data 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
To make the mandate_details forward compatible , instead of storing update mandate id in mandate details we store it in the new column mandate data.  Currently in mandate_data column we only store update_mandate_id


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

- Create an MA and an MCA
- Make a mandate_payment 
- And then make an update_mandate_payment with the mandate_id generated in the previous step
-  The card would be updated and reflected when we do list mandate

<img width="1728" alt="Screenshot 2024-02-09 at 1 08 48 PM" src="https://github.com/juspay/hyperswitch/assets/55580080/13fdc4ba-479f-4f9f-ad65-56c5c14d9dbf">

![Screenshot 2024-02-09 at 1 11 56 PM](https://github.com/juspay/hyperswitch/assets/55580080/8f22d291-4c06-4bf5-a3cb-d6edf6a43f64)

<img width="1728" alt="Screenshot 2024-02-09 at 1 12 35 PM" src="https://github.com/juspay/hyperswitch/assets/55580080/74e4cb0f-aae3-451e-9b7a-647da8167c67">

![Screenshot 2024-02-09 at 1 13 19 PM](https://github.com/juspay/hyperswitch/assets/55580080/61594860-7353-4ebb-ad5e-a8a565331cb0)


## 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
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
