feat(core): addition of shipping address details in payment intent (#5112)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Sampras Lopes <Sampras.lopes@juspay.in>
This commit is contained in:
Prajjwal Kumar
2024-07-08 15:13:19 +05:30
committed by GitHub
parent 307135366e
commit 2d31d38c1e
16 changed files with 243 additions and 241 deletions

View File

@ -62,6 +62,7 @@ pub struct PaymentIntent {
pub customer_details: Option<Encryption>,
pub billing_details: Option<Encryption>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryption>,
}
#[derive(
@ -120,6 +121,7 @@ pub struct PaymentIntentNew {
pub customer_details: Option<Encryption>,
pub billing_details: Option<Encryption>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -136,6 +138,7 @@ pub enum PaymentIntentUpdate {
metadata: serde_json::Value,
updated_by: String,
},
Update(Box<PaymentIntentUpdateFields>),
PaymentCreateUpdate {
return_url: Option<String>,
status: Option<storage_enums::IntentStatus>,
@ -156,32 +159,6 @@ pub enum PaymentIntentUpdate {
updated_by: String,
incremental_authorization_allowed: Option<bool>,
},
Update {
amount: MinorUnit,
currency: storage_enums::Currency,
setup_future_usage: Option<storage_enums::FutureUsage>,
status: storage_enums::IntentStatus,
customer_id: Option<id_type::CustomerId>,
shipping_address_id: Option<String>,
billing_address_id: Option<String>,
return_url: Option<String>,
business_country: Option<storage_enums::CountryAlpha2>,
business_label: Option<String>,
description: Option<String>,
statement_descriptor_name: Option<String>,
statement_descriptor_suffix: Option<String>,
order_details: Option<Vec<pii::SecretSerdeValue>>,
metadata: Option<serde_json::Value>,
payment_confirm_source: Option<storage_enums::PaymentSource>,
updated_by: String,
session_expiry: Option<PrimitiveDateTime>,
fingerprint_id: Option<String>,
request_external_three_ds_authentication: Option<bool>,
frm_metadata: Option<pii::SecretSerdeValue>,
customer_details: Option<Encryption>,
billing_details: Option<Encryption>,
merchant_order_reference_id: Option<String>,
},
PaymentAttemptAndAttemptCountUpdate {
active_attempt_id: String,
attempt_count: i16,
@ -222,6 +199,35 @@ pub enum PaymentIntentUpdate {
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaymentIntentUpdateFields {
pub amount: MinorUnit,
pub currency: storage_enums::Currency,
pub setup_future_usage: Option<storage_enums::FutureUsage>,
pub status: storage_enums::IntentStatus,
pub customer_id: Option<id_type::CustomerId>,
pub shipping_address_id: Option<String>,
pub billing_address_id: Option<String>,
pub return_url: Option<String>,
pub business_country: Option<storage_enums::CountryAlpha2>,
pub business_label: Option<String>,
pub description: Option<String>,
pub statement_descriptor_name: Option<String>,
pub statement_descriptor_suffix: Option<String>,
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
pub metadata: Option<serde_json::Value>,
pub payment_confirm_source: Option<storage_enums::PaymentSource>,
pub updated_by: String,
pub session_expiry: Option<PrimitiveDateTime>,
pub fingerprint_id: Option<String>,
pub request_external_three_ds_authentication: Option<bool>,
pub frm_metadata: Option<pii::SecretSerdeValue>,
pub customer_details: Option<Encryption>,
pub billing_details: Option<Encryption>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryption>,
}
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
#[diesel(table_name = payment_intent)]
pub struct PaymentIntentUpdateInternal {
@ -259,6 +265,7 @@ pub struct PaymentIntentUpdateInternal {
pub customer_details: Option<Encryption>,
pub billing_details: Option<Encryption>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryption>,
}
impl PaymentIntentUpdate {
@ -297,6 +304,7 @@ impl PaymentIntentUpdate {
customer_details,
billing_details,
merchant_order_reference_id,
shipping_details,
} = self.into();
PaymentIntent {
amount: amount.unwrap_or(source.amount),
@ -338,6 +346,7 @@ impl PaymentIntentUpdate {
billing_details: billing_details.or(source.billing_details),
merchant_order_reference_id: merchant_order_reference_id
.or(source.merchant_order_reference_id),
shipping_details: shipping_details.or(source.shipping_details),
..source
}
}
@ -346,59 +355,6 @@ impl PaymentIntentUpdate {
impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
fn from(payment_intent_update: PaymentIntentUpdate) -> Self {
match payment_intent_update {
PaymentIntentUpdate::Update {
amount,
currency,
setup_future_usage,
status,
customer_id,
shipping_address_id,
billing_address_id,
return_url,
business_country,
business_label,
description,
statement_descriptor_name,
statement_descriptor_suffix,
order_details,
metadata,
payment_confirm_source,
updated_by,
session_expiry,
fingerprint_id,
request_external_three_ds_authentication,
frm_metadata,
customer_details,
billing_details,
merchant_order_reference_id,
} => Self {
amount: Some(amount),
currency: Some(currency),
status: Some(status),
setup_future_usage,
customer_id,
shipping_address_id,
billing_address_id,
modified_at: Some(common_utils::date_time::now()),
return_url,
business_country,
business_label,
description,
statement_descriptor_name,
statement_descriptor_suffix,
order_details,
metadata,
payment_confirm_source,
updated_by,
session_expiry,
fingerprint_id,
request_external_three_ds_authentication,
frm_metadata,
customer_details,
billing_details,
merchant_order_reference_id,
..Default::default()
},
PaymentIntentUpdate::MetadataUpdate {
metadata,
updated_by,
@ -408,6 +364,35 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
updated_by,
..Default::default()
},
PaymentIntentUpdate::Update(value) => Self {
amount: Some(value.amount),
currency: Some(value.currency),
setup_future_usage: value.setup_future_usage,
status: Some(value.status),
customer_id: value.customer_id,
shipping_address_id: value.shipping_address_id,
billing_address_id: value.billing_address_id,
return_url: value.return_url,
business_country: value.business_country,
business_label: value.business_label,
description: value.description,
statement_descriptor_name: value.statement_descriptor_name,
statement_descriptor_suffix: value.statement_descriptor_suffix,
order_details: value.order_details,
metadata: value.metadata,
payment_confirm_source: value.payment_confirm_source,
updated_by: value.updated_by,
session_expiry: value.session_expiry,
fingerprint_id: value.fingerprint_id,
request_external_three_ds_authentication: value
.request_external_three_ds_authentication,
frm_metadata: value.frm_metadata,
customer_details: value.customer_details,
billing_details: value.billing_details,
merchant_order_reference_id: value.merchant_order_reference_id,
shipping_details: value.shipping_details,
..Default::default()
},
PaymentIntentUpdate::PaymentCreateUpdate {
return_url,
status,

View File

@ -893,6 +893,7 @@ diesel::table! {
billing_details -> Nullable<Bytea>,
#[max_length = 255]
merchant_order_reference_id -> Nullable<Varchar>,
shipping_details -> Nullable<Bytea>,
}
}

View File

@ -65,4 +65,5 @@ pub struct PaymentIntent {
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
}

View File

@ -532,6 +532,7 @@ impl behaviour::Conversion for PaymentIntent {
customer_details: self.customer_details.map(Encryption::from),
billing_details: self.billing_details.map(Encryption::from),
merchant_order_reference_id: self.merchant_order_reference_id,
shipping_details: self.shipping_details.map(Encryption::from),
})
}
@ -598,6 +599,10 @@ impl behaviour::Conversion for PaymentIntent {
.async_lift(inner_decrypt)
.await?,
merchant_order_reference_id: storage_model.merchant_order_reference_id,
shipping_details: storage_model
.shipping_details
.async_lift(inner_decrypt)
.await?,
})
}
.await
@ -654,6 +659,7 @@ impl behaviour::Conversion for PaymentIntent {
customer_details: self.customer_details.map(Encryption::from),
billing_details: self.billing_details.map(Encryption::from),
merchant_order_reference_id: self.merchant_order_reference_id,
shipping_details: self.shipping_details.map(Encryption::from),
})
}
}

View File

@ -135,6 +135,36 @@ pub struct PaymentIntentNew {
pub charges: Option<pii::SecretSerdeValue>,
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
}
#[derive(Debug, Clone, Serialize)]
pub struct PaymentIntentUpdateFields {
pub amount: MinorUnit,
pub currency: storage_enums::Currency,
pub setup_future_usage: Option<storage_enums::FutureUsage>,
pub status: storage_enums::IntentStatus,
pub customer_id: Option<id_type::CustomerId>,
pub shipping_address_id: Option<String>,
pub billing_address_id: Option<String>,
pub return_url: Option<String>,
pub business_country: Option<storage_enums::CountryAlpha2>,
pub business_label: Option<String>,
pub description: Option<String>,
pub statement_descriptor_name: Option<String>,
pub statement_descriptor_suffix: Option<String>,
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
pub metadata: Option<serde_json::Value>,
pub frm_metadata: Option<pii::SecretSerdeValue>,
pub payment_confirm_source: Option<storage_enums::PaymentSource>,
pub updated_by: String,
pub fingerprint_id: Option<String>,
pub session_expiry: Option<PrimitiveDateTime>,
pub request_external_three_ds_authentication: Option<bool>,
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
}
#[derive(Debug, Clone, Serialize)]
@ -151,6 +181,7 @@ pub enum PaymentIntentUpdate {
metadata: serde_json::Value,
updated_by: String,
},
Update(Box<PaymentIntentUpdateFields>),
PaymentCreateUpdate {
return_url: Option<String>,
status: Option<storage_enums::IntentStatus>,
@ -171,32 +202,6 @@ pub enum PaymentIntentUpdate {
incremental_authorization_allowed: Option<bool>,
updated_by: String,
},
Update {
amount: MinorUnit,
currency: storage_enums::Currency,
setup_future_usage: Option<storage_enums::FutureUsage>,
status: storage_enums::IntentStatus,
customer_id: Option<id_type::CustomerId>,
shipping_address_id: Option<String>,
billing_address_id: Option<String>,
return_url: Option<String>,
business_country: Option<storage_enums::CountryAlpha2>,
business_label: Option<String>,
description: Option<String>,
statement_descriptor_name: Option<String>,
statement_descriptor_suffix: Option<String>,
order_details: Option<Vec<pii::SecretSerdeValue>>,
metadata: Option<serde_json::Value>,
frm_metadata: Option<pii::SecretSerdeValue>,
payment_confirm_source: Option<storage_enums::PaymentSource>,
updated_by: String,
fingerprint_id: Option<String>,
session_expiry: Option<PrimitiveDateTime>,
request_external_three_ds_authentication: Option<bool>,
customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
merchant_order_reference_id: Option<String>,
},
PaymentAttemptAndAttemptCountUpdate {
active_attempt_id: String,
attempt_count: i16,
@ -275,64 +280,12 @@ pub struct PaymentIntentUpdateInternal {
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
}
impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
fn from(payment_intent_update: PaymentIntentUpdate) -> Self {
match payment_intent_update {
PaymentIntentUpdate::Update {
amount,
currency,
setup_future_usage,
status,
customer_id,
shipping_address_id,
billing_address_id,
return_url,
business_country,
business_label,
description,
statement_descriptor_name,
statement_descriptor_suffix,
order_details,
metadata,
payment_confirm_source,
updated_by,
fingerprint_id,
session_expiry,
request_external_three_ds_authentication,
frm_metadata,
customer_details,
billing_details,
merchant_order_reference_id,
} => Self {
amount: Some(amount),
currency: Some(currency),
status: Some(status),
setup_future_usage,
customer_id,
shipping_address_id,
billing_address_id,
modified_at: Some(common_utils::date_time::now()),
return_url,
business_country,
business_label,
description,
statement_descriptor_name,
statement_descriptor_suffix,
order_details,
metadata,
payment_confirm_source,
updated_by,
fingerprint_id,
session_expiry,
request_external_three_ds_authentication,
frm_metadata,
customer_details,
billing_details,
merchant_order_reference_id,
..Default::default()
},
PaymentIntentUpdate::MetadataUpdate {
metadata,
updated_by,
@ -342,6 +295,35 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
updated_by,
..Default::default()
},
PaymentIntentUpdate::Update(value) => Self {
amount: Some(value.amount),
currency: Some(value.currency),
setup_future_usage: value.setup_future_usage,
status: Some(value.status),
customer_id: value.customer_id,
shipping_address_id: value.shipping_address_id,
billing_address_id: value.billing_address_id,
return_url: value.return_url,
business_country: value.business_country,
business_label: value.business_label,
description: value.description,
statement_descriptor_name: value.statement_descriptor_name,
statement_descriptor_suffix: value.statement_descriptor_suffix,
order_details: value.order_details,
metadata: value.metadata,
payment_confirm_source: value.payment_confirm_source,
updated_by: value.updated_by,
session_expiry: value.session_expiry,
fingerprint_id: value.fingerprint_id,
request_external_three_ds_authentication: value
.request_external_three_ds_authentication,
frm_metadata: value.frm_metadata,
customer_details: value.customer_details,
billing_details: value.billing_details,
merchant_order_reference_id: value.merchant_order_reference_id,
shipping_details: value.shipping_details,
..Default::default()
},
PaymentIntentUpdate::PaymentCreateUpdate {
return_url,
status,
@ -484,7 +466,10 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
}
}
use diesel_models::{encryption::Encryption, PaymentIntentUpdate as DieselPaymentIntentUpdate};
use diesel_models::{
encryption::Encryption, PaymentIntentUpdate as DieselPaymentIntentUpdate,
PaymentIntentUpdateFields as DieselPaymentIntentUpdateFields,
};
impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
fn from(value: PaymentIntentUpdate) -> Self {
@ -511,6 +496,36 @@ impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
metadata,
updated_by,
},
PaymentIntentUpdate::Update(value) => {
Self::Update(Box::new(DieselPaymentIntentUpdateFields {
amount: value.amount,
currency: value.currency,
setup_future_usage: value.setup_future_usage,
status: value.status,
customer_id: value.customer_id,
shipping_address_id: value.shipping_address_id,
billing_address_id: value.billing_address_id,
return_url: value.return_url,
business_country: value.business_country,
business_label: value.business_label,
description: value.description,
statement_descriptor_name: value.statement_descriptor_name,
statement_descriptor_suffix: value.statement_descriptor_suffix,
order_details: value.order_details,
metadata: value.metadata,
payment_confirm_source: value.payment_confirm_source,
updated_by: value.updated_by,
session_expiry: value.session_expiry,
fingerprint_id: value.fingerprint_id,
request_external_three_ds_authentication: value
.request_external_three_ds_authentication,
frm_metadata: value.frm_metadata,
customer_details: value.customer_details.map(Encryption::from),
billing_details: value.billing_details.map(Encryption::from),
merchant_order_reference_id: value.merchant_order_reference_id,
shipping_details: value.shipping_details.map(Encryption::from),
}))
}
PaymentIntentUpdate::PaymentCreateUpdate {
return_url,
status,
@ -548,57 +563,6 @@ impl From<PaymentIntentUpdate> for DieselPaymentIntentUpdate {
updated_by,
incremental_authorization_allowed,
},
PaymentIntentUpdate::Update {
amount,
currency,
setup_future_usage,
status,
customer_id,
shipping_address_id,
billing_address_id,
return_url,
business_country,
business_label,
description,
statement_descriptor_name,
statement_descriptor_suffix,
order_details,
metadata,
payment_confirm_source,
updated_by,
fingerprint_id,
session_expiry,
request_external_three_ds_authentication,
frm_metadata,
customer_details,
billing_details,
merchant_order_reference_id,
} => Self::Update {
amount,
currency,
setup_future_usage,
status,
customer_id,
shipping_address_id,
billing_address_id,
return_url,
business_country,
business_label,
description,
statement_descriptor_name,
statement_descriptor_suffix,
order_details,
metadata,
payment_confirm_source,
updated_by,
fingerprint_id,
session_expiry,
request_external_three_ds_authentication,
frm_metadata,
customer_details: customer_details.map(Encryption::from),
billing_details: billing_details.map(Encryption::from),
merchant_order_reference_id,
},
PaymentIntentUpdate::PaymentAttemptAndAttemptCountUpdate {
active_attempt_id,
attempt_count,
@ -702,6 +666,7 @@ impl From<PaymentIntentUpdateInternal> for diesel_models::PaymentIntentUpdateInt
customer_details,
billing_details,
merchant_order_reference_id,
shipping_details,
} = value;
Self {
@ -738,6 +703,7 @@ impl From<PaymentIntentUpdateInternal> for diesel_models::PaymentIntentUpdateInt
customer_details: customer_details.map(Encryption::from),
billing_details: billing_details.map(Encryption::from),
merchant_order_reference_id,
shipping_details: shipping_details.map(Encryption::from),
}
}
}

View File

@ -224,7 +224,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.first_name)
.and_then(|shipping_details| shipping_details.first_name)
})
}
@ -233,7 +233,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.last_name)
.and_then(|shipping_details| shipping_details.last_name)
})
}
@ -242,7 +242,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.line1)
.and_then(|shipping_details| shipping_details.line1)
})
}
@ -251,7 +251,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.line2)
.and_then(|shipping_details| shipping_details.line2)
})
}
@ -260,7 +260,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.city)
.and_then(|shipping_details| shipping_details.city)
})
}
@ -269,7 +269,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.state)
.and_then(|shipping_details| shipping_details.state)
})
}
@ -278,7 +278,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.country)
.and_then(|shipping_details| shipping_details.country)
})
}
@ -287,7 +287,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
shipping_address
.clone()
.address
.and_then(|shipping_address_details| shipping_address_details.zip)
.and_then(|shipping_details| shipping_details.zip)
})
}

