From 2a7c6a8c3a719522f846faa04eee11afc0dae465 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 12 Dec 2023 00:09:50 +0530 Subject: [PATCH 01/19] feat(core): enable surcharge support for all connectors --- crates/api_models/src/payments.rs | 4 +--- .../src/payments/payment_attempt.rs | 10 +++++++++ crates/router/src/connector/paypal.rs | 9 +------- crates/router/src/connector/trustpay.rs | 20 +++-------------- crates/router/src/connector/utils.rs | 4 ++-- .../src/core/payments/flows/authorize_flow.rs | 6 ----- .../payments/operations/payment_approve.rs | 2 +- .../payments/operations/payment_cancel.rs | 2 +- .../payments/operations/payment_capture.rs | 2 +- .../operations/payment_complete_authorize.rs | 2 +- .../payments/operations/payment_confirm.rs | 6 ++--- .../payments/operations/payment_create.rs | 10 ++++++++- .../payments/operations/payment_reject.rs | 2 +- .../payments/operations/payment_response.rs | 5 +---- .../payments/operations/payment_session.rs | 2 +- .../core/payments/operations/payment_start.rs | 2 +- .../payments/operations/payment_status.rs | 2 +- .../payments/operations/payment_update.rs | 22 +++++++++++++++---- .../payments_incremental_authorization.rs | 2 +- crates/router/src/services/api.rs | 4 ---- crates/router/src/types.rs | 2 +- 21 files changed, 58 insertions(+), 62 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index b19f4d7b7db..7c5f4585656 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -319,9 +319,7 @@ impl PaymentsRequest { pub fn get_total_capturable_amount(&self) -> Option { let surcharge_amount = self .surcharge_details - .map(|surcharge_details| { - surcharge_details.surcharge_amount + surcharge_details.tax_amount.unwrap_or(0) - }) + .map(|surcharge_details| surcharge_details.get_total_surcharge_amount()) .unwrap_or(0); self.amount .map(|amount| i64::from(amount) + surcharge_amount) diff --git a/crates/data_models/src/payments/payment_attempt.rs b/crates/data_models/src/payments/payment_attempt.rs index f7b849f1d4e..61e48cb64e9 100644 --- a/crates/data_models/src/payments/payment_attempt.rs +++ b/crates/data_models/src/payments/payment_attempt.rs @@ -156,6 +156,16 @@ pub struct PaymentAttempt { pub unified_message: Option, } +impl PaymentAttempt { + pub fn get_total_amount(&self) -> i64 { + self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) + } + pub fn get_total_surcharge_amount(&self) -> Option { + self.surcharge_amount + .map(|surcharge_amount| surcharge_amount + self.tax_amount.unwrap_or(0)) + } +} + #[derive(Clone, Debug, Eq, PartialEq)] pub struct PaymentListFilters { pub connector: Vec, diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs index a0d39178902..f449255a5f6 100644 --- a/crates/router/src/connector/paypal.rs +++ b/crates/router/src/connector/paypal.rs @@ -265,10 +265,6 @@ impl ConnectorValidation for Paypal { ), } } - - fn validate_if_surcharge_implemented(&self) -> CustomResult<(), errors::ConnectorError> { - Ok(()) - } } impl @@ -428,10 +424,7 @@ impl ConnectorIntegration CustomResult<(), errors::ConnectorError> { - Ok(()) - } -} +impl ConnectorValidation for Trustpay {} impl api::Payment for Trustpay {} @@ -435,12 +431,7 @@ impl _connectors: &settings::Connectors, ) -> CustomResult, errors::ConnectorError> { let currency = req.request.get_currency()?; - let amount = req - .request - .surcharge_details - .as_ref() - .map(|surcharge_details| surcharge_details.final_amount) - .unwrap_or(req.request.get_amount()?); + let amount = req.request.get_amount()?; let connector_router_data = trustpay::TrustpayRouterData::try_from(( &self.get_currency_unit(), currency, @@ -552,12 +543,7 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let amount = req - .request - .surcharge_details - .as_ref() - .map(|surcharge_details| surcharge_details.final_amount) - .unwrap_or(req.request.amount); + let amount = req.request.amount; let connector_router_data = trustpay::TrustpayRouterData::try_from(( &self.get_currency_unit(), req.request.currency, diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 3990fc9c7e4..1133dc29739 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -27,8 +27,8 @@ use crate::{ }, pii::PeekInterface, types::{ - self, api, storage::payment_attempt::PaymentAttemptExt, transformers::ForeignTryFrom, - ApplePayPredecryptData, PaymentsCancelData, ResponseId, + self, api, transformers::ForeignTryFrom, ApplePayPredecryptData, PaymentsCancelData, + ResponseId, }, utils::{OptionExt, ValueExt}, }; diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs index 4ef23f481a2..c934c7c2cd6 100644 --- a/crates/router/src/core/payments/flows/authorize_flow.rs +++ b/crates/router/src/core/payments/flows/authorize_flow.rs @@ -76,12 +76,6 @@ impl Feature for types::PaymentsAu .connector .validate_capture_method(self.request.capture_method) .to_payment_failed_response()?; - if self.request.surcharge_details.is_some() { - connector - .connector - .validate_if_surcharge_implemented() - .to_payment_failed_response()?; - } if self.should_proceed_with_authorize() { self.decide_authentication_type(); diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs index 37a3e1a1412..31b06e8cb2f 100644 --- a/crates/router/src/core/payments/operations/payment_approve.rs +++ b/crates/router/src/core/payments/operations/payment_approve.rs @@ -139,7 +139,7 @@ impl payment_method_type.or(payment_attempt.payment_method_type); payment_attempt.payment_experience = request.payment_experience; currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.amount.into(); + amount = payment_attempt.get_total_amount().into(); helpers::validate_customer_id_mandatory_cases( request.setup_future_usage.is_some(), diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs index 7c8fbcc3497..5e6a35f3300 100644 --- a/crates/router/src/core/payments/operations/payment_cancel.rs +++ b/crates/router/src/core/payments/operations/payment_cancel.rs @@ -102,7 +102,7 @@ impl .await?; let currency = payment_attempt.currency.get_required_value("currency")?; - let amount = payment_attempt.amount.into(); + let amount = payment_attempt.get_total_amount().into(); payment_attempt.cancellation_reason = request.cancellation_reason.clone(); diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs index 65b91f0401c..f0d517d2891 100644 --- a/crates/router/src/core/payments/operations/payment_capture.rs +++ b/crates/router/src/core/payments/operations/payment_capture.rs @@ -124,7 +124,7 @@ impl currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.amount.into(); + amount = payment_attempt.get_total_amount().into(); let shipping_address = helpers::create_or_find_address_for_payment_by_request( db, diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index 48b503b96b0..fd758e7a965 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -135,7 +135,7 @@ impl .payment_experience .or(payment_attempt.payment_experience); currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.amount.into(); + amount = payment_attempt.get_total_amount().into(); helpers::validate_customer_id_mandatory_cases( request.setup_future_usage.is_some(), diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 612ddadc1c5..b62ae5f89b5 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -377,7 +377,7 @@ impl payment_attempt.capture_method = request.capture_method.or(payment_attempt.capture_method); currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.amount.into(); + amount = payment_attempt.get_total_amount().into(); helpers::validate_customer_id_mandatory_cases( request.setup_future_usage.is_some(), @@ -731,7 +731,7 @@ impl m_db.update_payment_attempt_with_attempt_id( m_payment_data_payment_attempt, storage::PaymentAttemptUpdate::ConfirmUpdate { - amount: payment_data.amount.into(), + amount: payment_data.payment_attempt.amount, currency: payment_data.currency, status: attempt_status, payment_method, @@ -779,7 +779,7 @@ impl m_db.update_payment_intent( m_payment_data_payment_intent, storage::PaymentIntentUpdate::Update { - amount: payment_data.amount.into(), + amount: payment_data.payment_intent.amount, currency: payment_data.currency, setup_future_usage, status: intent_status, diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index cbce6ba9e97..667edf578a1 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -297,7 +297,7 @@ impl .map(|(payment_method_data, additional_payment_data)| { payment_method_data.apply_additional_payment_data(additional_payment_data) }); - + let amount = payment_attempt.get_total_amount().into(); let payment_data = PaymentData { flow: PhantomData, payment_intent, @@ -644,6 +644,12 @@ impl PaymentCreate { } else { utils::get_payment_attempt_id(payment_id, 1) }; + let surcharge_amount = request + .surcharge_details + .map(|surcharge_details| surcharge_details.surcharge_amount); + let tax_amount = request + .surcharge_details + .and_then(|surcharge_details| surcharge_details.tax_amount); Ok(( storage::PaymentAttemptNew { @@ -669,6 +675,8 @@ impl PaymentCreate { payment_token: request.payment_token.clone(), mandate_id: request.mandate_id.clone(), business_sub_label: request.business_sub_label.clone(), + surcharge_amount, + tax_amount, mandate_details: request .mandate_data .as_ref() diff --git a/crates/router/src/core/payments/operations/payment_reject.rs b/crates/router/src/core/payments/operations/payment_reject.rs index 03bf6dd46b6..cd9fa926d19 100644 --- a/crates/router/src/core/payments/operations/payment_reject.rs +++ b/crates/router/src/core/payments/operations/payment_reject.rs @@ -100,7 +100,7 @@ impl .await?; let currency = payment_attempt.currency.get_required_value("currency")?; - let amount = payment_attempt.amount.into(); + let amount = payment_attempt.get_total_amount().into(); let frm_response = db .find_fraud_check_by_payment_id(payment_intent.payment_id.clone(), merchant_account.merchant_id.clone()) diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index f92487d74a7..8b301c525fd 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -24,10 +24,7 @@ use crate::{ services::RedirectForm, types::{ self, api, - storage::{ - self, enums, - payment_attempt::{AttemptStatusExt, PaymentAttemptExt}, - }, + storage::{self, enums, payment_attempt::AttemptStatusExt}, transformers::{ForeignFrom, ForeignTryFrom}, CaptureSyncResponse, }, diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index 572bc710b96..d0c96dfa58f 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -93,7 +93,7 @@ impl payment_attempt.payment_method = Some(storage_enums::PaymentMethod::Wallet); - let amount = payment_intent.amount.into(); + let amount = payment_attempt.get_total_amount().into(); let shipping_address = helpers::create_or_find_address_for_payment_by_request( db, diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index 887edd030d1..a471f92eee3 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -89,7 +89,7 @@ impl .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.amount.into(); + amount = payment_attempt.get_total_amount().into(); let shipping_address = helpers::create_or_find_address_for_payment_by_request( db, diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index 0320cf50663..cfdf37abef9 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -244,7 +244,7 @@ async fn get_tracker_for_sync< let payment_id_str = payment_attempt.payment_id.clone(); currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.amount.into(); + amount = payment_attempt.get_total_amount().into(); let shipping_address = helpers::get_address_by_id( db, diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 84f11124c73..5ca27de9889 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use api_models::enums::FrmSuggestion; +use api_models::{enums::FrmSuggestion, payments::RequestSurchargeDetails}; use async_trait::async_trait; use common_utils::ext_traits::{AsyncExt, Encode, ValueExt}; use error_stack::{report, IntoReport, ResultExt}; @@ -281,11 +281,25 @@ impl }) .await .transpose()?; - let next_operation: BoxedOperation<'a, F, api::PaymentsRequest, Ctx> = + let (next_operation, amount): (BoxedOperation<'a, F, api::PaymentsRequest, Ctx>, _) = if request.confirm.unwrap_or(false) { - Box::new(operations::PaymentConfirm) + let amount = { + let amount = request + .amount + .map(Into::into) + .unwrap_or(payment_attempt.amount); + payment_attempt.amount = amount; + payment_intent.amount = amount; + let surcharge_amount = request + .surcharge_details + .as_ref() + .map(RequestSurchargeDetails::get_total_surcharge_amount) + .or(payment_attempt.get_total_surcharge_amount()); + (amount + surcharge_amount.unwrap_or(0)).into() + }; + (Box::new(operations::PaymentConfirm), amount) } else { - Box::new(self) + (Box::new(self), amount) }; payment_intent.status = match request.payment_method_data.as_ref() { diff --git a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs index 7346c46df12..025143380e4 100644 --- a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs +++ b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs @@ -92,7 +92,7 @@ impl .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; let currency = payment_attempt.currency.get_required_value("currency")?; - let amount = payment_attempt.amount; + let amount = payment_attempt.get_total_amount(); let profile_id = payment_intent .profile_id diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs index 918aab929ac..83f532fceb1 100644 --- a/crates/router/src/services/api.rs +++ b/crates/router/src/services/api.rs @@ -96,10 +96,6 @@ pub trait ConnectorValidation: ConnectorCommon { fn is_webhook_source_verification_mandatory(&self) -> bool { false } - - fn validate_if_surcharge_implemented(&self) -> CustomResult<(), errors::ConnectorError> { - Err(errors::ConnectorError::NotImplemented(format!("Surcharge for {}", self.id())).into()) - } } #[async_trait::async_trait] diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index aa563c647ea..6f50bf9852a 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -38,7 +38,7 @@ use crate::{ payments::{types, PaymentData, RecurringMandatePaymentData}, }, services, - types::{storage::payment_attempt::PaymentAttemptExt, transformers::ForeignFrom}, + types::transformers::ForeignFrom, utils::OptionExt, }; From 22ca09d9a838cf44a45f573a2507d4407fb616bc Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 12 Dec 2023 09:42:30 +0530 Subject: [PATCH 02/19] fix: calculate display_total_surcharge_amount from int --- crates/router/src/core/payments/types.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs index 001082d2c92..84f85b8b7d4 100644 --- a/crates/router/src/core/payments/types.rs +++ b/crates/router/src/core/payments/types.rs @@ -219,13 +219,15 @@ impl ForeignTryFrom<(&SurchargeDetails, &PaymentAttempt)> for SurchargeDetailsRe currency.to_currency_base_unit_asf64(surcharge_details.tax_on_surcharge_amount)?; let display_final_amount = currency.to_currency_base_unit_asf64(surcharge_details.final_amount)?; + let display_total_surcharge_amount = currency.to_currency_base_unit_asf64( + surcharge_details.surcharge_amount + surcharge_details.tax_on_surcharge_amount, + )?; Ok(Self { surcharge: surcharge_details.surcharge.clone().into(), tax_on_surcharge: surcharge_details.tax_on_surcharge.clone().map(Into::into), display_surcharge_amount, display_tax_on_surcharge_amount, - display_total_surcharge_amount: display_surcharge_amount - + display_tax_on_surcharge_amount, + display_total_surcharge_amount, display_final_amount, }) } From e4f0c429be9b837342729d910b1bc54cc982ea98 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 12 Dec 2023 12:27:23 +0530 Subject: [PATCH 03/19] address comments --- crates/router/src/connector/utils.rs | 25 +++++++++++++++++++ .../surcharge_decision_configs.rs | 1 + crates/router/src/core/payments.rs | 1 + .../router/src/core/payments/transformers.rs | 21 +++++++++++++--- crates/router/src/core/payments/types.rs | 3 +++ crates/router/src/types.rs | 8 ++++++ 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 1133dc29739..25c51c5425e 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -349,6 +349,10 @@ pub trait PaymentsAuthorizeRequestData { fn get_connector_mandate_id(&self) -> Result; fn get_complete_authorize_url(&self) -> Result; fn get_ip_address_as_optional(&self) -> Option>; + fn get_original_amount(&self) -> i64; + fn get_surcharge_amount(&self) -> Option; + fn get_tax_on_surcharge_amount(&self) -> Option; + fn get_total_surcharge_amount(&self) -> Option; } pub trait PaymentMethodTokenizationRequestData { @@ -455,6 +459,27 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { .map(|ip| Secret::new(ip.to_string())) }) } + fn get_original_amount(&self) -> i64 { + self.surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.original_amount) + .unwrap_or(self.amount) + } + fn get_surcharge_amount(&self) -> Option { + self.surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.surcharge_amount) + } + fn get_tax_on_surcharge_amount(&self) -> Option { + self.surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.tax_on_surcharge_amount) + } + fn get_total_surcharge_amount(&self) -> Option { + self.surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.get_total_surcharge_amount()) + } } pub trait ConnectorCustomerData { diff --git a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs index e130795e945..db1064b36a7 100644 --- a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs +++ b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs @@ -310,6 +310,7 @@ fn get_surcharge_details_from_surcharge_output( .transpose()? .unwrap_or(0); Ok(types::SurchargeDetails { + original_amount: payment_attempt.amount, surcharge: match surcharge_details.surcharge { surcharge_decision_configs::SurchargeOutput::Fixed { amount } => { common_utils_types::Surcharge::Fixed(amount) diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 73af17f9d66..ab7f8a81f96 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -562,6 +562,7 @@ where payment_data.payment_attempt.amount + surcharge_amount + tax_on_surcharge_amount; Ok(Some(api::SessionSurchargeDetails::PreDetermined( types::SurchargeDetails { + original_amount: payment_data.payment_attempt.amount, surcharge: Surcharge::Fixed(surcharge_amount), tax_on_surcharge: None, surcharge_amount, diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index bd6d03e5625..bac59465b45 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -1032,6 +1032,11 @@ impl TryFrom> for types::PaymentsAuthoriz None } }); + let amount = payment_data + .surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.final_amount) + .unwrap_or(payment_data.amount.into()); Ok(Self { payment_method_data: payment_method_data.get_required_value("payment_method_data")?, setup_future_usage: payment_data.payment_intent.setup_future_usage, @@ -1042,7 +1047,7 @@ impl TryFrom> for types::PaymentsAuthoriz statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix, statement_descriptor: payment_data.payment_intent.statement_descriptor_name, capture_method: payment_data.payment_attempt.capture_method, - amount: payment_data.amount.into(), + amount, currency: payment_data.currency, browser_info, email: payment_data.email, @@ -1417,6 +1422,11 @@ impl TryFrom> for types::CompleteAuthoriz payload: redirect.json_payload, } }); + let amount = payment_data + .surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.final_amount) + .unwrap_or(payment_data.amount.into()); Ok(Self { setup_future_usage: payment_data.payment_intent.setup_future_usage, @@ -1426,7 +1436,7 @@ impl TryFrom> for types::CompleteAuthoriz confirm: payment_data.payment_attempt.confirm, statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix, capture_method: payment_data.payment_attempt.capture_method, - amount: payment_data.amount.into(), + amount, currency: payment_data.currency, browser_info, email: payment_data.email, @@ -1491,12 +1501,17 @@ impl TryFrom> for types::PaymentsPreProce .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "browser_info", })?; + let amount = payment_data + .surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.final_amount) + .unwrap_or(payment_data.amount.into()); Ok(Self { payment_method_data, email: payment_data.email, currency: Some(payment_data.currency), - amount: Some(payment_data.amount.into()), + amount: Some(amount), payment_method_type: payment_data.payment_attempt.payment_method_type, setup_mandate_details: payment_data.setup_mandate, capture_method: payment_data.payment_attempt.capture_method, diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs index 84f85b8b7d4..00160db9855 100644 --- a/crates/router/src/core/payments/types.rs +++ b/crates/router/src/core/payments/types.rs @@ -178,6 +178,8 @@ impl MultipleCaptureData { #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] pub struct SurchargeDetails { + /// original_amount + pub original_amount: i64, /// surcharge value pub surcharge: common_types::Surcharge, /// tax on surcharge value @@ -198,6 +200,7 @@ impl From<(&RequestSurchargeDetails, &PaymentAttempt)> for SurchargeDetails { let surcharge_amount = request_surcharge_details.surcharge_amount; let tax_on_surcharge_amount = request_surcharge_details.tax_amount.unwrap_or(0); Self { + original_amount: payment_attempt.amount, surcharge: common_types::Surcharge::Fixed(request_surcharge_details.surcharge_amount), tax_on_surcharge: None, surcharge_amount, diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index 6f50bf9852a..e6123235209 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -371,6 +371,14 @@ pub struct PayoutsFulfillResponseData { #[derive(Debug, Clone)] pub struct PaymentsAuthorizeData { pub payment_method_data: payments::PaymentMethodData, + /// total amount (original_amount + surcharge_amount + tax_on_surcharge_amount) + /// If connector supports separate field for surcharge amount, consider using below functions defined on `PaymentsAuthorizeData` to fetch original amount and surcharge amount separately + /// ``` + /// get_original_amount() + /// get_surcharge_amount() + /// get_tax_on_surcharge_amount() + /// get_total_surcharge_amount() // returns surcharge_amount + tax_on_surcharge_amount + /// ``` pub amount: i64, pub email: Option, pub currency: storage_enums::Currency, From 54d42875a1df3c7271e84189c4166077fc469beb Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 12 Dec 2023 14:05:20 +0530 Subject: [PATCH 04/19] remove redundant call to populate_payment_data() and handle surcharge for payment retry --- crates/router/src/core/payments.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index ab7f8a81f96..777ba9882c2 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -204,10 +204,6 @@ where ); if should_continue_transaction { - operation - .to_domain()? - .populate_payment_data(state, &mut payment_data, &merchant_account) - .await?; payment_data = match connector_details { api::ConnectorCallType::PreDetermined(connector) => { let schedule_time = if should_add_task_to_process_tracker { @@ -484,6 +480,13 @@ where .surcharge_applicable .unwrap_or(false) { + if let Some(surcharge_details) = payment_data.payment_attempt.get_surcharge_details() { + // if retry payment, surcharge would have been populated from the previous attempt. Use the same surcharge + let surcharge_details = + types::SurchargeDetails::from((&surcharge_details, &payment_data.payment_attempt)); + payment_data.surcharge_details = Some(surcharge_details); + return Ok(()); + } let raw_card_key = payment_data .payment_method_data .as_ref() From 4bcd7f61cb9e1e883aa2e3eb134c4119a20ac856 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 12 Dec 2023 16:08:10 +0530 Subject: [PATCH 05/19] fix: add net_amount field in PaymentResponse --- crates/api_models/src/payments.rs | 5 +++++ crates/router/src/core/payments/transformers.rs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 7c5f4585656..7a148b2973c 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -2023,6 +2023,11 @@ pub struct PaymentsResponse { #[schema(example = 100)] pub amount: i64, + /// The payment net amount. net_amount = amount + surcharge_details.surcharge_amount + surcharge_details.tax_amount, + /// If no surcharge_details, net_amount = amount + #[schema(example = 110)] + pub net_amount: i64, + /// The maximum amount that could be captured from the payment #[schema(minimum = 100, example = 6540)] pub amount_capturable: Option, diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index bac59465b45..8ed9143c445 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -564,6 +564,7 @@ where }); services::ApplicationResponse::JsonWithHeaders(( response + .set_net_amount(payment_attempt.get_total_amount()) .set_payment_id(Some(payment_attempt.payment_id)) .set_merchant_id(Some(payment_attempt.merchant_id)) .set_status(payment_intent.status) @@ -713,6 +714,7 @@ where } None => services::ApplicationResponse::JsonWithHeaders(( api::PaymentsResponse { + net_amount: payment_attempt.get_total_amount(), payment_id: Some(payment_attempt.payment_id), merchant_id: Some(payment_attempt.merchant_id), status: payment_intent.status, From 22313138736f342d6a1327e951270e0067d5ab50 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:50:01 +0000 Subject: [PATCH 06/19] docs(openapi): re-generate OpenAPI specification --- openapi/openapi_spec.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index f77638a43db..b5b8c00b0d5 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -10165,6 +10165,7 @@ "required": [ "status", "amount", + "net_amount", "currency", "payment_method", "attempt_count" @@ -10199,6 +10200,12 @@ "description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,", "example": 100 }, + "net_amount": { + "type": "integer", + "format": "int64", + "description": "The payment net amount. net_amount = amount + surcharge_details.surcharge_amount + surcharge_details.tax_amount,\nIf no surcharge_details, net_amount = amount", + "example": 110 + }, "amount_capturable": { "type": "integer", "format": "int64", From 82cc4389b0e523e1a693745a7b7c6d346a22ec2c Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 12 Dec 2023 19:23:51 +0530 Subject: [PATCH 07/19] do amount operation for PaymentsSessionData --- crates/router/src/core/payments/transformers.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 872d22baa68..4dbd714b83d 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -1300,9 +1300,14 @@ impl TryFrom> for types::PaymentsSessionD .collect::, _>>() }) .transpose()?; + let amount = payment_data + .surcharge_details + .as_ref() + .map(|surcharge_details| surcharge_details.final_amount) + .unwrap_or(payment_data.amount.into()); Ok(Self { - amount: payment_data.amount.into(), + amount, currency: payment_data.currency, country: payment_data.address.billing.and_then(|billing_address| { billing_address.address.and_then(|address| address.country) From a907bb54ce0fb9c3acb0d1facbb793ac7cc39978 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 07:04:51 +0000 Subject: [PATCH 08/19] chore: update Cargo.lock --- Cargo.lock | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f1ab2cd342..b58631632e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1668,7 +1668,7 @@ dependencies = [ "once_cell", "phonenumber", "proptest", - "quick-xml", + "quick-xml 0.28.2", "rand 0.8.5", "regex", "reqwest", @@ -3539,6 +3539,7 @@ version = "0.1.0" dependencies = [ "bytes 1.5.0", "diesel", + "erased-serde", "serde", "serde_json", "subtle", @@ -4330,7 +4331,7 @@ dependencies = [ "itertools 0.11.0", "lazy_static", "nom", - "quick-xml", + "quick-xml 0.28.2", "regex", "regex-cache", "serde", @@ -4621,6 +4622,16 @@ dependencies = [ "serde", ] +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.33" @@ -5087,6 +5098,7 @@ dependencies = [ "openssl", "pm_auth", "qrcode", + "quick-xml 0.31.0", "rand 0.8.5", "rand_chacha 0.3.1", "rdkafka", From 3c386e1c044c2a0dec56717a6167bc8200f18ca5 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Sat, 16 Dec 2023 13:16:40 +0530 Subject: [PATCH 09/19] create net_amount field in payment_attempt --- .../src/payments/payment_attempt.rs | 17 +++++++++ crates/diesel_models/src/payment_attempt.rs | 38 ++++++++++++++++++- .../src/query/payment_attempt.rs | 4 +- crates/diesel_models/src/schema.rs | 1 + crates/diesel_models/src/user/sample_data.rs | 2 + crates/router/src/core/payments/helpers.rs | 1 + .../router/src/core/payments/transformers.rs | 4 +- .../src/mock_db/payment_attempt.rs | 3 +- .../src/payments/payment_attempt.rs | 6 +++ .../down.sql | 2 + .../up.sql | 8 ++++ 11 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 migrations/2023-12-15-062816__net_amount_in_payment_attempt/down.sql create mode 100644 migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql diff --git a/crates/data_models/src/payments/payment_attempt.rs b/crates/data_models/src/payments/payment_attempt.rs index 61e48cb64e9..3e6ba9e37f8 100644 --- a/crates/data_models/src/payments/payment_attempt.rs +++ b/crates/data_models/src/payments/payment_attempt.rs @@ -107,6 +107,7 @@ pub struct PaymentAttempt { pub attempt_id: String, pub status: storage_enums::AttemptStatus, pub amount: i64, + pub net_amount: i64, pub currency: Option, pub save_to_locker: Option, pub connector: Option, @@ -183,6 +184,9 @@ pub struct PaymentAttemptNew { pub attempt_id: String, pub status: storage_enums::AttemptStatus, pub amount: i64, + /// amount + surcharge_amount + tax_amount + /// This field will always be derived before updating in the Database + pub net_amount: i64, pub currency: Option, // pub auto_capture: Option, pub save_to_locker: Option, @@ -230,6 +234,19 @@ pub struct PaymentAttemptNew { pub unified_message: Option, } +impl PaymentAttemptNew { + /// returns amount + surcharge_amount + tax_amount + pub fn calculate_net_amount(&self) -> i64 { + self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) + } + + pub fn populate_derived_fields(self) -> Self { + let mut payment_attempt_new = self; + payment_attempt_new.net_amount = payment_attempt_new.calculate_net_amount(); + payment_attempt_new + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum PaymentAttemptUpdate { Update { diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index b1e8e144a9e..e1c23d4ca58 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -63,6 +63,7 @@ pub struct PaymentAttempt { pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, + pub net_amount: i64, } #[derive(Clone, Debug, Eq, PartialEq, Queryable, Serialize, Deserialize)] @@ -128,6 +129,20 @@ pub struct PaymentAttemptNew { pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, + pub net_amount: i64, +} + +impl PaymentAttemptNew { + /// returns amount + surcharge_amount + tax_amount + pub fn calculate_net_amount(&self) -> i64 { + self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) + } + + pub fn populate_derived_fields(self) -> Self { + let mut payment_attempt_new = self; + payment_attempt_new.net_amount = payment_attempt_new.calculate_net_amount(); + payment_attempt_new + } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -279,6 +294,7 @@ pub enum PaymentAttemptUpdate { #[diesel(table_name = payment_attempt)] pub struct PaymentAttemptUpdateInternal { amount: Option, + net_amount: Option, currency: Option, status: Option, connector_transaction_id: Option, @@ -316,10 +332,29 @@ pub struct PaymentAttemptUpdateInternal { unified_message: Option>, } +impl PaymentAttemptUpdateInternal { + pub fn populate_derived_fields(self, source: &PaymentAttempt) -> Self { + let mut update_internal = self; + update_internal.net_amount = Some( + update_internal.amount.unwrap_or(source.amount) + + update_internal + .surcharge_amount + .or(source.surcharge_amount) + .unwrap_or(0) + + update_internal + .tax_amount + .or(source.tax_amount) + .unwrap_or(0), + ); + update_internal + } +} + impl PaymentAttemptUpdate { pub fn apply_changeset(self, source: PaymentAttempt) -> PaymentAttempt { let PaymentAttemptUpdateInternal { amount, + net_amount, currency, status, connector_transaction_id, @@ -355,9 +390,10 @@ impl PaymentAttemptUpdate { encoded_data, unified_code, unified_message, - } = self.into(); + } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source); PaymentAttempt { amount: amount.unwrap_or(source.amount), + net_amount: net_amount.unwrap_or(source.net_amount), currency: currency.or(source.currency), status: status.unwrap_or(source.status), connector_transaction_id: connector_transaction_id.or(source.connector_transaction_id), diff --git a/crates/diesel_models/src/query/payment_attempt.rs b/crates/diesel_models/src/query/payment_attempt.rs index 9e9195f5e0b..ebd0dcd7351 100644 --- a/crates/diesel_models/src/query/payment_attempt.rs +++ b/crates/diesel_models/src/query/payment_attempt.rs @@ -23,7 +23,7 @@ use crate::{ impl PaymentAttemptNew { #[instrument(skip(conn))] pub async fn insert(self, conn: &PgPooledConn) -> StorageResult { - generics::generic_insert(conn, self).await + generics::generic_insert(conn, self.populate_derived_fields()).await } } @@ -44,7 +44,7 @@ impl PaymentAttempt { dsl::attempt_id .eq(self.attempt_id.to_owned()) .and(dsl::merchant_id.eq(self.merchant_id.to_owned())), - PaymentAttemptUpdateInternal::from(payment_attempt), + PaymentAttemptUpdateInternal::from(payment_attempt).populate_derived_fields(&self), ) .await { diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 0d4ab83d823..8382d382659 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -642,6 +642,7 @@ diesel::table! { unified_code -> Nullable, #[max_length = 1024] unified_message -> Nullable, + net_amount -> Int8, } } diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs index 959d1ad9ee7..10b1a7afd2f 100644 --- a/crates/diesel_models/src/user/sample_data.rs +++ b/crates/diesel_models/src/user/sample_data.rs @@ -62,6 +62,7 @@ pub struct PaymentAttemptBatchNew { pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, + pub net_amount: i64, } #[allow(dead_code)] @@ -114,6 +115,7 @@ impl PaymentAttemptBatchNew { encoded_data: self.encoded_data, unified_code: self.unified_code, unified_message: self.unified_message, + net_amount: self.net_amount, } } } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 341699c0925..7c245659439 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3167,6 +3167,7 @@ impl AttemptType { merchant_connector_id: None, unified_code: None, unified_message: None, + net_amount: old_payment_attempt.net_amount, } } diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 2781afff51f..26f744d7d91 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -565,7 +565,7 @@ where }); services::ApplicationResponse::JsonWithHeaders(( response - .set_net_amount(payment_attempt.get_total_amount()) + .set_net_amount(payment_attempt.net_amount) .set_payment_id(Some(payment_attempt.payment_id)) .set_merchant_id(Some(payment_attempt.merchant_id)) .set_status(payment_intent.status) @@ -715,7 +715,7 @@ where } None => services::ApplicationResponse::JsonWithHeaders(( api::PaymentsResponse { - net_amount: payment_attempt.get_total_amount(), + net_amount: payment_attempt.net_amount, payment_id: Some(payment_attempt.payment_id), merchant_id: Some(payment_attempt.merchant_id), status: payment_intent.status, diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs index 6137b444f96..24863ddc568 100644 --- a/crates/storage_impl/src/mock_db/payment_attempt.rs +++ b/crates/storage_impl/src/mock_db/payment_attempt.rs @@ -97,7 +97,7 @@ impl PaymentAttemptInterface for MockDb { #[allow(clippy::as_conversions)] let id = payment_attempts.len() as i32; let time = common_utils::date_time::now(); - + let payment_attempt = payment_attempt.populate_derived_fields(); let payment_attempt = PaymentAttempt { id, payment_id: payment_attempt.payment_id, @@ -105,6 +105,7 @@ impl PaymentAttemptInterface for MockDb { attempt_id: payment_attempt.attempt_id, status: payment_attempt.status, amount: payment_attempt.amount, + net_amount: payment_attempt.net_amount, currency: payment_attempt.currency, save_to_locker: payment_attempt.save_to_locker, connector: payment_attempt.connector, diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 425cdd216fe..3511e1aac61 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -331,6 +331,7 @@ impl PaymentAttemptInterface for KVRouterStore { .await } MerchantStorageScheme::RedisKv => { + let payment_attempt = payment_attempt.populate_derived_fields(); let key = format!( "mid_{}_pid_{}", payment_attempt.merchant_id, payment_attempt.payment_id @@ -343,6 +344,7 @@ impl PaymentAttemptInterface for KVRouterStore { attempt_id: payment_attempt.attempt_id.clone(), status: payment_attempt.status, amount: payment_attempt.amount, + net_amount: payment_attempt.net_amount, currency: payment_attempt.currency, save_to_locker: payment_attempt.save_to_locker, connector: payment_attempt.connector.clone(), @@ -1035,6 +1037,7 @@ impl DataModelExt for PaymentAttempt { attempt_id: self.attempt_id, status: self.status, amount: self.amount, + net_amount: self.net_amount, currency: self.currency, save_to_locker: self.save_to_locker, connector: self.connector, @@ -1087,6 +1090,7 @@ impl DataModelExt for PaymentAttempt { attempt_id: storage_model.attempt_id, status: storage_model.status, amount: storage_model.amount, + net_amount: storage_model.net_amount, currency: storage_model.currency, save_to_locker: storage_model.save_to_locker, connector: storage_model.connector, @@ -1139,6 +1143,7 @@ impl DataModelExt for PaymentAttemptNew { fn to_storage_model(self) -> Self::StorageModel { DieselPaymentAttemptNew { + net_amount: self.calculate_net_amount(), payment_id: self.payment_id, merchant_id: self.merchant_id, attempt_id: self.attempt_id, @@ -1236,6 +1241,7 @@ impl DataModelExt for PaymentAttemptNew { merchant_connector_id: storage_model.merchant_connector_id, unified_code: storage_model.unified_code, unified_message: storage_model.unified_message, + net_amount: storage_model.net_amount, } } } diff --git a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/down.sql b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/down.sql new file mode 100644 index 00000000000..93cd6341a9b --- /dev/null +++ b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE payment_attempt DROP COLUMN IF EXISTS net_amount; \ No newline at end of file diff --git a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql new file mode 100644 index 00000000000..3bd317219fd --- /dev/null +++ b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql @@ -0,0 +1,8 @@ + +ALTER TABLE payment_attempt +ADD COLUMN IF NOT EXISTS net_amount BIGINT; + +UPDATE payment_attempt pa +SET net_amount = pa.amount + COALESCE(pa.surcharge_amount, 0) + COALESCE(pa.tax_amount, 0); + +ALTER TABLE payment_attempt ALTER COLUMN net_amount SET NOT NULL; From bb456952950fce12a9a9e46d8ba2916624c3c112 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Mon, 18 Dec 2023 10:48:57 +0530 Subject: [PATCH 10/19] address comments --- .../2023-12-15-062816__net_amount_in_payment_attempt/up.sql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql index 3bd317219fd..f1d013ef5de 100644 --- a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql +++ b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql @@ -1,8 +1,7 @@ - ALTER TABLE payment_attempt -ADD COLUMN IF NOT EXISTS net_amount BIGINT; +ADD COLUMN IF NOT EXISTS net_amount BIGINT NOT NULL DEFAULT 0; +// Backfill UPDATE payment_attempt pa SET net_amount = pa.amount + COALESCE(pa.surcharge_amount, 0) + COALESCE(pa.tax_amount, 0); -ALTER TABLE payment_attempt ALTER COLUMN net_amount SET NOT NULL; From acb3f2350d9eac4eedec282dd94691b1fa215c20 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Mon, 18 Dec 2023 10:51:18 +0530 Subject: [PATCH 11/19] add comments in up.sql file --- .../2023-12-15-062816__net_amount_in_payment_attempt/up.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql index f1d013ef5de..1f1eaa0c0ba 100644 --- a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql +++ b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql @@ -1,7 +1,7 @@ ALTER TABLE payment_attempt ADD COLUMN IF NOT EXISTS net_amount BIGINT NOT NULL DEFAULT 0; -// Backfill +-- Backfill UPDATE payment_attempt pa SET net_amount = pa.amount + COALESCE(pa.surcharge_amount, 0) + COALESCE(pa.tax_amount, 0); From 80f6ad12bb7058b31c47b498814adcce97545695 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Mon, 18 Dec 2023 12:10:33 +0530 Subject: [PATCH 12/19] use net_amount field directly --- crates/storage_impl/src/payments/payment_attempt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 3511e1aac61..dd0a19961c7 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -1143,7 +1143,7 @@ impl DataModelExt for PaymentAttemptNew { fn to_storage_model(self) -> Self::StorageModel { DieselPaymentAttemptNew { - net_amount: self.calculate_net_amount(), + net_amount: self.net_amount, payment_id: self.payment_id, merchant_id: self.merchant_id, attempt_id: self.attempt_id, From f107d6aed5bd81d947034427f0fa5e92e08428b1 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Mon, 18 Dec 2023 12:33:37 +0530 Subject: [PATCH 13/19] do not populate surcharge and tax amount for manually retried payment --- crates/router/src/core/payments/helpers.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 7c245659439..dd41ed5f718 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3123,8 +3123,8 @@ impl AttemptType { error_message: None, offer_amount: old_payment_attempt.offer_amount, - surcharge_amount: old_payment_attempt.surcharge_amount, - tax_amount: old_payment_attempt.tax_amount, + surcharge_amount: None, + tax_amount: None, payment_method_id: None, payment_method: None, capture_method: old_payment_attempt.capture_method, From 40a4f3bcd9ddaf0e797547eebe28dcc51f7b17b5 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Mon, 18 Dec 2023 12:37:09 +0530 Subject: [PATCH 14/19] address comments --- crates/router/src/core/payments/helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index dd41ed5f718..837bc7ad7ed 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3167,7 +3167,7 @@ impl AttemptType { merchant_connector_id: None, unified_code: None, unified_message: None, - net_amount: old_payment_attempt.net_amount, + net_amount: old_payment_attempt.amount, } } From 395a93b79b9580ff70f9302063f1d4babf6412f8 Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Mon, 18 Dec 2023 16:00:11 +0530 Subject: [PATCH 15/19] make net_amount field optional in payment_attempt --- crates/diesel_models/src/payment_attempt.rs | 21 +++++++++++++++---- crates/diesel_models/src/schema.rs | 2 +- crates/diesel_models/src/user/sample_data.rs | 2 +- .../src/payments/payment_attempt.rs | 8 +++---- .../up.sql | 4 +--- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index e1c23d4ca58..d08c146b0b8 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -63,7 +63,15 @@ pub struct PaymentAttempt { pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: i64, + pub net_amount: Option, +} + +impl PaymentAttempt { + pub fn get_or_calculate_net_amount(&self) -> i64 { + self.net_amount.unwrap_or( + self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0), + ) + } } #[derive(Clone, Debug, Eq, PartialEq, Queryable, Serialize, Deserialize)] @@ -129,7 +137,7 @@ pub struct PaymentAttemptNew { pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: i64, + pub net_amount: Option, } impl PaymentAttemptNew { @@ -138,9 +146,14 @@ impl PaymentAttemptNew { self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) } + pub fn get_or_calculate_net_amount(&self) -> i64 { + self.net_amount + .unwrap_or_else(|| self.calculate_net_amount()) + } + pub fn populate_derived_fields(self) -> Self { let mut payment_attempt_new = self; - payment_attempt_new.net_amount = payment_attempt_new.calculate_net_amount(); + payment_attempt_new.net_amount = Some(payment_attempt_new.calculate_net_amount()); payment_attempt_new } } @@ -393,7 +406,7 @@ impl PaymentAttemptUpdate { } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source); PaymentAttempt { amount: amount.unwrap_or(source.amount), - net_amount: net_amount.unwrap_or(source.net_amount), + net_amount: net_amount.or(source.net_amount), currency: currency.or(source.currency), status: status.unwrap_or(source.status), connector_transaction_id: connector_transaction_id.or(source.connector_transaction_id), diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 8382d382659..336edc24035 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -642,7 +642,7 @@ diesel::table! { unified_code -> Nullable, #[max_length = 1024] unified_message -> Nullable, - net_amount -> Int8, + net_amount -> Nullable, } } diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs index 10b1a7afd2f..5a1ea696c56 100644 --- a/crates/diesel_models/src/user/sample_data.rs +++ b/crates/diesel_models/src/user/sample_data.rs @@ -62,7 +62,7 @@ pub struct PaymentAttemptBatchNew { pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: i64, + pub net_amount: Option, } #[allow(dead_code)] diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index dd0a19961c7..f8f752c6bc8 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -1037,7 +1037,7 @@ impl DataModelExt for PaymentAttempt { attempt_id: self.attempt_id, status: self.status, amount: self.amount, - net_amount: self.net_amount, + net_amount: Some(self.net_amount), currency: self.currency, save_to_locker: self.save_to_locker, connector: self.connector, @@ -1084,13 +1084,13 @@ impl DataModelExt for PaymentAttempt { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { + net_amount: storage_model.get_or_calculate_net_amount(), id: storage_model.id, payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, status: storage_model.status, amount: storage_model.amount, - net_amount: storage_model.net_amount, currency: storage_model.currency, save_to_locker: storage_model.save_to_locker, connector: storage_model.connector, @@ -1143,7 +1143,7 @@ impl DataModelExt for PaymentAttemptNew { fn to_storage_model(self) -> Self::StorageModel { DieselPaymentAttemptNew { - net_amount: self.net_amount, + net_amount: Some(self.net_amount), payment_id: self.payment_id, merchant_id: self.merchant_id, attempt_id: self.attempt_id, @@ -1194,6 +1194,7 @@ impl DataModelExt for PaymentAttemptNew { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { + net_amount: storage_model.get_or_calculate_net_amount(), payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, @@ -1241,7 +1242,6 @@ impl DataModelExt for PaymentAttemptNew { merchant_connector_id: storage_model.merchant_connector_id, unified_code: storage_model.unified_code, unified_message: storage_model.unified_message, - net_amount: storage_model.net_amount, } } } diff --git a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql index 1f1eaa0c0ba..fa86b097ef2 100644 --- a/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql +++ b/migrations/2023-12-15-062816__net_amount_in_payment_attempt/up.sql @@ -1,7 +1,5 @@ ALTER TABLE payment_attempt -ADD COLUMN IF NOT EXISTS net_amount BIGINT NOT NULL DEFAULT 0; - +ADD COLUMN IF NOT EXISTS net_amount BIGINT; -- Backfill UPDATE payment_attempt pa SET net_amount = pa.amount + COALESCE(pa.surcharge_amount, 0) + COALESCE(pa.tax_amount, 0); - From 7fa1ac5a1b45c403bc5d189fdf5d0e3a3f88985b Mon Sep 17 00:00:00 2001 From: hrithikeshvm Date: Tue, 19 Dec 2023 16:37:09 +0530 Subject: [PATCH 16/19] refactor: refactor amount field in PaymentAttempt data_model --- crates/data_models/src/payments.rs | 4 +- .../src/payments/payment_attempt.rs | 59 ++++++++++++++++--- crates/diesel_models/src/payment_attempt.rs | 5 -- crates/router/src/connector/utils.rs | 3 +- .../core/fraud_check/flows/checkout_flow.rs | 2 +- .../fraud_check/flows/fulfillment_flow.rs | 2 +- .../core/fraud_check/flows/record_return.rs | 2 +- .../src/core/fraud_check/flows/sale_flow.rs | 2 +- .../fraud_check/flows/transaction_flow.rs | 2 +- crates/router/src/core/payment_link.rs | 2 +- .../router/src/core/payment_methods/cards.rs | 10 ++-- .../surcharge_decision_configs.rs | 7 ++- crates/router/src/core/payments.rs | 34 ++++++----- crates/router/src/core/payments/helpers.rs | 29 +++++---- .../payments/operations/payment_approve.rs | 2 +- .../payments/operations/payment_cancel.rs | 2 +- .../payments/operations/payment_capture.rs | 2 +- .../operations/payment_complete_authorize.rs | 2 +- .../payments/operations/payment_confirm.rs | 10 ++-- .../payments/operations/payment_create.rs | 6 +- .../payments/operations/payment_reject.rs | 2 +- .../payments/operations/payment_response.rs | 8 ++- .../payments/operations/payment_session.rs | 2 +- .../core/payments/operations/payment_start.rs | 2 +- .../payments/operations/payment_status.rs | 2 +- .../payments/operations/payment_update.rs | 14 ++--- .../payments_incremental_authorization.rs | 23 ++++---- crates/router/src/core/payments/retry.rs | 6 +- crates/router/src/core/payments/routing.rs | 6 +- .../router/src/core/payments/transformers.rs | 26 ++++---- crates/router/src/core/payments/types.rs | 5 +- crates/router/src/core/refunds.rs | 8 +-- .../src/services/kafka/payment_attempt.rs | 6 +- .../src/services/kafka/payment_intent.rs | 2 +- crates/router/src/types.rs | 2 +- .../src/types/storage/payment_attempt.rs | 16 ++--- crates/router/src/types/transformers.rs | 5 +- .../src/mock_db/payment_attempt.rs | 8 +-- .../src/mock_db/payment_intent.rs | 2 +- .../src/payments/payment_attempt.rs | 24 +++----- .../src/payments/payment_intent.rs | 6 +- 41 files changed, 206 insertions(+), 156 deletions(-) diff --git a/crates/data_models/src/payments.rs b/crates/data_models/src/payments.rs index b3e2c2e520a..73df1bbe8b0 100644 --- a/crates/data_models/src/payments.rs +++ b/crates/data_models/src/payments.rs @@ -15,7 +15,9 @@ pub struct PaymentIntent { pub payment_id: String, pub merchant_id: String, pub status: storage_enums::IntentStatus, - pub amount: i64, + /// This amount may not be equal to authorized_amount due to surcharge
+ /// Authorized amount can be fetched from PaymentAttempt + pub original_amount: i64, pub currency: Option, pub amount_captured: Option, pub customer_id: Option, diff --git a/crates/data_models/src/payments/payment_attempt.rs b/crates/data_models/src/payments/payment_attempt.rs index 3e6ba9e37f8..bcd1618e5ff 100644 --- a/crates/data_models/src/payments/payment_attempt.rs +++ b/crates/data_models/src/payments/payment_attempt.rs @@ -1,5 +1,6 @@ use api_models::enums::Connector; use common_enums as storage_enums; +use diesel_models::PaymentAttempt as DieselPaymentAttempt; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; @@ -106,15 +107,12 @@ pub struct PaymentAttempt { pub merchant_id: String, pub attempt_id: String, pub status: storage_enums::AttemptStatus, - pub amount: i64, - pub net_amount: i64, + pub amount: AttemptAmount, pub currency: Option, pub save_to_locker: Option, pub connector: Option, pub error_message: Option, pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, pub payment_method_id: Option, pub payment_method: Option, pub connector_transaction_id: Option, @@ -157,9 +155,56 @@ pub struct PaymentAttempt { pub unified_message: Option, } -impl PaymentAttempt { - pub fn get_total_amount(&self) -> i64 { - self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct AttemptAmount { + amount: i64, + surcharge_amount: Option, + tax_amount: Option, + net_amount: i64, +} + +pub trait GetAttemptAmount { + fn get_attempt_amount(&self) -> AttemptAmount; +} + +impl GetAttemptAmount for DieselPaymentAttempt { + fn get_attempt_amount(&self) -> AttemptAmount { + AttemptAmount { + amount: self.amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, + net_amount: self.get_or_calculate_net_amount(), + } + } +} + +impl GetAttemptAmount for PaymentAttemptNew { + fn get_attempt_amount(&self) -> AttemptAmount { + AttemptAmount { + amount: self.amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, + net_amount: self.calculate_net_amount(), + } + } +} + +impl AttemptAmount { + pub fn set_original_amount(&mut self, amount: i64) { + self.amount = amount; + self.net_amount = self.amount + self.get_total_surcharge_amount().unwrap_or(0); + } + pub fn get_authorize_amount(&self) -> i64 { + self.net_amount + } + pub fn get_original_amount(&self) -> i64 { + self.amount + } + pub fn get_surcharge_amount(&self) -> Option { + self.surcharge_amount + } + pub fn get_tax_amount_on_surcharge(&self) -> Option { + self.tax_amount } pub fn get_total_surcharge_amount(&self) -> Option { self.surcharge_amount diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index d08c146b0b8..1f8a481b85a 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -146,11 +146,6 @@ impl PaymentAttemptNew { self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) } - pub fn get_or_calculate_net_amount(&self) -> i64 { - self.net_amount - .unwrap_or_else(|| self.calculate_net_amount()) - } - pub fn populate_derived_fields(self) -> Self { let mut payment_attempt_new = self; payment_attempt_new.net_amount = Some(payment_attempt_new.calculate_net_amount()); diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index d06caf3ae20..f7e3c21fd07 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -118,7 +118,8 @@ where enums::AttemptStatus::Charged => { let captured_amount = types::Capturable::get_capture_amount(&self.request, payment_data); - let total_capturable_amount = payment_data.payment_attempt.get_total_amount(); + let total_capturable_amount = + payment_data.payment_attempt.amount.get_authorize_amount(); if Some(total_capturable_amount) == captured_amount { enums::AttemptStatus::Charged } else if captured_amount.is_some() { diff --git a/crates/router/src/core/fraud_check/flows/checkout_flow.rs b/crates/router/src/core/fraud_check/flows/checkout_flow.rs index 7f8993af527..722db1a8571 100644 --- a/crates/router/src/core/fraud_check/flows/checkout_flow.rs +++ b/crates/router/src/core/fraud_check/flows/checkout_flow.rs @@ -69,7 +69,7 @@ impl ConstructFlowSpecificData( connector_meta_data: merchant_connector_account.get_metadata(), amount_captured: payment_intent.amount_captured, request: FraudCheckFulfillmentData { - amount: payment_attempt.amount, + amount: payment_attempt.amount.get_authorize_amount(), order_details: payment_intent.order_details.clone(), fulfillment_req: fulfillment_request, }, diff --git a/crates/router/src/core/fraud_check/flows/record_return.rs b/crates/router/src/core/fraud_check/flows/record_return.rs index bd0ba3e4f7f..980d1e84ce4 100644 --- a/crates/router/src/core/fraud_check/flows/record_return.rs +++ b/crates/router/src/core/fraud_check/flows/record_return.rs @@ -68,7 +68,7 @@ impl ConstructFlowSpecificData, response_payment_method_types: &mut [ResponsePaymentMethodsEnabled], ) -> errors::RouterResult { - if payment_attempt.surcharge_amount.is_some() { + if payment_attempt.amount.get_surcharge_amount().is_some() { Ok(api_surcharge_decision_configs::MerchantSurchargeConfigs::default()) } else { let algorithm_ref: routing_types::RoutingAlgorithmRef = merchant_account @@ -1804,7 +1804,7 @@ pub async fn call_surcharge_decision_management_for_saved_card( payment_intent: storage::PaymentIntent, customer_payment_method_response: &mut api::CustomerPaymentMethodsListResponse, ) -> errors::RouterResult<()> { - if payment_attempt.surcharge_amount.is_some() { + if payment_attempt.amount.get_surcharge_amount().is_some() { Ok(()) } else { let algorithm_ref: routing_types::RoutingAlgorithmRef = merchant_account @@ -2295,10 +2295,10 @@ fn filter_payment_amount_based( payment_intent: &storage::PaymentIntent, pm: &RequestPaymentMethodTypes, ) -> bool { - let amount = payment_intent.amount; + let amount = payment_intent.original_amount; (pm.maximum_amount.map_or(true, |amt| amount <= amt.into()) && pm.minimum_amount.map_or(true, |amt| amount >= amt.into())) - || payment_intent.amount == 0 + || payment_intent.original_amount == 0 } async fn filter_payment_mandate_based( diff --git a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs index db1064b36a7..f9f5c348df7 100644 --- a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs +++ b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs @@ -294,7 +294,7 @@ fn get_surcharge_details_from_surcharge_output( let surcharge_amount = match surcharge_details.surcharge.clone() { surcharge_decision_configs::SurchargeOutput::Fixed { amount } => amount, surcharge_decision_configs::SurchargeOutput::Rate(percentage) => percentage - .apply_and_ceil_result(payment_attempt.amount) + .apply_and_ceil_result(payment_attempt.amount.get_original_amount()) .change_context(ConfigError::DslExecutionError) .attach_printable("Failed to Calculate surcharge amount by applying percentage")?, }; @@ -309,8 +309,9 @@ fn get_surcharge_details_from_surcharge_output( }) .transpose()? .unwrap_or(0); + let original_amount = payment_attempt.amount.get_original_amount(); Ok(types::SurchargeDetails { - original_amount: payment_attempt.amount, + original_amount, surcharge: match surcharge_details.surcharge { surcharge_decision_configs::SurchargeOutput::Fixed { amount } => { common_utils_types::Surcharge::Fixed(amount) @@ -322,7 +323,7 @@ fn get_surcharge_details_from_surcharge_output( tax_on_surcharge: surcharge_details.tax_on_surcharge, surcharge_amount, tax_on_surcharge_amount, - final_amount: payment_attempt.amount + surcharge_amount + tax_on_surcharge_amount, + final_amount: original_amount + surcharge_amount + tax_on_surcharge_amount, }) } diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 44c46732529..38b99491ba0 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -497,7 +497,9 @@ where .surcharge_applicable .unwrap_or(false) { - if let Some(surcharge_details) = payment_data.payment_attempt.get_surcharge_details() { + if let Some(surcharge_details) = + payment_data.payment_attempt.get_request_surcharge_details() + { // if retry payment, surcharge would have been populated from the previous attempt. Use the same surcharge let surcharge_details = types::SurchargeDetails::from((&surcharge_details, &payment_data.payment_attempt)); @@ -540,16 +542,12 @@ where payment_data.surcharge_details = calculated_surcharge_details; } else { - let surcharge_details = - payment_data - .payment_attempt - .get_surcharge_details() - .map(|surcharge_details| { - types::SurchargeDetails::from(( - &surcharge_details, - &payment_data.payment_attempt, - )) - }); + let surcharge_details = payment_data + .payment_attempt + .get_request_surcharge_details() + .map(|surcharge_details| { + types::SurchargeDetails::from((&surcharge_details, &payment_data.payment_attempt)) + }); payment_data.surcharge_details = surcharge_details; } Ok(()) @@ -576,13 +574,17 @@ pub async fn call_surcharge_decision_management_for_session_flow( where O: Send + Clone + Sync, { - if let Some(surcharge_amount) = payment_data.payment_attempt.surcharge_amount { - let tax_on_surcharge_amount = payment_data.payment_attempt.tax_amount.unwrap_or(0); - let final_amount = - payment_data.payment_attempt.amount + surcharge_amount + tax_on_surcharge_amount; + if let Some(surcharge_amount) = payment_data.payment_attempt.amount.get_surcharge_amount() { + let tax_on_surcharge_amount = payment_data + .payment_attempt + .amount + .get_tax_amount_on_surcharge() + .unwrap_or(0); + let original_amount = payment_data.payment_attempt.amount.get_original_amount(); + let final_amount = original_amount + surcharge_amount + tax_on_surcharge_amount; Ok(Some(api::SessionSurchargeDetails::PreDetermined( types::SurchargeDetails { - original_amount: payment_data.payment_attempt.amount, + original_amount, surcharge: Surcharge::Fixed(surcharge_amount), tax_on_surcharge: None, surcharge_amount, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 837bc7ad7ed..f2fb92018f6 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -618,17 +618,22 @@ pub fn validate_amount_to_capture_and_capture_method( .map(|payment_attempt| payment_attempt.capture_method.unwrap_or_default())) .unwrap_or_default(); if capture_method == api_enums::CaptureMethod::Automatic { - let original_amount = request - .amount - .map(|amount| amount.into()) - .or(payment_attempt.map(|payment_attempt| payment_attempt.amount)); + let original_amount = + request + .amount + .map(|amount| amount.into()) + .or(payment_attempt + .map(|payment_attempt| payment_attempt.amount.get_original_amount())); let surcharge_amount = request .surcharge_details .map(|surcharge_details| surcharge_details.get_total_surcharge_amount()) .or_else(|| { payment_attempt.map(|payment_attempt| { - payment_attempt.surcharge_amount.unwrap_or(0) - + payment_attempt.tax_amount.unwrap_or(0) + payment_attempt.amount.get_surcharge_amount().unwrap_or(0) + + payment_attempt + .amount + .get_tax_amount_on_surcharge() + .unwrap_or(0) }) }) .unwrap_or(0); @@ -2597,7 +2602,7 @@ mod tests { payment_id: "23".to_string(), merchant_id: "22".to_string(), status: storage_enums::IntentStatus::RequiresCapture, - amount: 200, + original_amount: 200, currency: None, amount_captured: None, customer_id: None, @@ -2652,7 +2657,7 @@ mod tests { payment_id: "23".to_string(), merchant_id: "22".to_string(), status: storage_enums::IntentStatus::RequiresCapture, - amount: 200, + original_amount: 200, currency: None, amount_captured: None, customer_id: None, @@ -2707,7 +2712,7 @@ mod tests { payment_id: "23".to_string(), merchant_id: "22".to_string(), status: storage_enums::IntentStatus::RequiresCapture, - amount: 200, + original_amount: 200, currency: None, amount_captured: None, customer_id: None, @@ -3115,7 +3120,7 @@ impl AttemptType { // A new payment attempt is getting created so, used the same function which is used to populate status in PaymentCreate Flow. status: payment_attempt_status_fsm(payment_method_data, Some(true)), - amount: old_payment_attempt.amount, + amount: old_payment_attempt.amount.get_original_amount(), currency: old_payment_attempt.currency, save_to_locker: old_payment_attempt.save_to_locker, @@ -3160,14 +3165,14 @@ impl AttemptType { error_reason: None, multiple_capture_count: None, connector_response_reference_id: None, - amount_capturable: old_payment_attempt.amount, + amount_capturable: old_payment_attempt.amount.get_original_amount(), updated_by: storage_scheme.to_string(), authentication_data: None, encoded_data: None, merchant_connector_id: None, unified_code: None, unified_message: None, - net_amount: old_payment_attempt.amount, + net_amount: old_payment_attempt.amount.get_original_amount(), } } diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs index 1a6945b09c8..688a3e199ff 100644 --- a/crates/router/src/core/payments/operations/payment_approve.rs +++ b/crates/router/src/core/payments/operations/payment_approve.rs @@ -139,7 +139,7 @@ impl payment_method_type.or(payment_attempt.payment_method_type); payment_attempt.payment_experience = request.payment_experience; currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.get_total_amount().into(); + amount = payment_attempt.amount.get_authorize_amount().into(); helpers::validate_customer_id_mandatory_cases( request.setup_future_usage.is_some(), diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs index 9810980cd34..40d272314ff 100644 --- a/crates/router/src/core/payments/operations/payment_cancel.rs +++ b/crates/router/src/core/payments/operations/payment_cancel.rs @@ -102,7 +102,7 @@ impl .await?; let currency = payment_attempt.currency.get_required_value("currency")?; - let amount = payment_attempt.get_total_amount().into(); + let amount = payment_attempt.amount.get_authorize_amount().into(); payment_attempt.cancellation_reason = request.cancellation_reason.clone(); diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs index 3986b16ce35..51ab9a07ecd 100644 --- a/crates/router/src/core/payments/operations/payment_capture.rs +++ b/crates/router/src/core/payments/operations/payment_capture.rs @@ -124,7 +124,7 @@ impl currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.get_total_amount().into(); + amount = payment_attempt.amount.get_authorize_amount().into(); let shipping_address = helpers::create_or_find_address_for_payment_by_request( db, diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index abb08d14d92..1663d989311 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -135,7 +135,7 @@ impl .payment_experience .or(payment_attempt.payment_experience); currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.get_total_amount().into(); + amount = payment_attempt.amount.get_authorize_amount().into(); helpers::validate_customer_id_mandatory_cases( request.setup_future_usage.is_some(), diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 58983f264c7..53bd9004e9c 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -104,7 +104,7 @@ impl if let Some(order_details) = &request.order_details { helpers::validate_order_details_amount( order_details.to_owned(), - payment_intent.amount, + payment_intent.original_amount, )?; } @@ -377,7 +377,7 @@ impl payment_attempt.capture_method = request.capture_method.or(payment_attempt.capture_method); currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.get_total_amount().into(); + amount = payment_attempt.amount.get_authorize_amount().into(); helpers::validate_customer_id_mandatory_cases( request.setup_future_usage.is_some(), @@ -705,7 +705,7 @@ impl .surcharge_details .as_ref() .map(|surcharge_details| surcharge_details.final_amount) - .unwrap_or(payment_data.payment_attempt.amount); + .unwrap_or(payment_data.payment_attempt.amount.get_authorize_amount()); let m_payment_data_payment_attempt = payment_data.payment_attempt.clone(); let m_browser_info = browser_info.clone(); @@ -732,7 +732,7 @@ impl m_db.update_payment_attempt_with_attempt_id( m_payment_data_payment_attempt, storage::PaymentAttemptUpdate::ConfirmUpdate { - amount: payment_data.payment_attempt.amount, + amount: payment_data.payment_attempt.amount.get_original_amount(), currency: payment_data.currency, status: attempt_status, payment_method, @@ -780,7 +780,7 @@ impl m_db.update_payment_intent( m_payment_data_payment_intent, storage::PaymentIntentUpdate::Update { - amount: payment_data.payment_intent.amount, + amount: payment_data.payment_intent.original_amount, currency: payment_data.currency, setup_future_usage, status: intent_status, diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 798678e64df..6269fa4ef49 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -189,7 +189,7 @@ impl if let Some(order_details) = &request.order_details { helpers::validate_order_details_amount( order_details.to_owned(), - payment_intent.amount, + payment_intent.original_amount, )?; } @@ -297,7 +297,7 @@ impl .map(|(payment_method_data, additional_payment_data)| { payment_method_data.apply_additional_payment_data(additional_payment_data) }); - let amount = payment_attempt.get_total_amount().into(); + let amount = payment_attempt.amount.get_authorize_amount().into(); let payment_data = PaymentData { flow: PhantomData, payment_intent, @@ -457,7 +457,7 @@ impl .payment_attempt .straight_through_algorithm .clone(); - let authorized_amount = payment_data.payment_attempt.amount; + let authorized_amount = payment_data.payment_attempt.amount.get_authorize_amount(); let merchant_connector_id = payment_data.payment_attempt.merchant_connector_id.clone(); let surcharge_amount = payment_data diff --git a/crates/router/src/core/payments/operations/payment_reject.rs b/crates/router/src/core/payments/operations/payment_reject.rs index 37c7dfd1bae..a605c81be79 100644 --- a/crates/router/src/core/payments/operations/payment_reject.rs +++ b/crates/router/src/core/payments/operations/payment_reject.rs @@ -100,7 +100,7 @@ impl .await?; let currency = payment_attempt.currency.get_required_value("currency")?; - let amount = payment_attempt.get_total_amount().into(); + let amount = payment_attempt.amount.get_authorize_amount().into(); let frm_response = db .find_fraud_check_by_payment_id(payment_intent.payment_id.clone(), merchant_account.merchant_id.clone()) diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 8b301c525fd..80c72daae39 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -100,6 +100,8 @@ impl PostUpdateTracker, types::PaymentsIncrementalAu report!(errors::ApiErrorResponse::InternalServerError) .attach_printable("missing incremental_authorization_details in payment_data") })?; + let updated_original_amount = payment_data.payment_attempt.amount.get_original_amount() + + incremental_authorization_details.additional_amount; // Update payment_intent and payment_attempt 'amount' if incremental_authorization is successful let (option_payment_attempt_update, option_payment_intent_update) = match router_data.response.clone() { @@ -111,12 +113,12 @@ impl PostUpdateTracker, types::PaymentsIncrementalAu if status == AuthorizationStatus::Success { (Some( storage::PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate { - amount: incremental_authorization_details.total_amount, + amount: updated_original_amount, amount_capturable: incremental_authorization_details.total_amount, }, ), Some( storage::PaymentIntentUpdate::IncrementalAuthorizationAmountUpdate { - amount: incremental_authorization_details.total_amount, + amount: updated_original_amount, }, )) } else { @@ -700,7 +702,7 @@ async fn payment_response_update_tracker( multiple_capture_data.update_capture(updated_capture); } - let authorized_amount = payment_data.payment_attempt.get_total_amount(); + let authorized_amount = payment_data.payment_attempt.amount.get_authorize_amount(); payment_attempt_update = Some(storage::PaymentAttemptUpdate::AmountToCaptureUpdate { status: multiple_capture_data.get_attempt_status(authorized_amount), diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index 6f7dcd6c11a..8e77ce1ae80 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -93,7 +93,7 @@ impl payment_attempt.payment_method = Some(storage_enums::PaymentMethod::Wallet); - let amount = payment_attempt.get_total_amount().into(); + let amount = payment_attempt.amount.get_authorize_amount().into(); let shipping_address = helpers::create_or_find_address_for_payment_by_request( db, diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index 8896e4e43ef..93273417130 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -89,7 +89,7 @@ impl .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.get_total_amount().into(); + amount = payment_attempt.amount.get_authorize_amount().into(); let shipping_address = helpers::create_or_find_address_for_payment_by_request( db, diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index c5311ce3d03..904a96c16e9 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -244,7 +244,7 @@ async fn get_tracker_for_sync< let payment_id_str = payment_attempt.payment_id.clone(); currency = payment_attempt.currency.get_required_value("currency")?; - amount = payment_attempt.get_total_amount().into(); + amount = payment_attempt.amount.get_authorize_amount().into(); let shipping_address = helpers::get_address_by_id( db, diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 153ded14f4b..17973a5fce5 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -63,7 +63,7 @@ impl if let Some(order_details) = &request.order_details { helpers::validate_order_details_amount( order_details.to_owned(), - payment_intent.amount, + payment_intent.original_amount, )?; } @@ -142,7 +142,7 @@ impl request.amount_to_capture, request .surcharge_details - .or(payment_attempt.get_surcharge_details()), + .or(payment_attempt.get_request_surcharge_details()), ) .change_context(errors::ApiErrorResponse::InvalidDataFormat { field_name: "amount_to_capture".to_string(), @@ -161,7 +161,7 @@ impl let amount = request .amount - .unwrap_or_else(|| payment_attempt.amount.into()); + .unwrap_or_else(|| payment_attempt.amount.get_original_amount().into()); if request.confirm.unwrap_or(false) { helpers::validate_customer_id_mandatory_cases( @@ -287,14 +287,14 @@ impl let amount = request .amount .map(Into::into) - .unwrap_or(payment_attempt.amount); - payment_attempt.amount = amount; - payment_intent.amount = amount; + .unwrap_or(payment_attempt.amount.get_original_amount()); + payment_attempt.amount.set_original_amount(amount); + payment_intent.original_amount = amount; let surcharge_amount = request .surcharge_details .as_ref() .map(RequestSurchargeDetails::get_total_surcharge_amount) - .or(payment_attempt.get_total_surcharge_amount()); + .or(payment_attempt.amount.get_total_surcharge_amount()); (amount + surcharge_amount.unwrap_or(0)).into() }; (Box::new(operations::PaymentConfirm), amount) diff --git a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs index f707fe3a1da..01bbb802976 100644 --- a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs +++ b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs @@ -74,12 +74,6 @@ impl })? } - if request.amount < payment_intent.amount { - Err(errors::ApiErrorResponse::PreconditionFailed { - message: "Amount should be greater than original authorized amount".to_owned(), - })? - } - let attempt_id = payment_intent.active_attempt.get_id().clone(); let payment_attempt = db .find_payment_attempt_by_payment_id_merchant_id_attempt_id( @@ -91,8 +85,14 @@ impl .await .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + if request.amount < payment_attempt.amount.get_authorize_amount() { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "Amount should be greater than original authorized amount".to_owned(), + })? + } + let currency = payment_attempt.currency.get_required_value("currency")?; - let amount = payment_attempt.get_total_amount(); + let previously_amount = payment_attempt.amount.get_authorize_amount(); let profile_id = payment_intent .profile_id @@ -114,7 +114,7 @@ impl payment_intent, payment_attempt, currency, - amount: amount.into(), + amount: previously_amount.into(), email: None, mandate_id: None, mandate_connector: None, @@ -143,7 +143,7 @@ impl frm_message: None, payment_link_data: None, incremental_authorization_details: Some(IncrementalAuthorizationDetails { - additional_amount: request.amount - amount, + additional_amount: request.amount - previously_amount, total_amount: request.amount, reason: request.reason.clone(), authorization_id: None, @@ -213,7 +213,10 @@ impl error_code: None, error_message: None, connector_authorization_id: None, - previously_authorized_amount: payment_data.payment_intent.amount, + previously_authorized_amount: payment_data + .payment_attempt + .amount + .get_authorize_amount(), }; let authorization = db .store diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs index 0fd45c5af3b..f415bfc1ade 100644 --- a/crates/router/src/core/payments/retry.rs +++ b/crates/router/src/core/payments/retry.rs @@ -463,13 +463,13 @@ pub fn make_new_payment_attempt( payment_id: old_payment_attempt.payment_id, merchant_id: old_payment_attempt.merchant_id, status: old_payment_attempt.status, - amount: old_payment_attempt.amount, + amount: old_payment_attempt.amount.get_original_amount(), currency: old_payment_attempt.currency, save_to_locker: old_payment_attempt.save_to_locker, offer_amount: old_payment_attempt.offer_amount, - surcharge_amount: old_payment_attempt.surcharge_amount, - tax_amount: old_payment_attempt.tax_amount, + surcharge_amount: old_payment_attempt.amount.get_surcharge_amount(), + tax_amount: old_payment_attempt.amount.get_tax_amount_on_surcharge(), payment_method_id: old_payment_attempt.payment_method_id, payment_method: old_payment_attempt.payment_method, payment_method_type: old_payment_attempt.payment_method_type, diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs index 96cd6561519..d58d769a63b 100644 --- a/crates/router/src/core/payments/routing.rs +++ b/crates/router/src/core/payments/routing.rs @@ -150,7 +150,7 @@ where }; let payment_input = dsl_inputs::PaymentInput { - amount: payment_data.payment_intent.amount, + amount: payment_data.payment_intent.original_amount, card_bin: payment_data .payment_method_data .as_ref() @@ -772,7 +772,7 @@ pub async fn perform_session_flow_routing( }; let payment_input = dsl_inputs::PaymentInput { - amount: session_input.payment_intent.amount, + amount: session_input.payment_intent.original_amount, currency: session_input .payment_intent .currency @@ -1011,7 +1011,7 @@ pub fn make_dsl_input_for_surcharge( payment_type: None, }; let payment_input = dsl_inputs::PaymentInput { - amount: payment_attempt.amount, + amount: payment_attempt.amount.get_authorize_amount(), // currency is always populated in payment_attempt during payment create currency: payment_attempt .currency diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 26f744d7d91..aecd9f1b154 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -363,7 +363,7 @@ where .as_ref() .get_required_value("currency")?; let amount = currency - .to_currency_base_unit(payment_attempt.amount) + .to_currency_base_unit(payment_attempt.amount.get_authorize_amount()) .into_report() .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "amount", @@ -439,13 +439,13 @@ where .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "payment_method_data", })?; - let surcharge_details = - payment_attempt - .surcharge_amount - .map(|surcharge_amount| RequestSurchargeDetails { - surcharge_amount, - tax_amount: payment_attempt.tax_amount, - }); + let surcharge_details = payment_attempt + .amount + .get_surcharge_amount() + .map(|surcharge_amount| RequestSurchargeDetails { + surcharge_amount, + tax_amount: payment_attempt.amount.get_tax_amount_on_surcharge(), + }); let merchant_decision = payment_intent.merchant_decision.to_owned(); let frm_message = payment_data.frm_message.map(FrmMessage::foreign_from); @@ -565,11 +565,11 @@ where }); services::ApplicationResponse::JsonWithHeaders(( response - .set_net_amount(payment_attempt.net_amount) + .set_net_amount(payment_attempt.amount.get_authorize_amount()) .set_payment_id(Some(payment_attempt.payment_id)) .set_merchant_id(Some(payment_attempt.merchant_id)) .set_status(payment_intent.status) - .set_amount(payment_attempt.amount) + .set_amount(payment_attempt.amount.get_original_amount()) .set_amount_capturable(Some(payment_attempt.amount_capturable)) .set_amount_received(payment_intent.amount_captured) .set_surcharge_details(surcharge_details) @@ -715,11 +715,11 @@ where } None => services::ApplicationResponse::JsonWithHeaders(( api::PaymentsResponse { - net_amount: payment_attempt.net_amount, + net_amount: payment_attempt.amount.get_authorize_amount(), payment_id: Some(payment_attempt.payment_id), merchant_id: Some(payment_attempt.merchant_id), status: payment_intent.status, - amount: payment_attempt.amount, + amount: payment_attempt.amount.get_original_amount(), amount_capturable: None, amount_received: payment_intent.amount_captured, client_secret: payment_intent.client_secret.map(masking::Secret::new), @@ -858,7 +858,7 @@ impl ForeignFrom<(storage::PaymentIntent, storage::PaymentAttempt)> for api::Pay payment_id: Some(pi.payment_id), merchant_id: Some(pi.merchant_id), status: pi.status, - amount: pi.amount, + amount: pi.original_amount, amount_capturable: pi.amount_captured, client_secret: pi.client_secret.map(|s| s.into()), created: Some(pi.created_at), diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs index 00160db9855..77a9cefa55c 100644 --- a/crates/router/src/core/payments/types.rs +++ b/crates/router/src/core/payments/types.rs @@ -199,13 +199,14 @@ impl From<(&RequestSurchargeDetails, &PaymentAttempt)> for SurchargeDetails { ) -> Self { let surcharge_amount = request_surcharge_details.surcharge_amount; let tax_on_surcharge_amount = request_surcharge_details.tax_amount.unwrap_or(0); + let original_amount = payment_attempt.amount.get_original_amount(); Self { - original_amount: payment_attempt.amount, + original_amount, surcharge: common_types::Surcharge::Fixed(request_surcharge_details.surcharge_amount), tax_on_surcharge: None, surcharge_amount, tax_on_surcharge_amount, - final_amount: payment_attempt.amount + surcharge_amount + tax_on_surcharge_amount, + final_amount: original_amount + surcharge_amount + tax_on_surcharge_amount, } } } diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 6cc118b0f3c..5da87c3c0c2 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -167,7 +167,7 @@ pub async fn trigger_refund_to_gateway( &routed_through, merchant_account, key_store, - (payment_attempt.amount, currency), + (payment_attempt.amount.get_authorize_amount(), currency), payment_intent, payment_attempt, refund, @@ -436,7 +436,7 @@ pub async fn sync_refund_with_gateway( &connector_id, merchant_account, key_store, - (payment_attempt.amount, currency), + (payment_attempt.amount.get_authorize_amount(), currency), payment_intent, payment_attempt, refund, @@ -612,7 +612,7 @@ pub async fn validate_and_create_refund( let total_amount_captured = payment_intent .amount_captured - .unwrap_or(payment_attempt.amount); + .unwrap_or(payment_attempt.amount.get_authorize_amount()); validator::validate_refund_amount(total_amount_captured, &all_refunds, refund_amount) .change_context(errors::ApiErrorResponse::RefundAmountExceedsPaymentAmount)?; @@ -639,7 +639,7 @@ pub async fn validate_and_create_refund( .set_connector_transaction_id(connecter_transaction_id.to_string()) .set_connector(connector) .set_refund_type(req.refund_type.unwrap_or_default().foreign_into()) - .set_total_amount(payment_attempt.amount) + .set_total_amount(payment_attempt.amount.get_authorize_amount()) .set_refund_amount(refund_amount) .set_currency(currency) .set_created_at(Some(common_utils::date_time::now())) diff --git a/crates/router/src/services/kafka/payment_attempt.rs b/crates/router/src/services/kafka/payment_attempt.rs index ea0721f418e..353ea65c6d3 100644 --- a/crates/router/src/services/kafka/payment_attempt.rs +++ b/crates/router/src/services/kafka/payment_attempt.rs @@ -48,14 +48,14 @@ impl<'a> KafkaPaymentAttempt<'a> { merchant_id: &attempt.merchant_id, attempt_id: &attempt.attempt_id, status: attempt.status, - amount: attempt.amount, + amount: attempt.amount.get_original_amount(), currency: attempt.currency, save_to_locker: attempt.save_to_locker, connector: attempt.connector.as_ref(), error_message: attempt.error_message.as_ref(), offer_amount: attempt.offer_amount, - surcharge_amount: attempt.surcharge_amount, - tax_amount: attempt.tax_amount, + surcharge_amount: attempt.amount.get_surcharge_amount(), + tax_amount: attempt.amount.get_tax_amount_on_surcharge(), payment_method_id: attempt.payment_method_id.as_ref(), payment_method: attempt.payment_method, connector_transaction_id: attempt.connector_transaction_id.as_ref(), diff --git a/crates/router/src/services/kafka/payment_intent.rs b/crates/router/src/services/kafka/payment_intent.rs index 70980a6e865..b8acde96338 100644 --- a/crates/router/src/services/kafka/payment_intent.rs +++ b/crates/router/src/services/kafka/payment_intent.rs @@ -37,7 +37,7 @@ impl<'a> KafkaPaymentIntent<'a> { payment_id: &intent.payment_id, merchant_id: &intent.merchant_id, status: intent.status, - amount: intent.amount, + amount: intent.original_amount, currency: intent.currency, amount_captured: intent.amount_captured, customer_id: intent.customer_id.as_ref(), diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index cc14fe36a04..45a54b7e814 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -642,7 +642,7 @@ impl Capturable for PaymentsSyncData { payment_data .payment_attempt .amount_to_capture - .or_else(|| Some(payment_data.payment_attempt.get_total_amount())) + .or_else(|| Some(payment_data.payment_attempt.amount.get_authorize_amount())) } } diff --git a/crates/router/src/types/storage/payment_attempt.rs b/crates/router/src/types/storage/payment_attempt.rs index 13b9f3dd5d5..be0f6afed05 100644 --- a/crates/router/src/types/storage/payment_attempt.rs +++ b/crates/router/src/types/storage/payment_attempt.rs @@ -15,8 +15,9 @@ pub trait PaymentAttemptExt { ) -> RouterResult; fn get_next_capture_id(&self) -> String; - fn get_total_amount(&self) -> i64; - fn get_surcharge_details(&self) -> Option; + fn get_request_surcharge_details( + &self, + ) -> Option; } impl PaymentAttemptExt for PaymentAttempt { @@ -58,17 +59,16 @@ impl PaymentAttemptExt for PaymentAttempt { let next_sequence_number = self.multiple_capture_count.unwrap_or_default() + 1; format!("{}_{}", self.attempt_id.clone(), next_sequence_number) } - fn get_surcharge_details(&self) -> Option { - self.surcharge_amount.map(|surcharge_amount| { + fn get_request_surcharge_details( + &self, + ) -> Option { + self.amount.get_surcharge_amount().map(|surcharge_amount| { api_models::payments::RequestSurchargeDetails { surcharge_amount, - tax_amount: self.tax_amount, + tax_amount: self.amount.get_tax_amount_on_surcharge(), } }) } - fn get_total_amount(&self) -> i64 { - self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0) - } } pub trait AttemptStatusExt { diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 5bd03fe833a..96acf7cfdab 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -813,7 +813,7 @@ impl ForeignFrom for api_models::payments::PaymentAttem Self { attempt_id: payment_attempt.attempt_id, status: payment_attempt.status, - amount: payment_attempt.amount, + amount: payment_attempt.amount.get_original_amount(), currency: payment_attempt.currency, connector: payment_attempt.connector, error_message: payment_attempt.error_reason, @@ -933,7 +933,8 @@ impl currency: payment_attempt.map(|pa| pa.currency.unwrap_or_default()), shipping: shipping.map(api_types::Address::from), billing: billing.map(api_types::Address::from), - amount: payment_attempt.map(|pa| api_types::Amount::from(pa.amount)), + amount: payment_attempt + .map(|pa| api_types::Amount::from(pa.amount.get_original_amount())), email: customer .and_then(|cust| cust.email.as_ref().map(|em| pii::Email::from(em.clone()))), phone: customer.and_then(|cust| cust.phone.as_ref().map(|p| p.clone().into_inner())), diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs index 24863ddc568..52c1bfc9f16 100644 --- a/crates/storage_impl/src/mock_db/payment_attempt.rs +++ b/crates/storage_impl/src/mock_db/payment_attempt.rs @@ -3,7 +3,8 @@ use common_utils::errors::CustomResult; use data_models::{ errors::StorageError, payments::payment_attempt::{ - PaymentAttempt, PaymentAttemptInterface, PaymentAttemptNew, PaymentAttemptUpdate, + GetAttemptAmount, PaymentAttempt, PaymentAttemptInterface, PaymentAttemptNew, + PaymentAttemptUpdate, }, }; use diesel_models::enums as storage_enums; @@ -100,19 +101,16 @@ impl PaymentAttemptInterface for MockDb { let payment_attempt = payment_attempt.populate_derived_fields(); let payment_attempt = PaymentAttempt { id, + amount: payment_attempt.get_attempt_amount(), payment_id: payment_attempt.payment_id, merchant_id: payment_attempt.merchant_id, attempt_id: payment_attempt.attempt_id, status: payment_attempt.status, - amount: payment_attempt.amount, - net_amount: payment_attempt.net_amount, currency: payment_attempt.currency, save_to_locker: payment_attempt.save_to_locker, connector: payment_attempt.connector, error_message: payment_attempt.error_message, offer_amount: payment_attempt.offer_amount, - surcharge_amount: payment_attempt.surcharge_amount, - tax_amount: payment_attempt.tax_amount, payment_method_id: payment_attempt.payment_method_id, payment_method: payment_attempt.payment_method, connector_transaction_id: None, diff --git a/crates/storage_impl/src/mock_db/payment_intent.rs b/crates/storage_impl/src/mock_db/payment_intent.rs index 1da3df0bdef..982c6fe75d7 100644 --- a/crates/storage_impl/src/mock_db/payment_intent.rs +++ b/crates/storage_impl/src/mock_db/payment_intent.rs @@ -74,7 +74,7 @@ impl PaymentIntentInterface for MockDb { payment_id: new.payment_id, merchant_id: new.merchant_id, status: new.status, - amount: new.amount, + original_amount: new.amount, currency: new.currency, amount_captured: new.amount_captured, customer_id: new.customer_id, diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index f8f752c6bc8..c13d5cbbc5a 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -5,8 +5,8 @@ use data_models::{ mandates::{MandateAmountData, MandateDataType}, payments::{ payment_attempt::{ - PaymentAttempt, PaymentAttemptInterface, PaymentAttemptNew, PaymentAttemptUpdate, - PaymentListFilters, + GetAttemptAmount, PaymentAttempt, PaymentAttemptInterface, PaymentAttemptNew, + PaymentAttemptUpdate, PaymentListFilters, }, PaymentIntent, }, @@ -343,15 +343,12 @@ impl PaymentAttemptInterface for KVRouterStore { merchant_id: payment_attempt.merchant_id.clone(), attempt_id: payment_attempt.attempt_id.clone(), status: payment_attempt.status, - amount: payment_attempt.amount, - net_amount: payment_attempt.net_amount, + amount: payment_attempt.get_attempt_amount(), currency: payment_attempt.currency, save_to_locker: payment_attempt.save_to_locker, connector: payment_attempt.connector.clone(), error_message: payment_attempt.error_message.clone(), offer_amount: payment_attempt.offer_amount, - surcharge_amount: payment_attempt.surcharge_amount, - tax_amount: payment_attempt.tax_amount, payment_method_id: payment_attempt.payment_method_id.clone(), payment_method: payment_attempt.payment_method, connector_transaction_id: None, @@ -1036,15 +1033,15 @@ impl DataModelExt for PaymentAttempt { merchant_id: self.merchant_id, attempt_id: self.attempt_id, status: self.status, - amount: self.amount, - net_amount: Some(self.net_amount), + amount: self.amount.get_original_amount(), + net_amount: Some(self.amount.get_authorize_amount()), currency: self.currency, save_to_locker: self.save_to_locker, connector: self.connector, error_message: self.error_message, offer_amount: self.offer_amount, - surcharge_amount: self.surcharge_amount, - tax_amount: self.tax_amount, + surcharge_amount: self.amount.get_surcharge_amount(), + tax_amount: self.amount.get_tax_amount_on_surcharge(), payment_method_id: self.payment_method_id, payment_method: self.payment_method, connector_transaction_id: self.connector_transaction_id, @@ -1084,20 +1081,17 @@ impl DataModelExt for PaymentAttempt { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { - net_amount: storage_model.get_or_calculate_net_amount(), + amount: storage_model.get_attempt_amount(), id: storage_model.id, payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, status: storage_model.status, - amount: storage_model.amount, currency: storage_model.currency, save_to_locker: storage_model.save_to_locker, connector: storage_model.connector, error_message: storage_model.error_message, offer_amount: storage_model.offer_amount, - surcharge_amount: storage_model.surcharge_amount, - tax_amount: storage_model.tax_amount, payment_method_id: storage_model.payment_method_id, payment_method: storage_model.payment_method, connector_transaction_id: storage_model.connector_transaction_id, @@ -1194,7 +1188,7 @@ impl DataModelExt for PaymentAttemptNew { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { - net_amount: storage_model.get_or_calculate_net_amount(), + net_amount: storage_model.calculate_net_amount(), payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, diff --git a/crates/storage_impl/src/payments/payment_intent.rs b/crates/storage_impl/src/payments/payment_intent.rs index 61229ca890c..d4e966713fe 100644 --- a/crates/storage_impl/src/payments/payment_intent.rs +++ b/crates/storage_impl/src/payments/payment_intent.rs @@ -66,7 +66,7 @@ impl PaymentIntentInterface for KVRouterStore { payment_id: new.payment_id.clone(), merchant_id: new.merchant_id.clone(), status: new.status, - amount: new.amount, + original_amount: new.amount, currency: new.currency, amount_captured: new.amount_captured, customer_id: new.customer_id.clone(), @@ -824,7 +824,7 @@ impl DataModelExt for PaymentIntent { payment_id: self.payment_id, merchant_id: self.merchant_id, status: self.status, - amount: self.amount, + amount: self.original_amount, currency: self.currency, amount_captured: self.amount_captured, customer_id: self.customer_id, @@ -868,7 +868,7 @@ impl DataModelExt for PaymentIntent { payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, status: storage_model.status, - amount: storage_model.amount, + original_amount: storage_model.amount, currency: storage_model.currency, amount_captured: storage_model.amount_captured, customer_id: storage_model.customer_id, From f134a69be1dc5c0896831503932e13fcc5c110fe Mon Sep 17 00:00:00 2001 From: hrithikesh026 Date: Fri, 12 Jan 2024 15:19:11 +0530 Subject: [PATCH 17/19] resolve merge related issues --- crates/router/src/connector/cybersource/transformers.rs | 6 +++--- crates/router/src/connector/utils.rs | 2 +- crates/router/src/core/payment_link.rs | 2 +- crates/router/src/core/payments/helpers.rs | 2 -- .../router/src/core/payments/operations/payment_confirm.rs | 2 +- .../router/src/core/payments/operations/payment_create.rs | 2 +- .../router/src/core/payments/operations/payment_update.rs | 2 +- crates/router/src/types.rs | 4 ++-- 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index e83b23603e9..a641a3b5027 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -1986,9 +1986,9 @@ impl resource_id: types::ResponseId::NoResponseId, redirection_data, mandate_reference: None, - connector_metadata: Some( - serde_json::json!({"three_ds_data":three_ds_data}), - ), + connector_metadata: Some(serde_json::json!({ + "three_ds_data": three_ds_data + })), network_txn_id: None, connector_response_reference_id, incremental_authorization_allowed: None, diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index bc1cc64fbb3..afba1478943 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -117,7 +117,7 @@ where } enums::AttemptStatus::Charged => { let captured_amount = - types::Capturable::get_capture_amount(&self.request, payment_data); + types::Capturable::get_captured_amount(&self.request, payment_data); let total_capturable_amount = payment_data.payment_attempt.amount.get_authorize_amount(); if Some(total_capturable_amount) == captured_amount { diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index 84cd726a7e4..893b157b890 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -105,7 +105,7 @@ pub async fn intiate_payment_link_flow( payment_intent.client_secret.clone(), )?; let amount = currency - .to_currency_base_unit(payment_intent.amount) + .to_currency_base_unit(payment_intent.original_amount) .into_report() .change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?; let order_details = validate_order_details(payment_intent.order_details.clone(), currency)?; diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 8b361f377ab..888c2560a8a 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3101,8 +3101,6 @@ impl AttemptType { offer_amount: old_payment_attempt.offer_amount, surcharge_amount: None, tax_amount: None, - surcharge_amount: None, - tax_amount: None, payment_method_id: None, payment_method: None, capture_method: old_payment_attempt.capture_method, diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 1666aff4fcd..5af22b7e4d4 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -110,7 +110,7 @@ impl if let Some(order_details) = &request.order_details { helpers::validate_order_details_amount( order_details.to_owned(), - payment_intent.amount, + payment_intent.original_amount, false, )?; } diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 41154baafd3..5a15c085a80 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -244,7 +244,7 @@ impl if let Some(order_details) = &request.order_details { helpers::validate_order_details_amount( order_details.to_owned(), - payment_intent.amount, + payment_intent.original_amount, false, )?; } diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 9603284762c..5ae4c6c4818 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -63,7 +63,7 @@ impl if let Some(order_details) = &request.order_details { helpers::validate_order_details_amount( order_details.to_owned(), - payment_intent.amount, + payment_intent.original_amount, false, )?; } diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index ae1b007c224..e8dc827a41d 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -658,7 +658,7 @@ impl Capturable for PaymentsAuthorizeData { | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, } }, - common_enums::CaptureMethod::Manual => Some(payment_data.payment_attempt.get_total_amount()), + common_enums::CaptureMethod::Manual => Some(payment_data.payment_attempt.amount.get_authorize_amount()), // In case of manual multiple, amount capturable must be inferred from all captures. common_enums::CaptureMethod::ManualMultiple | // Scheduled capture is not supported as of now @@ -735,7 +735,7 @@ impl Capturable for CompleteAuthorizeData { | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, } }, - common_enums::CaptureMethod::Manual => Some(payment_data.payment_attempt.get_total_amount()), + common_enums::CaptureMethod::Manual => Some(payment_data.payment_attempt.amount.get_authorize_amount()), // In case of manual multiple, amount capturable must be inferred from all captures. common_enums::CaptureMethod::ManualMultiple | // Scheduled capture is not supported as of now From b5a9ebdd8e485a1177f38723024b09de9b3c19bd Mon Sep 17 00:00:00 2001 From: hrithikesh026 Date: Fri, 19 Jan 2024 11:22:55 +0530 Subject: [PATCH 18/19] fix(core): include surcharge_amount in frm request --- crates/data_models/src/payments/payment_attempt.rs | 8 ++++++++ crates/router/src/core/fraud_check.rs | 10 ++++++++++ crates/router/src/core/payment_methods/cards.rs | 10 ++++++++-- crates/router/src/core/payments.rs | 9 ++++----- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/crates/data_models/src/payments/payment_attempt.rs b/crates/data_models/src/payments/payment_attempt.rs index bcd1618e5ff..fb83e2c3edd 100644 --- a/crates/data_models/src/payments/payment_attempt.rs +++ b/crates/data_models/src/payments/payment_attempt.rs @@ -194,6 +194,14 @@ impl AttemptAmount { self.amount = amount; self.net_amount = self.amount + self.get_total_surcharge_amount().unwrap_or(0); } + pub fn set_surcharge_amount(&mut self, surcharge_amount: i64) { + self.surcharge_amount = Some(surcharge_amount); + self.net_amount = self.amount + self.get_total_surcharge_amount().unwrap_or(0); + } + pub fn set_tax_amount(&mut self, tax_amount: i64) { + self.tax_amount = Some(tax_amount); + self.net_amount = self.amount + self.get_total_surcharge_amount().unwrap_or(0); + } pub fn get_authorize_amount(&self) -> i64 { self.net_amount } diff --git a/crates/router/src/core/fraud_check.rs b/crates/router/src/core/fraud_check.rs index ad3a7638774..a84d4e45d84 100644 --- a/crates/router/src/core/fraud_check.rs +++ b/crates/router/src/core/fraud_check.rs @@ -81,6 +81,16 @@ where .payment_attempt .connector_transaction_id .clone(); + if let Some(surcharge_details) = &payment_data.surcharge_details { + frm_data + .payment_attempt + .amount + .set_surcharge_amount(surcharge_details.surcharge_amount); + frm_data + .payment_attempt + .amount + .set_tax_amount(surcharge_details.tax_on_surcharge_amount); + } let mut router_data = frm_data .construct_router_data( diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 9feb7b62e62..6ade8e4af8a 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -1088,8 +1088,14 @@ pub async fn list_payment_methods( ) .await?; - // filter out connectors based on the business country - let filtered_mcas = helpers::filter_mca_based_on_business_profile(all_mcas, profile_id); + // filter out connectors based on the business profile and connector types + let filtered_mcas = { + let filter_list = helpers::filter_mca_based_on_business_profile(all_mcas, profile_id); + filter_list + .into_iter() + .filter(|mca| mca.connector_type == common_enums::ConnectorType::FizOperations) + .collect::>() + }; logger::debug!(mca_before_filtering=?filtered_mcas); diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index b42f58f0623..319acd740bf 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -173,6 +173,10 @@ where let mut connector_http_status_code = None; let mut external_latency = None; if let Some(connector_details) = connector { + operation + .to_domain()? + .populate_payment_data(state, &mut payment_data, &merchant_account) + .await?; // Fetch and check FRM configs #[cfg(feature = "frm")] let mut frm_info = None; @@ -1031,11 +1035,6 @@ where merchant_connector_account.get_mca_id(); } - operation - .to_domain()? - .populate_payment_data(state, payment_data, merchant_account) - .await?; - let (pd, tokenization_action) = get_connector_tokenization_action_when_confirm_true( state, operation, From c67c9fea030874ba9f5e335215fdb300db74abfc Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 06:04:31 +0000 Subject: [PATCH 19/19] chore: update Cargo.lock --- Cargo.lock | 100 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b58631632e4..3f9c7ef079e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -118,7 +118,7 @@ dependencies = [ "parse-size", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -255,7 +255,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -564,18 +564,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1292,7 +1292,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "syn_derive", ] @@ -1425,6 +1425,7 @@ dependencies = [ "error-stack", "luhn", "masking", + "router_env", "serde", "serde_json", "thiserror", @@ -1613,7 +1614,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1727,6 +1728,17 @@ dependencies = [ "toml 0.7.4", ] +[[package]] +name = "connector_configs" +version = "0.1.0" +dependencies = [ + "api_models", + "serde", + "serde_with", + "toml 0.7.4", + "utoipa", +] + [[package]] name = "constant_time_eq" version = "0.2.6" @@ -1999,7 +2011,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2010,7 +2022,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2147,7 +2159,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2177,7 +2189,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2234,7 +2246,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2254,6 +2266,7 @@ name = "drainer" version = "0.1.0" dependencies = [ "async-bb8-diesel", + "async-trait", "bb8", "clap", "common_utils", @@ -2386,6 +2399,7 @@ version = "0.1.0" dependencies = [ "api_models", "common_enums", + "connector_configs", "currency_conversion", "euclid", "getrandom 0.2.11", @@ -2582,7 +2596,7 @@ checksum = "b0fa992f1656e1707946bbba340ad244f0814009ef8c0118eb7b658395f19a2e" dependencies = [ "frunk_proc_macro_helpers", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2594,7 +2608,7 @@ dependencies = [ "frunk_core", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2606,7 +2620,7 @@ dependencies = [ "frunk_core", "frunk_proc_macro_helpers", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2719,7 +2733,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3981,7 +3995,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4267,7 +4281,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4357,7 +4371,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4499,9 +4513,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -4634,9 +4648,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -5150,7 +5164,7 @@ dependencies = [ "serde", "serde_json", "strum 0.24.1", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5210,7 +5224,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.39", + "syn 2.0.48", "walkdir", ] @@ -5556,7 +5570,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5620,7 +5634,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5670,7 +5684,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5695,7 +5709,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -6086,7 +6100,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -6108,9 +6122,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -6126,7 +6140,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -6234,7 +6248,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -6246,7 +6260,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "test-case-core", ] @@ -6325,7 +6339,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -6515,7 +6529,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -7101,7 +7115,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -7250,7 +7264,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -7284,7 +7298,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7586,7 +7600,7 @@ checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]]