diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index edd2206a6c..45b5dd125d 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -3150,28 +3150,26 @@ pub enum GiftCardData { BhnCardNetwork(BHNGiftCardDetails), } -#[cfg(feature = "v2")] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum BalanceCheckPaymentMethodData { GiftCard(GiftCardData), } -#[cfg(feature = "v2")] #[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)] pub struct ApplyPaymentMethodDataRequest { pub payment_methods: Vec, } -#[cfg(feature = "v2")] #[derive(Debug, serde::Serialize, Clone, ToSchema)] pub struct ApplyPaymentMethodDataResponse { pub remaining_amount: MinorUnit, + #[schema(value_type = Currency)] + pub currency: common_enums::Currency, pub requires_additional_pm_data: bool, pub surcharge_details: Option>, } -#[cfg(feature = "v2")] #[derive(Debug, serde::Serialize, Clone, ToSchema)] pub struct ApplyPaymentMethodDataSurchargeResponseItem { #[schema(value_type = PaymentMethod)] diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs index 0cc1cf797e..f31b1f0f52 100644 --- a/crates/common_utils/src/types.rs +++ b/crates/common_utils/src/types.rs @@ -382,6 +382,7 @@ impl AmountConvertor for MinorUnitForConnector { Hash, ToSchema, PartialOrd, + Ord, )] #[diesel(sql_type = sql_types::BigInt)] pub struct MinorUnit(i64); diff --git a/crates/router/src/core.rs b/crates/router/src/core.rs index e180c1a9af..530868dc49 100644 --- a/crates/router/src/core.rs +++ b/crates/router/src/core.rs @@ -27,8 +27,6 @@ pub mod external_service_auth; pub mod files; #[cfg(feature = "frm")] pub mod fraud_check; -#[cfg(feature = "v2")] -pub mod gift_card; pub mod gsm; pub mod health_check; #[cfg(feature = "v1")] @@ -36,6 +34,8 @@ pub mod locker_migration; pub mod mandate; pub mod metrics; pub mod payment_link; +#[cfg(feature = "v2")] +pub mod payment_method_balance; pub mod payment_methods; pub mod payments; #[cfg(feature = "payouts")] diff --git a/crates/router/src/core/gift_card.rs b/crates/router/src/core/payment_method_balance.rs similarity index 96% rename from crates/router/src/core/gift_card.rs rename to crates/router/src/core/payment_method_balance.rs index 8b3e1fb792..ca51024346 100644 --- a/crates/router/src/core/gift_card.rs +++ b/crates/router/src/core/payment_method_balance.rs @@ -228,20 +228,17 @@ pub async fn payments_apply_pm_data_core( .await .attach_printable("Failed to retrieve payment method balances from redis")?; - let total_balance: i64 = balances - .values() - .map(|value| value.balance.get_amount_as_i64()) - .sum(); + let total_balance: MinorUnit = balances.values().map(|value| value.balance).sum(); - let remaining_amount = payment_intent - .amount_details - .order_amount - .get_amount_as_i64() - .saturating_sub(total_balance); + // remaining_amount cannot be negative, hence using max with 0. This situation can arise when + // the gift card balance exceeds the order amount + let remaining_amount = + (payment_intent.amount_details.order_amount - total_balance).max(MinorUnit::zero()); let resp = ApplyPaymentMethodDataResponse { - remaining_amount: MinorUnit::new(remaining_amount), - requires_additional_pm_data: remaining_amount > 0, + remaining_amount, + currency: payment_intent.amount_details.currency, + requires_additional_pm_data: remaining_amount.is_greater_than(0), surcharge_details: None, // TODO: Implement surcharge recalculation logic }; diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index bdb8b87c5a..092780e88c 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -11,7 +11,7 @@ use router_env::{env, instrument, logger, tracing, types, Flow}; use super::app::ReqState; #[cfg(feature = "v2")] -use crate::core::gift_card; +use crate::core::payment_method_balance; #[cfg(feature = "v2")] use crate::core::revenue_recovery::api as recovery; use crate::{ @@ -3163,15 +3163,17 @@ pub async fn payment_check_gift_card_balance( let merchant_context = domain::MerchantContext::NormalMerchant(Box::new( domain::Context(auth.merchant_account, auth.key_store), )); - Box::pin(gift_card::payments_check_gift_card_balance_core( - state, - merchant_context, - auth.profile, - req_state, - request, - header_payload.clone(), - payment_id, - )) + Box::pin( + payment_method_balance::payments_check_gift_card_balance_core( + state, + merchant_context, + auth.profile, + req_state, + request, + header_payload.clone(), + payment_id, + ), + ) .await }, auth::api_or_client_auth( @@ -3219,7 +3221,7 @@ pub async fn payments_apply_pm_data( let merchant_context = domain::MerchantContext::NormalMerchant(Box::new( domain::Context(auth.merchant_account, auth.key_store), )); - Box::pin(gift_card::payments_apply_pm_data_core( + Box::pin(payment_method_balance::payments_apply_pm_data_core( state, merchant_context, req_state,