feat(core): Add support for partial auth in proxy payments [V2] (#9503)

Co-authored-by: Chikke Srujan <chikke.srujan@Chikke-Srujan-V9P7D4K9V0.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
chikke srujan
2025-09-30 12:07:57 +05:30
committed by GitHub
parent 69ac99d5db
commit c90744a6aa
21 changed files with 259 additions and 59 deletions

View File

@ -238,7 +238,7 @@ where
}) && payment_data
.payment_intent
.enable_partial_authorization
.is_some_and(|val| val)
.is_some_and(|val| val.is_true())
{
Ok(enums::AttemptStatus::PartiallyAuthorized)
} else if capturable_amount.is_some_and(|capturable_amount| {
@ -246,7 +246,7 @@ where
}) && !payment_data
.payment_intent
.enable_partial_authorization
.is_some_and(|val| val)
.is_some_and(|val| val.is_true())
{
Err(ApiErrorResponse::IntegrityCheckFailed {
reason: "capturable_amount is less than the total attempt amount"

View File

@ -3437,6 +3437,7 @@ fn construct_zero_auth_payments_request(
is_iframe_redirection_enabled: None,
merchant_connector_details: None,
return_raw_connector_response: None,
enable_partial_authorization: None,
})
}

View File

@ -190,6 +190,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentIntentData<F>, PaymentsUpda
frm_metadata,
request_external_three_ds_authentication,
set_active_attempt_id,
enable_partial_authorization,
} = request.clone();
let batch_encrypted_data = domain_types::crypto_operation(
@ -296,6 +297,8 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentIntentData<F>, PaymentsUpda
allowed_payment_method_types: allowed_payment_method_types
.or(payment_intent.allowed_payment_method_types),
active_attempt_id,
enable_partial_authorization: enable_partial_authorization
.or(payment_intent.enable_partial_authorization),
..payment_intent
};
@ -381,6 +384,7 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentIntentData<F>, PaymentsUpdateIn
active_attempt_id: Some(intent.active_attempt_id),
force_3ds_challenge: intent.force_3ds_challenge,
is_iframe_redirection_enabled: intent.is_iframe_redirection_enabled,
enable_partial_authorization: intent.enable_partial_authorization,
}));
let new_payment_intent = db

View File

@ -434,7 +434,7 @@ pub async fn construct_payment_router_data_for_authorize<'a>(
order_id: None,
locale: None,
payment_channel: None,
enable_partial_authorization: None,
enable_partial_authorization: payment_data.payment_intent.enable_partial_authorization,
enable_overcapture: None,
};
let connector_mandate_request_reference_id = payment_data
@ -479,8 +479,11 @@ pub async fn construct_payment_router_data_for_authorize<'a>(
connector_wallets_details: None,
request,
response: Err(hyperswitch_domain_models::router_data::ErrorResponse::default()),
amount_captured: None,
minor_amount_captured: None,
amount_captured: payment_data
.payment_intent
.amount_captured
.map(|amt| amt.get_amount_as_i64()),
minor_amount_captured: payment_data.payment_intent.amount_captured,
access_token: None,
session_token: None,
reference_id: None,
@ -2467,6 +2470,7 @@ where
request_external_three_ds_authentication: payment_intent
.request_external_three_ds_authentication,
payment_type,
enable_partial_authorization: payment_intent.enable_partial_authorization,
},
vec![],
)))

View File

@ -12,7 +12,9 @@ impl ForeignFrom<AttemptStatus> for RevenueRecoveryPaymentsAttemptStatus {
AttemptStatus::Authorized
| AttemptStatus::Charged
| AttemptStatus::AutoRefunded
| AttemptStatus::PartiallyAuthorized => Self::Succeeded,
| AttemptStatus::PartiallyAuthorized
| AttemptStatus::PartialCharged
| AttemptStatus::PartialChargedAndChargeable => Self::Succeeded,
AttemptStatus::Started
| AttemptStatus::AuthenticationSuccessful
@ -32,8 +34,6 @@ impl ForeignFrom<AttemptStatus> for RevenueRecoveryPaymentsAttemptStatus {
AttemptStatus::Voided
| AttemptStatus::VoidedPostCharge
| AttemptStatus::ConfirmationAwaited
| AttemptStatus::PartialCharged
| AttemptStatus::PartialChargedAndChargeable
| AttemptStatus::PaymentMethodAwaited
| AttemptStatus::AuthenticationPending
| AttemptStatus::DeviceDataCollectionPending
@ -57,6 +57,7 @@ impl ForeignFrom<api_models::payments::RecoveryPaymentsCreate>
next_billing_at: None,
billing_started_at: data.billing_started_at,
metadata: data.metadata,
enable_partial_authorization: data.enable_partial_authorization,
}
}
}

View File

@ -1,5 +1,8 @@
#[cfg(feature = "v2")]
use ::common_types::{payments, primitive_wrappers::RequestExtendedAuthorizationBool};
use ::common_types::{
payments,
primitive_wrappers::{EnablePartialAuthorizationBool, RequestExtendedAuthorizationBool},
};
#[cfg(feature = "v2")]
use common_enums;
#[cfg(feature = "v2")]
@ -178,6 +181,7 @@ pub struct KafkaPaymentIntent<'a> {
pub customer_present: common_enums::PresenceOfCustomerDuringPayment,
pub routing_algorithm_id: Option<&'a id_type::RoutingId>,
pub payment_link_config: Option<&'a PaymentLinkConfigRequestForPayments>,
pub enable_partial_authorization: Option<EnablePartialAuthorizationBool>,
#[serde(flatten)]
infra_values: Option<Value>,
@ -239,6 +243,7 @@ impl<'a> KafkaPaymentIntent<'a> {
created_by,
is_iframe_redirection_enabled,
is_payment_id_from_merchant,
enable_partial_authorization,
} = intent;
Self {
@ -314,6 +319,7 @@ impl<'a> KafkaPaymentIntent<'a> {
routing_algorithm_id: routing_algorithm_id.as_ref(),
payment_link_config: payment_link_config.as_ref(),
infra_values,
enable_partial_authorization: *enable_partial_authorization,
}
}
}

View File

@ -1,5 +1,8 @@
#[cfg(feature = "v2")]
use ::common_types::{payments, primitive_wrappers::RequestExtendedAuthorizationBool};
use ::common_types::{
payments,
primitive_wrappers::{EnablePartialAuthorizationBool, RequestExtendedAuthorizationBool},
};
#[cfg(feature = "v2")]
use common_enums::{self, RequestIncrementalAuthorization};
use common_utils::{
@ -131,6 +134,7 @@ pub struct KafkaPaymentIntentEvent<'a> {
pub customer_present: common_enums::PresenceOfCustomerDuringPayment,
pub routing_algorithm_id: Option<&'a id_type::RoutingId>,
pub payment_link_config: Option<&'a PaymentLinkConfigRequestForPayments>,
pub enable_partial_authorization: Option<EnablePartialAuthorizationBool>,
#[serde(flatten)]
infra_values: Option<Value>,
@ -251,6 +255,7 @@ impl<'a> KafkaPaymentIntentEvent<'a> {
created_by,
is_iframe_redirection_enabled,
is_payment_id_from_merchant,
enable_partial_authorization,
} = intent;
Self {
@ -326,6 +331,7 @@ impl<'a> KafkaPaymentIntentEvent<'a> {
routing_algorithm_id: routing_algorithm_id.as_ref(),
payment_link_config: payment_link_config.as_ref(),
infra_values,
enable_partial_authorization: *enable_partial_authorization,
}
}
}