fix(router): skip external three_ds flow for recurring payments (#5730)

This commit is contained in:
Sai Harsha Vardhan
2024-08-28 15:15:45 +05:30
committed by GitHub
parent c555a88c67
commit 64836ba405
6 changed files with 15 additions and 4 deletions

View File

@ -969,7 +969,7 @@ pub struct VerifyRequest {
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>, pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq, Copy)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum MandateTransactionType { pub enum MandateTransactionType {
NewMandateTransaction, NewMandateTransaction,

View File

@ -264,6 +264,7 @@ where
&connector_details, &connector_details,
&business_profile, &business_profile,
&key_store, &key_store,
mandate_type,
) )
.await?; .await?;
if should_continue_transaction { if should_continue_transaction {

View File

@ -5016,6 +5016,7 @@ pub async fn get_payment_external_authentication_flow_during_confirm<F: Clone>(
business_profile: &domain::BusinessProfile, business_profile: &domain::BusinessProfile,
payment_data: &mut PaymentData<F>, payment_data: &mut PaymentData<F>,
connector_call_type: &api::ConnectorCallType, connector_call_type: &api::ConnectorCallType,
mandate_type: Option<api_models::payments::MandateTransactionType>,
) -> RouterResult<Option<PaymentExternalAuthenticationFlow>> { ) -> RouterResult<Option<PaymentExternalAuthenticationFlow>> {
let authentication_id = payment_data.payment_attempt.authentication_id.clone(); let authentication_id = payment_data.payment_attempt.authentication_id.clone();
let is_authentication_type_3ds = payment_data.payment_attempt.authentication_type let is_authentication_type_3ds = payment_data.payment_attempt.authentication_type
@ -5050,7 +5051,11 @@ pub async fn get_payment_external_authentication_flow_during_confirm<F: Clone>(
authentication_id.map(|authentication_id| { authentication_id.map(|authentication_id| {
PaymentExternalAuthenticationFlow::PostAuthenticationFlow { authentication_id } PaymentExternalAuthenticationFlow::PostAuthenticationFlow { authentication_id }
}) })
} else if separate_authentication_requested && is_authentication_type_3ds { } else if separate_authentication_requested
&& is_authentication_type_3ds
&& mandate_type
!= Some(api_models::payments::MandateTransactionType::RecurringMandateTransaction)
{
if let Some((connector_data, card_number)) = if let Some((connector_data, card_number)) =
connector_supports_separate_authn.zip(card_number) connector_supports_separate_authn.zip(card_number)
{ {

View File

@ -166,6 +166,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
Ok(()) Ok(())
} }
#[allow(clippy::too_many_arguments)]
async fn call_external_three_ds_authentication_if_eligible<'a>( async fn call_external_three_ds_authentication_if_eligible<'a>(
&'a self, &'a self,
_state: &SessionState, _state: &SessionState,
@ -174,6 +175,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
_connector_call_type: &ConnectorCallType, _connector_call_type: &ConnectorCallType,
_merchant_account: &domain::BusinessProfile, _merchant_account: &domain::BusinessProfile,
_key_store: &domain::MerchantKeyStore, _key_store: &domain::MerchantKeyStore,
_mandate_type: Option<api_models::payments::MandateTransactionType>,
) -> CustomResult<(), errors::ApiErrorResponse> { ) -> CustomResult<(), errors::ApiErrorResponse> {
Ok(()) Ok(())
} }

View File

@ -529,7 +529,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
})?; })?;
let m_state = state.clone(); let m_state = state.clone();
let m_mandate_type = mandate_type.clone(); let m_mandate_type = mandate_type;
let m_merchant_account = merchant_account.clone(); let m_merchant_account = merchant_account.clone();
let m_request = request.clone(); let m_request = request.clone();
let m_key_store = key_store.clone(); let m_key_store = key_store.clone();
@ -853,6 +853,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
populate_surcharge_details(state, payment_data).await populate_surcharge_details(state, payment_data).await
} }
#[allow(clippy::too_many_arguments)]
async fn call_external_three_ds_authentication_if_eligible<'a>( async fn call_external_three_ds_authentication_if_eligible<'a>(
&'a self, &'a self,
state: &SessionState, state: &SessionState,
@ -861,6 +862,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
connector_call_type: &ConnectorCallType, connector_call_type: &ConnectorCallType,
business_profile: &domain::BusinessProfile, business_profile: &domain::BusinessProfile,
key_store: &domain::MerchantKeyStore, key_store: &domain::MerchantKeyStore,
mandate_type: Option<api_models::payments::MandateTransactionType>,
) -> CustomResult<(), errors::ApiErrorResponse> { ) -> CustomResult<(), errors::ApiErrorResponse> {
let external_authentication_flow = let external_authentication_flow =
helpers::get_payment_external_authentication_flow_during_confirm( helpers::get_payment_external_authentication_flow_during_confirm(
@ -869,6 +871,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
business_profile, business_profile,
payment_data, payment_data,
connector_call_type, connector_call_type,
mandate_type,
) )
.await?; .await?;
payment_data.authentication = match external_authentication_flow { payment_data.authentication = match external_authentication_flow {

View File

@ -170,7 +170,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
} = helpers::get_token_pm_type_mandate_details( } = helpers::get_token_pm_type_mandate_details(
state, state,
request, request,
mandate_type.clone(), mandate_type,
merchant_account, merchant_account,
merchant_key_store, merchant_key_store,
None, None,