From b6c81ec086343d3a130d3a90d8674944037c2cd3 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 02:03:40 +0530 Subject: [PATCH 01/10] refactor(business_profile): wrap `webhook_details`, `payment_link_config` and `payout_link_config` fields within `Secret` in diesel and domain models This also requires the `webhook_details` field in merchant account to be wrapped within `Secret`. --- crates/api_models/src/admin.rs | 8 +++---- crates/diesel_models/src/business_profile.rs | 24 +++++++++---------- crates/diesel_models/src/merchant_account.rs | 14 +++++------ .../src/business_profile.rs | 12 +++++----- .../src/merchant_account.rs | 10 ++++---- crates/router/src/core/admin.rs | 12 ++++++---- crates/router/src/core/payment_link.rs | 2 +- crates/router/src/types/api/admin.rs | 11 +++++---- 8 files changed, 50 insertions(+), 43 deletions(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index c80a188534f6..5f5d08a20443 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -169,10 +169,10 @@ impl MerchantAccountCreate { pub fn get_webhook_details_as_value( &self, - ) -> CustomResult, errors::ParsingError> { + ) -> CustomResult, errors::ParsingError> { self.webhook_details .as_ref() - .map(|webhook_details| webhook_details.encode_to_value()) + .map(|webhook_details| webhook_details.encode_to_value().map(Secret::new)) .transpose() } @@ -375,7 +375,7 @@ pub struct MerchantAccountResponse { /// Webhook related details #[schema(value_type = Option)] - pub webhook_details: Option, + pub webhook_details: Option>, /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[serde(skip)] @@ -1874,7 +1874,7 @@ pub struct BusinessProfileResponse { pub session_expiry: Option, /// Default Payment Link config for all payment links created under this business profile - pub payment_link_config: Option, + pub payment_link_config: Option>, /// External 3DS authentication details pub authentication_connector_details: Option, diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index cc4dbe6b605e..620a861807b6 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -41,7 +41,7 @@ pub struct BusinessProfile { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -50,10 +50,10 @@ pub struct BusinessProfile { pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -79,7 +79,7 @@ pub struct BusinessProfileNew { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -88,10 +88,10 @@ pub struct BusinessProfileNew { pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -114,7 +114,7 @@ pub struct BusinessProfileUpdateInternal { pub enable_payment_response_hash: Option, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -123,10 +123,10 @@ pub struct BusinessProfileUpdateInternal { pub is_recon_enabled: Option, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -148,7 +148,7 @@ pub enum BusinessProfileUpdate { enable_payment_response_hash: Option, payment_response_hash_key: Option, redirect_to_merchant_with_http_post: Option, - webhook_details: Option, + webhook_details: Option, metadata: Option, routing_algorithm: Option, intent_fulfillment_time: Option, @@ -156,10 +156,10 @@ pub enum BusinessProfileUpdate { payout_routing_algorithm: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, - payment_link_config: Option, + payment_link_config: Option, session_expiry: Option, authentication_connector_details: Option, - payout_link_config: Option, + payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, collect_shipping_details_from_wallet_connector: Option, diff --git a/crates/diesel_models/src/merchant_account.rs b/crates/diesel_models/src/merchant_account.rs index 3aa4088f3b07..a8924c53ed59 100644 --- a/crates/diesel_models/src/merchant_account.rs +++ b/crates/diesel_models/src/merchant_account.rs @@ -36,7 +36,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -70,7 +70,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -152,7 +152,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -219,7 +219,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -268,7 +268,7 @@ pub struct MerchantAccountNew { pub merchant_name: Option, pub merchant_details: Option, pub return_url: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub enable_payment_response_hash: Option, @@ -299,7 +299,7 @@ pub struct MerchantAccountNew { pub merchant_name: Option, pub merchant_details: Option, pub return_url: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub enable_payment_response_hash: Option, @@ -330,7 +330,7 @@ pub struct MerchantAccountUpdateInternal { pub merchant_name: Option, pub merchant_details: Option, pub return_url: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub enable_payment_response_hash: Option, diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs index e6b2bcbe5b11..0be4a0262750 100644 --- a/crates/hyperswitch_domain_models/src/business_profile.rs +++ b/crates/hyperswitch_domain_models/src/business_profile.rs @@ -29,7 +29,7 @@ pub struct BusinessProfile { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -37,10 +37,10 @@ pub struct BusinessProfile { pub payout_routing_algorithm: Option, pub is_recon_enabled: bool, pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -62,7 +62,7 @@ pub enum BusinessProfileUpdate { enable_payment_response_hash: Option, payment_response_hash_key: Option, redirect_to_merchant_with_http_post: Option, - webhook_details: Option, + webhook_details: Option, metadata: Option, routing_algorithm: Option, intent_fulfillment_time: Option, @@ -70,10 +70,10 @@ pub enum BusinessProfileUpdate { payout_routing_algorithm: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, - payment_link_config: Option, + payment_link_config: Option, session_expiry: Option, authentication_connector_details: Option, - payout_link_config: Option, + payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, collect_shipping_details_from_wallet_connector: Option, diff --git a/crates/hyperswitch_domain_models/src/merchant_account.rs b/crates/hyperswitch_domain_models/src/merchant_account.rs index ce11cd566c61..ca414918a0bb 100644 --- a/crates/hyperswitch_domain_models/src/merchant_account.rs +++ b/crates/hyperswitch_domain_models/src/merchant_account.rs @@ -29,7 +29,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -65,7 +65,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -136,7 +136,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -203,7 +203,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -249,7 +249,7 @@ pub enum MerchantAccountUpdate { merchant_name: OptionalEncryptableName, merchant_details: OptionalEncryptableValue, return_url: Option, - webhook_details: Option, + webhook_details: Option, sub_merchants_enabled: Option, parent_merchant_id: Option, enable_payment_response_hash: Option, diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index a85cb1f8faea..8096d073c21d 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1034,7 +1034,8 @@ pub async fn merchant_account_update( .as_ref() .map(Encode::encode_to_value) .transpose() - .change_context(errors::ApiErrorResponse::InternalServerError)?, + .change_context(errors::ApiErrorResponse::InternalServerError)? + .map(Secret::new), routing_algorithm: req.routing_algorithm, sub_merchants_enabled: req.sub_merchants_enabled, @@ -3363,7 +3364,8 @@ pub async fn update_business_profile( }, ) }) - .transpose()?; + .transpose()? + .map(Secret::new); if let Some(ref routing_algorithm) = request.routing_algorithm { let _: api_models::routing::RoutingAlgorithm = routing_algorithm @@ -3388,7 +3390,8 @@ pub async fn update_business_profile( message: e.to_string() })), }) - .transpose()?; + .transpose()? + .map(Secret::new); let extended_card_info_config = request .extended_card_info_config @@ -3423,7 +3426,8 @@ pub async fn update_business_profile( message: e.to_string() })), }) - .transpose()?; + .transpose()? + .map(Secret::new); let business_profile_update = storage::business_profile::BusinessProfileUpdate::Update { profile_name: request.profile_name, diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index ef39a34a11e6..4c4403f30808 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -526,7 +526,7 @@ pub fn extract_payment_link_config( pub fn get_payment_link_config_based_on_priority( payment_create_link_config: Option, - business_link_config: Option, + business_link_config: Option>, merchant_name: String, default_domain_name: String, payment_link_config_id: Option, diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs index acbca54f4b1b..767febdb7df8 100644 --- a/crates/router/src/types/api/admin.rs +++ b/crates/router/src/types/api/admin.rs @@ -145,7 +145,7 @@ pub async fn business_profile_response( enable_payment_response_hash: item.enable_payment_response_hash, payment_response_hash_key: item.payment_response_hash_key, redirect_to_merchant_with_http_post: item.redirect_to_merchant_with_http_post, - webhook_details: item.webhook_details.map(Secret::new), + webhook_details: item.webhook_details, metadata: item.metadata, routing_algorithm: item.routing_algorithm, intent_fulfillment_time: item.intent_fulfillment_time, @@ -205,7 +205,8 @@ pub async fn create_business_profile( }, ) }) - .transpose()?; + .transpose()? + .map(Secret::new); let payment_response_hash_key = request .payment_response_hash_key @@ -221,7 +222,8 @@ pub async fn create_business_profile( field_name: "payment_link_config_value", }) }) - .transpose()?; + .transpose()? + .map(Secret::new); let outgoing_webhook_custom_http_headers = request .outgoing_webhook_custom_http_headers .async_map(|headers| create_encrypted_data(state, key_store, headers)) @@ -243,7 +245,8 @@ pub async fn create_business_profile( message: e.to_string() })), }) - .transpose()?; + .transpose()? + .map(Secret::new); Ok(storage::business_profile::BusinessProfileNew { profile_id, From 3ab4f2cf6800767ca83c630516af789dc789b6d1 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 02:06:18 +0530 Subject: [PATCH 02/10] refactor(business_profile): remove `Secret` wrapper around `authentication_connector_details` in v2 diesel and domain models --- crates/diesel_models/src/business_profile.rs | 8 ++++---- crates/hyperswitch_domain_models/src/business_profile.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 620a861807b6..9b653939e6c7 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -489,7 +489,7 @@ pub struct BusinessProfile { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -526,7 +526,7 @@ pub struct BusinessProfileNew { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -560,7 +560,7 @@ pub struct BusinessProfileUpdateInternal { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -592,7 +592,7 @@ pub enum BusinessProfileUpdate { applepay_verified_domains: Option>, payment_link_config: Option, session_expiry: Option, - authentication_connector_details: Option, + authentication_connector_details: Option, payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs index 0be4a0262750..f34558365278 100644 --- a/crates/hyperswitch_domain_models/src/business_profile.rs +++ b/crates/hyperswitch_domain_models/src/business_profile.rs @@ -402,7 +402,7 @@ pub struct BusinessProfile { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -434,7 +434,7 @@ pub enum BusinessProfileUpdate { applepay_verified_domains: Option>, payment_link_config: Option, session_expiry: Option, - authentication_connector_details: Option, + authentication_connector_details: Option, payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, From f9f903e9bd6cbdfa67dfbb230bccae7b8a6537dc Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 03:27:35 +0530 Subject: [PATCH 03/10] fix: fix issues with OpenAPI spec generation --- api-reference/openapi_spec.json | 1 + crates/api_models/src/admin.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 040df7d84f04..1ee0e8a9c280 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -7265,6 +7265,7 @@ "nullable": true }, "payment_link_config": { + "type": "object", "description": "Default Payment Link config for all payment links created under this business profile", "nullable": true }, diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 5f5d08a20443..b4fd34b6e2a2 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -1874,6 +1874,7 @@ pub struct BusinessProfileResponse { pub session_expiry: Option, /// Default Payment Link config for all payment links created under this business profile + #[schema(value_type = Option)] pub payment_link_config: Option>, /// External 3DS authentication details From e28ba0d291beef88d043e62bb70cae66113b8336 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 14:50:46 +0530 Subject: [PATCH 04/10] refactor(business_profile): remove `Serialize` and `Deserialize` derives on diesel models --- crates/diesel_models/src/business_profile.rs | 22 ++------------------ 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 9b653939e6c7..88f98840c487 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -20,16 +20,7 @@ use crate::schema_v2::business_profile; any(feature = "v1", feature = "v2"), not(feature = "business_profile_v2") ))] -#[derive( - Clone, - Debug, - serde::Deserialize, - serde::Serialize, - Identifiable, - Queryable, - Selectable, - router_derive::DebugAsDisplay, -)] +#[derive(Clone, Debug, Identifiable, Queryable, Selectable, router_derive::DebugAsDisplay)] #[diesel(table_name = business_profile, primary_key(profile_id), check_for_backend(diesel::pg::Pg))] pub struct BusinessProfile { pub profile_id: String, @@ -461,16 +452,7 @@ impl BusinessProfileUpdate { /// If two adjacent columns have the same type, then the compiler will not throw any error, but the /// fields read / written will be interchanged #[cfg(all(feature = "v2", feature = "business_profile_v2"))] -#[derive( - Clone, - Debug, - serde::Deserialize, - serde::Serialize, - Identifiable, - Queryable, - Selectable, - router_derive::DebugAsDisplay, -)] +#[derive(Clone, Debug, Identifiable, Queryable, Selectable, router_derive::DebugAsDisplay)] #[diesel(table_name = business_profile, primary_key(profile_id), check_for_backend(diesel::pg::Pg))] pub struct BusinessProfile { pub profile_id: String, From a529eb44c4acc9bcbb276c9fdababdaca5487645 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 14:54:10 +0530 Subject: [PATCH 05/10] refactor(business_profile): copy `AuthenticationConnectorDetails` to `diesel_models` --- crates/api_models/src/admin.rs | 2 +- crates/api_models/src/enums.rs | 30 ------------------- crates/common_enums/src/enums.rs | 30 +++++++++++++++++++ crates/common_enums/src/lib.rs | 3 +- crates/diesel_models/src/business_profile.rs | 9 ++++++ .../router/src/core/authentication/utils.rs | 2 +- 6 files changed, 43 insertions(+), 33 deletions(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index b4fd34b6e2a2..09b74158723a 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -248,7 +248,7 @@ impl MerchantAccountCreate { pub struct AuthenticationConnectorDetails { /// List of authentication connectors #[schema(value_type = Vec)] - pub authentication_connectors: Vec, + pub authentication_connectors: Vec, /// URL of the (customer service) website that will be shown to the shopper in case of technical errors during the 3D Secure 2 process. pub three_ds_requestor_url: String, } diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index f04053767395..00c2f84f8927 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -303,36 +303,6 @@ impl Connector { } } -#[derive( - Clone, - Copy, - Debug, - Eq, - Hash, - PartialEq, - serde::Serialize, - serde::Deserialize, - strum::Display, - strum::EnumString, - ToSchema, -)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum AuthenticationConnectors { - Threedsecureio, - Netcetera, - Gpayments, -} - -impl AuthenticationConnectors { - pub fn is_separate_version_call_required(&self) -> bool { - match self { - Self::Threedsecureio | Self::Netcetera => false, - Self::Gpayments => true, - } - } -} - #[cfg(feature = "payouts")] #[derive( Clone, diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 6ec400ec81c4..e3017a740451 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -2517,6 +2517,36 @@ pub enum ReconStatus { Disabled, } +#[derive( + Clone, + Copy, + Debug, + Eq, + Hash, + PartialEq, + serde::Serialize, + serde::Deserialize, + strum::Display, + strum::EnumString, + ToSchema, +)] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum AuthenticationConnectors { + Threedsecureio, + Netcetera, + Gpayments, +} + +impl AuthenticationConnectors { + pub fn is_separate_version_call_required(&self) -> bool { + match self { + Self::Threedsecureio | Self::Netcetera => false, + Self::Gpayments => true, + } + } +} + #[derive( Clone, Debug, diff --git a/crates/common_enums/src/lib.rs b/crates/common_enums/src/lib.rs index b2dce21d2e66..14966d15b5f5 100644 --- a/crates/common_enums/src/lib.rs +++ b/crates/common_enums/src/lib.rs @@ -1,4 +1,5 @@ pub mod enums; -pub use enums::*; pub mod transformers; + +pub use enums::*; pub use transformers::*; diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 88f98840c487..b94159b52278 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -1,3 +1,4 @@ +use common_enums::AuthenticationConnectors; #[cfg(all(feature = "v2", feature = "business_profile_v2"))] use common_enums::OrderFulfillmentTimeOrigin; use common_utils::{encryption::Encryption, pii}; @@ -885,3 +886,11 @@ impl From for BusinessProfile { } } } + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +pub struct AuthenticationConnectorDetails { + pub authentication_connectors: Vec, + pub three_ds_requestor_url: String, +} + +common_utils::impl_to_sql_from_sql_json!(AuthenticationConnectorDetails); diff --git a/crates/router/src/core/authentication/utils.rs b/crates/router/src/core/authentication/utils.rs index 0ed55999831d..5d94ea77cd6d 100644 --- a/crates/router/src/core/authentication/utils.rs +++ b/crates/router/src/core/authentication/utils.rs @@ -269,7 +269,7 @@ pub async fn get_authentication_connector_data( key_store: &domain::MerchantKeyStore, business_profile: &storage::BusinessProfile, ) -> RouterResult<( - api_models::enums::AuthenticationConnectors, + common_enums::AuthenticationConnectors, payments::helpers::MerchantConnectorAccountType, )> { let authentication_details: api_models::admin::AuthenticationConnectorDetails = From 2b39faed52a9d6a3647eb8aa249190c17e817a74 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 15:57:16 +0530 Subject: [PATCH 06/10] refactor(business_profile): use `AuthenticationConnectorDetails` instead of `serde_json::Value` for `authentication_connector_details` in diesel and domain models --- crates/diesel_models/src/business_profile.rs | 19 ++++++++------- .../src/business_profile.rs | 12 ++++++---- crates/router/src/core/admin.rs | 9 ++----- .../router/src/core/authentication/utils.rs | 24 +++++++------------ crates/router/src/core/payments.rs | 18 ++++---------- crates/router/src/types/api/admin.rs | 18 ++++++-------- crates/router/src/types/transformers.rs | 22 +++++++++++++++++ 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index b94159b52278..d64457a0c2ce 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -44,7 +44,7 @@ pub struct BusinessProfile { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -82,7 +82,7 @@ pub struct BusinessProfileNew { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -117,7 +117,7 @@ pub struct BusinessProfileUpdateInternal { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -150,7 +150,7 @@ pub enum BusinessProfileUpdate { applepay_verified_domains: Option>, payment_link_config: Option, session_expiry: Option, - authentication_connector_details: Option, + authentication_connector_details: Option, payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, @@ -472,7 +472,7 @@ pub struct BusinessProfile { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -509,7 +509,7 @@ pub struct BusinessProfileNew { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -543,7 +543,7 @@ pub struct BusinessProfileUpdateInternal { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -575,7 +575,7 @@ pub enum BusinessProfileUpdate { applepay_verified_domains: Option>, payment_link_config: Option, session_expiry: Option, - authentication_connector_details: Option, + authentication_connector_details: Option, payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, @@ -887,7 +887,8 @@ impl From for BusinessProfile { } } -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, diesel::AsExpression)] +#[diesel(sql_type = diesel::sql_types::Jsonb)] pub struct AuthenticationConnectorDetails { pub authentication_connectors: Vec, pub three_ds_requestor_url: String, diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs index f34558365278..c8e757706e35 100644 --- a/crates/hyperswitch_domain_models/src/business_profile.rs +++ b/crates/hyperswitch_domain_models/src/business_profile.rs @@ -8,7 +8,9 @@ use common_utils::{ pii, types::keymanager, }; -use diesel_models::business_profile::BusinessProfileUpdateInternal; +use diesel_models::business_profile::{ + AuthenticationConnectorDetails, BusinessProfileUpdateInternal, +}; use error_stack::ResultExt; use masking::{PeekInterface, Secret}; @@ -39,7 +41,7 @@ pub struct BusinessProfile { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -72,7 +74,7 @@ pub enum BusinessProfileUpdate { applepay_verified_domains: Option>, payment_link_config: Option, session_expiry: Option, - authentication_connector_details: Option, + authentication_connector_details: Option, payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, @@ -402,7 +404,7 @@ pub struct BusinessProfile { pub applepay_verified_domains: Option>, pub payment_link_config: Option, pub session_expiry: Option, - pub authentication_connector_details: Option, + pub authentication_connector_details: Option, pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, @@ -434,7 +436,7 @@ pub enum BusinessProfileUpdate { applepay_verified_domains: Option>, payment_link_config: Option, session_expiry: Option, - authentication_connector_details: Option, + authentication_connector_details: Option, payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 8096d073c21d..286508c4149e 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -49,7 +49,7 @@ use crate::{ types::{self as domain_types, AsyncLift}, }, storage::{self, enums::MerchantStorageScheme}, - transformers::{ForeignTryFrom, ForeignTryInto}, + transformers::{ForeignInto, ForeignTryFrom, ForeignTryInto}, }, utils, }; @@ -3450,12 +3450,7 @@ pub async fn update_business_profile( session_expiry: request.session_expiry.map(i64::from), authentication_connector_details: request .authentication_connector_details - .as_ref() - .map(Encode::encode_to_value) - .transpose() - .change_context(errors::ApiErrorResponse::InvalidDataValue { - field_name: "authentication_connector_details", - })?, + .map(ForeignInto::foreign_into), payout_link_config, extended_card_info_config, use_billing_as_payment_method_billing: request.use_billing_as_payment_method_billing, diff --git a/crates/router/src/core/authentication/utils.rs b/crates/router/src/core/authentication/utils.rs index 5d94ea77cd6d..ebfa60374761 100644 --- a/crates/router/src/core/authentication/utils.rs +++ b/crates/router/src/core/authentication/utils.rs @@ -1,4 +1,3 @@ -use common_utils::ext_traits::ValueExt; use error_stack::ResultExt; use hyperswitch_domain_models::router_data_v2::ExternalAuthenticationFlowData; @@ -272,21 +271,14 @@ pub async fn get_authentication_connector_data( common_enums::AuthenticationConnectors, payments::helpers::MerchantConnectorAccountType, )> { - let authentication_details: api_models::admin::AuthenticationConnectorDetails = - business_profile - .authentication_connector_details - .clone() - .get_required_value("authentication_details") - .change_context(errors::ApiErrorResponse::UnprocessableEntity { - message: "authentication_connector_details is not available in business profile" - .into(), - }) - .attach_printable("authentication_connector_details not configured by the merchant")? - .parse_value("AuthenticationConnectorDetails") - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable( - "Error while parsing authentication_connector_details from business_profile", - )?; + let authentication_details = business_profile + .authentication_connector_details + .clone() + .get_required_value("authentication_details") + .change_context(errors::ApiErrorResponse::UnprocessableEntity { + message: "authentication_connector_details is not available in business profile".into(), + }) + .attach_printable("authentication_connector_details not configured by the merchant")?; let authentication_connector = authentication_details .authentication_connectors .first() diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 78d0d8fd79d3..79cbeccdf2e1 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -4161,19 +4161,11 @@ pub async fn payment_external_authentication( id: profile_id.to_string(), })?; - let authentication_details: api_models::admin::AuthenticationConnectorDetails = - business_profile - .authentication_connector_details - .clone() - .get_required_value("authentication_connector_details") - .attach_printable("authentication_connector_details not configured by the merchant")? - .parse_value("AuthenticationConnectorDetails") - .change_context(errors::ApiErrorResponse::UnprocessableEntity { - message: "Invalid data format found for authentication_connector_details".into(), - }) - .attach_printable( - "Error while parsing authentication_connector_details from business_profile", - )?; + let authentication_details = business_profile + .authentication_connector_details + .clone() + .get_required_value("authentication_connector_details") + .attach_printable("authentication_connector_details not configured by the merchant")?; let authentication_response = Box::pin(authentication_core::perform_authentication( &state, diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs index 767febdb7df8..7553854a1d59 100644 --- a/crates/router/src/types/api/admin.rs +++ b/crates/router/src/types/api/admin.rs @@ -25,7 +25,11 @@ use masking::{ExposeInterface, PeekInterface, Secret}; use crate::{ core::{errors, payment_methods::cards::create_encrypted_data}, routes::SessionState, - types::{domain, storage, transformers::ForeignTryFrom, ForeignFrom}, + types::{ + domain, storage, + transformers::{ForeignInto, ForeignTryFrom}, + ForeignFrom, + }, }; impl ForeignFrom for OrganizationResponse { @@ -157,10 +161,7 @@ pub async fn business_profile_response( session_expiry: item.session_expiry, authentication_connector_details: item .authentication_connector_details - .map(|authentication_connector_details| { - authentication_connector_details.parse_value("AuthenticationDetails") - }) - .transpose()?, + .map(ForeignInto::foreign_into), payout_link_config: item .payout_link_config .map(|payout_link_config| payout_link_config.parse_value("BusinessPayoutLinkConfig")) @@ -294,12 +295,7 @@ pub async fn create_business_profile( .or(Some(common_utils::consts::DEFAULT_SESSION_EXPIRY)), authentication_connector_details: request .authentication_connector_details - .as_ref() - .map(Encode::encode_to_value) - .transpose() - .change_context(errors::ApiErrorResponse::InvalidDataValue { - field_name: "authentication_connector_details", - })?, + .map(ForeignInto::foreign_into), payout_link_config, is_connector_agnostic_mit_enabled: request.is_connector_agnostic_mit_enabled, is_extended_card_info_enabled: None, diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index d25d9e9c39d1..113a6beb64c0 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -1622,3 +1622,25 @@ impl TryFrom for api_models::webhook_events::EventRetrieveRespons }) } } + +impl ForeignFrom + for diesel_models::business_profile::AuthenticationConnectorDetails +{ + fn foreign_from(item: api_models::admin::AuthenticationConnectorDetails) -> Self { + Self { + authentication_connectors: item.authentication_connectors, + three_ds_requestor_url: item.three_ds_requestor_url, + } + } +} + +impl ForeignFrom + for api_models::admin::AuthenticationConnectorDetails +{ + fn foreign_from(item: diesel_models::business_profile::AuthenticationConnectorDetails) -> Self { + Self { + authentication_connectors: item.authentication_connectors, + three_ds_requestor_url: item.three_ds_requestor_url, + } + } +} From abee7ad62d1cf2098855bf85d34d65d2d083b3cc Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Tue, 6 Aug 2024 20:17:41 +0530 Subject: [PATCH 07/10] refactor(business_profile): use `WebhookDetails` instead of `serde_json::Value` for `webhook_details` in diesel and domain models --- crates/api_models/src/admin.rs | 15 ++------- crates/diesel_models/src/business_profile.rs | 31 +++++++++++++----- crates/diesel_models/src/merchant_account.rs | 16 +++++----- .../src/business_profile.rs | 10 +++--- .../src/merchant_account.rs | 13 ++++---- crates/router/src/core/admin.rs | 27 ++-------------- crates/router/src/core/webhooks/outgoing.rs | 7 +--- crates/router/src/types/api/admin.rs | 17 ++-------- crates/router/src/types/transformers.rs | 32 +++++++++++++++++++ 9 files changed, 84 insertions(+), 84 deletions(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 09b74158723a..78650a2434c4 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -167,15 +167,6 @@ impl MerchantAccountCreate { .transpose() } - pub fn get_webhook_details_as_value( - &self, - ) -> CustomResult, errors::ParsingError> { - self.webhook_details - .as_ref() - .map(|webhook_details| webhook_details.encode_to_value().map(Secret::new)) - .transpose() - } - pub fn parse_routing_algorithm(&self) -> CustomResult<(), errors::ParsingError> { match self.routing_algorithm { Some(ref routing_algorithm) => { @@ -374,8 +365,7 @@ pub struct MerchantAccountResponse { pub merchant_details: Option>, /// Webhook related details - #[schema(value_type = Option)] - pub webhook_details: Option>, + pub webhook_details: Option, /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[serde(skip)] @@ -1842,8 +1832,7 @@ pub struct BusinessProfileResponse { pub redirect_to_merchant_with_http_post: bool, /// Webhook related details - #[schema(value_type = Option)] - pub webhook_details: Option, + pub webhook_details: Option, /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. #[schema(value_type = Option, example = r#"{ "city": "NY", "unit": "245" }"#)] diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index d64457a0c2ce..41332ec35503 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -3,6 +3,7 @@ use common_enums::AuthenticationConnectors; use common_enums::OrderFulfillmentTimeOrigin; use common_utils::{encryption::Encryption, pii}; use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable}; +use masking::Secret; #[cfg(all( any(feature = "v1", feature = "v2"), @@ -33,7 +34,7 @@ pub struct BusinessProfile { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -71,7 +72,7 @@ pub struct BusinessProfileNew { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -106,7 +107,7 @@ pub struct BusinessProfileUpdateInternal { pub enable_payment_response_hash: Option, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -140,7 +141,7 @@ pub enum BusinessProfileUpdate { enable_payment_response_hash: Option, payment_response_hash_key: Option, redirect_to_merchant_with_http_post: Option, - webhook_details: Option, + webhook_details: Option, metadata: Option, routing_algorithm: Option, intent_fulfillment_time: Option, @@ -465,7 +466,7 @@ pub struct BusinessProfile { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] @@ -502,7 +503,7 @@ pub struct BusinessProfileNew { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] @@ -536,7 +537,7 @@ pub struct BusinessProfileUpdateInternal { pub enable_payment_response_hash: Option, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub is_recon_enabled: Option, #[diesel(deserialize_as = super::OptionalDieselArray)] @@ -569,7 +570,7 @@ pub enum BusinessProfileUpdate { enable_payment_response_hash: Option, payment_response_hash_key: Option, redirect_to_merchant_with_http_post: Option, - webhook_details: Option, + webhook_details: Option, metadata: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, @@ -895,3 +896,17 @@ pub struct AuthenticationConnectorDetails { } common_utils::impl_to_sql_from_sql_json!(AuthenticationConnectorDetails); + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, diesel::AsExpression)] +#[diesel(sql_type = diesel::sql_types::Json)] +pub struct WebhookDetails { + pub webhook_version: Option, + pub webhook_username: Option, + pub webhook_password: Option>, + pub webhook_url: Option>, + pub payment_created_enabled: Option, + pub payment_succeeded_enabled: Option, + pub payment_failed_enabled: Option, +} + +common_utils::impl_to_sql_from_sql_json!(WebhookDetails); diff --git a/crates/diesel_models/src/merchant_account.rs b/crates/diesel_models/src/merchant_account.rs index a8924c53ed59..dd830f204348 100644 --- a/crates/diesel_models/src/merchant_account.rs +++ b/crates/diesel_models/src/merchant_account.rs @@ -1,7 +1,6 @@ use common_utils::{encryption::Encryption, pii}; use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable}; -use crate::enums as storage_enums; #[cfg(all( any(feature = "v1", feature = "v2"), not(feature = "merchant_account_v2") @@ -9,6 +8,7 @@ use crate::enums as storage_enums; use crate::schema::merchant_account; #[cfg(all(feature = "v2", feature = "merchant_account_v2"))] use crate::schema_v2::merchant_account; +use crate::{business_profile::WebhookDetails, enums as storage_enums}; /// Note: The order of fields in the struct is important. /// This should be in the same order as the fields in the schema.rs file, otherwise the code will not compile @@ -36,7 +36,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -70,7 +70,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -152,7 +152,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -219,7 +219,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: Option, pub merchant_details: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: Option, @@ -268,7 +268,7 @@ pub struct MerchantAccountNew { pub merchant_name: Option, pub merchant_details: Option, pub return_url: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub enable_payment_response_hash: Option, @@ -299,7 +299,7 @@ pub struct MerchantAccountNew { pub merchant_name: Option, pub merchant_details: Option, pub return_url: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub enable_payment_response_hash: Option, @@ -330,7 +330,7 @@ pub struct MerchantAccountUpdateInternal { pub merchant_name: Option, pub merchant_details: Option, pub return_url: Option, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub enable_payment_response_hash: Option, diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs index c8e757706e35..ae52c33add02 100644 --- a/crates/hyperswitch_domain_models/src/business_profile.rs +++ b/crates/hyperswitch_domain_models/src/business_profile.rs @@ -9,7 +9,7 @@ use common_utils::{ types::keymanager, }; use diesel_models::business_profile::{ - AuthenticationConnectorDetails, BusinessProfileUpdateInternal, + AuthenticationConnectorDetails, BusinessProfileUpdateInternal, WebhookDetails, }; use error_stack::ResultExt; use masking::{PeekInterface, Secret}; @@ -31,7 +31,7 @@ pub struct BusinessProfile { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub routing_algorithm: Option, pub intent_fulfillment_time: Option, @@ -64,7 +64,7 @@ pub enum BusinessProfileUpdate { enable_payment_response_hash: Option, payment_response_hash_key: Option, redirect_to_merchant_with_http_post: Option, - webhook_details: Option, + webhook_details: Option, metadata: Option, routing_algorithm: Option, intent_fulfillment_time: Option, @@ -398,7 +398,7 @@ pub struct BusinessProfile { pub enable_payment_response_hash: bool, pub payment_response_hash_key: Option, pub redirect_to_merchant_with_http_post: bool, - pub webhook_details: Option, + pub webhook_details: Option, pub metadata: Option, pub is_recon_enabled: bool, pub applepay_verified_domains: Option>, @@ -430,7 +430,7 @@ pub enum BusinessProfileUpdate { enable_payment_response_hash: Option, payment_response_hash_key: Option, redirect_to_merchant_with_http_post: Option, - webhook_details: Option, + webhook_details: Option, metadata: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, diff --git a/crates/hyperswitch_domain_models/src/merchant_account.rs b/crates/hyperswitch_domain_models/src/merchant_account.rs index ca414918a0bb..d8af32255060 100644 --- a/crates/hyperswitch_domain_models/src/merchant_account.rs +++ b/crates/hyperswitch_domain_models/src/merchant_account.rs @@ -8,7 +8,8 @@ use common_utils::{ types::keymanager::{self}, }; use diesel_models::{ - enums::MerchantStorageScheme, merchant_account::MerchantAccountUpdateInternal, + business_profile::WebhookDetails, enums::MerchantStorageScheme, + merchant_account::MerchantAccountUpdateInternal, }; use error_stack::ResultExt; use masking::{PeekInterface, Secret}; @@ -29,7 +30,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -65,7 +66,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -136,7 +137,7 @@ pub struct MerchantAccountSetter { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -203,7 +204,7 @@ pub struct MerchantAccount { pub redirect_to_merchant_with_http_post: bool, pub merchant_name: OptionalEncryptableName, pub merchant_details: OptionalEncryptableValue, - pub webhook_details: Option, + pub webhook_details: Option, pub sub_merchants_enabled: Option, pub parent_merchant_id: Option, pub publishable_key: String, @@ -249,7 +250,7 @@ pub enum MerchantAccountUpdate { merchant_name: OptionalEncryptableName, merchant_details: OptionalEncryptableValue, return_url: Option, - webhook_details: Option, + webhook_details: Option, sub_merchants_enabled: Option, parent_merchant_id: Option, enable_payment_response_hash: Option, diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 286508c4149e..e36e1c4b1991 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -288,11 +288,7 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate { }, )?; - let webhook_details = self.get_webhook_details_as_value().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "webhook details", - }, - )?; + let webhook_details = self.webhook_details.clone().map(ForeignInto::foreign_into); let pm_collect_link_config = self.get_pm_link_config_as_value().change_context( errors::ApiErrorResponse::InvalidDataValue { @@ -1029,13 +1025,7 @@ pub async fn merchant_account_update( return_url: req.return_url.map(|a| a.to_string()), - webhook_details: req - .webhook_details - .as_ref() - .map(Encode::encode_to_value) - .transpose() - .change_context(errors::ApiErrorResponse::InternalServerError)? - .map(Secret::new), + webhook_details: req.webhook_details.map(ForeignInto::foreign_into), routing_algorithm: req.routing_algorithm, sub_merchants_enabled: req.sub_merchants_enabled, @@ -3354,18 +3344,7 @@ pub async fn update_business_profile( helpers::validate_intent_fulfillment_expiry(intent_fulfillment_expiry.to_owned())?; } - let webhook_details = request - .webhook_details - .as_ref() - .map(|webhook_details| { - webhook_details.encode_to_value().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "webhook details", - }, - ) - }) - .transpose()? - .map(Secret::new); + let webhook_details = request.webhook_details.map(ForeignInto::foreign_into); if let Some(ref routing_algorithm) = request.routing_algorithm { let _: api_models::routing::RoutingAlgorithm = routing_algorithm diff --git a/crates/router/src/core/webhooks/outgoing.rs b/crates/router/src/core/webhooks/outgoing.rs index 39b9fac33b3e..416075050b3d 100644 --- a/crates/router/src/core/webhooks/outgoing.rs +++ b/crates/router/src/core/webhooks/outgoing.rs @@ -536,17 +536,12 @@ pub(crate) async fn add_outgoing_webhook_retry_task_to_process_tracker( fn get_webhook_url_from_business_profile( business_profile: &diesel_models::business_profile::BusinessProfile, ) -> CustomResult { - let webhook_details_json = business_profile + let webhook_details = business_profile .webhook_details .clone() .get_required_value("webhook_details") .change_context(errors::WebhooksFlowError::MerchantWebhookDetailsNotFound)?; - let webhook_details: api::WebhookDetails = - webhook_details_json - .parse_value("WebhookDetails") - .change_context(errors::WebhooksFlowError::MerchantWebhookDetailsNotFound)?; - webhook_details .webhook_url .get_required_value("webhook_url") diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs index 7553854a1d59..c41a30480847 100644 --- a/crates/router/src/types/api/admin.rs +++ b/crates/router/src/types/api/admin.rs @@ -70,7 +70,7 @@ impl ForeignTryFrom for MerchantAccountResponse { payment_response_hash_key: item.payment_response_hash_key, redirect_to_merchant_with_http_post: item.redirect_to_merchant_with_http_post, merchant_details: item.merchant_details, - webhook_details: item.webhook_details, + webhook_details: item.webhook_details.clone().map(ForeignInto::foreign_into), routing_algorithm: item.routing_algorithm, sub_merchants_enabled: item.sub_merchants_enabled, parent_merchant_id: item.parent_merchant_id, @@ -149,7 +149,7 @@ pub async fn business_profile_response( enable_payment_response_hash: item.enable_payment_response_hash, payment_response_hash_key: item.payment_response_hash_key, redirect_to_merchant_with_http_post: item.redirect_to_merchant_with_http_post, - webhook_details: item.webhook_details, + webhook_details: item.webhook_details.map(ForeignInto::foreign_into), metadata: item.metadata, routing_algorithm: item.routing_algorithm, intent_fulfillment_time: item.intent_fulfillment_time, @@ -196,18 +196,7 @@ pub async fn create_business_profile( let current_time = common_utils::date_time::now(); - let webhook_details = request - .webhook_details - .as_ref() - .map(|webhook_details| { - webhook_details.encode_to_value().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "webhook details", - }, - ) - }) - .transpose()? - .map(Secret::new); + let webhook_details = request.webhook_details.map(ForeignInto::foreign_into); let payment_response_hash_key = request .payment_response_hash_key diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 113a6beb64c0..d47cf8ffb49e 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -1644,3 +1644,35 @@ impl ForeignFrom + for diesel_models::business_profile::WebhookDetails +{ + fn foreign_from(item: api_models::admin::WebhookDetails) -> Self { + Self { + webhook_version: item.webhook_version, + webhook_username: item.webhook_username, + webhook_password: item.webhook_password, + webhook_url: item.webhook_url, + payment_created_enabled: item.payment_created_enabled, + payment_succeeded_enabled: item.payment_succeeded_enabled, + payment_failed_enabled: item.payment_failed_enabled, + } + } +} + +impl ForeignFrom + for api_models::admin::WebhookDetails +{ + fn foreign_from(item: diesel_models::business_profile::WebhookDetails) -> Self { + Self { + webhook_version: item.webhook_version, + webhook_username: item.webhook_username, + webhook_password: item.webhook_password, + webhook_url: item.webhook_url, + payment_created_enabled: item.payment_created_enabled, + payment_succeeded_enabled: item.payment_succeeded_enabled, + payment_failed_enabled: item.payment_failed_enabled, + } + } +} From ab3ecc9a2831751780c1826e00072723162918e0 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Wed, 7 Aug 2024 01:54:04 +0530 Subject: [PATCH 08/10] refactor(business_profile): use `BusinessPaymentLinkConfig` and `BusinessPayoutLinkConfig` instead of `serde_json::Value` in diesel and domain models --- crates/api_models/src/admin.rs | 4 +- crates/diesel_models/src/business_profile.rs | 73 +++++++++--- .../src/business_profile.rs | 19 +-- crates/router/src/core/admin.rs | 20 +--- crates/router/src/core/payment_link.rs | 18 +-- crates/router/src/core/payouts.rs | 15 +-- crates/router/src/types/api/admin.rs | 41 ++----- crates/router/src/types/transformers.rs | 108 ++++++++++++++++++ 8 files changed, 196 insertions(+), 102 deletions(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 78650a2434c4..feee34863900 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -1863,8 +1863,8 @@ pub struct BusinessProfileResponse { pub session_expiry: Option, /// Default Payment Link config for all payment links created under this business profile - #[schema(value_type = Option)] - pub payment_link_config: Option>, + #[schema(value_type = Option)] + pub payment_link_config: Option, /// External 3DS authentication details pub authentication_connector_details: Option, diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 41332ec35503..28590dd0690b 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -1,3 +1,5 @@ +use std::collections::{HashMap, HashSet}; + use common_enums::AuthenticationConnectors; #[cfg(all(feature = "v2", feature = "business_profile_v2"))] use common_enums::OrderFulfillmentTimeOrigin; @@ -43,10 +45,10 @@ pub struct BusinessProfile { pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -81,10 +83,10 @@ pub struct BusinessProfileNew { pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -116,10 +118,10 @@ pub struct BusinessProfileUpdateInternal { pub is_recon_enabled: Option, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -149,10 +151,10 @@ pub enum BusinessProfileUpdate { payout_routing_algorithm: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, - payment_link_config: Option, + payment_link_config: Option, session_expiry: Option, authentication_connector_details: Option, - payout_link_config: Option, + payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, collect_shipping_details_from_wallet_connector: Option, @@ -471,10 +473,10 @@ pub struct BusinessProfile { pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -508,10 +510,10 @@ pub struct BusinessProfileNew { pub is_recon_enabled: bool, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -542,10 +544,10 @@ pub struct BusinessProfileUpdateInternal { pub is_recon_enabled: Option, #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -574,10 +576,10 @@ pub enum BusinessProfileUpdate { metadata: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, - payment_link_config: Option, + payment_link_config: Option, session_expiry: Option, authentication_connector_details: Option, - payout_link_config: Option, + payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, collect_shipping_details_from_wallet_connector: Option, @@ -910,3 +912,42 @@ pub struct WebhookDetails { } common_utils::impl_to_sql_from_sql_json!(WebhookDetails); + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, diesel::AsExpression)] +#[diesel(sql_type = diesel::sql_types::Jsonb)] +pub struct BusinessPaymentLinkConfig { + pub domain_name: Option, + #[serde(flatten)] + pub default_config: Option, + pub business_specific_configs: Option>, + pub allowed_domains: Option>, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +pub struct PaymentLinkConfigRequest { + pub theme: Option, + pub logo: Option, + pub seller_name: Option, + pub sdk_layout: Option, + pub display_sdk_only: Option, + pub enabled_saved_payment_method: Option, +} + +common_utils::impl_to_sql_from_sql_json!(BusinessPaymentLinkConfig); + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, diesel::AsExpression)] +#[diesel(sql_type = diesel::sql_types::Jsonb)] +pub struct BusinessPayoutLinkConfig { + #[serde(flatten)] + pub config: BusinessGenericLinkConfig, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +pub struct BusinessGenericLinkConfig { + pub domain_name: Option, + pub allowed_domains: HashSet, + #[serde(flatten)] + pub ui_config: common_utils::link_utils::GenericLinkUiConfig, +} + +common_utils::impl_to_sql_from_sql_json!(BusinessPayoutLinkConfig); diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs index ae52c33add02..304d3fc1518e 100644 --- a/crates/hyperswitch_domain_models/src/business_profile.rs +++ b/crates/hyperswitch_domain_models/src/business_profile.rs @@ -9,7 +9,8 @@ use common_utils::{ types::keymanager, }; use diesel_models::business_profile::{ - AuthenticationConnectorDetails, BusinessProfileUpdateInternal, WebhookDetails, + AuthenticationConnectorDetails, BusinessPaymentLinkConfig, BusinessPayoutLinkConfig, + BusinessProfileUpdateInternal, WebhookDetails, }; use error_stack::ResultExt; use masking::{PeekInterface, Secret}; @@ -39,10 +40,10 @@ pub struct BusinessProfile { pub payout_routing_algorithm: Option, pub is_recon_enabled: bool, pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -72,10 +73,10 @@ pub enum BusinessProfileUpdate { payout_routing_algorithm: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, - payment_link_config: Option, + payment_link_config: Option, session_expiry: Option, authentication_connector_details: Option, - payout_link_config: Option, + payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, collect_shipping_details_from_wallet_connector: Option, @@ -402,10 +403,10 @@ pub struct BusinessProfile { pub metadata: Option, pub is_recon_enabled: bool, pub applepay_verified_domains: Option>, - pub payment_link_config: Option, + pub payment_link_config: Option, pub session_expiry: Option, pub authentication_connector_details: Option, - pub payout_link_config: Option, + pub payout_link_config: Option, pub is_extended_card_info_enabled: Option, pub extended_card_info_config: Option, pub is_connector_agnostic_mit_enabled: Option, @@ -434,10 +435,10 @@ pub enum BusinessProfileUpdate { metadata: Option, is_recon_enabled: Option, applepay_verified_domains: Option>, - payment_link_config: Option, + payment_link_config: Option, session_expiry: Option, authentication_connector_details: Option, - payout_link_config: Option, + payout_link_config: Option, extended_card_info_config: Option, use_billing_as_payment_method_billing: Option, collect_shipping_details_from_wallet_connector: Option, diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index e36e1c4b1991..d8052eddfe80 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -3358,19 +3358,13 @@ pub async fn update_business_profile( let payment_link_config = request .payment_link_config - .as_ref() .map(|payment_link_conf| match payment_link_conf.validate() { - Ok(_) => payment_link_conf.encode_to_value().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "payment_link_config", - }, - ), + Ok(_) => Ok(payment_link_conf.foreign_into()), Err(e) => Err(report!(errors::ApiErrorResponse::InvalidRequestData { message: e.to_string() })), }) - .transpose()? - .map(Secret::new); + .transpose()?; let extended_card_info_config = request .extended_card_info_config @@ -3394,19 +3388,13 @@ pub async fn update_business_profile( let payout_link_config = request .payout_link_config - .as_ref() .map(|payout_conf| match payout_conf.config.validate() { - Ok(_) => payout_conf.encode_to_value().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "payout_link_config", - }, - ), + Ok(_) => Ok(payout_conf.foreign_into()), Err(e) => Err(report!(errors::ApiErrorResponse::InvalidRequestData { message: e.to_string() })), }) - .transpose()? - .map(Secret::new); + .transpose()?; let business_profile_update = storage::business_profile::BusinessProfileUpdate::Update { profile_name: request.profile_name, diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index 4c4403f30808..7b95edbda975 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -526,39 +526,33 @@ pub fn extract_payment_link_config( pub fn get_payment_link_config_based_on_priority( payment_create_link_config: Option, - business_link_config: Option>, + business_link_config: Option, merchant_name: String, default_domain_name: String, payment_link_config_id: Option, ) -> Result<(PaymentLinkConfig, String), error_stack::Report> { let (domain_name, business_theme_configs, allowed_domains) = if let Some(business_config) = business_link_config { - let extracted_value: api_models::admin::BusinessPaymentLinkConfig = business_config - .parse_value("BusinessPaymentLinkConfig") - .change_context(errors::ApiErrorResponse::InvalidDataValue { - field_name: "payment_link_config", - }) - .attach_printable("Invalid payment_link_config given in business config")?; logger::info!( "domain name set to custom domain https://{:?}", - extracted_value.domain_name + business_config.domain_name ); ( - extracted_value + business_config .domain_name .clone() .map(|d_name| format!("https://{}", d_name)) .unwrap_or_else(|| default_domain_name.clone()), payment_link_config_id .and_then(|id| { - extracted_value + business_config .business_specific_configs .as_ref() .and_then(|specific_configs| specific_configs.get(&id).cloned()) }) - .or(extracted_value.default_config), - extracted_value.allowed_domains, + .or(business_config.default_config), + business_config.allowed_domains, ) } else { (default_domain_name, None, None) diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs index 75756a963909..1350bf00c2b7 100644 --- a/crates/router/src/core/payouts.rs +++ b/crates/router/src/core/payouts.rs @@ -5,7 +5,7 @@ pub mod retry; pub mod validator; use std::vec::IntoIter; -use api_models::{self, admin, enums as api_enums, payouts::PayoutLinkResponse}; +use api_models::{self, enums as api_enums, payouts::PayoutLinkResponse}; #[cfg(feature = "payout_retry")] use common_enums::PayoutRetryType; use common_utils::{ @@ -2505,18 +2505,7 @@ pub async fn create_payout_link( // Fetch all configs let default_config = &state.conf.generic_link.payout_link; - let profile_config = business_profile - .payout_link_config - .as_ref() - .map(|config| { - config - .clone() - .parse_value::("BusinessPayoutLinkConfig") - }) - .transpose() - .change_context(errors::ApiErrorResponse::InvalidDataValue { - field_name: "payout_link_config in business_profile", - })?; + let profile_config = &business_profile.payout_link_config; let profile_ui_config = profile_config.as_ref().map(|c| c.config.ui_config.clone()); let ui_config = payout_link_config_req .as_ref() diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs index c41a30480847..90b29f13b4b3 100644 --- a/crates/router/src/types/api/admin.rs +++ b/crates/router/src/types/api/admin.rs @@ -12,15 +12,15 @@ pub use api_models::{ organization::{OrganizationId, OrganizationRequest, OrganizationResponse}, }; use common_utils::{ - ext_traits::{AsyncExt, Encode, ValueExt}, + ext_traits::{AsyncExt, ValueExt}, types::keymanager::Identifier, }; use diesel_models::organization::OrganizationBridge; -use error_stack::{report, ResultExt}; +use error_stack::ResultExt; use hyperswitch_domain_models::{ merchant_key_store::MerchantKeyStore, type_encryption::decrypt_optional, }; -use masking::{ExposeInterface, PeekInterface, Secret}; +use masking::{ExposeInterface, PeekInterface}; use crate::{ core::{errors, payment_methods::cards::create_encrypted_data}, @@ -157,15 +157,12 @@ pub async fn business_profile_response( #[cfg(feature = "payouts")] payout_routing_algorithm: item.payout_routing_algorithm, applepay_verified_domains: item.applepay_verified_domains, - payment_link_config: item.payment_link_config, + payment_link_config: item.payment_link_config.map(ForeignInto::foreign_into), session_expiry: item.session_expiry, authentication_connector_details: item .authentication_connector_details .map(ForeignInto::foreign_into), - payout_link_config: item - .payout_link_config - .map(|payout_link_config| payout_link_config.parse_value("BusinessPayoutLinkConfig")) - .transpose()?, + payout_link_config: item.payout_link_config.map(ForeignInto::foreign_into), use_billing_as_payment_method_billing: item.use_billing_as_payment_method_billing, extended_card_info_config: item .extended_card_info_config @@ -203,17 +200,7 @@ pub async fn create_business_profile( .or(merchant_account.payment_response_hash_key) .unwrap_or(common_utils::crypto::generate_cryptographically_secure_random_string(64)); - let payment_link_config_value = request - .payment_link_config - .map(|pl_config| { - pl_config - .encode_to_value() - .change_context(errors::ApiErrorResponse::InvalidDataValue { - field_name: "payment_link_config_value", - }) - }) - .transpose()? - .map(Secret::new); + let payment_link_config_value = request.payment_link_config.map(ForeignInto::foreign_into); let outgoing_webhook_custom_http_headers = request .outgoing_webhook_custom_http_headers .async_map(|headers| create_encrypted_data(state, key_store, headers)) @@ -222,21 +209,7 @@ pub async fn create_business_profile( .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to encrypt outgoing webhook custom HTTP headers")?; - let payout_link_config = request - .payout_link_config - .as_ref() - .map(|payout_conf| match payout_conf.config.validate() { - Ok(_) => payout_conf.encode_to_value().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "payout_link_config", - }, - ), - Err(e) => Err(report!(errors::ApiErrorResponse::InvalidRequestData { - message: e.to_string() - })), - }) - .transpose()? - .map(Secret::new); + let payout_link_config = request.payout_link_config.map(ForeignInto::foreign_into); Ok(storage::business_profile::BusinessProfileNew { profile_id, diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index d47cf8ffb49e..378028b2acdc 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -1676,3 +1676,111 @@ impl ForeignFrom } } } + +impl ForeignFrom + for diesel_models::business_profile::BusinessPaymentLinkConfig +{ + fn foreign_from(item: api_models::admin::BusinessPaymentLinkConfig) -> Self { + Self { + domain_name: item.domain_name, + default_config: item.default_config.map(ForeignInto::foreign_into), + business_specific_configs: item.business_specific_configs.map(|map| { + map.into_iter() + .map(|(k, v)| (k, v.foreign_into())) + .collect() + }), + allowed_domains: item.allowed_domains, + } + } +} + +impl ForeignFrom + for api_models::admin::BusinessPaymentLinkConfig +{ + fn foreign_from(item: diesel_models::business_profile::BusinessPaymentLinkConfig) -> Self { + Self { + domain_name: item.domain_name, + default_config: item.default_config.map(ForeignInto::foreign_into), + business_specific_configs: item.business_specific_configs.map(|map| { + map.into_iter() + .map(|(k, v)| (k, v.foreign_into())) + .collect() + }), + allowed_domains: item.allowed_domains, + } + } +} + +impl ForeignFrom + for diesel_models::business_profile::PaymentLinkConfigRequest +{ + fn foreign_from(item: api_models::admin::PaymentLinkConfigRequest) -> Self { + Self { + theme: item.theme, + logo: item.logo, + seller_name: item.seller_name, + sdk_layout: item.sdk_layout, + display_sdk_only: item.display_sdk_only, + enabled_saved_payment_method: item.enabled_saved_payment_method, + } + } +} + +impl ForeignFrom + for api_models::admin::PaymentLinkConfigRequest +{ + fn foreign_from(item: diesel_models::business_profile::PaymentLinkConfigRequest) -> Self { + Self { + theme: item.theme, + logo: item.logo, + seller_name: item.seller_name, + sdk_layout: item.sdk_layout, + display_sdk_only: item.display_sdk_only, + enabled_saved_payment_method: item.enabled_saved_payment_method, + } + } +} + +impl ForeignFrom + for diesel_models::business_profile::BusinessPayoutLinkConfig +{ + fn foreign_from(item: api_models::admin::BusinessPayoutLinkConfig) -> Self { + Self { + config: item.config.foreign_into(), + } + } +} + +impl ForeignFrom + for api_models::admin::BusinessPayoutLinkConfig +{ + fn foreign_from(item: diesel_models::business_profile::BusinessPayoutLinkConfig) -> Self { + Self { + config: item.config.foreign_into(), + } + } +} + +impl ForeignFrom + for diesel_models::business_profile::BusinessGenericLinkConfig +{ + fn foreign_from(item: api_models::admin::BusinessGenericLinkConfig) -> Self { + Self { + domain_name: item.domain_name, + allowed_domains: item.allowed_domains, + ui_config: item.ui_config, + } + } +} + +impl ForeignFrom + for api_models::admin::BusinessGenericLinkConfig +{ + fn foreign_from(item: diesel_models::business_profile::BusinessGenericLinkConfig) -> Self { + Self { + domain_name: item.domain_name, + allowed_domains: item.allowed_domains, + ui_config: item.ui_config, + } + } +} From ee99b62a20e7ddf17b4f4f524e7ee3a879f4de9e Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Wed, 7 Aug 2024 01:55:28 +0530 Subject: [PATCH 09/10] docs: re-generate OpenAPI specification --- api-reference/openapi_spec.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 1ee0e8a9c280..cc53e69cb768 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -7265,8 +7265,11 @@ "nullable": true }, "payment_link_config": { - "type": "object", - "description": "Default Payment Link config for all payment links created under this business profile", + "allOf": [ + { + "$ref": "#/components/schemas/BusinessPaymentLinkConfig" + } + ], "nullable": true }, "authentication_connector_details": { From 9b71d29bdb3ae62580316e824992da2ccc48f563 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde Date: Wed, 7 Aug 2024 02:42:25 +0530 Subject: [PATCH 10/10] refactor(business_profile): address `clippy::large_enum_variant` thrown on `BusinessProfileUpdate` enum --- crates/diesel_models/src/business_profile.rs | 333 +++++++++-------- .../src/business_profile.rs | 338 +++++++++--------- crates/router/src/core/admin.rs | 66 ++-- .../src/types/storage/business_profile.rs | 3 +- 4 files changed, 389 insertions(+), 351 deletions(-) diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 28590dd0690b..6de77d5c5fde 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -131,37 +131,44 @@ pub struct BusinessProfileUpdateInternal { pub outgoing_webhook_custom_http_headers: Option, } +#[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "business_profile_v2") +))] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct BusinessProfileGeneralUpdate { + pub profile_name: Option, + pub return_url: Option, + pub enable_payment_response_hash: Option, + pub payment_response_hash_key: Option, + pub redirect_to_merchant_with_http_post: Option, + pub webhook_details: Option, + pub metadata: Option, + pub routing_algorithm: Option, + pub intent_fulfillment_time: Option, + pub frm_routing_algorithm: Option, + pub payout_routing_algorithm: Option, + pub is_recon_enabled: Option, + pub applepay_verified_domains: Option>, + pub payment_link_config: Option, + pub session_expiry: Option, + pub authentication_connector_details: Option, + pub payout_link_config: Option, + pub extended_card_info_config: Option, + pub use_billing_as_payment_method_billing: Option, + pub collect_shipping_details_from_wallet_connector: Option, + pub collect_billing_details_from_wallet_connector: Option, + pub is_connector_agnostic_mit_enabled: Option, + pub outgoing_webhook_custom_http_headers: Option, +} + #[cfg(all( any(feature = "v1", feature = "v2"), not(feature = "business_profile_v2") ))] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum BusinessProfileUpdate { - Update { - profile_name: Option, - return_url: Option, - enable_payment_response_hash: Option, - payment_response_hash_key: Option, - redirect_to_merchant_with_http_post: Option, - webhook_details: Option, - metadata: Option, - routing_algorithm: Option, - intent_fulfillment_time: Option, - frm_routing_algorithm: Option, - payout_routing_algorithm: Option, - is_recon_enabled: Option, - applepay_verified_domains: Option>, - payment_link_config: Option, - session_expiry: Option, - authentication_connector_details: Option, - payout_link_config: Option, - extended_card_info_config: Option, - use_billing_as_payment_method_billing: Option, - collect_shipping_details_from_wallet_connector: Option, - collect_billing_details_from_wallet_connector: Option, - is_connector_agnostic_mit_enabled: Option, - outgoing_webhook_custom_http_headers: Option, - }, + Update(Box), RoutingAlgorithmUpdate { routing_algorithm: Option, payout_routing_algorithm: Option, @@ -183,57 +190,60 @@ impl From for BusinessProfileUpdateInternal { let now = common_utils::date_time::now(); match business_profile_update { - BusinessProfileUpdate::Update { - profile_name, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - routing_algorithm, - intent_fulfillment_time, - frm_routing_algorithm, - payout_routing_algorithm, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - extended_card_info_config, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers, - } => Self { - profile_name, - modified_at: now, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - routing_algorithm, - intent_fulfillment_time, - frm_routing_algorithm, - payout_routing_algorithm, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - is_extended_card_info_enabled: None, - extended_card_info_config, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers, - }, + BusinessProfileUpdate::Update(update) => { + let BusinessProfileGeneralUpdate { + profile_name, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + routing_algorithm, + intent_fulfillment_time, + frm_routing_algorithm, + payout_routing_algorithm, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + extended_card_info_config, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers, + } = *update; + Self { + profile_name, + modified_at: now, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + routing_algorithm, + intent_fulfillment_time, + frm_routing_algorithm, + payout_routing_algorithm, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + is_extended_card_info_enabled: None, + extended_card_info_config, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers, + } + } BusinessProfileUpdate::RoutingAlgorithmUpdate { routing_algorithm, payout_routing_algorithm, @@ -563,36 +573,40 @@ pub struct BusinessProfileUpdateInternal { pub default_fallback_routing: Option, } +#[cfg(all(feature = "v2", feature = "business_profile_v2"))] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct BusinessProfileGeneralUpdate { + pub profile_name: Option, + pub return_url: Option, + pub enable_payment_response_hash: Option, + pub payment_response_hash_key: Option, + pub redirect_to_merchant_with_http_post: Option, + pub webhook_details: Option, + pub metadata: Option, + pub is_recon_enabled: Option, + pub applepay_verified_domains: Option>, + pub payment_link_config: Option, + pub session_expiry: Option, + pub authentication_connector_details: Option, + pub payout_link_config: Option, + pub extended_card_info_config: Option, + pub use_billing_as_payment_method_billing: Option, + pub collect_shipping_details_from_wallet_connector: Option, + pub collect_billing_details_from_wallet_connector: Option, + pub is_connector_agnostic_mit_enabled: Option, + pub outgoing_webhook_custom_http_headers: Option, + pub routing_algorithm_id: Option, + pub order_fulfillment_time: Option, + pub order_fulfillment_time_origin: Option, + pub frm_routing_algorithm_id: Option, + pub payout_routing_algorithm_id: Option, + pub default_fallback_routing: Option, +} + #[cfg(all(feature = "v2", feature = "business_profile_v2"))] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum BusinessProfileUpdate { - Update { - profile_name: Option, - return_url: Option, - enable_payment_response_hash: Option, - payment_response_hash_key: Option, - redirect_to_merchant_with_http_post: Option, - webhook_details: Option, - metadata: Option, - is_recon_enabled: Option, - applepay_verified_domains: Option>, - payment_link_config: Option, - session_expiry: Option, - authentication_connector_details: Option, - payout_link_config: Option, - extended_card_info_config: Option, - use_billing_as_payment_method_billing: Option, - collect_shipping_details_from_wallet_connector: Option, - collect_billing_details_from_wallet_connector: Option, - is_connector_agnostic_mit_enabled: Option, - outgoing_webhook_custom_http_headers: Option, - routing_algorithm_id: Option, - order_fulfillment_time: Option, - order_fulfillment_time_origin: Option, - frm_routing_algorithm_id: Option, - payout_routing_algorithm_id: Option, - default_fallback_routing: Option, - }, + Update(Box), RoutingAlgorithmUpdate { routing_algorithm_id: Option, payout_routing_algorithm_id: Option, @@ -611,61 +625,64 @@ impl From for BusinessProfileUpdateInternal { let now = common_utils::date_time::now(); match business_profile_update { - BusinessProfileUpdate::Update { - profile_name, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - extended_card_info_config, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers, - routing_algorithm_id, - order_fulfillment_time, - order_fulfillment_time_origin, - frm_routing_algorithm_id, - payout_routing_algorithm_id, - default_fallback_routing, - } => Self { - profile_name, - modified_at: now, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - is_extended_card_info_enabled: None, - extended_card_info_config, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers, - routing_algorithm_id, - order_fulfillment_time, - order_fulfillment_time_origin, - frm_routing_algorithm_id, - payout_routing_algorithm_id, - default_fallback_routing, - }, + BusinessProfileUpdate::Update(update) => { + let BusinessProfileGeneralUpdate { + profile_name, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + extended_card_info_config, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers, + routing_algorithm_id, + order_fulfillment_time, + order_fulfillment_time_origin, + frm_routing_algorithm_id, + payout_routing_algorithm_id, + default_fallback_routing, + } = *update; + Self { + profile_name, + modified_at: now, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + is_extended_card_info_enabled: None, + extended_card_info_config, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers, + routing_algorithm_id, + order_fulfillment_time, + order_fulfillment_time_origin, + frm_routing_algorithm_id, + payout_routing_algorithm_id, + default_fallback_routing, + } + } BusinessProfileUpdate::RoutingAlgorithmUpdate { routing_algorithm_id, payout_routing_algorithm_id, diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs index 304d3fc1518e..779dcdb2fbb1 100644 --- a/crates/hyperswitch_domain_models/src/business_profile.rs +++ b/crates/hyperswitch_domain_models/src/business_profile.rs @@ -53,37 +53,44 @@ pub struct BusinessProfile { pub outgoing_webhook_custom_http_headers: OptionalEncryptableValue, } +#[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "business_profile_v2") +))] +#[derive(Debug)] +pub struct BusinessProfileGeneralUpdate { + pub profile_name: Option, + pub return_url: Option, + pub enable_payment_response_hash: Option, + pub payment_response_hash_key: Option, + pub redirect_to_merchant_with_http_post: Option, + pub webhook_details: Option, + pub metadata: Option, + pub routing_algorithm: Option, + pub intent_fulfillment_time: Option, + pub frm_routing_algorithm: Option, + pub payout_routing_algorithm: Option, + pub is_recon_enabled: Option, + pub applepay_verified_domains: Option>, + pub payment_link_config: Option, + pub session_expiry: Option, + pub authentication_connector_details: Option, + pub payout_link_config: Option, + pub extended_card_info_config: Option, + pub use_billing_as_payment_method_billing: Option, + pub collect_shipping_details_from_wallet_connector: Option, + pub collect_billing_details_from_wallet_connector: Option, + pub is_connector_agnostic_mit_enabled: Option, + pub outgoing_webhook_custom_http_headers: OptionalEncryptableValue, +} + #[cfg(all( any(feature = "v1", feature = "v2"), not(feature = "business_profile_v2") ))] #[derive(Debug)] pub enum BusinessProfileUpdate { - Update { - profile_name: Option, - return_url: Option, - enable_payment_response_hash: Option, - payment_response_hash_key: Option, - redirect_to_merchant_with_http_post: Option, - webhook_details: Option, - metadata: Option, - routing_algorithm: Option, - intent_fulfillment_time: Option, - frm_routing_algorithm: Option, - payout_routing_algorithm: Option, - is_recon_enabled: Option, - applepay_verified_domains: Option>, - payment_link_config: Option, - session_expiry: Option, - authentication_connector_details: Option, - payout_link_config: Option, - extended_card_info_config: Option, - use_billing_as_payment_method_billing: Option, - collect_shipping_details_from_wallet_connector: Option, - collect_billing_details_from_wallet_connector: Option, - is_connector_agnostic_mit_enabled: Option, - outgoing_webhook_custom_http_headers: OptionalEncryptableValue, - }, + Update(Box), RoutingAlgorithmUpdate { routing_algorithm: Option, payout_routing_algorithm: Option, @@ -105,58 +112,62 @@ impl From for BusinessProfileUpdateInternal { let now = date_time::now(); match business_profile_update { - BusinessProfileUpdate::Update { - profile_name, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - routing_algorithm, - intent_fulfillment_time, - frm_routing_algorithm, - payout_routing_algorithm, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - extended_card_info_config, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers, - } => Self { - profile_name, - modified_at: now, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - routing_algorithm, - intent_fulfillment_time, - frm_routing_algorithm, - payout_routing_algorithm, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - is_extended_card_info_enabled: None, - extended_card_info_config, - is_connector_agnostic_mit_enabled, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers - .map(Encryption::from), - }, + BusinessProfileUpdate::Update(update) => { + let BusinessProfileGeneralUpdate { + profile_name, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + routing_algorithm, + intent_fulfillment_time, + frm_routing_algorithm, + payout_routing_algorithm, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + extended_card_info_config, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers, + } = *update; + + Self { + profile_name, + modified_at: now, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + routing_algorithm, + intent_fulfillment_time, + frm_routing_algorithm, + payout_routing_algorithm, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + is_extended_card_info_enabled: None, + extended_card_info_config, + is_connector_agnostic_mit_enabled, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers + .map(Encryption::from), + } + } BusinessProfileUpdate::RoutingAlgorithmUpdate { routing_algorithm, payout_routing_algorithm, @@ -422,36 +433,40 @@ pub struct BusinessProfile { pub default_fallback_routing: Option, } +#[cfg(all(feature = "v2", feature = "business_profile_v2"))] +#[derive(Debug)] +pub struct BusinessProfileGeneralUpdate { + pub profile_name: Option, + pub return_url: Option, + pub enable_payment_response_hash: Option, + pub payment_response_hash_key: Option, + pub redirect_to_merchant_with_http_post: Option, + pub webhook_details: Option, + pub metadata: Option, + pub is_recon_enabled: Option, + pub applepay_verified_domains: Option>, + pub payment_link_config: Option, + pub session_expiry: Option, + pub authentication_connector_details: Option, + pub payout_link_config: Option, + pub extended_card_info_config: Option, + pub use_billing_as_payment_method_billing: Option, + pub collect_shipping_details_from_wallet_connector: Option, + pub collect_billing_details_from_wallet_connector: Option, + pub is_connector_agnostic_mit_enabled: Option, + pub outgoing_webhook_custom_http_headers: OptionalEncryptableValue, + pub routing_algorithm_id: Option, + pub order_fulfillment_time: Option, + pub order_fulfillment_time_origin: Option, + pub frm_routing_algorithm_id: Option, + pub payout_routing_algorithm_id: Option, + pub default_fallback_routing: Option, +} + #[cfg(all(feature = "v2", feature = "business_profile_v2"))] #[derive(Debug)] pub enum BusinessProfileUpdate { - Update { - profile_name: Option, - return_url: Option, - enable_payment_response_hash: Option, - payment_response_hash_key: Option, - redirect_to_merchant_with_http_post: Option, - webhook_details: Option, - metadata: Option, - is_recon_enabled: Option, - applepay_verified_domains: Option>, - payment_link_config: Option, - session_expiry: Option, - authentication_connector_details: Option, - payout_link_config: Option, - extended_card_info_config: Option, - use_billing_as_payment_method_billing: Option, - collect_shipping_details_from_wallet_connector: Option, - collect_billing_details_from_wallet_connector: Option, - is_connector_agnostic_mit_enabled: Option, - outgoing_webhook_custom_http_headers: OptionalEncryptableValue, - routing_algorithm_id: Option, - order_fulfillment_time: Option, - order_fulfillment_time_origin: Option, - frm_routing_algorithm_id: Option, - payout_routing_algorithm_id: Option, - default_fallback_routing: Option, - }, + Update(Box), RoutingAlgorithmUpdate { routing_algorithm_id: Option, payout_routing_algorithm_id: Option, @@ -470,62 +485,65 @@ impl From for BusinessProfileUpdateInternal { let now = date_time::now(); match business_profile_update { - BusinessProfileUpdate::Update { - profile_name, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - extended_card_info_config, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers, - routing_algorithm_id, - order_fulfillment_time, - order_fulfillment_time_origin, - frm_routing_algorithm_id, - payout_routing_algorithm_id, - default_fallback_routing, - } => Self { - profile_name, - modified_at: now, - return_url, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - webhook_details, - metadata, - is_recon_enabled, - applepay_verified_domains, - payment_link_config, - session_expiry, - authentication_connector_details, - payout_link_config, - is_extended_card_info_enabled: None, - extended_card_info_config, - is_connector_agnostic_mit_enabled, - use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector, - outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers - .map(Encryption::from), - routing_algorithm_id, - order_fulfillment_time, - order_fulfillment_time_origin, - frm_routing_algorithm_id, - payout_routing_algorithm_id, - default_fallback_routing, - }, + BusinessProfileUpdate::Update(update) => { + let BusinessProfileGeneralUpdate { + profile_name, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + extended_card_info_config, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers, + routing_algorithm_id, + order_fulfillment_time, + order_fulfillment_time_origin, + frm_routing_algorithm_id, + payout_routing_algorithm_id, + default_fallback_routing, + } = *update; + Self { + profile_name, + modified_at: now, + return_url, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + webhook_details, + metadata, + is_recon_enabled, + applepay_verified_domains, + payment_link_config, + session_expiry, + authentication_connector_details, + payout_link_config, + is_extended_card_info_enabled: None, + extended_card_info_config, + is_connector_agnostic_mit_enabled, + use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector, + outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers + .map(Encryption::from), + routing_algorithm_id, + order_fulfillment_time, + order_fulfillment_time_origin, + frm_routing_algorithm_id, + payout_routing_algorithm_id, + default_fallback_routing, + } + } BusinessProfileUpdate::RoutingAlgorithmUpdate { routing_algorithm_id, payout_routing_algorithm_id, diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index d8052eddfe80..ed1ee3a6c6af 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -3396,38 +3396,40 @@ pub async fn update_business_profile( }) .transpose()?; - let business_profile_update = storage::business_profile::BusinessProfileUpdate::Update { - profile_name: request.profile_name, - return_url: request.return_url.map(|return_url| return_url.to_string()), - enable_payment_response_hash: request.enable_payment_response_hash, - payment_response_hash_key: request.payment_response_hash_key, - redirect_to_merchant_with_http_post: request.redirect_to_merchant_with_http_post, - webhook_details, - metadata: request.metadata, - routing_algorithm: request.routing_algorithm, - intent_fulfillment_time: request.intent_fulfillment_time.map(i64::from), - frm_routing_algorithm: request.frm_routing_algorithm, - #[cfg(feature = "payouts")] - payout_routing_algorithm: request.payout_routing_algorithm, - #[cfg(not(feature = "payouts"))] - payout_routing_algorithm: None, - is_recon_enabled: None, - applepay_verified_domains: request.applepay_verified_domains, - payment_link_config, - session_expiry: request.session_expiry.map(i64::from), - authentication_connector_details: request - .authentication_connector_details - .map(ForeignInto::foreign_into), - payout_link_config, - extended_card_info_config, - use_billing_as_payment_method_billing: request.use_billing_as_payment_method_billing, - collect_shipping_details_from_wallet_connector: request - .collect_shipping_details_from_wallet_connector, - collect_billing_details_from_wallet_connector: request - .collect_billing_details_from_wallet_connector, - is_connector_agnostic_mit_enabled: request.is_connector_agnostic_mit_enabled, - outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers.map(Into::into), - }; + let business_profile_update = + storage::BusinessProfileUpdate::Update(Box::new(storage::BusinessProfileGeneralUpdate { + profile_name: request.profile_name, + return_url: request.return_url.map(|return_url| return_url.to_string()), + enable_payment_response_hash: request.enable_payment_response_hash, + payment_response_hash_key: request.payment_response_hash_key, + redirect_to_merchant_with_http_post: request.redirect_to_merchant_with_http_post, + webhook_details, + metadata: request.metadata, + routing_algorithm: request.routing_algorithm, + intent_fulfillment_time: request.intent_fulfillment_time.map(i64::from), + frm_routing_algorithm: request.frm_routing_algorithm, + #[cfg(feature = "payouts")] + payout_routing_algorithm: request.payout_routing_algorithm, + #[cfg(not(feature = "payouts"))] + payout_routing_algorithm: None, + is_recon_enabled: None, + applepay_verified_domains: request.applepay_verified_domains, + payment_link_config, + session_expiry: request.session_expiry.map(i64::from), + authentication_connector_details: request + .authentication_connector_details + .map(ForeignInto::foreign_into), + payout_link_config, + extended_card_info_config, + use_billing_as_payment_method_billing: request.use_billing_as_payment_method_billing, + collect_shipping_details_from_wallet_connector: request + .collect_shipping_details_from_wallet_connector, + collect_billing_details_from_wallet_connector: request + .collect_billing_details_from_wallet_connector, + is_connector_agnostic_mit_enabled: request.is_connector_agnostic_mit_enabled, + outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers + .map(Into::into), + })); let updated_business_profile = db .update_business_profile_by_profile_id(business_profile, business_profile_update) diff --git a/crates/router/src/types/storage/business_profile.rs b/crates/router/src/types/storage/business_profile.rs index d7c7d66b99ef..4780b3d032fd 100644 --- a/crates/router/src/types/storage/business_profile.rs +++ b/crates/router/src/types/storage/business_profile.rs @@ -1,3 +1,4 @@ pub use diesel_models::business_profile::{ - BusinessProfile, BusinessProfileNew, BusinessProfileUpdate, BusinessProfileUpdateInternal, + BusinessProfile, BusinessProfileGeneralUpdate, BusinessProfileNew, BusinessProfileUpdate, + BusinessProfileUpdateInternal, };