From 751f16eaee254ab8f0068e2e9e81e3e4b7fe133f Mon Sep 17 00:00:00 2001 From: SamraatBansal <55536657+SamraatBansal@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:17:58 +0530 Subject: [PATCH] refactor(connector): [noon] update and add recommended fields (#2381) Co-authored-by: Arjun Karthik --- .../router/src/connector/noon/transformers.rs | 56 ++++++++++++++++++- crates/router/src/connector/utils.rs | 8 +++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs index 749c8c8dea7b..21a6501bb50f 100644 --- a/crates/router/src/connector/noon/transformers.rs +++ b/crates/router/src/connector/noon/transformers.rs @@ -1,3 +1,4 @@ +use common_utils::pii; use error_stack::ResultExt; use masking::Secret; use serde::{Deserialize, Serialize}; @@ -36,6 +37,23 @@ pub struct NoonSubscriptionData { name: String, } +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct NoonBillingAddress { + street: Option>, + street2: Option>, + city: Option, + state_province: Option>, + country: Option, + postal_code: Option>, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct NoonBilling { + address: NoonBillingAddress, +} + #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct NoonOrder { @@ -46,6 +64,7 @@ pub struct NoonOrder { reference: String, //Short description of the order. name: String, + ip_address: Option>, } #[derive(Debug, Serialize)] @@ -164,6 +183,7 @@ pub struct NoonPaymentsRequest { configuration: NoonConfiguration, payment_data: NoonPaymentData, subscription: Option, + billing: Option, } impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { @@ -247,6 +267,27 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { .take(50) .collect(); + let ip_address = item.request.get_ip_address_as_optional(); + + let channel = NoonChannels::Web; + + let billing = item + .address + .billing + .clone() + .and_then(|billing_address| billing_address.address) + .map(|address| NoonBilling { + address: NoonBillingAddress { + street: address.line1, + street2: address.line2, + city: address.city, + // If state is passed in request, country becomes mandatory, keep a check while debugging failed payments + state_province: address.state, + country: address.country, + postal_code: address.zip, + }, + }); + let (subscription, tokenize_c_c) = match item.request.setup_future_usage.is_some().then_some(( NoonSubscriptionData { @@ -261,10 +302,11 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { let order = NoonOrder { amount: conn_utils::to_currency_base_unit(item.request.amount, item.request.currency)?, currency, - channel: NoonChannels::Web, + channel, category, reference: item.connector_request_reference_id.clone(), name, + ip_address, }; let payment_action = if item.request.is_auto_capture()? { NoonPaymentActions::Sale @@ -274,6 +316,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { Ok(Self { api_operation: NoonApiOperations::Initiate, order, + billing, configuration: NoonConfiguration { payment_action, return_url: item.request.router_return_url.clone(), @@ -333,7 +376,8 @@ impl From for enums::AttemptStatus { fn from(item: NoonPaymentStatus) -> Self { match item { NoonPaymentStatus::Authorized => Self::Authorized, - NoonPaymentStatus::Captured | NoonPaymentStatus::PartiallyCaptured => Self::Charged, + NoonPaymentStatus::Captured => Self::Charged, + NoonPaymentStatus::PartiallyCaptured => Self::PartialCharged, NoonPaymentStatus::Reversed => Self::Voided, NoonPaymentStatus::Cancelled | NoonPaymentStatus::Expired => Self::AuthenticationFailed, NoonPaymentStatus::ThreeDsEnrollInitiated | NoonPaymentStatus::ThreeDsEnrollChecked => { @@ -444,6 +488,7 @@ pub struct NoonActionTransaction { #[serde(rename_all = "camelCase")] pub struct NoonActionOrder { id: String, + cancellation_reason: Option, } #[derive(Debug, Serialize)] @@ -459,6 +504,7 @@ impl TryFrom<&types::PaymentsCaptureRouterData> for NoonPaymentsActionRequest { fn try_from(item: &types::PaymentsCaptureRouterData) -> Result { let order = NoonActionOrder { id: item.request.connector_transaction_id.clone(), + cancellation_reason: None, }; let transaction = NoonActionTransaction { amount: conn_utils::to_currency_base_unit( @@ -488,6 +534,11 @@ impl TryFrom<&types::PaymentsCancelRouterData> for NoonPaymentsCancelRequest { fn try_from(item: &types::PaymentsCancelRouterData) -> Result { let order = NoonActionOrder { id: item.request.connector_transaction_id.clone(), + cancellation_reason: item + .request + .cancellation_reason + .clone() + .map(|reason| reason.chars().take(100).collect()), // Max 100 chars }; Ok(Self { api_operation: NoonApiOperations::Reverse, @@ -501,6 +552,7 @@ impl TryFrom<&types::RefundsRouterData> for NoonPaymentsActionRequest { fn try_from(item: &types::RefundsRouterData) -> Result { let order = NoonActionOrder { id: item.request.connector_transaction_id.clone(), + cancellation_reason: None, }; let transaction = NoonActionTransaction { amount: conn_utils::to_currency_base_unit( diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 4f59c38ea7c9..455646f619e2 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -283,6 +283,7 @@ pub trait PaymentsAuthorizeRequestData { fn get_payment_method_type(&self) -> Result; fn get_connector_mandate_id(&self) -> Result; fn get_complete_authorize_url(&self) -> Result; + fn get_ip_address_as_optional(&self) -> Option>; } impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { @@ -370,6 +371,13 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { self.connector_mandate_id() .ok_or_else(missing_field_err("connector_mandate_id")) } + fn get_ip_address_as_optional(&self) -> Option> { + self.browser_info.clone().and_then(|browser_info| { + browser_info + .ip_address + .map(|ip| Secret::new(ip.to_string())) + }) + } } pub trait ConnectorCustomerData {