View File

@ -3161,6 +3161,7 @@ mod tests {
customer_details: None,
billing_details: None,
merchant_order_reference_id: None,
shipping_details: None,
};
let req_cs = Some("1".to_string());
assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent).is_ok());
@ -3224,6 +3225,7 @@ mod tests {
customer_details: None,
billing_details: None,
merchant_order_reference_id: None,
shipping_details: None,
};
let req_cs = Some("1".to_string());
assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent,).is_err())
@ -3285,6 +3287,7 @@ mod tests {
customer_details: None,
billing_details: None,
merchant_order_reference_id: None,
shipping_details: None,
};
let req_cs = Some("1".to_string());
assert!(authenticate_client_secret(req_cs.as_ref(), &payment_intent).is_err())

View File

@ -10,6 +10,7 @@ use async_trait::async_trait;
use common_utils::ext_traits::{AsyncExt, Encode, StringExt, ValueExt};
use error_stack::{report, ResultExt};
use futures::FutureExt;
use hyperswitch_domain_models::payments::payment_intent::PaymentIntentUpdateFields;
use masking::{ExposeInterface, PeekInterface};
use router_derive::PaymentOperation;
use router_env::{instrument, logger, tracing};
@ -1223,6 +1224,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
let billing_details = billing_address
.async_and_then(|_| async { create_encrypted_data(key_store, billing_address).await })
.await;
let shipping_address = payment_data.address.get_shipping();
let shipping_details = shipping_address
.async_and_then(|_| async { create_encrypted_data(key_store, shipping_address).await })
.await;
let m_payment_data_payment_intent = payment_data.payment_intent.clone();
let m_customer_id = customer_id.clone();
let m_shipping_address_id = shipping_address_id.clone();
@ -1244,7 +1249,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
async move {
m_db.update_payment_intent(
m_payment_data_payment_intent,
storage::PaymentIntentUpdate::Update {
storage::PaymentIntentUpdate::Update(Box::new(PaymentIntentUpdateFields {
amount: payment_data.payment_intent.amount,
currency: payment_data.currency,
setup_future_usage,
@ -1269,7 +1274,8 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
customer_details,
merchant_order_reference_id: None,
billing_details,
},
shipping_details,
})),
&m_key_store,
storage_scheme,
)

View File

@ -1055,6 +1055,16 @@ impl PaymentCreate {
})
.await;
// Derivation of directly supplied Shipping Address data in our Payment Create Request
// Encrypting our Shipping Address Details to be stored in Payment Intent
let shipping_details = request
.shipping
.clone()
.async_and_then(|_| async {
create_encrypted_data(key_store, request.shipping.clone()).await
})
.await;
// 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()
@ -1129,6 +1139,7 @@ impl PaymentCreate {
billing_details,
customer_details,
merchant_order_reference_id: request.merchant_order_reference_id.clone(),
shipping_details,
})
}

