From b6b9e4f912e1c61cd31ab91be587ffb08c9f3a5b Mon Sep 17 00:00:00 2001 From: Seemebadnekai <51400137+SagarDevAchar@users.noreply.github.com> Date: Sun, 5 Nov 2023 16:21:32 +0530 Subject: [PATCH] feat(connector): [Fiserv] Currency Unit Conversion (#2715) --- crates/router/src/connector/fiserv.rs | 28 +++++- .../src/connector/fiserv/transformers.rs | 97 +++++++++++++------ 2 files changed, 95 insertions(+), 30 deletions(-) diff --git a/crates/router/src/connector/fiserv.rs b/crates/router/src/connector/fiserv.rs index 70f58ffe6eb0..35d40f1a3fb6 100644 --- a/crates/router/src/connector/fiserv.rs +++ b/crates/router/src/connector/fiserv.rs @@ -104,6 +104,10 @@ impl ConnectorCommon for Fiserv { "fiserv" } + fn get_currency_unit(&self) -> api::CurrencyUnit { + api::CurrencyUnit::Base + } + fn common_get_content_type(&self) -> &'static str { "application/json" } @@ -400,7 +404,13 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_request = fiserv::FiservCaptureRequest::try_from(req)?; + let router_obj = fiserv::FiservRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.amount_to_capture, + req, + ))?; + let connector_request = fiserv::FiservCaptureRequest::try_from(&router_obj)?; let fiserv_payments_capture_request = types::RequestBody::log_and_get_request_body( &connector_request, utils::Encode::::encode_to_string_of_json, @@ -505,7 +515,13 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_request = fiserv::FiservPaymentsRequest::try_from(req)?; + let router_obj = fiserv::FiservRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.amount, + req, + ))?; + let connector_request = fiserv::FiservPaymentsRequest::try_from(&router_obj)?; let fiserv_payments_request = types::RequestBody::log_and_get_request_body( &connector_request, utils::Encode::::encode_to_string_of_json, @@ -592,7 +608,13 @@ impl ConnectorIntegration, ) -> CustomResult, errors::ConnectorError> { - let connector_request = fiserv::FiservRefundRequest::try_from(req)?; + let router_obj = fiserv::FiservRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.refund_amount, + req, + ))?; + let connector_request = fiserv::FiservRefundRequest::try_from(&router_obj)?; let fiserv_refund_request = types::RequestBody::log_and_get_request_body( &connector_request, utils::Encode::::encode_to_string_of_json, diff --git a/crates/router/src/connector/fiserv/transformers.rs b/crates/router/src/connector/fiserv/transformers.rs index ae8eed0af314..2d07da7f47a4 100644 --- a/crates/router/src/connector/fiserv/transformers.rs +++ b/crates/router/src/connector/fiserv/transformers.rs @@ -9,6 +9,38 @@ use crate::{ types::{self, api, storage::enums}, }; +#[derive(Debug, Serialize)] +pub struct FiservRouterData { + pub amount: String, + pub router_data: T, +} + +impl + TryFrom<( + &types::api::CurrencyUnit, + types::storage::enums::Currency, + i64, + T, + )> for FiservRouterData +{ + type Error = error_stack::Report; + + fn try_from( + (currency_unit, currency, amount, router_data): ( + &types::api::CurrencyUnit, + types::storage::enums::Currency, + i64, + T, + ), + ) -> Result { + let amount = utils::get_amount_as_string(currency_unit, amount, currency)?; + Ok(Self { + amount, + router_data, + }) + } +} + #[derive(Debug, Serialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub struct FiservPaymentsRequest { @@ -99,23 +131,25 @@ pub enum TransactionInteractionPosConditionCode { CardNotPresentEcom, } -impl TryFrom<&types::PaymentsAuthorizeRouterData> for FiservPaymentsRequest { +impl TryFrom<&FiservRouterData<&types::PaymentsAuthorizeRouterData>> for FiservPaymentsRequest { type Error = error_stack::Report; - fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { - let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?; + fn try_from( + item: &FiservRouterData<&types::PaymentsAuthorizeRouterData>, + ) -> Result { + let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?; let amount = Amount { - total: utils::to_currency_base_unit(item.request.amount, item.request.currency)?, - currency: item.request.currency.to_string(), + total: item.amount.clone(), + currency: item.router_data.request.currency.to_string(), }; let transaction_details = TransactionDetails { capture_flag: Some(matches!( - item.request.capture_method, + item.router_data.request.capture_method, Some(enums::CaptureMethod::Automatic) | None )), reversal_reason_code: None, - merchant_transaction_id: item.connector_request_reference_id.clone(), + merchant_transaction_id: item.router_data.connector_request_reference_id.clone(), }; - let metadata = item.get_connector_meta()?; + let metadata = item.router_data.get_connector_meta()?; let session: SessionObject = metadata .parse_value("SessionObject") .change_context(errors::ConnectorError::RequestEncodingFailed)?; @@ -133,7 +167,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for FiservPaymentsRequest { //card not present in online transaction pos_condition_code: TransactionInteractionPosConditionCode::CardNotPresentEcom, }; - let source = match item.request.payment_method_data.clone() { + let source = match item.router_data.request.payment_method_data.clone() { api::PaymentMethodData::Card(ref ccard) => { let card = CardData { card_data: ccard.card_number.clone(), @@ -389,35 +423,40 @@ pub struct SessionObject { pub terminal_id: String, } -impl TryFrom<&types::PaymentsCaptureRouterData> for FiservCaptureRequest { +impl TryFrom<&FiservRouterData<&types::PaymentsCaptureRouterData>> for FiservCaptureRequest { type Error = error_stack::Report; - fn try_from(item: &types::PaymentsCaptureRouterData) -> Result { - let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?; + fn try_from( + item: &FiservRouterData<&types::PaymentsCaptureRouterData>, + ) -> Result { + let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?; let metadata = item + .router_data .connector_meta_data .clone() .ok_or(errors::ConnectorError::RequestEncodingFailed)?; let session: SessionObject = metadata .parse_value("SessionObject") .change_context(errors::ConnectorError::RequestEncodingFailed)?; - let amount = - utils::to_currency_base_unit(item.request.amount_to_capture, item.request.currency)?; Ok(Self { amount: Amount { - total: amount, - currency: item.request.currency.to_string(), + total: item.amount.clone(), + currency: item.router_data.request.currency.to_string(), }, transaction_details: TransactionDetails { capture_flag: Some(true), reversal_reason_code: None, - merchant_transaction_id: item.connector_request_reference_id.clone(), + merchant_transaction_id: item.router_data.connector_request_reference_id.clone(), }, merchant_details: MerchantDetails { merchant_id: auth.merchant_account, terminal_id: Some(session.terminal_id), }, reference_transaction_details: ReferenceTransactionDetails { - reference_transaction_id: item.request.connector_transaction_id.to_string(), + reference_transaction_id: item + .router_data + .request + .connector_transaction_id + .to_string(), }, }) } @@ -477,11 +516,14 @@ pub struct FiservRefundRequest { reference_transaction_details: ReferenceTransactionDetails, } -impl TryFrom<&types::RefundsRouterData> for FiservRefundRequest { +impl TryFrom<&FiservRouterData<&types::RefundsRouterData>> for FiservRefundRequest { type Error = error_stack::Report; - fn try_from(item: &types::RefundsRouterData) -> Result { - let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?; + fn try_from( + item: &FiservRouterData<&types::RefundsRouterData>, + ) -> Result { + let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?; let metadata = item + .router_data .connector_meta_data .clone() .ok_or(errors::ConnectorError::RequestEncodingFailed)?; @@ -490,18 +532,19 @@ impl TryFrom<&types::RefundsRouterData> for FiservRefundRequest { .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Self { amount: Amount { - total: utils::to_currency_base_unit( - item.request.refund_amount, - item.request.currency, - )?, - currency: item.request.currency.to_string(), + total: item.amount.clone(), + currency: item.router_data.request.currency.to_string(), }, merchant_details: MerchantDetails { merchant_id: auth.merchant_account, terminal_id: Some(session.terminal_id), }, reference_transaction_details: ReferenceTransactionDetails { - reference_transaction_id: item.request.connector_transaction_id.to_string(), + reference_transaction_id: item + .router_data + .request + .connector_transaction_id + .to_string(), }, }) }