diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index 002c9f7d5b..c28d0ab820 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -108,6 +108,8 @@ pub struct PaymentAttempt { pub is_overcapture_enabled: Option, pub network_details: Option, pub is_stored_credential: Option, + /// stores the authorized amount in case of partial authorization + pub authorized_amount: Option, #[diesel(deserialize_as = RequiredFromNullable)] pub payment_method_type_v2: storage_enums::PaymentMethod, pub connector_payment_id: Option, @@ -228,6 +230,8 @@ pub struct PaymentAttempt { pub is_overcapture_enabled: Option, pub network_details: Option, pub is_stored_credential: Option, + /// stores the authorized amount in case of partial authorization + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -371,6 +375,7 @@ pub struct PaymentAttemptNew { pub processor_merchant_id: Option, pub created_by: Option, pub connector_request_reference_id: Option, + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -456,6 +461,7 @@ pub struct PaymentAttemptNew { pub network_transaction_id: Option, pub network_details: Option, pub is_stored_credential: Option, + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -589,6 +595,7 @@ pub enum PaymentAttemptUpdate { charges: Option, setup_future_usage_applied: Option, is_overcapture_enabled: Option, + authorized_amount: Option, }, UnresolvedResponseUpdate { status: storage_enums::AttemptStatus, @@ -1024,6 +1031,7 @@ impl PaymentAttemptUpdateInternal { network_details: source.network_details, attempts_group_id: source.attempts_group_id, is_stored_credential: source.is_stored_credential, + authorized_amount: source.authorized_amount, } } } @@ -1095,6 +1103,7 @@ pub struct PaymentAttemptUpdateInternal { pub network_details: Option, pub is_stored_credential: Option, pub request_extended_authorization: Option, + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -1291,6 +1300,7 @@ impl PaymentAttemptUpdate { network_details, is_stored_credential, request_extended_authorization, + authorized_amount, } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source); PaymentAttempt { amount: amount.unwrap_or(source.amount), @@ -1366,6 +1376,7 @@ impl PaymentAttemptUpdate { is_stored_credential: is_stored_credential.or(source.is_stored_credential), request_extended_authorization: request_extended_authorization .or(source.request_extended_authorization), + authorized_amount: authorized_amount.or(source.authorized_amount), ..source } } @@ -2708,6 +2719,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::AuthenticationTypeUpdate { authentication_type, @@ -2777,6 +2789,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::ConfirmUpdate { amount, @@ -2882,6 +2895,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential, request_extended_authorization, + authorized_amount: None, }, PaymentAttemptUpdate::VoidUpdate { status, @@ -2952,6 +2966,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::RejectUpdate { status, @@ -3023,6 +3038,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::BlocklistUpdate { status, @@ -3094,6 +3110,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::ConnectorMandateDetailUpdate { connector_mandate_detail, @@ -3163,6 +3180,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::PaymentMethodDetailsUpdate { payment_method_id, @@ -3232,6 +3250,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::ResponseUpdate { status, @@ -3260,6 +3279,7 @@ impl From for PaymentAttemptUpdateInternal { setup_future_usage_applied, network_transaction_id, is_overcapture_enabled, + authorized_amount, } => { let (connector_transaction_id, processor_transaction_data) = connector_transaction_id @@ -3331,6 +3351,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount, } } PaymentAttemptUpdate::ErrorUpdate { @@ -3420,6 +3441,7 @@ impl From for PaymentAttemptUpdateInternal { network_details, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, } } PaymentAttemptUpdate::StatusUpdate { status, updated_by } => Self { @@ -3487,6 +3509,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::UpdateTrackers { payment_token, @@ -3564,6 +3587,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::UnresolvedResponseUpdate { status, @@ -3646,6 +3670,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, } } PaymentAttemptUpdate::PreprocessingUpdate { @@ -3727,6 +3752,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, } } PaymentAttemptUpdate::CaptureUpdate { @@ -3798,6 +3824,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::AmountToCaptureUpdate { status, @@ -3868,6 +3895,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::ConnectorResponse { authentication_data, @@ -3947,6 +3975,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, } } PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate { @@ -4017,6 +4046,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::AuthenticationUpdate { status, @@ -4089,6 +4119,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, PaymentAttemptUpdate::ManualUpdate { status, @@ -4170,6 +4201,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, } } PaymentAttemptUpdate::PostSessionTokensUpdate { @@ -4240,6 +4272,7 @@ impl From for PaymentAttemptUpdateInternal { network_details: None, is_stored_credential: None, request_extended_authorization: None, + authorized_amount: None, }, } } diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 7cddb53603..f11f9318f1 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -1084,6 +1084,7 @@ diesel::table! { is_overcapture_enabled -> Nullable, network_details -> Nullable, is_stored_credential -> Nullable, + authorized_amount -> Nullable, } } diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs index 93ad4299c5..b57a192bfe 100644 --- a/crates/diesel_models/src/schema_v2.rs +++ b/crates/diesel_models/src/schema_v2.rs @@ -1026,6 +1026,7 @@ diesel::table! { is_overcapture_enabled -> Nullable, network_details -> Nullable, is_stored_credential -> Nullable, + authorized_amount -> Nullable, payment_method_type_v2 -> Nullable, #[max_length = 128] connector_payment_id -> Nullable, diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs index 5f6aa33b0b..987b0f704b 100644 --- a/crates/diesel_models/src/user/sample_data.rs +++ b/crates/diesel_models/src/user/sample_data.rs @@ -221,6 +221,7 @@ pub struct PaymentAttemptBatchNew { pub network_transaction_id: Option, pub network_details: Option, pub is_stored_credential: Option, + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -311,6 +312,7 @@ impl PaymentAttemptBatchNew { network_transaction_id: self.network_transaction_id, network_details: self.network_details, is_stored_credential: self.is_stored_credential, + authorized_amount: self.authorized_amount, } } } diff --git a/crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs b/crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs index 6754778539..0b9aa148e1 100644 --- a/crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs @@ -357,6 +357,13 @@ pub struct PaymentsRequest { pub processing: Option, pub shipping: Option, pub items: Option>, + pub partial_authorization: Option, +} + +#[skip_serializing_none] +#[derive(Debug, Default, Serialize)] +pub struct CheckoutPartialAuthorization { + pub enabled: bool, } #[derive(Debug, Serialize, Deserialize)] @@ -698,6 +705,12 @@ impl TryFrom<&CheckoutRouterData<&PaymentsAuthorizeRouterData>> for PaymentsRequ (None, None, None, None) }; + let partial_authorization = item.router_data.request.enable_partial_authorization.map( + |enable_partial_authorization| CheckoutPartialAuthorization { + enabled: *enable_partial_authorization, + }, + ); + let request = Self { source: source_var, amount: item.amount.to_owned(), @@ -716,6 +729,7 @@ impl TryFrom<&CheckoutRouterData<&PaymentsAuthorizeRouterData>> for PaymentsRequ processing, shipping, items, + partial_authorization, }; Ok(request) @@ -1012,10 +1026,28 @@ impl TryFrom> for PaymentsAuthorize incremental_authorization_allowed: None, charges: None, }; + + let (amount_captured, minor_amount_capturable) = match item.data.request.capture_method { + Some(enums::CaptureMethod::Manual) | Some(enums::CaptureMethod::ManualMultiple) => { + (None, item.response.amount) + } + _ => (item.response.amount.map(MinorUnit::get_amount_as_i64), None), + }; + + let authorized_amount = item + .data + .request + .enable_partial_authorization + .filter(|flag| flag.is_true()) + .and(item.response.amount); + Ok(Self { status, response: Ok(payments_response_data), connector_response: additional_information, + authorized_amount, + amount_captured, + minor_amount_capturable, ..item.data }) } diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index b1ad3ac295..9846ba5d5a 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -6829,6 +6829,7 @@ pub(crate) fn convert_payment_authorize_router_response( is_payment_id_from_merchant: data.is_payment_id_from_merchant, l2_l3_data: data.l2_l3_data.clone(), minor_amount_capturable: data.minor_amount_capturable, + authorized_amount: data.authorized_amount, } } diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index bcce5d5978..f7e5ec78cb 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -493,6 +493,8 @@ pub struct PaymentAttempt { pub created_by: Option, pub connector_request_reference_id: Option, pub network_transaction_id: Option, + /// stores the authorized amount in case of partial authorization + pub authorized_amount: Option, } impl PaymentAttempt { @@ -627,6 +629,7 @@ impl PaymentAttempt { created_by: None, connector_request_reference_id: None, network_transaction_id: None, + authorized_amount: None, }) } @@ -718,6 +721,7 @@ impl PaymentAttempt { created_by: None, connector_request_reference_id: None, network_transaction_id: None, + authorized_amount: None, }) } @@ -815,6 +819,7 @@ impl PaymentAttempt { created_by: None, connector_request_reference_id: None, network_transaction_id: None, + authorized_amount: None, }) } @@ -935,6 +940,7 @@ impl PaymentAttempt { created_by: None, connector_request_reference_id, network_transaction_id: None, + authorized_amount: None, }) } @@ -1039,6 +1045,8 @@ pub struct PaymentAttempt { pub is_overcapture_enabled: Option, pub network_details: Option, pub is_stored_credential: Option, + /// stores the authorized amount in case of partial authorization + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -1338,6 +1346,7 @@ pub struct PaymentAttemptNew { pub network_transaction_id: Option, pub network_details: Option, pub is_stored_credential: Option, + pub authorized_amount: Option, } #[cfg(feature = "v1")] @@ -1466,6 +1475,7 @@ pub enum PaymentAttemptUpdate { setup_future_usage_applied: Option, debit_routing_savings: Option, is_overcapture_enabled: Option, + authorized_amount: Option, }, UnresolvedResponseUpdate { status: storage_enums::AttemptStatus, @@ -1775,6 +1785,7 @@ impl PaymentAttemptUpdate { network_transaction_id, debit_routing_savings: _, is_overcapture_enabled, + authorized_amount, } => DieselPaymentAttemptUpdate::ResponseUpdate { status, connector, @@ -1802,6 +1813,7 @@ impl PaymentAttemptUpdate { setup_future_usage_applied, network_transaction_id, is_overcapture_enabled, + authorized_amount, }, Self::UnresolvedResponseUpdate { status, @@ -2187,6 +2199,7 @@ impl behaviour::Conversion for PaymentAttempt { is_overcapture_enabled: self.is_overcapture_enabled, network_details: self.network_details, is_stored_credential: self.is_stored_credential, + authorized_amount: self.authorized_amount, }) } @@ -2289,6 +2302,7 @@ impl behaviour::Conversion for PaymentAttempt { is_overcapture_enabled: storage_model.is_overcapture_enabled, network_details: storage_model.network_details, is_stored_credential: storage_model.is_stored_credential, + authorized_amount: storage_model.authorized_amount, }) } .await @@ -2382,6 +2396,7 @@ impl behaviour::Conversion for PaymentAttempt { network_transaction_id: self.network_transaction_id, network_details: self.network_details, is_stored_credential: self.is_stored_credential, + authorized_amount: self.authorized_amount, }) } } @@ -2456,6 +2471,7 @@ impl behaviour::Conversion for PaymentAttempt { created_by, connector_request_reference_id, network_transaction_id, + authorized_amount, } = self; let AttemptAmountDetails { @@ -2556,6 +2572,7 @@ impl behaviour::Conversion for PaymentAttempt { network_details: None, attempts_group_id, is_stored_credential: None, + authorized_amount, }) } @@ -2681,6 +2698,7 @@ impl behaviour::Conversion for PaymentAttempt { .and_then(|created_by| created_by.parse::().ok()), connector_request_reference_id: storage_model.connector_request_reference_id, network_transaction_id: storage_model.network_transaction_id, + authorized_amount: storage_model.authorized_amount, }) } .await @@ -2742,6 +2760,7 @@ impl behaviour::Conversion for PaymentAttempt { created_by, connector_request_reference_id, network_transaction_id, + authorized_amount, } = self; let card_network = payment_method_data @@ -2838,6 +2857,7 @@ impl behaviour::Conversion for PaymentAttempt { network_details: None, attempts_group_id, is_stored_credential: None, + authorized_amount, }) } } diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index 0c22d02550..90ecd26a8e 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -92,6 +92,9 @@ pub struct RouterData { pub minor_amount_captured: Option, pub minor_amount_capturable: Option, + // stores the authorized amount in case of partial authorization + pub authorized_amount: Option, + pub integrity_check: Result<(), IntegrityCheckError>, pub additional_merchant_data: Option, diff --git a/crates/hyperswitch_interfaces/src/conversion_impls.rs b/crates/hyperswitch_interfaces/src/conversion_impls.rs index ed83c8235f..a1172f160c 100644 --- a/crates/hyperswitch_interfaces/src/conversion_impls.rs +++ b/crates/hyperswitch_interfaces/src/conversion_impls.rs @@ -89,6 +89,7 @@ fn get_default_router_data( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, } } diff --git a/crates/router/src/core/authentication/transformers.rs b/crates/router/src/core/authentication/transformers.rs index 273da3e00c..6ed04f1522 100644 --- a/crates/router/src/core/authentication/transformers.rs +++ b/crates/router/src/core/authentication/transformers.rs @@ -210,6 +210,7 @@ pub fn construct_router_data( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }) } 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 8d744b7623..c222ff3b40 100644 --- a/crates/router/src/core/fraud_check/flows/checkout_flow.rs +++ b/crates/router/src/core/fraud_check/flows/checkout_flow.rs @@ -162,6 +162,7 @@ impl ConstructFlowSpecificData( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } 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 a86b829b86..1853f48db6 100644 --- a/crates/router/src/core/fraud_check/flows/record_return.rs +++ b/crates/router/src/core/fraud_check/flows/record_return.rs @@ -133,6 +133,7 @@ impl ConstructFlowSpecificData( is_payment_id_from_merchant: router_data.is_payment_id_from_merchant, l2_l3_data: router_data.l2_l3_data, minor_amount_capturable: router_data.minor_amount_capturable, + authorized_amount: router_data.authorized_amount, } } @@ -4805,6 +4806,7 @@ impl AttemptType { network_transaction_id: None, network_details: None, is_stored_credential: old_payment_attempt.is_stored_credential, + authorized_amount: old_payment_attempt.authorized_amount, } } diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 55a868beec..985450ad1a 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -1415,7 +1415,8 @@ impl PaymentCreate { connector_request_reference_id: None, network_transaction_id:None, network_details:None, - is_stored_credential + is_stored_credential, + authorized_amount: None, }, additional_pm_data, diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 914daaff9d..f12d394f4a 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -1939,6 +1939,7 @@ async fn payment_response_update_tracker( debit_routing_savings, network_transaction_id: resp_network_transaction_id, is_overcapture_enabled, + authorized_amount: router_data.authorized_amount, }), ), }; @@ -2031,7 +2032,10 @@ 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 + .authorized_amount + .unwrap_or_else(|| payment_data.payment_attempt.get_total_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/retry.rs b/crates/router/src/core/payments/retry.rs index d76d4df6b0..1e7c0ad546 100644 --- a/crates/router/src/core/payments/retry.rs +++ b/crates/router/src/core/payments/retry.rs @@ -547,6 +547,7 @@ where .network_transaction_id .clone(), is_overcapture_enabled: None, + authorized_amount: router_data.authorized_amount, }; #[cfg(feature = "v1")] @@ -749,6 +750,7 @@ pub fn make_new_payment_attempt( network_transaction_id: old_payment_attempt.network_transaction_id, network_details: Default::default(), is_stored_credential: old_payment_attempt.is_stored_credential, + authorized_amount: old_payment_attempt.authorized_amount, } } diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index fd18e6dda9..a8d4e986db 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -187,6 +187,7 @@ where is_payment_id_from_merchant: payment_data.payment_intent.is_payment_id_from_merchant, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -521,6 +522,7 @@ pub async fn construct_payment_router_data_for_authorize<'a>( is_payment_id_from_merchant: payment_data.payment_intent.is_payment_id_from_merchant, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -865,6 +867,7 @@ pub async fn construct_payment_router_data_for_capture<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -996,6 +999,7 @@ pub async fn construct_router_data_for_psync<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -1348,6 +1352,7 @@ pub async fn construct_payment_router_data_for_sdk_session<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -1574,6 +1579,7 @@ pub async fn construct_payment_router_data_for_setup_mandate<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -1846,6 +1852,7 @@ where is_payment_id_from_merchant: payment_data.payment_intent.is_payment_id_from_merchant, l2_l3_data, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -2042,6 +2049,7 @@ pub async fn construct_payment_router_data_for_update_metadata<'a>( is_payment_id_from_merchant: payment_data.payment_intent.is_payment_id_from_merchant, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) diff --git a/crates/router/src/core/relay/utils.rs b/crates/router/src/core/relay/utils.rs index 4515ac1ff2..fb54ec4693 100644 --- a/crates/router/src/core/relay/utils.rs +++ b/crates/router/src/core/relay/utils.rs @@ -147,6 +147,7 @@ pub async fn construct_relay_refund_router_data( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) diff --git a/crates/router/src/core/unified_authentication_service/utils.rs b/crates/router/src/core/unified_authentication_service/utils.rs index 3842370f5c..586dbed99f 100644 --- a/crates/router/src/core/unified_authentication_service/utils.rs +++ b/crates/router/src/core/unified_authentication_service/utils.rs @@ -130,6 +130,7 @@ pub fn construct_uas_router_data( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }) } diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 367973ddbd..5f9cf67223 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -231,6 +231,7 @@ pub async fn construct_payout_router_data<'a, F>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -405,6 +406,7 @@ pub async fn construct_refund_router_data<'a, F>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -611,6 +613,7 @@ pub async fn construct_refund_router_data<'a, F>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) @@ -1054,6 +1057,7 @@ pub async fn construct_accept_dispute_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -1157,6 +1161,7 @@ pub async fn construct_submit_evidence_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -1269,6 +1274,7 @@ pub async fn construct_upload_file_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -1342,6 +1348,7 @@ pub async fn construct_dispute_list_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }) } @@ -1447,6 +1454,7 @@ pub async fn construct_dispute_sync_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -1575,6 +1583,7 @@ pub async fn construct_payments_dynamic_tax_calculation_router_data( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -1681,6 +1690,7 @@ pub async fn construct_defend_dispute_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } @@ -1781,6 +1791,7 @@ pub async fn construct_retrieve_file_router_data<'a>( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } diff --git a/crates/router/src/core/webhooks/utils.rs b/crates/router/src/core/webhooks/utils.rs index 0344d7d010..ec10eb2fb7 100644 --- a/crates/router/src/core/webhooks/utils.rs +++ b/crates/router/src/core/webhooks/utils.rs @@ -143,6 +143,7 @@ pub async fn construct_webhook_router_data( is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, }; Ok(router_data) } diff --git a/crates/router/src/services/kafka/payment_attempt.rs b/crates/router/src/services/kafka/payment_attempt.rs index 68659698c5..6f5257827a 100644 --- a/crates/router/src/services/kafka/payment_attempt.rs +++ b/crates/router/src/services/kafka/payment_attempt.rs @@ -281,6 +281,7 @@ impl<'a> KafkaPaymentAttempt<'a> { created_by, connector_request_reference_id, network_transaction_id: _, + authorized_amount: _, } = attempt; let (connector_payment_id, connector_payment_data) = connector_payment_id diff --git a/crates/router/src/services/kafka/payment_attempt_event.rs b/crates/router/src/services/kafka/payment_attempt_event.rs index 5e18c5909e..ed0c6177c4 100644 --- a/crates/router/src/services/kafka/payment_attempt_event.rs +++ b/crates/router/src/services/kafka/payment_attempt_event.rs @@ -283,6 +283,7 @@ impl<'a> KafkaPaymentAttemptEvent<'a> { created_by, connector_request_reference_id, network_transaction_id: _, + authorized_amount: _, } = attempt; let (connector_payment_id, connector_payment_data) = connector_payment_id diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index def5782d5d..7e257a71a9 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -1308,6 +1308,7 @@ impl ForeignFrom<(&RouterData, T2) is_payment_id_from_merchant: data.is_payment_id_from_merchant, l2_l3_data: data.l2_l3_data.clone(), minor_amount_capturable: data.minor_amount_capturable, + authorized_amount: data.authorized_amount, } } } @@ -1379,6 +1380,7 @@ impl is_payment_id_from_merchant: data.is_payment_id_from_merchant, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, } } } diff --git a/crates/router/src/types/api/verify_connector.rs b/crates/router/src/types/api/verify_connector.rs index d233c0696c..76dfb72b76 100644 --- a/crates/router/src/types/api/verify_connector.rs +++ b/crates/router/src/types/api/verify_connector.rs @@ -136,6 +136,7 @@ impl VerifyConnectorData { is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, } } } diff --git a/crates/router/src/types/storage/payment_attempt.rs b/crates/router/src/types/storage/payment_attempt.rs index 8332135b31..a2420cd26b 100644 --- a/crates/router/src/types/storage/payment_attempt.rs +++ b/crates/router/src/types/storage/payment_attempt.rs @@ -230,6 +230,7 @@ mod tests { network_transaction_id: Default::default(), network_details: Default::default(), is_stored_credential: None, + authorized_amount: Default::default(), }; let store = state @@ -325,6 +326,7 @@ mod tests { network_transaction_id: Default::default(), network_details: Default::default(), is_stored_credential: Default::default(), + authorized_amount: Default::default(), }; let store = state .stores @@ -433,6 +435,7 @@ mod tests { network_transaction_id: Default::default(), network_details: Default::default(), is_stored_credential: Default::default(), + authorized_amount: Default::default(), }; let store = state .stores diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs index 0fd23ee212..47f73daa3d 100644 --- a/crates/router/src/utils/user/sample_data.rs +++ b/crates/router/src/utils/user/sample_data.rs @@ -395,6 +395,7 @@ pub async fn generate_sample_data( network_transaction_id: None, network_details: None, is_stored_credential: None, + authorized_amount: None, }; let refund = if refunds_count < number_of_refunds && !is_failed_payment { diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 8d7493d0c4..2d28cd2008 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -562,6 +562,7 @@ pub trait ConnectorActions: Connector { is_payment_id_from_merchant: None, l2_l3_data: None, minor_amount_capturable: None, + authorized_amount: None, } } diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs index 2bf5daac6b..e8ab234d99 100644 --- a/crates/storage_impl/src/mock_db/payment_attempt.rs +++ b/crates/storage_impl/src/mock_db/payment_attempt.rs @@ -242,6 +242,7 @@ impl PaymentAttemptInterface for MockDb { is_overcapture_enabled: None, network_details: payment_attempt.network_details, is_stored_credential: payment_attempt.is_stored_credential, + authorized_amount: payment_attempt.authorized_amount, }; payment_attempts.push(payment_attempt.clone()); Ok(payment_attempt) diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 1cfe605cd0..ac26295afd 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -696,6 +696,7 @@ impl PaymentAttemptInterface for KVRouterStore { is_overcapture_enabled: None, network_details: payment_attempt.network_details.clone(), is_stored_credential: payment_attempt.is_stored_credential, + authorized_amount: payment_attempt.authorized_amount, }; let field = format!("pa_{}", created_attempt.attempt_id); @@ -1908,6 +1909,7 @@ impl DataModelExt for PaymentAttempt { is_overcapture_enabled: self.is_overcapture_enabled, network_details: self.network_details, is_stored_credential: self.is_stored_credential, + authorized_amount: self.authorized_amount, } } @@ -2005,6 +2007,7 @@ impl DataModelExt for PaymentAttempt { is_overcapture_enabled: storage_model.is_overcapture_enabled, network_details: storage_model.network_details, is_stored_credential: storage_model.is_stored_credential, + authorized_amount: storage_model.authorized_amount, } } } @@ -2099,6 +2102,7 @@ impl DataModelExt for PaymentAttemptNew { network_transaction_id: self.network_transaction_id, network_details: self.network_details, is_stored_credential: self.is_stored_credential, + authorized_amount: self.authorized_amount, } } @@ -2186,6 +2190,7 @@ impl DataModelExt for PaymentAttemptNew { network_transaction_id: storage_model.network_transaction_id, network_details: storage_model.network_details, is_stored_credential: storage_model.is_stored_credential, + authorized_amount: storage_model.authorized_amount, } } } diff --git a/migrations/2025-09-29-074746_add_authorized_amount_to_payment_attempt/down.sql b/migrations/2025-09-29-074746_add_authorized_amount_to_payment_attempt/down.sql new file mode 100644 index 0000000000..a21763df87 --- /dev/null +++ b/migrations/2025-09-29-074746_add_authorized_amount_to_payment_attempt/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE payment_attempt DROP COLUMN IF EXISTS authorized_amount; \ No newline at end of file diff --git a/migrations/2025-09-29-074746_add_authorized_amount_to_payment_attempt/up.sql b/migrations/2025-09-29-074746_add_authorized_amount_to_payment_attempt/up.sql new file mode 100644 index 0000000000..aa7a4ec240 --- /dev/null +++ b/migrations/2025-09-29-074746_add_authorized_amount_to_payment_attempt/up.sql @@ -0,0 +1,3 @@ +-- Your SQL goes here +ALTER TABLE payment_attempt +ADD COLUMN IF NOT EXISTS authorized_amount BIGINT; \ No newline at end of file