feat(customers): update billing and shipping address types to OptionalEncryptableValue and enhance decryption handling (#11374)

This commit is contained in:
Gaurav Rawat
2026-02-26 16:38:48 +05:30
committed by GitHub
parent 1e7eff50bb
commit 6dfa4037ee
3 changed files with 107 additions and 19 deletions

View File

@@ -78,8 +78,8 @@ pub struct Customer {
pub default_payment_method_id: Option<id_type::GlobalPaymentMethodId>,
pub updated_by: Option<String>,
pub merchant_reference_id: Option<id_type::CustomerId>,
pub default_billing_address: Option<Encryption>,
pub default_shipping_address: Option<Encryption>,
pub default_billing_address: OptionalEncryptableValue,
pub default_shipping_address: OptionalEncryptableValue,
pub id: id_type::GlobalCustomerId,
pub version: common_enums::ApiVersion,
pub status: DeleteStatus,
@@ -317,8 +317,8 @@ impl behaviour::Conversion for Customer {
connector_customer: self.connector_customer,
default_payment_method_id: self.default_payment_method_id,
updated_by: self.updated_by,
default_billing_address: self.default_billing_address,
default_shipping_address: self.default_shipping_address,
default_billing_address: self.default_billing_address.map(Encryption::from),
default_shipping_address: self.default_shipping_address.map(Encryption::from),
version: self.version,
status: self.status,
tax_registration_id: self.tax_registration_id.map(Encryption::from),
@@ -364,6 +364,60 @@ impl behaviour::Conversion for Customer {
},
)?;
let default_billing_address = item
.default_billing_address
.async_lift(|inner| async {
types::crypto_operation(
state,
common_utils::type_name!(Self),
types::CryptoOperation::DecryptOptional(inner),
keymanager::Identifier::Merchant(item.merchant_id.clone()),
key.peek(),
)
.await
.and_then(|val| val.try_into_optionaloperation())
})
.await
.change_context(ValidationError::InvalidValue {
message: "Failed to decrypt default billing address".to_string(),
})?;
let default_shipping_address = item
.default_shipping_address
.async_lift(|inner| async {
types::crypto_operation(
state,
common_utils::type_name!(Self),
types::CryptoOperation::DecryptOptional(inner),
keymanager::Identifier::Merchant(item.merchant_id.clone()),
key.peek(),
)
.await
.and_then(|val| val.try_into_optionaloperation())
})
.await
.change_context(ValidationError::InvalidValue {
message: "Failed to decrypt default shipping address".to_string(),
})?;
let document_details = item
.document_details
.async_lift(|inner| async {
types::crypto_operation(
state,
common_utils::type_name!(Self),
types::CryptoOperation::DecryptOptional(inner),
keymanager::Identifier::Merchant(item.merchant_id.clone()),
key.peek(),
)
.await
.and_then(|val| val.try_into_optionaloperation())
})
.await
.change_context(ValidationError::InvalidValue {
message: "Failed to decrypt document details".to_string(),
})?;
Ok(Self {
id: item.id,
merchant_reference_id: item.merchant_reference_id,
@@ -385,12 +439,12 @@ impl behaviour::Conversion for Customer {
connector_customer: item.connector_customer,
default_payment_method_id: item.default_payment_method_id,
updated_by: item.updated_by,
default_billing_address: item.default_billing_address,
default_shipping_address: item.default_shipping_address,
default_billing_address,
default_shipping_address,
version: item.version,
status: item.status,
tax_registration_id: encryptable_customer.tax_registration_id,
document_details: None,
document_details,
created_by: item
.created_by
.and_then(|created_by| created_by.parse::<CreatedBy>().ok()),
@@ -417,8 +471,8 @@ impl behaviour::Conversion for Customer {
modified_at: now,
connector_customer: self.connector_customer,
updated_by: self.updated_by,
default_billing_address: self.default_billing_address,
default_shipping_address: self.default_shipping_address,
default_billing_address: self.default_billing_address.map(Encryption::from),
default_shipping_address: self.default_shipping_address.map(Encryption::from),
version: common_types::consts::API_VERSION,
status: self.status,
tax_registration_id: self.tax_registration_id.map(Encryption::from),
@@ -443,8 +497,8 @@ pub struct CustomerGeneralUpdate {
pub phone_country_code: Option<String>,
pub metadata: Option<pii::SecretSerdeValue>,
pub connector_customer: Box<Option<common_types::customers::ConnectorCustomerMap>>,
pub default_billing_address: Option<Encryption>,
pub default_shipping_address: Option<Encryption>,
pub default_billing_address: OptionalEncryptableValue,
pub default_shipping_address: OptionalEncryptableValue,
pub default_payment_method_id: Option<Option<id_type::GlobalPaymentMethodId>>,
pub status: Option<DeleteStatus>,
pub tax_registration_id: crypto::OptionalEncryptableSecretString,
@@ -496,8 +550,8 @@ impl From<CustomerUpdate> for CustomerUpdateInternal {
metadata,
connector_customer: *connector_customer,
modified_at: date_time::now(),
default_billing_address,
default_shipping_address,
default_billing_address: default_billing_address.map(Encryption::from),
default_shipping_address: default_shipping_address.map(Encryption::from),
default_payment_method_id,
updated_by: None,
status,

View File

@@ -370,8 +370,8 @@ impl CustomerCreateBridge for customers::CustomerRequest {
modified_at: common_utils::date_time::now(),
default_payment_method_id: None,
updated_by: None,
default_billing_address: encrypted_customer_billing_address.map(Into::into),
default_shipping_address: encrypted_customer_shipping_address.map(Into::into),
default_billing_address: encrypted_customer_billing_address,
default_shipping_address: encrypted_customer_shipping_address,
version: common_types::consts::API_VERSION,
status: common_enums::DeleteStatus::Active,
tax_registration_id: encryptable_customer.tax_registration_id,
@@ -1502,8 +1502,8 @@ impl CustomerUpdateBridge for customers::CustomerUpdateRequest {
metadata: self.metadata.clone(),
description: self.description.clone(),
connector_customer: Box::new(None),
default_billing_address: encrypted_customer_billing_address.map(Into::into),
default_shipping_address: encrypted_customer_shipping_address.map(Into::into),
default_billing_address: encrypted_customer_billing_address,
default_shipping_address: encrypted_customer_shipping_address,
default_payment_method_id: Some(self.default_payment_method_id.clone()),
status: None,
last_modified_by: None,

View File

@@ -79,6 +79,40 @@ impl TryFrom<customer::Customer> for CustomerResponse {
})
})
.transpose()?;
let default_billing_address = cust
.default_billing_address
.as_ref()
.map(|encryptable| {
encryptable
.clone()
.into_inner()
.parse_value::<api_models::payments::AddressDetails>("AddressDetails")
.map_err(|err| {
router_env::logger::error!(?err, "Failed to parse default_billing_address");
err
})
})
.transpose()?;
let default_shipping_address = cust
.default_shipping_address
.as_ref()
.map(|encryptable| {
encryptable
.clone()
.into_inner()
.parse_value::<api_models::payments::AddressDetails>("AddressDetails")
.map_err(|err| {
router_env::logger::error!(
?err,
"Failed to parse default_shipping_address"
);
err
})
})
.transpose()?;
Ok(Self(customers::CustomerResponse {
id: cust.id,
merchant_reference_id: cust.merchant_reference_id,
@@ -90,8 +124,8 @@ impl TryFrom<customer::Customer> for CustomerResponse {
description: cust.description,
created_at: cust.created_at,
metadata: cust.metadata,
default_billing_address: None,
default_shipping_address: None,
default_billing_address,
default_shipping_address,
default_payment_method_id: cust.default_payment_method_id,
tax_registration_id: cust.tax_registration_id,
document_details,