mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat: add macro to generate ToEncryptable trait (#6313)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
use api_models::customers::CustomerRequestWithEncryption;
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
use common_enums::DeleteStatus;
|
||||
use common_utils::{
|
||||
crypto, date_time,
|
||||
crypto::{self, Encryptable},
|
||||
date_time,
|
||||
encryption::Encryption,
|
||||
errors::{CustomResult, ValidationError},
|
||||
id_type, pii,
|
||||
@ -13,19 +13,23 @@ use common_utils::{
|
||||
};
|
||||
use diesel_models::customers::CustomerUpdateInternal;
|
||||
use error_stack::ResultExt;
|
||||
use masking::{PeekInterface, Secret};
|
||||
use masking::{PeekInterface, Secret, SwitchStrategy};
|
||||
use rustc_hash::FxHashMap;
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
use crate::type_encryption as types;
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, router_derive::ToEncryption)]
|
||||
pub struct Customer {
|
||||
pub customer_id: id_type::CustomerId,
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
pub name: crypto::OptionalEncryptableName,
|
||||
pub email: crypto::OptionalEncryptableEmail,
|
||||
pub phone: crypto::OptionalEncryptablePhone,
|
||||
#[encrypt]
|
||||
pub name: Option<Encryptable<Secret<String>>>,
|
||||
#[encrypt]
|
||||
pub email: Option<Encryptable<Secret<String, pii::EmailStrategy>>>,
|
||||
#[encrypt]
|
||||
pub phone: Option<Encryptable<Secret<String>>>,
|
||||
pub phone_country_code: Option<String>,
|
||||
pub description: Option<Description>,
|
||||
pub created_at: PrimitiveDateTime,
|
||||
@ -39,12 +43,15 @@ pub struct Customer {
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, router_derive::ToEncryption)]
|
||||
pub struct Customer {
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
pub name: crypto::OptionalEncryptableName,
|
||||
pub email: crypto::OptionalEncryptableEmail,
|
||||
pub phone: crypto::OptionalEncryptablePhone,
|
||||
#[encrypt]
|
||||
pub name: Option<Encryptable<Secret<String>>>,
|
||||
#[encrypt]
|
||||
pub email: Option<Encryptable<Secret<String, pii::EmailStrategy>>>,
|
||||
#[encrypt]
|
||||
pub phone: Option<Encryptable<Secret<String>>>,
|
||||
pub phone_country_code: Option<String>,
|
||||
pub description: Option<Description>,
|
||||
pub created_at: PrimitiveDateTime,
|
||||
@ -98,8 +105,8 @@ impl super::behaviour::Conversion for Customer {
|
||||
let decrypted = types::crypto_operation(
|
||||
state,
|
||||
common_utils::type_name!(Self::DstType),
|
||||
types::CryptoOperation::BatchDecrypt(CustomerRequestWithEncryption::to_encryptable(
|
||||
CustomerRequestWithEncryption {
|
||||
types::CryptoOperation::BatchDecrypt(EncryptedCustomer::to_encryptable(
|
||||
EncryptedCustomer {
|
||||
name: item.name.clone(),
|
||||
phone: item.phone.clone(),
|
||||
email: item.email.clone(),
|
||||
@ -113,16 +120,23 @@ impl super::behaviour::Conversion for Customer {
|
||||
.change_context(ValidationError::InvalidValue {
|
||||
message: "Failed while decrypting customer data".to_string(),
|
||||
})?;
|
||||
let encryptable_customer = CustomerRequestWithEncryption::from_encryptable(decrypted)
|
||||
.change_context(ValidationError::InvalidValue {
|
||||
let encryptable_customer = EncryptedCustomer::from_encryptable(decrypted).change_context(
|
||||
ValidationError::InvalidValue {
|
||||
message: "Failed while decrypting customer data".to_string(),
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
customer_id: item.customer_id,
|
||||
merchant_id: item.merchant_id,
|
||||
name: encryptable_customer.name,
|
||||
email: encryptable_customer.email,
|
||||
email: encryptable_customer.email.map(|email| {
|
||||
let encryptable: Encryptable<Secret<String, pii::EmailStrategy>> = Encryptable::new(
|
||||
email.clone().into_inner().switch_strategy(),
|
||||
email.into_encrypted(),
|
||||
);
|
||||
encryptable
|
||||
}),
|
||||
phone: encryptable_customer.phone,
|
||||
phone_country_code: item.phone_country_code,
|
||||
description: item.description,
|
||||
@ -198,8 +212,8 @@ impl super::behaviour::Conversion for Customer {
|
||||
let decrypted = types::crypto_operation(
|
||||
state,
|
||||
common_utils::type_name!(Self::DstType),
|
||||
types::CryptoOperation::BatchDecrypt(CustomerRequestWithEncryption::to_encryptable(
|
||||
CustomerRequestWithEncryption {
|
||||
types::CryptoOperation::BatchDecrypt(EncryptedCustomer::to_encryptable(
|
||||
EncryptedCustomer {
|
||||
name: item.name.clone(),
|
||||
phone: item.phone.clone(),
|
||||
email: item.email.clone(),
|
||||
@ -213,17 +227,24 @@ impl super::behaviour::Conversion for Customer {
|
||||
.change_context(ValidationError::InvalidValue {
|
||||
message: "Failed while decrypting customer data".to_string(),
|
||||
})?;
|
||||
let encryptable_customer = CustomerRequestWithEncryption::from_encryptable(decrypted)
|
||||
.change_context(ValidationError::InvalidValue {
|
||||
let encryptable_customer = EncryptedCustomer::from_encryptable(decrypted).change_context(
|
||||
ValidationError::InvalidValue {
|
||||
message: "Failed while decrypting customer data".to_string(),
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
id: item.id,
|
||||
merchant_reference_id: item.merchant_reference_id,
|
||||
merchant_id: item.merchant_id,
|
||||
name: encryptable_customer.name,
|
||||
email: encryptable_customer.email,
|
||||
email: encryptable_customer.email.map(|email| {
|
||||
let encryptable: Encryptable<Secret<String, pii::EmailStrategy>> = Encryptable::new(
|
||||
email.clone().into_inner().switch_strategy(),
|
||||
email.into_encrypted(),
|
||||
);
|
||||
encryptable
|
||||
}),
|
||||
phone: encryptable_customer.phone,
|
||||
phone_country_code: item.phone_country_code,
|
||||
description: item.description,
|
||||
|
||||
@ -10,16 +10,18 @@ use diesel_models::{enums, merchant_connector_account::MerchantConnectorAccountU
|
||||
use error_stack::ResultExt;
|
||||
use masking::{PeekInterface, Secret};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde_json::Value;
|
||||
|
||||
use super::behaviour;
|
||||
use crate::type_encryption::{crypto_operation, CryptoOperation};
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, router_derive::ToEncryption)]
|
||||
pub struct MerchantConnectorAccount {
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
pub connector_name: String,
|
||||
pub connector_account_details: Encryptable<pii::SecretSerdeValue>,
|
||||
#[encrypt]
|
||||
pub connector_account_details: Encryptable<Secret<Value>>,
|
||||
pub test_mode: Option<bool>,
|
||||
pub disabled: Option<bool>,
|
||||
pub merchant_connector_id: id_type::MerchantConnectorAccountId,
|
||||
@ -38,8 +40,10 @@ pub struct MerchantConnectorAccount {
|
||||
pub applepay_verified_domains: Option<Vec<String>>,
|
||||
pub pm_auth_config: Option<pii::SecretSerdeValue>,
|
||||
pub status: enums::ConnectorStatus,
|
||||
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
#[encrypt]
|
||||
pub connector_wallets_details: Option<Encryptable<Secret<Value>>>,
|
||||
#[encrypt]
|
||||
pub additional_merchant_data: Option<Encryptable<Secret<Value>>>,
|
||||
pub version: common_enums::ApiVersion,
|
||||
}
|
||||
|
||||
@ -51,12 +55,13 @@ impl MerchantConnectorAccount {
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, router_derive::ToEncryption)]
|
||||
pub struct MerchantConnectorAccount {
|
||||
pub id: id_type::MerchantConnectorAccountId,
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
pub connector_name: String,
|
||||
pub connector_account_details: Encryptable<pii::SecretSerdeValue>,
|
||||
#[encrypt]
|
||||
pub connector_account_details: Encryptable<Secret<Value>>,
|
||||
pub disabled: Option<bool>,
|
||||
pub payment_methods_enabled: Option<Vec<pii::SecretSerdeValue>>,
|
||||
pub connector_type: enums::ConnectorType,
|
||||
@ -70,8 +75,10 @@ pub struct MerchantConnectorAccount {
|
||||
pub applepay_verified_domains: Option<Vec<String>>,
|
||||
pub pm_auth_config: Option<pii::SecretSerdeValue>,
|
||||
pub status: enums::ConnectorStatus,
|
||||
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
#[encrypt]
|
||||
pub connector_wallets_details: Option<Encryptable<Secret<Value>>>,
|
||||
#[encrypt]
|
||||
pub additional_merchant_data: Option<Encryptable<Secret<Value>>>,
|
||||
pub version: common_enums::ApiVersion,
|
||||
}
|
||||
|
||||
@ -179,11 +186,13 @@ impl behaviour::Conversion for MerchantConnectorAccount {
|
||||
let decrypted_data = crypto_operation(
|
||||
state,
|
||||
type_name!(Self::DstType),
|
||||
CryptoOperation::BatchDecrypt(EncryptedMca::to_encryptable(EncryptedMca {
|
||||
connector_account_details: other.connector_account_details,
|
||||
additional_merchant_data: other.additional_merchant_data,
|
||||
connector_wallets_details: other.connector_wallets_details,
|
||||
})),
|
||||
CryptoOperation::BatchDecrypt(EncryptedMerchantConnectorAccount::to_encryptable(
|
||||
EncryptedMerchantConnectorAccount {
|
||||
connector_account_details: other.connector_account_details,
|
||||
additional_merchant_data: other.additional_merchant_data,
|
||||
connector_wallets_details: other.connector_wallets_details,
|
||||
},
|
||||
)),
|
||||
identifier.clone(),
|
||||
key.peek(),
|
||||
)
|
||||
@ -193,11 +202,10 @@ impl behaviour::Conversion for MerchantConnectorAccount {
|
||||
message: "Failed while decrypting connector account details".to_string(),
|
||||
})?;
|
||||
|
||||
let decrypted_data = EncryptedMca::from_encryptable(decrypted_data).change_context(
|
||||
ValidationError::InvalidValue {
|
||||
let decrypted_data = EncryptedMerchantConnectorAccount::from_encryptable(decrypted_data)
|
||||
.change_context(ValidationError::InvalidValue {
|
||||
message: "Failed while decrypting connector account details".to_string(),
|
||||
},
|
||||
)?;
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
merchant_id: other.merchant_id,
|
||||
@ -308,11 +316,13 @@ impl behaviour::Conversion for MerchantConnectorAccount {
|
||||
let decrypted_data = crypto_operation(
|
||||
state,
|
||||
type_name!(Self::DstType),
|
||||
CryptoOperation::BatchDecrypt(EncryptedMca::to_encryptable(EncryptedMca {
|
||||
connector_account_details: other.connector_account_details,
|
||||
additional_merchant_data: other.additional_merchant_data,
|
||||
connector_wallets_details: other.connector_wallets_details,
|
||||
})),
|
||||
CryptoOperation::BatchDecrypt(EncryptedMerchantConnectorAccount::to_encryptable(
|
||||
EncryptedMerchantConnectorAccount {
|
||||
connector_account_details: other.connector_account_details,
|
||||
additional_merchant_data: other.additional_merchant_data,
|
||||
connector_wallets_details: other.connector_wallets_details,
|
||||
},
|
||||
)),
|
||||
identifier.clone(),
|
||||
key.peek(),
|
||||
)
|
||||
@ -322,11 +332,10 @@ impl behaviour::Conversion for MerchantConnectorAccount {
|
||||
message: "Failed while decrypting connector account details".to_string(),
|
||||
})?;
|
||||
|
||||
let decrypted_data = EncryptedMca::from_encryptable(decrypted_data).change_context(
|
||||
ValidationError::InvalidValue {
|
||||
let decrypted_data = EncryptedMerchantConnectorAccount::from_encryptable(decrypted_data)
|
||||
.change_context(ValidationError::InvalidValue {
|
||||
message: "Failed while decrypting connector account details".to_string(),
|
||||
},
|
||||
)?;
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
id: other.id,
|
||||
@ -502,121 +511,3 @@ impl From<MerchantConnectorAccountUpdate> for MerchantConnectorAccountUpdateInte
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct McaFromRequestfromUpdate {
|
||||
pub connector_account_details: Option<pii::SecretSerdeValue>,
|
||||
pub connector_wallets_details: Option<pii::SecretSerdeValue>,
|
||||
pub additional_merchant_data: Option<pii::SecretSerdeValue>,
|
||||
}
|
||||
pub struct McaFromRequest {
|
||||
pub connector_account_details: pii::SecretSerdeValue,
|
||||
pub connector_wallets_details: Option<pii::SecretSerdeValue>,
|
||||
pub additional_merchant_data: Option<pii::SecretSerdeValue>,
|
||||
}
|
||||
|
||||
pub struct DecryptedMca {
|
||||
pub connector_account_details: Encryptable<pii::SecretSerdeValue>,
|
||||
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
}
|
||||
|
||||
pub struct EncryptedMca {
|
||||
pub connector_account_details: Encryption,
|
||||
pub connector_wallets_details: Option<Encryption>,
|
||||
pub additional_merchant_data: Option<Encryption>,
|
||||
}
|
||||
|
||||
pub struct DecryptedUpdateMca {
|
||||
pub connector_account_details: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
|
||||
}
|
||||
|
||||
impl ToEncryptable<DecryptedMca, Secret<serde_json::Value>, Encryption> for EncryptedMca {
|
||||
fn from_encryptable(
|
||||
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
|
||||
) -> CustomResult<DecryptedMca, common_utils::errors::ParsingError> {
|
||||
Ok(DecryptedMca {
|
||||
connector_account_details: hashmap.remove("connector_account_details").ok_or(
|
||||
error_stack::report!(common_utils::errors::ParsingError::EncodeError(
|
||||
"Unable to convert from HashMap to DecryptedMca",
|
||||
)),
|
||||
)?,
|
||||
connector_wallets_details: hashmap.remove("connector_wallets_details"),
|
||||
additional_merchant_data: hashmap.remove("additional_merchant_data"),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_encryptable(self) -> FxHashMap<String, Encryption> {
|
||||
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
|
||||
|
||||
map.insert(
|
||||
"connector_account_details".to_string(),
|
||||
self.connector_account_details,
|
||||
);
|
||||
self.connector_wallets_details
|
||||
.map(|s| map.insert("connector_wallets_details".to_string(), s));
|
||||
self.additional_merchant_data
|
||||
.map(|s| map.insert("additional_merchant_data".to_string(), s));
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
impl ToEncryptable<DecryptedUpdateMca, Secret<serde_json::Value>, Secret<serde_json::Value>>
|
||||
for McaFromRequestfromUpdate
|
||||
{
|
||||
fn from_encryptable(
|
||||
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
|
||||
) -> CustomResult<DecryptedUpdateMca, common_utils::errors::ParsingError> {
|
||||
Ok(DecryptedUpdateMca {
|
||||
connector_account_details: hashmap.remove("connector_account_details"),
|
||||
connector_wallets_details: hashmap.remove("connector_wallets_details"),
|
||||
additional_merchant_data: hashmap.remove("additional_merchant_data"),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_encryptable(self) -> FxHashMap<String, Secret<serde_json::Value>> {
|
||||
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
|
||||
|
||||
self.connector_account_details
|
||||
.map(|cad| map.insert("connector_account_details".to_string(), cad));
|
||||
|
||||
self.connector_wallets_details
|
||||
.map(|s| map.insert("connector_wallets_details".to_string(), s));
|
||||
self.additional_merchant_data
|
||||
.map(|s| map.insert("additional_merchant_data".to_string(), s));
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
impl ToEncryptable<DecryptedMca, Secret<serde_json::Value>, Secret<serde_json::Value>>
|
||||
for McaFromRequest
|
||||
{
|
||||
fn from_encryptable(
|
||||
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
|
||||
) -> CustomResult<DecryptedMca, common_utils::errors::ParsingError> {
|
||||
Ok(DecryptedMca {
|
||||
connector_account_details: hashmap.remove("connector_account_details").ok_or(
|
||||
error_stack::report!(common_utils::errors::ParsingError::EncodeError(
|
||||
"Unable to convert from HashMap to DecryptedMca",
|
||||
)),
|
||||
)?,
|
||||
connector_wallets_details: hashmap.remove("connector_wallets_details"),
|
||||
additional_merchant_data: hashmap.remove("additional_merchant_data"),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_encryptable(self) -> FxHashMap<String, Secret<serde_json::Value>> {
|
||||
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
|
||||
|
||||
map.insert(
|
||||
"connector_account_details".to_string(),
|
||||
self.connector_account_details,
|
||||
);
|
||||
self.connector_wallets_details
|
||||
.map(|s| map.insert("connector_wallets_details".to_string(), s));
|
||||
self.additional_merchant_data
|
||||
.map(|s| map.insert("additional_merchant_data".to_string(), s));
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,11 +5,21 @@ use std::marker::PhantomData;
|
||||
use api_models::payments::Address;
|
||||
#[cfg(feature = "v2")]
|
||||
use api_models::payments::OrderDetailsWithAmount;
|
||||
use common_utils::{self, crypto::Encryptable, id_type, pii, types::MinorUnit};
|
||||
use common_utils::{
|
||||
self,
|
||||
crypto::Encryptable,
|
||||
encryption::Encryption,
|
||||
errors::CustomResult,
|
||||
id_type, pii,
|
||||
types::{keymanager::ToEncryptable, MinorUnit},
|
||||
};
|
||||
use diesel_models::payment_intent::TaxDetails;
|
||||
#[cfg(feature = "v2")]
|
||||
use error_stack::ResultExt;
|
||||
use masking::Secret;
|
||||
use router_derive::ToEncryption;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde_json::Value;
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
pub mod payment_attempt;
|
||||
@ -25,7 +35,7 @@ use crate::{business_profile, merchant_account};
|
||||
use crate::{errors, payment_method_data, ApiModelToDieselModelConvertor};
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
|
||||
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToEncryption)]
|
||||
pub struct PaymentIntent {
|
||||
pub payment_id: id_type::PaymentId,
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
@ -37,7 +47,7 @@ pub struct PaymentIntent {
|
||||
pub customer_id: Option<id_type::CustomerId>,
|
||||
pub description: Option<String>,
|
||||
pub return_url: Option<String>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
pub metadata: Option<Value>,
|
||||
pub connector_id: Option<String>,
|
||||
pub shipping_address_id: Option<String>,
|
||||
pub billing_address_id: Option<String>,
|
||||
@ -56,9 +66,9 @@ pub struct PaymentIntent {
|
||||
pub business_country: Option<storage_enums::CountryAlpha2>,
|
||||
pub business_label: Option<String>,
|
||||
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
|
||||
pub allowed_payment_method_types: Option<serde_json::Value>,
|
||||
pub connector_metadata: Option<serde_json::Value>,
|
||||
pub feature_metadata: Option<serde_json::Value>,
|
||||
pub allowed_payment_method_types: Option<Value>,
|
||||
pub connector_metadata: Option<Value>,
|
||||
pub feature_metadata: Option<Value>,
|
||||
pub attempt_count: i16,
|
||||
pub profile_id: Option<id_type::ProfileId>,
|
||||
pub payment_link_id: Option<String>,
|
||||
@ -78,10 +88,13 @@ 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>>>,
|
||||
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
|
||||
#[encrypt]
|
||||
pub customer_details: Option<Encryptable<Secret<Value>>>,
|
||||
#[encrypt]
|
||||
pub billing_details: Option<Encryptable<Secret<Value>>>,
|
||||
pub merchant_order_reference_id: Option<String>,
|
||||
pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
|
||||
#[encrypt]
|
||||
pub shipping_details: Option<Encryptable<Secret<Value>>>,
|
||||
pub is_payment_processor_token_flow: Option<bool>,
|
||||
pub organization_id: id_type::OrganizationId,
|
||||
pub tax_details: Option<TaxDetails>,
|
||||
@ -225,7 +238,7 @@ impl AmountDetails {
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
|
||||
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToEncryption)]
|
||||
pub struct PaymentIntent {
|
||||
/// The global identifier for the payment intent. This is generated by the system.
|
||||
/// The format of the global id is `{cell_id:5}_pay_{time_ordered_uuid:32}`.
|
||||
@ -292,19 +305,22 @@ pub struct PaymentIntent {
|
||||
/// Metadata related to fraud and risk management
|
||||
pub frm_metadata: Option<pii::SecretSerdeValue>,
|
||||
/// The details of the customer in a denormalized form. Only a subset of fields are stored.
|
||||
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
|
||||
#[encrypt]
|
||||
pub customer_details: Option<Encryptable<Secret<Value>>>,
|
||||
/// The reference id for the order in the merchant's system. This value can be passed by the merchant.
|
||||
pub merchant_reference_id: Option<id_type::PaymentReferenceId>,
|
||||
/// The billing address for the order in a denormalized form.
|
||||
#[encrypt(ty = Value)]
|
||||
pub billing_address: Option<Encryptable<Secret<Address>>>,
|
||||
/// The shipping address for the order in a denormalized form.
|
||||
#[encrypt(ty = Value)]
|
||||
pub shipping_address: Option<Encryptable<Secret<Address>>>,
|
||||
/// Capture method for the payment
|
||||
pub capture_method: storage_enums::CaptureMethod,
|
||||
/// Authentication type that is requested by the merchant for this payment.
|
||||
pub authentication_type: common_enums::AuthenticationType,
|
||||
/// This contains the pre routing results that are done when routing is done during listing the payment methods.
|
||||
pub prerouting_algorithm: Option<serde_json::Value>,
|
||||
pub prerouting_algorithm: Option<Value>,
|
||||
/// The organization id for the payment. This is derived from the merchant account
|
||||
pub organization_id: id_type::OrganizationId,
|
||||
/// Denotes the request by the merchant whether to enable a payment link for this payment.
|
||||
@ -323,7 +339,7 @@ pub struct PaymentIntent {
|
||||
impl PaymentIntent {
|
||||
fn get_request_incremental_authorization_value(
|
||||
request: &api_models::payments::PaymentsCreateIntentRequest,
|
||||
) -> common_utils::errors::CustomResult<
|
||||
) -> CustomResult<
|
||||
common_enums::RequestIncrementalAuthorization,
|
||||
errors::api_error_response::ApiErrorResponse,
|
||||
> {
|
||||
@ -364,8 +380,7 @@ impl PaymentIntent {
|
||||
request: api_models::payments::PaymentsCreateIntentRequest,
|
||||
billing_address: Option<Encryptable<Secret<Address>>>,
|
||||
shipping_address: Option<Encryptable<Secret<Address>>>,
|
||||
) -> common_utils::errors::CustomResult<Self, errors::api_error_response::ApiErrorResponse>
|
||||
{
|
||||
) -> CustomResult<Self, errors::api_error_response::ApiErrorResponse> {
|
||||
let allowed_payment_method_types = request
|
||||
.get_allowed_payment_method_types_as_value()
|
||||
.change_context(errors::api_error_response::ApiErrorResponse::InternalServerError)
|
||||
|
||||
@ -3,7 +3,7 @@ use common_enums as storage_enums;
|
||||
use common_utils::ext_traits::{Encode, ValueExt};
|
||||
use common_utils::{
|
||||
consts::{PAYMENTS_LIST_MAX_LIMIT_V1, PAYMENTS_LIST_MAX_LIMIT_V2},
|
||||
crypto::{self, Encryptable},
|
||||
crypto::Encryptable,
|
||||
encryption::Encryption,
|
||||
errors::{CustomResult, ValidationError},
|
||||
id_type,
|
||||
@ -21,7 +21,6 @@ use error_stack::ResultExt;
|
||||
#[cfg(feature = "v2")]
|
||||
use masking::ExposeInterface;
|
||||
use masking::{Deserialize, PeekInterface, Secret};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Serialize;
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
@ -1241,10 +1240,10 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
let decrypted_data = crypto_operation(
|
||||
state,
|
||||
type_name!(Self::DstType),
|
||||
CryptoOperation::BatchDecrypt(EncryptedPaymentIntentAddress::to_encryptable(
|
||||
EncryptedPaymentIntentAddress {
|
||||
billing: storage_model.billing_address,
|
||||
shipping: storage_model.shipping_address,
|
||||
CryptoOperation::BatchDecrypt(super::EncryptedPaymentIntent::to_encryptable(
|
||||
super::EncryptedPaymentIntent {
|
||||
billing_address: storage_model.billing_address,
|
||||
shipping_address: storage_model.shipping_address,
|
||||
customer_details: storage_model.customer_details,
|
||||
},
|
||||
)),
|
||||
@ -1254,7 +1253,7 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
.await
|
||||
.and_then(|val| val.try_into_batchoperation())?;
|
||||
|
||||
let data = EncryptedPaymentIntentAddress::from_encryptable(decrypted_data)
|
||||
let data = super::EncryptedPaymentIntent::from_encryptable(decrypted_data)
|
||||
.change_context(common_utils::errors::CryptoError::DecodingFailed)
|
||||
.attach_printable("Invalid batch operation data")?;
|
||||
|
||||
@ -1275,7 +1274,7 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
};
|
||||
|
||||
let billing_address = data
|
||||
.billing
|
||||
.billing_address
|
||||
.map(|billing| {
|
||||
billing.deserialize_inner_value(|value| value.parse_value("Address"))
|
||||
})
|
||||
@ -1284,7 +1283,7 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
.attach_printable("Error while deserializing Address")?;
|
||||
|
||||
let shipping_address = data
|
||||
.shipping
|
||||
.shipping_address
|
||||
.map(|shipping| {
|
||||
shipping.deserialize_inner_value(|value| value.parse_value("Address"))
|
||||
})
|
||||
@ -1513,10 +1512,10 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
let decrypted_data = crypto_operation(
|
||||
state,
|
||||
type_name!(Self::DstType),
|
||||
CryptoOperation::BatchDecrypt(EncryptedPaymentIntentAddress::to_encryptable(
|
||||
EncryptedPaymentIntentAddress {
|
||||
billing: storage_model.billing_details,
|
||||
shipping: storage_model.shipping_details,
|
||||
CryptoOperation::BatchDecrypt(super::EncryptedPaymentIntent::to_encryptable(
|
||||
super::EncryptedPaymentIntent {
|
||||
billing_details: storage_model.billing_details,
|
||||
shipping_details: storage_model.shipping_details,
|
||||
customer_details: storage_model.customer_details,
|
||||
},
|
||||
)),
|
||||
@ -1526,7 +1525,7 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
.await
|
||||
.and_then(|val| val.try_into_batchoperation())?;
|
||||
|
||||
let data = EncryptedPaymentIntentAddress::from_encryptable(decrypted_data)
|
||||
let data = super::EncryptedPaymentIntent::from_encryptable(decrypted_data)
|
||||
.change_context(common_utils::errors::CryptoError::DecodingFailed)
|
||||
.attach_printable("Invalid batch operation data")?;
|
||||
|
||||
@ -1578,9 +1577,9 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
shipping_cost: storage_model.shipping_cost,
|
||||
tax_details: storage_model.tax_details,
|
||||
customer_details: data.customer_details,
|
||||
billing_details: data.billing,
|
||||
billing_details: data.billing_details,
|
||||
merchant_order_reference_id: storage_model.merchant_order_reference_id,
|
||||
shipping_details: data.shipping,
|
||||
shipping_details: data.shipping_details,
|
||||
is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow,
|
||||
organization_id: storage_model.organization_id,
|
||||
skip_external_tax_calculation: storage_model.skip_external_tax_calculation,
|
||||
@ -1649,73 +1648,3 @@ impl behaviour::Conversion for PaymentIntent {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EncryptedPaymentIntentAddress {
|
||||
pub shipping: Option<Encryption>,
|
||||
pub billing: Option<Encryption>,
|
||||
pub customer_details: Option<Encryption>,
|
||||
}
|
||||
|
||||
pub struct PaymentAddressFromRequest {
|
||||
pub shipping: Option<Secret<serde_json::Value>>,
|
||||
pub billing: Option<Secret<serde_json::Value>>,
|
||||
pub customer_details: Option<Secret<serde_json::Value>>,
|
||||
}
|
||||
|
||||
pub struct DecryptedPaymentIntentAddress {
|
||||
pub shipping: crypto::OptionalEncryptableValue,
|
||||
pub billing: crypto::OptionalEncryptableValue,
|
||||
pub customer_details: crypto::OptionalEncryptableValue,
|
||||
}
|
||||
|
||||
impl ToEncryptable<DecryptedPaymentIntentAddress, Secret<serde_json::Value>, Encryption>
|
||||
for EncryptedPaymentIntentAddress
|
||||
{
|
||||
fn from_encryptable(
|
||||
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
|
||||
) -> CustomResult<DecryptedPaymentIntentAddress, common_utils::errors::ParsingError> {
|
||||
Ok(DecryptedPaymentIntentAddress {
|
||||
shipping: hashmap.remove("shipping"),
|
||||
billing: hashmap.remove("billing"),
|
||||
customer_details: hashmap.remove("customer_details"),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_encryptable(self) -> FxHashMap<String, Encryption> {
|
||||
let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
|
||||
|
||||
self.shipping.map(|s| map.insert("shipping".to_string(), s));
|
||||
self.billing.map(|s| map.insert("billing".to_string(), s));
|
||||
self.customer_details
|
||||
.map(|s| map.insert("customer_details".to_string(), s));
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
ToEncryptable<
|
||||
DecryptedPaymentIntentAddress,
|
||||
Secret<serde_json::Value>,
|
||||
Secret<serde_json::Value>,
|
||||
> for PaymentAddressFromRequest
|
||||
{
|
||||
fn from_encryptable(
|
||||
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
|
||||
) -> CustomResult<DecryptedPaymentIntentAddress, common_utils::errors::ParsingError> {
|
||||
Ok(DecryptedPaymentIntentAddress {
|
||||
shipping: hashmap.remove("shipping"),
|
||||
billing: hashmap.remove("billing"),
|
||||
customer_details: hashmap.remove("customer_details"),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_encryptable(self) -> FxHashMap<String, Secret<serde_json::Value>> {
|
||||
let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
|
||||
|
||||
self.shipping.map(|s| map.insert("shipping".to_string(), s));
|
||||
self.billing.map(|s| map.insert("billing".to_string(), s));
|
||||
self.customer_details
|
||||
.map(|s| map.insert("customer_details".to_string(), s));
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user