From 3e463bcccfd5974efc82dde119c46016b2685691 Mon Sep 17 00:00:00 2001 From: Sai Harsha Vardhan <56996463+sai-harsha-vardhan@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:52:18 +0530 Subject: [PATCH 1/4] revert: feat(router): mask keys in connector_account_details for merchant_connector_response in mca retrieve flow (#5890) --- .../src/router_data.rs | 70 +------------------ crates/router/src/types/transformers.rs | 24 ++----- 2 files changed, 5 insertions(+), 89 deletions(-) diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index df0b63833d9b..122acbb0adc0 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -7,7 +7,7 @@ use common_utils::{ types::MinorUnit, }; use error_stack::ResultExt; -use masking::{ExposeInterface, Secret}; +use masking::Secret; use crate::{payment_address::PaymentAddress, payment_method_data}; @@ -136,74 +136,6 @@ impl ConnectorAuthType { "ConnectorAuthType", )) } - - // show only first and last two digits of the key and mask others with * - // mask the entire key if it's length is less than or equal to 4 - fn mask_key(&self, key: String) -> Secret { - let key_len = key.len(); - let masked_key = if key_len <= 4 { - "*".repeat(key_len) - } else { - // Show the first two and last two characters, mask the rest with '*' - let mut masked_key = String::new(); - let key_len = key.len(); - // Iterate through characters by their index - for (index, character) in key.chars().enumerate() { - if index < 2 || index >= key_len - 2 { - masked_key.push(character); // Keep the first two and last two characters - } else { - masked_key.push('*'); // Mask the middle characters - } - } - masked_key - }; - Secret::new(masked_key) - } - - // Mask the keys in the auth_type - pub fn get_masked_keys(&self) -> Self { - match self { - Self::TemporaryAuth => Self::TemporaryAuth, - Self::NoKey => Self::NoKey, - Self::HeaderKey { api_key } => Self::HeaderKey { - api_key: self.mask_key(api_key.clone().expose()), - }, - Self::BodyKey { api_key, key1 } => Self::BodyKey { - api_key: self.mask_key(api_key.clone().expose()), - key1: self.mask_key(key1.clone().expose()), - }, - Self::SignatureKey { - api_key, - key1, - api_secret, - } => Self::SignatureKey { - api_key: self.mask_key(api_key.clone().expose()), - key1: self.mask_key(key1.clone().expose()), - api_secret: self.mask_key(api_secret.clone().expose()), - }, - Self::MultiAuthKey { - api_key, - key1, - api_secret, - key2, - } => Self::MultiAuthKey { - api_key: self.mask_key(api_key.clone().expose()), - key1: self.mask_key(key1.clone().expose()), - api_secret: self.mask_key(api_secret.clone().expose()), - key2: self.mask_key(key2.clone().expose()), - }, - Self::CurrencyAuthKey { auth_key_map } => Self::CurrencyAuthKey { - auth_key_map: auth_key_map.clone(), - }, - Self::CertificateAuth { - certificate, - private_key, - } => Self::CertificateAuth { - certificate: self.mask_key(certificate.clone().expose()), - private_key: self.mask_key(private_key.clone().expose()), - }, - } - } } #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index f883d1d4c507..a9913cee9afa 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -7,7 +7,7 @@ use api_models::{ use common_utils::{ consts::X_HS_LATENCY, crypto::Encryptable, - ext_traits::{Encode, StringExt, ValueExt}, + ext_traits::{StringExt, ValueExt}, fp_utils::when, pii, types::MinorUnit, @@ -15,7 +15,7 @@ use common_utils::{ use diesel_models::enums as storage_enums; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::payments::payment_intent::CustomerData; -use masking::{ExposeInterface, PeekInterface, Secret}; +use masking::{ExposeInterface, PeekInterface}; use super::domain; use crate::{ @@ -1149,29 +1149,13 @@ impl ForeignTryFrom } None => None, }; - // parse the connector_account_details into ConnectorAuthType - let connector_account_details: hyperswitch_domain_models::router_data::ConnectorAuthType = - item.connector_account_details - .clone() - .into_inner() - .parse_value("ConnectorAuthType") - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed while parsing value for ConnectorAuthType")?; - // get the masked keys from the ConnectorAuthType and encode it to secret value - let masked_connector_account_details = Secret::new( - connector_account_details - .get_masked_keys() - .encode_to_value() - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to encode ConnectorAuthType")?, - ); #[cfg(feature = "v2")] let response = Self { id: item.get_id(), connector_type: item.connector_type, connector_name: item.connector_name, connector_label: item.connector_label, - connector_account_details: masked_connector_account_details, + connector_account_details: item.connector_account_details.into_inner(), disabled: item.disabled, payment_methods_enabled, metadata: item.metadata, @@ -1211,7 +1195,7 @@ impl ForeignTryFrom connector_name: item.connector_name, connector_label: item.connector_label, merchant_connector_id: item.merchant_connector_id, - connector_account_details: masked_connector_account_details, + connector_account_details: item.connector_account_details.into_inner(), test_mode: item.test_mode, disabled: item.disabled, payment_methods_enabled, From 661bee9f8838f5fa2038c165bdeaac39981ce80c Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:27:43 +0000 Subject: [PATCH 2/4] chore(version): 2024.09.13.0-hotfix1 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8729392ac8f..0b1285acb6ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.09.13.0-hotfix1 + +### Revert + +- Feat(router): mask keys in connector_account_details for merchant_connector_response in mca retrieve flow ([#5890](https://github.com/juspay/hyperswitch/pull/5890)) ([`3e463bc`](https://github.com/juspay/hyperswitch/commit/3e463bcccfd5974efc82dde119c46016b2685691)) + +- - - + ## 2024.09.13.0 ### Features From f462c7329982e6f8c1c266a6e19f33560fba6615 Mon Sep 17 00:00:00 2001 From: Swangi Kumari <85639103+swangi-kumari@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:49:46 +0530 Subject: [PATCH 3/4] refactor(core): update response for PaymentsDynamicTaxCalculationResponse (#5910) --- api-reference-v2/openapi_spec.json | 28 +++++++- api-reference/openapi_spec.json | 28 +++++++- crates/api_models/src/payments.rs | 15 ++++ crates/openapi/src/openapi.rs | 1 + crates/openapi/src/openapi_v2.rs | 1 + .../router/src/core/payments/transformers.rs | 71 ++++++++++++++++++- 6 files changed, 140 insertions(+), 4 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index bda5fab29c02..8a2a8c98a08e 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -6212,6 +6212,28 @@ "BRW" ] }, + "DisplayAmountOnSdk": { + "type": "object", + "required": [ + "net_amount", + "order_tax_amount", + "shipping_cost" + ], + "properties": { + "net_amount": { + "type": "string", + "description": "net amount = amount + order_tax_amount + shipping_cost" + }, + "order_tax_amount": { + "type": "string", + "description": "order tax amount calculated by tax connectors" + }, + "shipping_cost": { + "type": "string", + "description": "shipping cost for the order" + } + } + }, "DisputeResponse": { "type": "object", "required": [ @@ -13537,7 +13559,8 @@ "type": "object", "required": [ "payment_id", - "net_amount" + "net_amount", + "display_amount" ], "properties": { "payment_id": { @@ -13562,6 +13585,9 @@ } ], "nullable": true + }, + "display_amount": { + "$ref": "#/components/schemas/DisplayAmountOnSdk" } } }, diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 9d6074fe16be..3e4994023e40 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -9831,6 +9831,28 @@ "BRW" ] }, + "DisplayAmountOnSdk": { + "type": "object", + "required": [ + "net_amount", + "order_tax_amount", + "shipping_cost" + ], + "properties": { + "net_amount": { + "type": "string", + "description": "net amount = amount + order_tax_amount + shipping_cost" + }, + "order_tax_amount": { + "type": "string", + "description": "order tax amount calculated by tax connectors" + }, + "shipping_cost": { + "type": "string", + "description": "shipping cost for the order" + } + } + }, "DisputeResponse": { "type": "object", "required": [ @@ -17535,7 +17557,8 @@ "type": "object", "required": [ "payment_id", - "net_amount" + "net_amount", + "display_amount" ], "properties": { "payment_id": { @@ -17560,6 +17583,9 @@ } ], "nullable": true + }, + "display_amount": { + "$ref": "#/components/schemas/DisplayAmountOnSdk" } } }, diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index abd795361bb8..9211a0655062 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -4619,6 +4619,21 @@ pub struct PaymentsDynamicTaxCalculationResponse { pub order_tax_amount: Option, /// shipping cost for the order pub shipping_cost: Option, + /// amount in Base Unit display format + pub display_amount: DisplayAmountOnSdk, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema)] +pub struct DisplayAmountOnSdk { + /// net amount = amount + order_tax_amount + shipping_cost + #[schema(value_type = String)] + pub net_amount: StringMajorUnit, + /// order tax amount calculated by tax connectors + #[schema(value_type = String)] + pub order_tax_amount: Option, + /// shipping cost for the order + #[schema(value_type = String)] + pub shipping_cost: Option, } #[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)] diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 3b63b7ac20f4..5c1597c7a883 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -606,6 +606,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::additional_info::UpiCollectAdditionalData, api_models::payments::PaymentsDynamicTaxCalculationRequest, api_models::payments::PaymentsDynamicTaxCalculationResponse, + api_models::payments::DisplayAmountOnSdk, )), modifiers(&SecurityAddon) )] diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 5393e8d6fae9..31feb8e85b12 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -522,6 +522,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::additional_info::UpiCollectAdditionalData, api_models::payments::PaymentsDynamicTaxCalculationRequest, api_models::payments::PaymentsDynamicTaxCalculationResponse, + api_models::payments::DisplayAmountOnSdk, )), modifiers(&SecurityAddon) )] diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 36961f337537..d94b413e626f 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -4,8 +4,13 @@ use api_models::payments::{ Address, CustomerDetails, CustomerDetailsResponse, FrmMessage, PaymentChargeRequest, PaymentChargeResponse, RequestSurchargeDetails, }; -use common_enums::RequestIncrementalAuthorization; -use common_utils::{consts::X_HS_LATENCY, fp_utils, pii::Email, types::MinorUnit}; +use common_enums::{Currency, RequestIncrementalAuthorization}; +use common_utils::{ + consts::X_HS_LATENCY, + fp_utils, + pii::Email, + types::{AmountConvertor, MinorUnit, StringMajorUnitForConnector}, +}; use diesel_models::ephemeral_key; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{payments::payment_intent::CustomerData, router_request_types}; @@ -503,18 +508,80 @@ where amount = amount + tax_amount; } + let currency = payment_data + .get_payment_attempt() + .currency + .get_required_value("currency")?; + Ok(services::ApplicationResponse::JsonWithHeaders(( Self { net_amount: amount, payment_id: payment_data.get_payment_attempt().payment_id.clone(), order_tax_amount, shipping_cost, + display_amount: api_models::payments::DisplayAmountOnSdk::foreign_try_from(( + amount, + shipping_cost, + order_tax_amount, + currency, + ))?, }, vec![], ))) } } +impl ForeignTryFrom<(MinorUnit, Option, Option, Currency)> + for api_models::payments::DisplayAmountOnSdk +{ + type Error = error_stack::Report; + + fn foreign_try_from( + (net_amount, shipping_cost, order_tax_amount, currency): ( + MinorUnit, + Option, + Option, + Currency, + ), + ) -> Result { + let major_unit_convertor = StringMajorUnitForConnector; + + let sdk_net_amount = major_unit_convertor + .convert(net_amount, currency) + .change_context(errors::ApiErrorResponse::PreconditionFailed { + message: "Failed to convert net_amount to base unit".to_string(), + }) + .attach_printable("Failed to convert net_amount to string major unit")?; + + let sdk_shipping_cost = shipping_cost + .map(|cost| { + major_unit_convertor + .convert(cost, currency) + .change_context(errors::ApiErrorResponse::PreconditionFailed { + message: "Failed to convert shipping_cost to base unit".to_string(), + }) + .attach_printable("Failed to convert shipping_cost to string major unit") + }) + .transpose()?; + + let sdk_order_tax_amount = order_tax_amount + .map(|cost| { + major_unit_convertor + .convert(cost, currency) + .change_context(errors::ApiErrorResponse::PreconditionFailed { + message: "Failed to convert order_tax_amount to base unit".to_string(), + }) + .attach_printable("Failed to convert order_tax_amount to string major unit") + }) + .transpose()?; + Ok(Self { + net_amount: sdk_net_amount, + shipping_cost: sdk_shipping_cost, + order_tax_amount: sdk_order_tax_amount, + }) + } +} + impl ToResponse for api::VerifyResponse where F: Clone, From 5e47f63781249d764011c453fcd5499114a3e0da Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:11:06 +0000 Subject: [PATCH 4/4] chore(version): 2024.09.13.0-hotfix2 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b1285acb6ad..66cd84096162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.09.13.0-hotfix2 + +### Refactors + +- **core:** Update response for PaymentsDynamicTaxCalculationResponse ([#5910](https://github.com/juspay/hyperswitch/pull/5910)) ([`f462c73`](https://github.com/juspay/hyperswitch/commit/f462c7329982e6f8c1c266a6e19f33560fba6615)) + +- - - + ## 2024.09.13.0-hotfix1 ### Revert