View File

@ -1,9 +1,7 @@
use std::marker::PhantomData;
use api_models::{
enums::FrmSuggestion,
mandates::RecurringDetails,
payments::{Address, RequestSurchargeDetails},
enums::FrmSuggestion, mandates::RecurringDetails, payments::RequestSurchargeDetails,
};
use async_trait::async_trait;
use common_utils::{
@ -11,7 +9,9 @@ use common_utils::{
pii::Email,
};
use error_stack::{report, ResultExt};
use hyperswitch_domain_models::payments::payment_intent::CustomerData;
use hyperswitch_domain_models::payments::payment_intent::{
CustomerData, PaymentIntentUpdateFields,
};
use router_derive::PaymentOperation;
use router_env::{instrument, tracing};
@ -221,14 +221,6 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
)
.await?;
let billing_details: Option<Address> = billing_address.as_ref().map(From::from);
payment_intent.billing_details = billing_details
.clone()
.async_and_then(|_| async {
create_encrypted_data(key_store, billing_details.clone()).await
})
.await;
let payment_method_billing = helpers::create_or_update_address_for_payment_by_request(
db,
request
@ -449,7 +441,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
customer_acceptance,
address: PaymentAddress::new(
shipping_address.as_ref().map(From::from),
billing_details,
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
@ -719,6 +711,26 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
.payment_intent
.statement_descriptor_suffix
.clone();
let billing_details = payment_data
.address
.get_payment_billing()
.async_and_then(|_| async {
create_encrypted_data(
key_store,
payment_data.address.get_payment_billing().cloned(),
)
.await
})
.await;
let shipping_details = payment_data
.address
.get_shipping()
.async_and_then(|_| async {
create_encrypted_data(key_store, payment_data.address.get_shipping().cloned()).await
})
.await;
let order_details = payment_data.payment_intent.order_details.clone();
let metadata = payment_data.payment_intent.metadata.clone();
let frm_metadata = payment_data.payment_intent.frm_metadata.clone();
@ -727,12 +739,11 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
.payment_intent
.merchant_order_reference_id
.clone();
let billing_details = payment_data.payment_intent.billing_details.clone();
payment_data.payment_intent = state
.store
.update_payment_intent(
payment_data.payment_intent.clone(),
storage::PaymentIntentUpdate::Update {
storage::PaymentIntentUpdate::Update(Box::new(PaymentIntentUpdateFields {
amount: payment_data.amount.into(),
currency: payment_data.currency,
setup_future_usage,
@ -759,7 +770,8 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
customer_details,
merchant_order_reference_id,
billing_details,
},
shipping_details,
})),
key_store,
storage_scheme,
)

View File

@ -34,10 +34,11 @@ pub struct KafkaPaymentIntent<'a> {
pub business_label: Option<&'a String>,
pub attempt_count: i16,
pub payment_confirm_source: Option<storage_enums::PaymentSource>,
pub billing_details: Option<Encryptable<Secret<Value>>>,
pub shipping_details: Option<Encryptable<Secret<Value>>>,
pub customer_email: Option<HashedString<pii::EmailStrategy>>,
pub feature_metadata: Option<&'a Value>,
pub merchant_order_reference_id: Option<&'a String>,
pub billing_details: Option<Encryptable<Secret<Value>>>,
}
impl<'a> KafkaPaymentIntent<'a> {
@ -67,6 +68,9 @@ impl<'a> KafkaPaymentIntent<'a> {
business_label: intent.business_label.as_ref(),
attempt_count: intent.attempt_count,
payment_confirm_source: intent.payment_confirm_source,
// TODO: use typed information here to avoid PII logging
billing_details: None,
shipping_details: None,
customer_email: intent
.customer_details
.as_ref()
@ -76,7 +80,6 @@ impl<'a> KafkaPaymentIntent<'a> {
.map(|email| HashedString::from(Secret::new(email.to_string()))),
feature_metadata: intent.feature_metadata.as_ref(),
merchant_order_reference_id: intent.merchant_order_reference_id.as_ref(),
billing_details: None,
}
}
}

View File

@ -35,10 +35,11 @@ pub struct KafkaPaymentIntentEvent<'a> {
pub business_label: Option<&'a String>,
pub attempt_count: i16,
pub payment_confirm_source: Option<storage_enums::PaymentSource>,
pub billing_details: Option<Encryptable<Secret<Value>>>,
pub shipping_details: Option<Encryptable<Secret<Value>>>,
pub customer_email: Option<HashedString<pii::EmailStrategy>>,
pub feature_metadata: Option<&'a Value>,
pub merchant_order_reference_id: Option<&'a String>,
pub billing_details: Option<Encryptable<Secret<Value>>>,
}
impl<'a> KafkaPaymentIntentEvent<'a> {
@ -68,6 +69,9 @@ impl<'a> KafkaPaymentIntentEvent<'a> {
business_label: intent.business_label.as_ref(),
attempt_count: intent.attempt_count,
payment_confirm_source: intent.payment_confirm_source,
// TODO: use typed information here to avoid PII logging
billing_details: None,
shipping_details: None,
customer_email: intent
.customer_details
.as_ref()
@ -77,7 +81,6 @@ impl<'a> KafkaPaymentIntentEvent<'a> {
.map(|email| HashedString::from(Secret::new(email.to_string()))),
feature_metadata: intent.feature_metadata.as_ref(),
merchant_order_reference_id: intent.merchant_order_reference_id.as_ref(),
billing_details: None,
}
}
}

View File

@ -47,7 +47,7 @@ pub use diesel_models::{
};
pub use hyperswitch_domain_models::payments::{
payment_attempt::{PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
payment_intent::{PaymentIntentNew, PaymentIntentUpdate},
payment_intent::{PaymentIntentNew, PaymentIntentUpdate, PaymentIntentUpdateFields},
PaymentIntent,
};
#[cfg(feature = "payouts")]

View File

@ -228,6 +228,7 @@ pub async fn generate_sample_data(
customer_details: None,
billing_details: None,
merchant_order_reference_id: Default::default(),
shipping_details: None,
};
let payment_attempt = PaymentAttemptBatchNew {
attempt_id: attempt_id.clone(),

View File

@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
ALTER TABLE payment_intent DROP COLUMN IF EXISTS shipping_details;

View File

@ -0,0 +1,2 @@
-- Your SQL goes here
ALTER TABLE payment_intent ADD COLUMN IF NOT EXISTS shipping_details BYTEA DEFAULT NULL;