diff --git a/config/config.example.toml b/config/config.example.toml index 1f32481fec..cf6703f43d 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -734,6 +734,9 @@ connector_list = "" [recipient_emails] recon = "test@example.com" +[cell_information] +id = "12345" # Default CellID for Global Cell Information + [network_tokenization_supported_card_networks] card_networks = "Visa, AmericanExpress, Mastercard" # Supported card networks for network tokenization diff --git a/config/deployments/env_specific.toml b/config/deployments/env_specific.toml index 319cdafed1..db43cac979 100644 --- a/config/deployments/env_specific.toml +++ b/config/deployments/env_specific.toml @@ -302,6 +302,9 @@ public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "p [user_auth_methods] encryption_key = "user_auth_table_encryption_key" # Encryption key used for encrypting data in user_authentication_methods table +[cell_information] +id = "12345" # Default CellID for Global Cell Information + [network_tokenization_service] # Network Tokenization Service Configuration generate_token_url= "" # base url to generate token fetch_token_url= "" # base url to fetch token diff --git a/config/development.toml b/config/development.toml index 6e56d5bb14..29beed992f 100644 --- a/config/development.toml +++ b/config/development.toml @@ -735,6 +735,9 @@ encryption_key = "A8EF32E029BC3342E54BF2E172A4D7AA43E8EF9D2C3A624A9F04E2EF79DC69 [locker_based_open_banking_connectors] connector_list = "" +[cell_information] +id = "12345" + [network_tokenization_supported_card_networks] card_networks = "Visa, AmericanExpress, Mastercard" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index afde434f40..e196e123e8 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -137,8 +137,8 @@ ebanx.base_url = "https://sandbox.ebanxpay.com/" fiserv.base_url = "https://cert.api.fiservapps.com/" fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox" fiuu.base_url = "https://sandbox.merchant.razer.com/" -fiuu.secondary_base_url="https://sandbox.merchant.razer.com/" -fiuu.third_base_url="https://api.merchant.razer.com/" +fiuu.secondary_base_url = "https://sandbox.merchant.razer.com/" +fiuu.third_base_url = "https://api.merchant.razer.com/" forte.base_url = "https://sandbox.forte.net/api/v3" globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" globepay.base_url = "https://pay.globepay.co/" @@ -380,7 +380,7 @@ open_banking_uk = { country = "DE,GB,AT,BE,CY,EE,ES,FI,FR,GR,HR,IE,IT,LT,LU,LV,M upi_collect = { country = "IN", currency = "INR" } [pm_filters.plaid] -open_banking_pis = {currency = "EUR,GBP"} +open_banking_pis = { currency = "EUR,GBP" } [pm_filters.zen] credit = { not_available_flows = { capture_method = "manual" } } @@ -552,7 +552,7 @@ sdk_eligible_payment_methods = "card" [multitenancy] enabled = false -global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default"} +global_tenant = { schema = "public", redis_key_prefix = "", clickhouse_database = "default" } [multitenancy.tenants] public = { name = "hyperswitch", base_url = "http://localhost:8080", schema = "public", redis_key_prefix = "", clickhouse_database = "default" } @@ -592,6 +592,9 @@ ach = { country = "US", currency = "USD" } [locker_based_open_banking_connectors] connector_list = "" +[cell_information] +id = "12345" + [network_tokenization_supported_card_networks] card_networks = "Visa, AmericanExpress, Mastercard" diff --git a/crates/common_utils/src/id_type/global_id.rs b/crates/common_utils/src/id_type/global_id.rs index 5ed23a177b..c0b6384abc 100644 --- a/crates/common_utils/src/id_type/global_id.rs +++ b/crates/common_utils/src/id_type/global_id.rs @@ -63,27 +63,29 @@ impl From for CellIdError { impl CellId { /// Create a new cell id from a string - fn from_str(cell_id_string: &str) -> Result { - let trimmed_input_string = cell_id_string.trim().to_string(); + pub fn from_str(cell_id_string: impl AsRef) -> Result { + let trimmed_input_string = cell_id_string.as_ref().trim().to_string(); let alphanumeric_id = AlphaNumericId::from(trimmed_input_string.into())?; let length_id = LengthId::from_alphanumeric_id(alphanumeric_id)?; Ok(Self(length_id)) } - pub fn from_string(input_string: String) -> error_stack::Result { - Self::from_str(&input_string).change_context( - errors::ValidationError::IncorrectValueProvided { - field_name: "cell_id", - }, - ) - } - /// Get the string representation of the cell id fn get_string_repr(&self) -> &str { &self.0 .0 .0 } } +impl<'de> serde::Deserialize<'de> for CellId { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let deserialized_string = String::deserialize(deserializer)?; + Self::from_str(deserialized_string.as_str()).map_err(serde::de::Error::custom) + } +} + /// Error generated from violation of constraints for MerchantReferenceId #[derive(Debug, Error, PartialEq, Eq)] pub(crate) enum GlobalIdError { diff --git a/crates/common_utils/src/id_type/global_id/payment_methods.rs b/crates/common_utils/src/id_type/global_id/payment_methods.rs index 5ccb774f6e..3929efd09b 100644 --- a/crates/common_utils/src/id_type/global_id/payment_methods.rs +++ b/crates/common_utils/src/id_type/global_id/payment_methods.rs @@ -28,8 +28,10 @@ pub enum GlobalPaymentMethodIdError { impl GlobalPaymentMethodId { /// Create a new GlobalPaymentMethodId from celll id information - pub fn generate(cell_id: &str) -> error_stack::Result { - let cell_id = CellId::from_string(cell_id.to_string())?; + pub fn generate(cell_id: &str) -> error_stack::Result { + let cell_id = CellId::from_str(cell_id) + .change_context(GlobalPaymentMethodIdError::ConstructionError) + .attach_printable("Failed to construct CellId from str")?; let global_id = GlobalId::generate(cell_id, GlobalEntity::PaymentMethod); Ok(Self(global_id)) } diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index 442561c2ca..83d159f6d2 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -33,7 +33,7 @@ payouts = ["api_models/payouts", "common_enums/payouts", "hyperswitch_connectors payout_retry = ["payouts"] recon = ["email", "api_models/recon"] retry = [] -v2 = ["customer_v2", "payment_methods_v2", "payment_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2"] +v2 = ["customer_v2", "payment_methods_v2", "payment_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2"] v1 = ["common_default", "api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1"] customer_v2 = ["api_models/customer_v2", "diesel_models/customer_v2", "hyperswitch_domain_models/customer_v2", "storage_impl/customer_v2"] payment_v2 = ["api_models/payment_v2", "diesel_models/payment_v2", "hyperswitch_domain_models/payment_v2", "storage_impl/payment_v2"] diff --git a/crates/router/src/configs/secrets_transformers.rs b/crates/router/src/configs/secrets_transformers.rs index 8c893b8831..e1b68efc44 100644 --- a/crates/router/src/configs/secrets_transformers.rs +++ b/crates/router/src/configs/secrets_transformers.rs @@ -498,6 +498,8 @@ pub(crate) async fn fetch_raw_secrets( decision: conf.decision, locker_based_open_banking_connectors: conf.locker_based_open_banking_connectors, grpc_client: conf.grpc_client, + #[cfg(feature = "v2")] + cell_information: conf.cell_information, network_tokenization_supported_card_networks: conf .network_tokenization_supported_card_networks, network_tokenization_service, diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index 675b8c44e2..0a7defc406 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -122,6 +122,8 @@ pub struct Settings { pub decision: Option, pub locker_based_open_banking_connectors: LockerBasedRecipientConnectorList, pub grpc_client: GrpcClientSettings, + #[cfg(feature = "v2")] + pub cell_information: CellInformation, pub network_tokenization_supported_card_networks: NetworkTokenizationSupportedCardNetworks, pub network_tokenization_service: Option>, pub network_tokenization_supported_connectors: NetworkTokenizationSupportedConnectors, @@ -854,6 +856,8 @@ impl Settings { self.generic_link.payment_method_collect.validate()?; self.generic_link.payout_link.validate()?; + #[cfg(feature = "v2")] + self.cell_information.validate()?; self.network_tokenization_service .as_ref() .map(|x| x.get_inner().validate()) @@ -940,6 +944,26 @@ pub struct ServerTls { pub certificate: PathBuf, } +#[cfg(feature = "v2")] +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +pub struct CellInformation { + pub id: common_utils::id_type::CellId, +} + +#[cfg(feature = "v2")] +impl Default for CellInformation { + fn default() -> Self { + // We provide a static default cell id for constructing application settings. + // This will only panic at application startup if we're unable to construct the default, + // around the time of deserializing application settings. + // And a panic at application startup is considered acceptable. + #[allow(clippy::expect_used)] + let cell_id = common_utils::id_type::CellId::from_str("defid") + .expect("Failed to create a default for Cell Id"); + Self { id: cell_id } + } +} + fn deserialize_hashmap_inner( value: HashMap, ) -> Result>, String> diff --git a/crates/router/src/configs/validations.rs b/crates/router/src/configs/validations.rs index 67db7b1266..7736d7b3f3 100644 --- a/crates/router/src/configs/validations.rs +++ b/crates/router/src/configs/validations.rs @@ -193,6 +193,19 @@ impl super::settings::GenericLinkEnvConfig { } } +#[cfg(feature = "v2")] +impl super::settings::CellInformation { + pub fn validate(&self) -> Result<(), ApplicationError> { + use common_utils::{fp_utils::when, id_type}; + + when(self == &super::settings::CellInformation::default(), || { + Err(ApplicationError::InvalidConfigurationValueError( + "CellId cannot be set to a default".into(), + )) + }) + } +} + impl super::settings::NetworkTokenizationService { pub fn validate(&self) -> Result<(), ApplicationError> { use common_utils::fp_utils::when;