Bug: [FEATURE] Inclusion of customer details in payment_intent column



### Feature Description

This change will insure storage of customer_details in our payment_intent table.
Which will help us to derive the customer_details directly in one db call.


### Possible Implementation

if customer_id alone is passed -> Derive customer_details from customer_table and put it in guest_customer_details,
if customer_id is not present -> Put the details in guest_customer_details.
if both are present -> we are ignoring the email, phone etc and deriving them from customer_table and adding to the guest_customer_details field.

### 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/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index bf275a0dd0f..d477142fe82 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -202,11 +202,11 @@ pub struct CustomerDetails {
     pub phone_country_code: Option<String>,
 }
 
-#[derive(Debug, serde::Serialize, Clone, ToSchema, PartialEq)]
+#[derive(Debug, Default, serde::Serialize, Clone, ToSchema, PartialEq, Setter)]
 pub struct CustomerDetailsResponse {
     /// The identifier for the customer.
-    #[schema(value_type = String, max_length = 64, min_length = 1, example = "cus_y3oqhf46pyzuxjbcn2giaqnb44")]
-    pub id: id_type::CustomerId,
+    #[schema(value_type = Option<String>, max_length = 64, min_length = 1, example = "cus_y3oqhf46pyzuxjbcn2giaqnb44")]
+    pub id: Option<id_type::CustomerId>,
 
     /// The customer's name
     #[schema(max_length = 255, value_type = Option<String>, example = "John Doe")]
diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs
index 6326eeef646..fa37eecdbfe 100644
--- a/crates/diesel_models/src/payment_intent.rs
+++ b/crates/diesel_models/src/payment_intent.rs
@@ -4,9 +4,9 @@ use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
-use crate::{enums as storage_enums, schema::payment_intent};
+use crate::{encryption::Encryption, enums as storage_enums, schema::payment_intent};
 
-#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize)]
+#[derive(Clone, Debug, PartialEq, Identifiable, Queryable, Serialize, Deserialize)]
 #[diesel(table_name = payment_intent, primary_key(payment_id, merchant_id))]
 pub struct PaymentIntent {
     pub payment_id: String,
@@ -59,10 +59,11 @@ pub struct PaymentIntent {
     pub request_external_three_ds_authentication: Option<bool>,
     pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
+    pub customer_details: Option<Encryption>,
 }
 
 #[derive(
-    Clone, Debug, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize,
+    Clone, Debug, PartialEq, Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize,
 )]
 #[diesel(table_name = payment_intent)]
 pub struct PaymentIntentNew {
@@ -114,6 +115,7 @@ pub struct PaymentIntentNew {
     pub request_external_three_ds_authentication: Option<bool>,
     pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
+    pub customer_details: Option<Encryption>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -130,12 +132,13 @@ pub enum PaymentIntentUpdate {
         metadata: pii::SecretSerdeValue,
         updated_by: String,
     },
-    ReturnUrlUpdate {
+    PaymentCreateUpdate {
         return_url: Option<String>,
         status: Option<storage_enums::IntentStatus>,
         customer_id: Option<id_type::CustomerId>,
         shipping_address_id: Option<String>,
         billing_address_id: Option<String>,
+        customer_details: Option<Encryption>,
         updated_by: String,
     },
     MerchantStatusUpdate {
@@ -171,6 +174,7 @@ pub enum PaymentIntentUpdate {
         fingerprint_id: Option<String>,
         request_external_three_ds_authentication: Option<bool>,
         frm_metadata: Option<pii::SecretSerdeValue>,
+        customer_details: Option<Encryption>,
     },
     PaymentAttemptAndAttemptCountUpdate {
         active_attempt_id: String,
@@ -246,6 +250,7 @@ pub struct PaymentIntentUpdateInternal {
     pub fingerprint_id: Option<String>,
     pub request_external_three_ds_authentication: Option<bool>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
+    pub customer_details: Option<Encryption>,
 }
 
 impl PaymentIntentUpdate {
@@ -281,6 +286,7 @@ impl PaymentIntentUpdate {
             fingerprint_id,
             request_external_three_ds_authentication,
             frm_metadata,
+            customer_details,
         } = self.into();
         PaymentIntent {
             amount: amount.unwrap_or(source.amount),
@@ -318,6 +324,7 @@ impl PaymentIntentUpdate {
             request_external_three_ds_authentication: request_external_three_ds_authentication
                 .or(source.request_external_three_ds_authentication),
             frm_metadata: frm_metadata.or(source.frm_metadata),
+            customer_details: customer_details.or(source.customer_details),
             ..source
         }
     }
@@ -348,6 +355,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 fingerprint_id,
                 request_external_three_ds_authentication,
                 frm_metadata,
+                customer_details,
             } => Self {
                 amount: Some(amount),
                 currency: Some(currency),
@@ -371,6 +379,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 fingerprint_id,
                 request_external_three_ds_authentication,
                 frm_metadata,
+                customer_details,
                 ..Default::default()
             },
             PaymentIntentUpdate::MetadataUpdate {
@@ -382,12 +391,13 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 updated_by,
                 ..Default::default()
             },
-            PaymentIntentUpdate::ReturnUrlUpdate {
+            PaymentIntentUpdate::PaymentCreateUpdate {
                 return_url,
                 status,
                 customer_id,
                 shipping_address_id,
                 billing_address_id,
+                customer_details,
                 updated_by,
             } => Self {
                 return_url,
@@ -395,6 +405,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 customer_id,
                 shipping_address_id,
                 billing_address_id,
+                customer_details,
                 modified_at: Some(common_utils::date_time::now()),
                 updated_by,
                 ..Default::default()
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 162dac1377e..6149af1f505 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -888,6 +888,7 @@ diesel::table! {
         request_external_three_ds_authentication -> Nullable<Bool>,
         charges -> Nullable<Jsonb>,
         frm_metadata -> Nullable<Jsonb>,
+        customer_details -> Nullable<Bytea>,
     }
 }
 
diff --git a/crates/hyperswitch_domain_models/src/payments.rs b/crates/hyperswitch_domain_models/src/payments.rs
index c09df82f87c..f6e4f888790 100644
--- a/crates/hyperswitch_domain_models/src/payments.rs
+++ b/crates/hyperswitch_domain_models/src/payments.rs
@@ -1,4 +1,5 @@
-use common_utils::{self, id_type, pii, types::MinorUnit};
+use common_utils::{self, crypto::Encryptable, id_type, pii, types::MinorUnit};
+use masking::Secret;
 use time::PrimitiveDateTime;
 
 pub mod payment_attempt;
@@ -9,7 +10,7 @@ use common_enums as storage_enums;
 use self::payment_attempt::PaymentAttempt;
 use crate::RemoteStorageObject;
 
-#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
+#[derive(Clone, Debug, PartialEq, serde::Serialize)]
 pub struct PaymentIntent {
     pub payment_id: String,
     pub merchant_id: String,
@@ -61,4 +62,5 @@ pub struct PaymentIntent {
     pub request_external_three_ds_authentication: Option<bool>,
     pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
+    pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
index 4f50948b480..1dca50e6482 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
@@ -4,6 +4,8 @@ use common_utils::{
     errors::{CustomResult, ValidationError},
     types::MinorUnit,
 };
+use error_stack::ResultExt;
+use masking::PeekInterface;
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
@@ -11,6 +13,7 @@ use super::PaymentIntent;
 use crate::{
     behaviour, errors,
     mandates::{MandateDataType, MandateDetails},
+    type_encryption::{decrypt, AsyncLift},
     ForeignIDRef, RemoteStorageObject,
 };
 
@@ -472,7 +475,8 @@ impl ForeignIDRef for PaymentAttempt {
 }
 
 use diesel_models::{
-    PaymentIntent as DieselPaymentIntent, PaymentIntentNew as DieselPaymentIntentNew,
+    encryption::Encryption, PaymentIntent as DieselPaymentIntent,
+    PaymentIntentNew as DieselPaymentIntentNew,
 };
 
 #[async_trait::async_trait]
@@ -525,61 +529,73 @@ impl behaviour::Conversion for PaymentIntent {
             request_external_three_ds_authentication: self.request_external_three_ds_authentication,
             charges: self.charges,
             frm_metadata: self.frm_metadata,
+            customer_details: self.customer_details.map(Encryption::from),
         })
     }
 
     async fn convert_back(
         storage_model: Self::DstType,
-        _key: &masking::Secret<Vec<u8>>,
+        key: &masking::Secret<Vec<u8>>,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
     {
-        Ok(Self {
-            payment_id: storage_model.payment_id,
-            merchant_id: storage_model.merchant_id,
-            status: storage_model.status,
-            amount: storage_model.amount,
-            currency: storage_model.currency,
-            amount_captured: storage_model.amount_captured,
-            customer_id: storage_model.customer_id,
-            description: storage_model.description,
-            return_url: storage_model.return_url,
-            metadata: storage_model.metadata,
-            connector_id: storage_model.connector_id,
-            shipping_address_id: storage_model.shipping_address_id,
-            billing_address_id: storage_model.billing_address_id,
-            statement_descriptor_name: storage_model.statement_descriptor_name,
-            statement_descriptor_suffix: storage_model.statement_descriptor_suffix,
-            created_at: storage_model.created_at,
-            modified_at: storage_model.modified_at,
-            last_synced: storage_model.last_synced,
-            setup_future_usage: storage_model.setup_future_usage,
-            off_session: storage_model.off_session,
-            client_secret: storage_model.client_secret,
-            active_attempt: RemoteStorageObject::ForeignID(storage_model.active_attempt_id),
-            business_country: storage_model.business_country,
-            business_label: storage_model.business_label,
-            order_details: storage_model.order_details,
-            allowed_payment_method_types: storage_model.allowed_payment_method_types,
-            connector_metadata: storage_model.connector_metadata,
-            feature_metadata: storage_model.feature_metadata,
-            attempt_count: storage_model.attempt_count,
-            profile_id: storage_model.profile_id,
-            merchant_decision: storage_model.merchant_decision,
-            payment_link_id: storage_model.payment_link_id,
-            payment_confirm_source: storage_model.payment_confirm_source,
-            updated_by: storage_model.updated_by,
-            surcharge_applicable: storage_model.surcharge_applicable,
-            request_incremental_authorization: storage_model.request_incremental_authorization,
-            incremental_authorization_allowed: storage_model.incremental_authorization_allowed,
-            authorization_count: storage_model.authorization_count,
-            fingerprint_id: storage_model.fingerprint_id,
-            session_expiry: storage_model.session_expiry,
-            request_external_three_ds_authentication: storage_model
-                .request_external_three_ds_authentication,
-            charges: storage_model.charges,
-            frm_metadata: storage_model.frm_metadata,
+        async {
+            let inner_decrypt = |inner| decrypt(inner, key.peek());
+            Ok::<Self, error_stack::Report<common_utils::errors::CryptoError>>(Self {
+                payment_id: storage_model.payment_id,
+                merchant_id: storage_model.merchant_id,
+                status: storage_model.status,
+                amount: storage_model.amount,
+                currency: storage_model.currency,
+                amount_captured: storage_model.amount_captured,
+                customer_id: storage_model.customer_id,
+                description: storage_model.description,
+                return_url: storage_model.return_url,
+                metadata: storage_model.metadata,
+                connector_id: storage_model.connector_id,
+                shipping_address_id: storage_model.shipping_address_id,
+                billing_address_id: storage_model.billing_address_id,
+                statement_descriptor_name: storage_model.statement_descriptor_name,
+                statement_descriptor_suffix: storage_model.statement_descriptor_suffix,
+                created_at: storage_model.created_at,
+                modified_at: storage_model.modified_at,
+                last_synced: storage_model.last_synced,
+                setup_future_usage: storage_model.setup_future_usage,
+                off_session: storage_model.off_session,
+                client_secret: storage_model.client_secret,
+                active_attempt: RemoteStorageObject::ForeignID(storage_model.active_attempt_id),
+                business_country: storage_model.business_country,
+                business_label: storage_model.business_label,
+                order_details: storage_model.order_details,
+                allowed_payment_method_types: storage_model.allowed_payment_method_types,
+                connector_metadata: storage_model.connector_metadata,
+                feature_metadata: storage_model.feature_metadata,
+                attempt_count: storage_model.attempt_count,
+                profile_id: storage_model.profile_id,
+                merchant_decision: storage_model.merchant_decision,
+                payment_link_id: storage_model.payment_link_id,
+                payment_confirm_source: storage_model.payment_confirm_source,
+                updated_by: storage_model.updated_by,
+                surcharge_applicable: storage_model.surcharge_applicable,
+                request_incremental_authorization: storage_model.request_incremental_authorization,
+                incremental_authorization_allowed: storage_model.incremental_authorization_allowed,
+                authorization_count: storage_model.authorization_count,
+                fingerprint_id: storage_model.fingerprint_id,
+                session_expiry: storage_model.session_expiry,
+                request_external_three_ds_authentication: storage_model
+                    .request_external_three_ds_authentication,
+                charges: storage_model.charges,
+                frm_metadata: storage_model.frm_metadata,
+                customer_details: storage_model
+                    .customer_details
+                    .async_lift(inner_decrypt)
+                    .await?,
+            })
+        }
+        .await
+        .change_context(ValidationError::InvalidValue {
+            message: "Failed while decrypting payment intent".to_string(),
         })
     }
 
@@ -628,6 +644,7 @@ impl behaviour::Conversion for PaymentIntent {
             request_external_three_ds_authentication: self.request_external_three_ds_authentication,
             charges: self.charges,
             frm_metadata: self.frm_metadata,
+            customer_details: self.customer_details.map(Encryption::from),
         })
     }
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
index 66ecf7ec57f..30fd1061c7f 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
@@ -1,10 +1,13 @@
 use common_enums as storage_enums;
 use common_utils::{
     consts::{PAYMENTS_LIST_MAX_LIMIT_V1, PAYMENTS_LIST_MAX_LIMIT_V2},
-    id_type, pii,
+    crypto::Encryptable,
+    id_type,
+    pii::{self, Email},
     types::MinorUnit,
 };
-use serde::{Deserialize, Serialize};
+use masking::{Deserialize, Secret};
+use serde::Serialize;
 use time::PrimitiveDateTime;
 
 use super::{payment_attempt::PaymentAttempt, PaymentIntent};
@@ -76,7 +79,15 @@ pub trait PaymentIntentInterface {
     ) -> error_stack::Result<Vec<String>, errors::StorageError>;
 }
 
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, PartialEq, router_derive::DebugAsDisplay, Serialize, Deserialize)]
+pub struct CustomerData {
+    pub name: Option<Secret<String>>,
+    pub email: Option<Email>,
+    pub phone: Option<Secret<String>>,
+    pub phone_country_code: Option<String>,
+}
+
+#[derive(Clone, Debug, PartialEq)]
 pub struct PaymentIntentNew {
     pub payment_id: String,
     pub merchant_id: String,
@@ -122,9 +133,10 @@ pub struct PaymentIntentNew {
     pub session_expiry: Option<PrimitiveDateTime>,
     pub request_external_three_ds_authentication: Option<bool>,
     pub charges: Option<pii::SecretSerdeValue>,
+    pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize)]
+#[derive(Debug, Clone, Serialize)]
 pub enum PaymentIntentUpdate {
     ResponseUpdate {
         status: storage_enums::IntentStatus,
@@ -138,12 +150,13 @@ pub enum PaymentIntentUpdate {
         metadata: pii::SecretSerdeValue,
         updated_by: String,
     },
-    ReturnUrlUpdate {
+    PaymentCreateUpdate {
         return_url: Option<String>,
         status: Option<storage_enums::IntentStatus>,
         customer_id: Option<id_type::CustomerId>,
         shipping_address_id: Option<String>,
         billing_address_id: Option<String>,
+        customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
         updated_by: String,
     },
     MerchantStatusUpdate {
@@ -179,6 +192,7 @@ pub enum PaymentIntentUpdate {
         fingerprint_id: Option<String>,
         session_expiry: Option<PrimitiveDateTime>,
         request_external_three_ds_authentication: Option<bool>,
+        customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
     },
     PaymentAttemptAndAttemptCountUpdate {
         active_attempt_id: String,
@@ -255,6 +269,7 @@ pub struct PaymentIntentUpdateInternal {
     pub session_expiry: Option<PrimitiveDateTime>,
     pub request_external_three_ds_authentication: Option<bool>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
+    pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
 }
 
 impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
@@ -282,6 +297,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 session_expiry,
                 request_external_three_ds_authentication,
                 frm_metadata,
+                customer_details,
             } => Self {
                 amount: Some(amount),
                 currency: Some(currency),
@@ -305,6 +321,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 session_expiry,
                 request_external_three_ds_authentication,
                 frm_metadata,
+                customer_details,
                 ..Default::default()
             },
             PaymentIntentUpdate::MetadataUpdate {
@@ -316,12 +333,13 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 updated_by,
                 ..Default::default()
             },
-            PaymentIntentUpdate::ReturnUrlUpdate {
+            PaymentIntentUpdate::PaymentCreateUpdate {
                 return_url,
                 status,
                 customer_id,
                 shipping_address_id,
                 billing_address_id,
+                customer_details,
                 updated_by,
             } => Self {
                 return_url,
@@ -329,6 +347,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 customer_id,
                 shipping_address_id,
                 billing_address_id,
+                customer_details,
                 modified_at: Some(common_utils::date_time::now()),
                 updated_by,
                 ..Default::default()
@@ -456,7 +475,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
     }
 }
 
-use diesel_models::PaymentIntentUpdate as DieselPaymentIntentUpdate;
+use diesel_models::{encryption::Encryption, PaymentIntentUpdate as DieselPaymentIntentUpdate};
 
 impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
     fn from(value: PaymentIntentUpdate) -> Self {
@@ -483,19 +502,21 @@ impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
                 metadata,
                 updated_by,
             },
-            PaymentIntentUpdate::ReturnUrlUpdate {
+            PaymentIntentUpdate::PaymentCreateUpdate {
                 return_url,
                 status,
                 customer_id,
                 shipping_address_id,
                 billing_address_id,
+                customer_details,
                 updated_by,
-            } => Self::ReturnUrlUpdate {
+            } => Self::PaymentCreateUpdate {
                 return_url,
                 status,
                 customer_id,
                 shipping_address_id,
                 billing_address_id,
+                customer_details: customer_details.map(Encryption::from),
                 updated_by,
             },
             PaymentIntentUpdate::MerchantStatusUpdate {
@@ -540,6 +561,7 @@ impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
                 session_expiry,
                 request_external_three_ds_authentication,
                 frm_metadata,
+                customer_details,
             } => Self::Update {
                 amount,
                 currency,
@@ -562,6 +584,7 @@ impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
                 session_expiry,
                 request_external_three_ds_authentication,
                 frm_metadata,
+                customer_details: customer_details.map(Encryption::from),
             },
             PaymentIntentUpdate::PaymentAttemptAndAttemptCountUpdate {
                 active_attempt_id,
@@ -663,6 +686,7 @@ impl From<PaymentIntentUpdateInternal> for diesel_models::PaymentIntentUpdateInt
             fingerprint_id,
             request_external_three_ds_authentication,
             frm_metadata,
+            customer_details,
         } = value;
 
         Self {
@@ -696,6 +720,7 @@ impl From<PaymentIntentUpdateInternal> for diesel_models::PaymentIntentUpdateInt
             fingerprint_id,
             request_external_three_ds_authentication,
             frm_metadata,
+            customer_details: customer_details.map(Encryption::from),
         }
     }
 }
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 53b0063c6ef..489cbe53c5c 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -22,6 +22,7 @@ use api_models::{
 use common_enums::enums::MerchantStorageScheme;
 use common_utils::{
     consts,
+    crypto::Encryptable,
     ext_traits::{AsyncExt, Encode, StringExt, ValueExt},
     generate_id, id_type,
 };
@@ -65,7 +66,7 @@ use crate::{
             types::{decrypt, encrypt_optional, AsyncLift},
         },
         storage::{self, enums, PaymentMethodListContext, PaymentTokenData},
-        transformers::ForeignFrom,
+        transformers::{ForeignFrom, ForeignTryFrom},
     },
     utils::{self, ConnectorResponseExt, OptionExt},
 };
@@ -466,8 +467,9 @@ pub async fn add_payment_method_data(
                         };
 
                         let updated_pmd = Some(PaymentMethodsData::Card(updated_card));
-                        let pm_data_encrypted =
-                            create_encrypted_data(&key_store, updated_pmd).await;
+                        let pm_data_encrypted = create_encrypted_data(&key_store, updated_pmd)
+                            .await
+                            .map(|details| details.into());
 
                         let pm_update = storage::PaymentMethodUpdate::AdditionalDataUpdate {
                             payment_method_data: pm_data_encrypted,
@@ -688,7 +690,9 @@ pub async fn add_payment_method(
                     let updated_pmd = updated_card.as_ref().map(|card| {
                         PaymentMethodsData::Card(CardDetailsPaymentMethod::from(card.clone()))
                     });
-                    let pm_data_encrypted = create_encrypted_data(key_store, updated_pmd).await;
+                    let pm_data_encrypted = create_encrypted_data(key_store, updated_pmd)
+                        .await
+                        .map(|details| details.into());
 
                     let pm_update = storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
                         payment_method_data: pm_data_encrypted,
@@ -762,7 +766,10 @@ pub async fn insert_payment_method(
         .card
         .as_ref()
         .map(|card| PaymentMethodsData::Card(CardDetailsPaymentMethod::from(card.clone())));
-    let pm_data_encrypted = create_encrypted_data(key_store, pm_card_details).await;
+    let pm_data_encrypted = create_encrypted_data(key_store, pm_card_details)
+        .await
+        .map(|details| details.into());
+
     create_payment_method(
         db,
         &req,
@@ -942,7 +949,9 @@ pub async fn update_customer_payment_method(
             let updated_pmd = updated_card
                 .as_ref()
                 .map(|card| PaymentMethodsData::Card(CardDetailsPaymentMethod::from(card.clone())));
-            let pm_data_encrypted = create_encrypted_data(&key_store, updated_pmd).await;
+            let pm_data_encrypted = create_encrypted_data(&key_store, updated_pmd)
+                .await
+                .map(|details| details.into());
 
             let pm_update = storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
                 payment_method_data: pm_data_encrypted,
@@ -2226,12 +2235,13 @@ pub async fn list_payment_methods(
         .then_some(billing_address.as_ref())
         .flatten();
 
-    let req = api_models::payments::PaymentsRequest::foreign_from((
+    let req = api_models::payments::PaymentsRequest::foreign_try_from((
         payment_attempt.as_ref(),
+        payment_intent.as_ref(),
         shipping_address.as_ref(),
         billing_address_for_calculating_required_fields,
         customer.as_ref(),
-    ));
+    ))?;
     let req_val = serde_json::to_value(req).ok();
     logger::debug!(filtered_payment_methods=?response);
 
@@ -4374,14 +4384,13 @@ pub async fn delete_payment_method(
 pub async fn create_encrypted_data<T>(
     key_store: &domain::MerchantKeyStore,
     data: Option<T>,
-) -> Option<Encryption>
+) -> Option<Encryptable<Secret<serde_json::Value>>>
 where
     T: Debug + serde::Serialize,
 {
     let key = key_store.key.get_inner().peek();
 
-    let encrypted_data: Option<Encryption> = data
-        .as_ref()
+    data.as_ref()
         .map(Encode::encode_to_value)
         .transpose()
         .change_context(errors::StorageError::SerializationFailed)
@@ -4399,9 +4408,6 @@ where
             logger::error!(err=?err);
             None
         })
-        .map(|details| details.into());
-
-    encrypted_data
 }
 
 pub async fn list_countries_currencies_for_connector_payment_method(
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index a60d75100db..a16f5ca44fa 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -18,7 +18,7 @@ use error_stack::{report, ResultExt};
 use futures::future::Either;
 use hyperswitch_domain_models::{
     mandates::MandateData,
-    payments::{payment_attempt::PaymentAttempt, PaymentIntent},
+    payments::{payment_attempt::PaymentAttempt, payment_intent::CustomerData, PaymentIntent},
     router_data::KlarnaSdkResponse,
 };
 use josekit::jwe;
@@ -44,7 +44,11 @@ use crate::{
         authentication,
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
         mandate::helpers::MandateGenericData,
-        payment_methods::{self, cards, vault},
+        payment_methods::{
+            self,
+            cards::{self, create_encrypted_data},
+            vault,
+        },
         payments,
         pm_auth::retrieve_payment_method_from_auth_service,
     },
@@ -1580,6 +1584,61 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
         .get_required_value("customer")
         .change_context(errors::StorageError::ValueNotFound("customer".to_owned()))?;
 
+    let temp_customer_data = if request_customer_details.name.is_some()
+        || request_customer_details.email.is_some()
+        || request_customer_details.phone.is_some()
+        || request_customer_details.phone_country_code.is_some()
+    {
+        Some(CustomerData {
+            name: request_customer_details.name.clone(),
+            email: request_customer_details.email.clone(),
+            phone: request_customer_details.phone.clone(),
+            phone_country_code: request_customer_details.phone_country_code.clone(),
+        })
+    } else {
+        None
+    };
+
+    // Updation of Customer Details for the cases where both customer_id and specific customer
+    // details are provided in Payment Update Request
+    let raw_customer_details = payment_data
+        .payment_intent
+        .customer_details
+        .clone()
+        .map(|customer_details_encrypted| {
+            customer_details_encrypted
+                .into_inner()
+                .expose()
+                .parse_value::<CustomerData>("CustomerData")
+        })
+        .transpose()
+        .change_context(errors::StorageError::DeserializationFailed)
+        .attach_printable("Failed to parse customer data from payment intent")?
+        .map(|parsed_customer_data| CustomerData {
+            name: request_customer_details
+                .name
+                .clone()
+                .or(parsed_customer_data.name.clone()),
+            email: request_customer_details
+                .email
+                .clone()
+                .or(parsed_customer_data.email.clone()),
+            phone: request_customer_details
+                .phone
+                .clone()
+                .or(parsed_customer_data.phone.clone()),
+            phone_country_code: request_customer_details
+                .phone_country_code
+                .clone()
+                .or(parsed_customer_data.phone_country_code.clone()),
+        })
+        .or(temp_customer_data);
+
+    payment_data.payment_intent.customer_details = raw_customer_details
+        .clone()
+        .async_and_then(|_| async { create_encrypted_data(key_store, raw_customer_details).await })
+        .await;
+
     let customer_id = request_customer_details
         .customer_id
         .or(payment_data.payment_intent.customer_id.clone());
@@ -3062,6 +3121,7 @@ mod tests {
             request_external_three_ds_authentication: None,
             charges: None,
             frm_metadata: None,
+            customer_details: None,
         };
         let req_cs = Some("1".to_string());
         assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent).is_ok());
@@ -3121,6 +3181,7 @@ mod tests {
             request_external_three_ds_authentication: None,
             charges: None,
             frm_metadata: None,
+            customer_details: None,
         };
         let req_cs = Some("1".to_string());
         assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent,).is_err())
@@ -3179,6 +3240,7 @@ mod tests {
             request_external_three_ds_authentication: None,
             charges: None,
             frm_metadata: None,
+            customer_details: None,
         };
         let req_cs = Some("1".to_string());
         assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent).is_err())
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index bfd63111e27..9c1e753776a 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -1084,6 +1084,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
             None
         };
 
+        let customer_details = payment_data.payment_intent.customer_details.clone();
         let business_sub_label = payment_data.payment_attempt.business_sub_label.clone();
         let authentication_type = payment_data.payment_attempt.authentication_type;
 
@@ -1255,6 +1256,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
                         session_expiry,
                         request_external_three_ds_authentication: None,
                         frm_metadata: m_frm_metadata,
+                        customer_details,
                     },
                     &m_key_store,
                     storage_scheme,
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 870fd78abe3..63ae07868a7 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -12,7 +12,8 @@ use diesel_models::{ephemeral_key, PaymentMethod};
 use error_stack::{self, ResultExt};
 use hyperswitch_domain_models::{
     mandates::{MandateData, MandateDetails},
-    payments::payment_attempt::PaymentAttempt,
+    payments::{payment_attempt::PaymentAttempt, payment_intent::CustomerData},
+    type_encryption::decrypt,
 };
 use masking::{ExposeInterface, PeekInterface, Secret};
 use router_derive::PaymentOperation;
@@ -26,6 +27,7 @@ use crate::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
         mandate::helpers as m_helpers,
         payment_link,
+        payment_methods::cards::create_encrypted_data,
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
         utils as core_utils,
     },
@@ -245,8 +247,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         };
 
         let payment_intent_new = Self::make_payment_intent(
+            state,
             &payment_id,
             merchant_account,
+            merchant_key_store,
             money,
             request,
             shipping_address
@@ -560,7 +564,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         state: &'b SessionState,
         _req_state: ReqState,
         mut payment_data: PaymentData<F>,
-        _customer: Option<domain::Customer>,
+        customer: Option<domain::Customer>,
         storage_scheme: enums::MerchantStorageScheme,
         _updated_customer: Option<storage::CustomerUpdate>,
         key_store: &domain::MerchantKeyStore,
@@ -628,16 +632,30 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
 
         let customer_id = payment_data.payment_intent.customer_id.clone();
 
+        let raw_customer_details = customer
+            .map(|customer| CustomerData::try_from(customer.clone()))
+            .transpose()?;
+
+        // Updation of Customer Details for the cases where both customer_id and specific customer
+        // details are provided in Payment Create Request
+        let customer_details = raw_customer_details
+            .clone()
+            .async_and_then(|_| async {
+                create_encrypted_data(key_store, raw_customer_details).await
+            })
+            .await;
+
         payment_data.payment_intent = state
             .store
             .update_payment_intent(
                 payment_data.payment_intent,
-                storage::PaymentIntentUpdate::ReturnUrlUpdate {
+                storage::PaymentIntentUpdate::PaymentCreateUpdate {
                     return_url: None,
                     status,
                     customer_id,
                     shipping_address_id: None,
                     billing_address_id: None,
+                    customer_details,
                     updated_by: storage_scheme.to_string(),
                 },
                 key_store,
@@ -815,7 +833,7 @@ impl PaymentCreate {
             additional_pm_data = payment_method_info
                 .as_ref()
                 .async_map(|pm_info| async {
-                    domain::types::decrypt::<serde_json::Value, masking::WithType>(
+                    decrypt::<serde_json::Value, masking::WithType>(
                         pm_info.payment_method_data.clone(),
                         key_store.key.get_inner().peek(),
                     )
@@ -956,8 +974,10 @@ impl PaymentCreate {
     #[instrument(skip_all)]
     #[allow(clippy::too_many_arguments)]
     async fn make_payment_intent(
+        _state: &SessionState,
         payment_id: &str,
         merchant_account: &domain::MerchantAccount,
+        key_store: &domain::MerchantKeyStore,
         money: (api::Amount, enums::Currency),
         request: &api::PaymentsRequest,
         shipping_address_id: Option<String>,
@@ -1023,6 +1043,30 @@ impl PaymentCreate {
             .change_context(errors::ApiErrorResponse::InternalServerError)?
             .map(Secret::new);
 
+        // Derivation of directly supplied Customer data in our Payment Create Request
+        let raw_customer_details = if request.customer_id.is_none()
+            && (request.name.is_some()
+                || request.email.is_some()
+                || request.phone.is_some()
+                || request.phone_country_code.is_some())
+        {
+            Some(CustomerData {
+                name: request.name.clone(),
+                phone: request.phone.clone(),
+                email: request.email.clone(),
+                phone_country_code: request.phone_country_code.clone(),
+            })
+        } else {
+            None
+        };
+
+        // Encrypting our Customer Details to be stored in Payment Intent
+        let customer_details = if raw_customer_details.is_some() {
+            create_encrypted_data(key_store, raw_customer_details).await
+        } else {
+            None
+        };
+
         Ok(storage::PaymentIntent {
             payment_id: payment_id.to_string(),
             merchant_id: merchant_account.merchant_id.to_string(),
@@ -1070,6 +1114,7 @@ impl PaymentCreate {
                 .request_external_three_ds_authentication,
             charges,
             frm_metadata: request.frm_metadata.clone(),
+            customer_details,
         })
     }
 
diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs
index a299b70e89b..8095660d4f2 100644
--- a/crates/router/src/core/payments/operations/payment_update.rs
+++ b/crates/router/src/core/payments/operations/payment_update.rs
@@ -4,8 +4,12 @@ use api_models::{
     enums::FrmSuggestion, mandates::RecurringDetails, payments::RequestSurchargeDetails,
 };
 use async_trait::async_trait;
-use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
+use common_utils::{
+    ext_traits::{AsyncExt, Encode, ValueExt},
+    pii::Email,
+};
 use error_stack::{report, ResultExt};
+use hyperswitch_domain_models::payments::payment_intent::CustomerData;
 use router_derive::PaymentOperation;
 use router_env::{instrument, tracing};
 
@@ -661,7 +665,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
             .await
             .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
 
-        let customer_id = customer.map(|c| c.customer_id);
+        let customer_id = customer.clone().map(|c| c.customer_id);
 
         let intent_status = {
             let current_intent_status = payment_data.payment_intent.status;
@@ -681,6 +685,8 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
             payment_data.payment_intent.billing_address_id.clone(),
         );
 
+        let customer_details = payment_data.payment_intent.customer_details.clone();
+
         let return_url = payment_data.payment_intent.return_url.clone();
         let setup_future_usage = payment_data.payment_intent.setup_future_usage;
         let business_label = payment_data.payment_intent.business_label.clone();
@@ -726,6 +732,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
                         .payment_intent
                         .request_external_three_ds_authentication,
                     frm_metadata,
+                    customer_details,
                 },
                 key_store,
                 storage_scheme,
@@ -740,6 +747,18 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
     }
 }
 
+impl TryFrom<domain::Customer> for CustomerData {
+    type Error = errors::ApiErrorResponse;
+    fn try_from(value: domain::Customer) -> Result<Self, Self::Error> {
+        Ok(Self {
+            name: value.name.map(|name| name.into_inner()),
+            email: value.email.map(Email::from),
+            phone: value.phone.map(|ph| ph.into_inner()),
+            phone_country_code: value.phone_country_code,
+        })
+    }
+}
+
 impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate {
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs
index 161a9a43532..d6ceeee65e7 100644
--- a/crates/router/src/core/payments/tokenization.rs
+++ b/crates/router/src/core/payments/tokenization.rs
@@ -210,14 +210,17 @@ where
                 });
 
                 let pm_data_encrypted =
-                    payment_methods::cards::create_encrypted_data(key_store, pm_card_details).await;
+                    payment_methods::cards::create_encrypted_data(key_store, pm_card_details)
+                        .await
+                        .map(|details| details.into());
 
                 let encrypted_payment_method_billing_address =
                     payment_methods::cards::create_encrypted_data(
                         key_store,
                         payment_method_billing_address,
                     )
-                    .await;
+                    .await
+                    .map(|details| details.into());
 
                 let mut payment_method_id = resp.payment_method_id.clone();
                 let mut locker_id = None;
@@ -509,7 +512,8 @@ where
                                         key_store,
                                         updated_pmd,
                                     )
-                                    .await;
+                                    .await
+                                    .map(|details| details.into());
 
                                 let pm_update =
                                     storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index 0dbbbbf674a..9fcce65fbaf 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -1,16 +1,17 @@
 use std::{fmt::Debug, marker::PhantomData, str::FromStr};
 
 use api_models::payments::{
-    FrmMessage, GetAddressFromPaymentMethodData, PaymentChargeRequest, PaymentChargeResponse,
-    RequestSurchargeDetails,
+    CustomerDetailsResponse, FrmMessage, GetAddressFromPaymentMethodData, PaymentChargeRequest,
+    PaymentChargeResponse, RequestSurchargeDetails,
 };
 #[cfg(feature = "payouts")]
 use api_models::payouts::PayoutAttemptResponse;
 use common_enums::RequestIncrementalAuthorization;
-use common_utils::{consts::X_HS_LATENCY, fp_utils, types::MinorUnit};
+use common_utils::{consts::X_HS_LATENCY, fp_utils, pii::Email, types::MinorUnit};
 use diesel_models::ephemeral_key;
 use error_stack::{report, ResultExt};
-use masking::{Maskable, PeekInterface, Secret};
+use hyperswitch_domain_models::payments::payment_intent::CustomerData;
+use masking::{ExposeInterface, Maskable, PeekInterface, Secret};
 use router_env::{instrument, metrics::add_attributes, tracing};
 
 use super::{flows::Feature, types::AuthenticationData, PaymentData};
@@ -506,7 +507,47 @@ where
         ))
     }
 
-    let customer_details_response = customer.as_ref().map(ForeignInto::foreign_into);
+    // For the case when we don't have Customer data directly stored in Payment intent
+    let customer_table_response: Option<CustomerDetailsResponse> =
+        customer.as_ref().map(ForeignInto::foreign_into);
+
+    // If we have customer data in Payment Intent, We are populating the Retrieve response from the
+    // same
+    let customer_details_response =
+        if let Some(customer_details_raw) = payment_intent.customer_details.clone() {
+            let customer_details_encrypted =
+                serde_json::from_value::<CustomerData>(customer_details_raw.into_inner().expose());
+            if let Ok(customer_details_encrypted_data) = customer_details_encrypted {
+                Some(CustomerDetailsResponse {
+                    id: customer_table_response.and_then(|customer_data| customer_data.id),
+                    name: customer_details_encrypted_data
+                        .name
+                        .or(customer.as_ref().and_then(|customer| {
+                            customer.name.as_ref().map(|name| name.clone().into_inner())
+                        })),
+                    email: customer_details_encrypted_data.email.or(customer
+                        .as_ref()
+                        .and_then(|customer| customer.email.clone().map(Email::from))),
+                    phone: customer_details_encrypted_data
+                        .phone
+                        .or(customer.as_ref().and_then(|customer| {
+                            customer
+                                .phone
+                                .as_ref()
+                                .map(|phone| phone.clone().into_inner())
+                        })),
+                    phone_country_code: customer_details_encrypted_data.phone_country_code.or(
+                        customer
+                            .as_ref()
+                            .and_then(|customer| customer.phone_country_code.clone()),
+                    ),
+                })
+            } else {
+                customer_table_response
+            }
+        } else {
+            customer_table_response
+        };
 
     headers.extend(
         external_latency
diff --git a/crates/router/src/core/payouts/helpers.rs b/crates/router/src/core/payouts/helpers.rs
index 0b54205bf67..6106ef29917 100644
--- a/crates/router/src/core/payouts/helpers.rs
+++ b/crates/router/src/core/payouts/helpers.rs
@@ -449,7 +449,9 @@ pub async fn save_payout_data_to_locker(
                     )
                 });
             (
-                cards::create_encrypted_data(key_store, Some(pm_data)).await,
+                cards::create_encrypted_data(key_store, Some(pm_data))
+                    .await
+                    .map(|details| details.into()),
                 payment_method,
             )
         } else {
diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs
index e31a4dd75c7..e78c2153bb7 100644
--- a/crates/router/src/core/pm_auth.rs
+++ b/crates/router/src/core/pm_auth.rs
@@ -421,6 +421,7 @@ async fn store_bank_details_in_payment_methods(
             let encrypted_data =
                 cards::create_encrypted_data(&key_store, Some(payment_method_data))
                     .await
+                    .map(|details| details.into())
                     .ok_or(ApiErrorResponse::InternalServerError)?;
             let pm_update = storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
                 payment_method_data: Some(encrypted_data),
@@ -432,6 +433,7 @@ async fn store_bank_details_in_payment_methods(
             let encrypted_data =
                 cards::create_encrypted_data(&key_store, Some(payment_method_data))
                     .await
+                    .map(|details| details.into())
                     .ok_or(ApiErrorResponse::InternalServerError)?;
             let pm_id = generate_id(consts::ID_LENGTH, "pm");
             let now = common_utils::date_time::now();
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index 57fc613af77..894f0ee95a8 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -14,6 +14,7 @@ use common_utils::{
 };
 use diesel_models::enums as storage_enums;
 use error_stack::{report, ResultExt};
+use hyperswitch_domain_models::payments::payment_intent::CustomerData;
 use masking::{ExposeInterface, PeekInterface};
 
 use super::domain;
@@ -1140,33 +1141,60 @@ impl ForeignTryFrom<&HeaderMap> for payments::HeaderPayload {
 }
 
 impl
-    ForeignFrom<(
+    ForeignTryFrom<(
         Option<&storage::PaymentAttempt>,
+        Option<&storage::PaymentIntent>,
         Option<&domain::Address>,
         Option<&domain::Address>,
         Option<&domain::Customer>,
     )> for payments::PaymentsRequest
 {
-    fn foreign_from(
+    type Error = error_stack::Report<errors::ApiErrorResponse>;
+    fn foreign_try_from(
         value: (
             Option<&storage::PaymentAttempt>,
+            Option<&storage::PaymentIntent>,
             Option<&domain::Address>,
             Option<&domain::Address>,
             Option<&domain::Customer>,
         ),
-    ) -> Self {
-        let (payment_attempt, shipping, billing, customer) = value;
-        Self {
+    ) -> Result<Self, Self::Error> {
+        let (payment_attempt, payment_intent, shipping, billing, customer) = value;
+        // Populating the dynamic fields directly, for the cases where we have customer details stored in
+        // Payment Intent
+        let customer_details_from_pi = payment_intent
+            .and_then(|payment_intent| payment_intent.customer_details.clone())
+            .map(|customer_details| {
+                customer_details
+                    .into_inner()
+                    .peek()
+                    .clone()
+                    .parse_value::<CustomerData>("CustomerData")
+                    .change_context(errors::ApiErrorResponse::InvalidDataValue {
+                        field_name: "customer_details",
+                    })
+                    .attach_printable("Failed to parse customer_details")
+            })
+            .transpose()
+            .change_context(errors::ApiErrorResponse::InvalidDataValue {
+                field_name: "customer_details",
+            })?;
+        Ok(Self {
             currency: payment_attempt.map(|pa| pa.currency.unwrap_or_default()),
             shipping: shipping.map(api_types::Address::from),
             billing: billing.map(api_types::Address::from),
             amount: payment_attempt.map(|pa| api_types::Amount::from(pa.amount)),
             email: customer
-                .and_then(|cust| cust.email.as_ref().map(|em| pii::Email::from(em.clone()))),
-            phone: customer.and_then(|cust| cust.phone.as_ref().map(|p| p.clone().into_inner())),
-            name: customer.and_then(|cust| cust.name.as_ref().map(|n| n.clone().into_inner())),
+                .and_then(|cust| cust.email.as_ref().map(|em| pii::Email::from(em.clone())))
+                .or(customer_details_from_pi.clone().and_then(|cd| cd.email)),
+            phone: customer
+                .and_then(|cust| cust.phone.as_ref().map(|p| p.clone().into_inner()))
+                .or(customer_details_from_pi.clone().and_then(|cd| cd.phone)),
+            name: customer
+                .and_then(|cust| cust.name.as_ref().map(|n| n.clone().into_inner()))
+                .or(customer_details_from_pi.clone().and_then(|cd| cd.name)),
             ..Self::default()
-        }
+        })
     }
 }
 
@@ -1266,7 +1294,7 @@ impl ForeignFrom<storage::GatewayStatusMap> for gsm_api_types::GsmResponse {
 impl ForeignFrom<&domain::Customer> for payments::CustomerDetailsResponse {
     fn foreign_from(customer: &domain::Customer) -> Self {
         Self {
-            id: customer.customer_id.clone(),
+            id: Some(customer.customer_id.clone()),
             name: customer
                 .name
                 .as_ref()
diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs
index a2909e5f3c7..97c063eb3ae 100644
--- a/crates/router/src/utils/user/sample_data.rs
+++ b/crates/router/src/utils/user/sample_data.rs
@@ -225,6 +225,7 @@ pub async fn generate_sample_data(
             request_external_three_ds_authentication: None,
             charges: None,
             frm_metadata: Default::default(),
+            customer_details: None,
         };
         let payment_attempt = PaymentAttemptBatchNew {
             attempt_id: attempt_id.clone(),
diff --git a/migrations/2024-06-12-060604_add_customer_details_in_payment_intent/down.sql b/migrations/2024-06-12-060604_add_customer_details_in_payment_intent/down.sql
new file mode 100644
index 00000000000..9b7bb65f082
--- /dev/null
+++ b/migrations/2024-06-12-060604_add_customer_details_in_payment_intent/down.sql
@@ -0,0 +1,2 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE payment_intent DROP COLUMN IF EXISTS customer_details;
diff --git a/migrations/2024-06-12-060604_add_customer_details_in_payment_intent/up.sql b/migrations/2024-06-12-060604_add_customer_details_in_payment_intent/up.sql
new file mode 100644
index 00000000000..8a92056017c
--- /dev/null
+++ b/migrations/2024-06-12-060604_add_customer_details_in_payment_intent/up.sql
@@ -0,0 +1,2 @@
+-- Your SQL goes here
+ALTER TABLE payment_intent ADD COLUMN IF NOT EXISTS customer_details BYTEA DEFAULT NULL;

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

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

## Description
<!-- Describe your changes in detail -->
This change will insure storage of customer_details in our payment_intent table.

if customer_id alone is passed -> Derive customer_details from customer_table and put it in guest_customer_details,
if customer_id is not present -> Put the details in guest_customer_details.
if both are present -> we are ignoring the email, phone etc and deriving them from customer_table and adding to the guest_customer_details field. 

### Additional Changes

- [ ] This PR modifies the API contract
- [x] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

The Db Migration:
```
ALTER TABLE payment_intent ADD COLUMN IF NOT EXISTS customer_details BYTEA DEFAULT NULL;
```

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
### Testing Scenarios
![Screenshot 2024-06-27 at 6 07 09 PM](https://github.com/juspay/hyperswitch/assets/61520228/a5d4078b-e121-49bb-abb9-4a071764b266)



### Payment create request with no `cus_id` and fields name, email, phone, phone country code
```
Response should be populated like this

```
    "customer_id": null,
    "customer": {
        "id": null,
        "name": "light",
        "email": "guest@example.com",
        "phone": "9xxxxxxxxx",
        "phone_country_code": "+91"
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "email": "guest@example.com",
    "name": "light",
    "phone": "9xxxxxxxxx",
    "phone_country_code": "+91",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```
<img width="1728" alt="Screenshot 2024-06-14 at 1 34 46 AM" src="https://github.com/juspay/hyperswitch/assets/61520228/13981494-97a5-4442-b1f0-aa14bdf539cb">

### Payment create request with some random `cus_id`
```
Response should be populated like this

```
    "customer_id": "id_12343",
    "customer": {
        "id": null,
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
   "customer_id": "id_12343",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```

### Payment create request with a created customer's `cus_id`
```
Response should be populated like this

```
    "customer_id": "id_12343",
    "customer": {
        "id": null,
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
   "customer_id": "id_12343",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```

### Payment create request with `cus_id` and all other data
```
Response should be populated like this

```
    "customer_id": null,
    "customer": {
        "id": null,
        "name": "light",
        "email": "guest@example.com",
        "phone": "9xxxxxxxxx",
        "phone_country_code": "+91"
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
   "customer_id": "id_12343",
     "name": "light",
     "email": "guest@example.com",
     "phone": "9xxxxxxxxx",
      "phone_country_code": "+91",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```

### Payment create request with name and payment confirm with email and phone
```
Response should be populated like this after confirm request

```
    "customer_id": null,
    "customer": {
        "id": null,
        "name": "light",
        "email": "guest@example.com",
        "phone": "9xxxxxxxxx",
        "phone_country_code": null
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
     "name": "light",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```
```
curl --location 'http://127.0.0.1:8080/payments/pay_7m0meCohmJxQJ4RzzlTm/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxxxxxxxxx' \
--data-raw '{
    "email": "guest@example.com",
    "phone": "9xxxxxxxxx",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4000003920000003",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_cvc": "123"
        }
    } 
}'
```

### Payment create request with name and payment update with email and phone
```
Response should be populated like this after update request

```
    "customer_id": null,
    "customer": {
        "id": null,
        "name": "light",
        "email": "payme@example.com",
        "phone": "9xxxxxxxxx",
        "phone_country_code": null
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
     "name": "light",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```
```
curl --location 'http://127.0.0.1:8080/payments/pay_7m0meCohmJxQJ4RzzlTm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_Sz1d4HlpPQ71WmZksJ7NghSNmy64WGRkAFy0vhOmTA5QrDUVYNRb43ZSFySsz5KX' \
--data-raw '{
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "2035",
            "card_holder_name": "John Doe",
            "card_cvc": "123"
        }
    },
    "email": "payme@example.com",   
    "phone": "9xxxxxxxxx"
}'
```

### Payment create request with id, name and payment update with email and phone
```
Response should be populated like this after update request

```
    "customer_id": "id_12343",
    "customer": {
        "id": "id_12343",
        "name": "light",
        "email": "payme@example.com",
        "phone": "9xxxxxxxxx",
        "phone_country_code": null
    },
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "id_12343",
     "name": "light",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```
```
curl --location 'http://127.0.0.1:8080/payments/pay_7m0meCohmJxQJ4RzzlTm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_Sz1d4HlpPQ71WmZksJ7NghSNmy64WGRkAFy0vhOmTA5QrDUVYNRb43ZSFySsz5KX' \
--data-raw '{
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "2035",
            "card_holder_name": "John Doe",
            "card_cvc": "123"
        }
    },
    "email": "payme@example.com",   
    "phone": "9xxxxxxxxx"
}'
```

### MCA of BOA, email in Payment create request and then List Payment Method with client secret
```
Response should be populated like this after update request

```
{
    "redirect_url": "https://google.com/success",
    "currency": "USD",
    "payment_methods": [
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "google_pay",
                    "payment_experience": [
                        {
                            "payment_experience_type": "redirect_to_url",
                            "eligible_connectors": [
                                "bankofamerica"
                            ]
                        }
                    ],
                    "card_networks": null,
                    "bank_names": null,
                    "bank_debits": null,
                    "bank_transfers": null,
                    "required_fields": {
                        "billing.address.zip": {
                            "required_field": "payment_method_data.billing.address.zip",
                            "display_name": "zip",
                            "field_type": "user_address_pincode",
                            "value": "94122"
                        },
                        "email": {
                            "required_field": "email",
                            "display_name": "email",
                            "field_type": "user_email_address",
                            "value": "payme@example.com"
                        },
........
```
curl --location 'http://127.0.0.1:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:xxxxx' \
--data-raw '
{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "email": "payme@example.com",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "setup_future_usage": "on_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}
'
```
```
curl --location 'http://127.0.0.1:8080/account/payment_methods?client_secret=pay_7m0meCohmJxQJ4RzzlTm_secret_ybvSTH07m5MGTGQDHA3R' \
--header 'Accept: application/json' \
--header 'api-key: xxxxxxxxx' \
--data ''
```

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

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
