feat(core): add support for connectors having separate version call for pre authentication (#4603)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Hrithikesh
2024-05-21 22:37:44 +05:30
committed by GitHub
parent fea2ea6d2c
commit 528d692a89
14 changed files with 121 additions and 17 deletions

View File

@ -273,6 +273,15 @@ pub enum AuthenticationConnectors {
Gpayments, Gpayments,
} }
impl AuthenticationConnectors {
pub fn is_separate_version_call_required(&self) -> bool {
match self {
Self::Threedsecureio | Self::Netcetera => false,
Self::Gpayments => true,
}
}
}
#[cfg(feature = "payouts")] #[cfg(feature = "payouts")]
#[derive( #[derive(
Clone, Clone,

View File

@ -204,6 +204,7 @@ impl api::IncomingWebhook for Gpayments {
impl api::ExternalAuthentication for Gpayments {} impl api::ExternalAuthentication for Gpayments {}
impl api::ConnectorAuthentication for Gpayments {} impl api::ConnectorAuthentication for Gpayments {}
impl api::ConnectorPreAuthentication for Gpayments {} impl api::ConnectorPreAuthentication for Gpayments {}
impl api::ConnectorPreAuthenticationVersionCall for Gpayments {}
impl api::ConnectorPostAuthentication for Gpayments {} impl api::ConnectorPostAuthentication for Gpayments {}
impl impl
ConnectorIntegration< ConnectorIntegration<
@ -221,6 +222,14 @@ impl
> for Gpayments > for Gpayments
{ {
} }
impl
ConnectorIntegration<
api::PreAuthenticationVersionCall,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
> for Gpayments
{
}
impl impl
ConnectorIntegration< ConnectorIntegration<
api::PostAuthentication, api::PostAuthentication,

View File

@ -228,6 +228,7 @@ fn build_endpoint(
} }
impl api::ConnectorPreAuthentication for Netcetera {} impl api::ConnectorPreAuthentication for Netcetera {}
impl api::ConnectorPreAuthenticationVersionCall for Netcetera {}
impl api::ExternalAuthentication for Netcetera {} impl api::ExternalAuthentication for Netcetera {}
impl api::ConnectorAuthentication for Netcetera {} impl api::ConnectorAuthentication for Netcetera {}
impl api::ConnectorPostAuthentication for Netcetera {} impl api::ConnectorPostAuthentication for Netcetera {}
@ -451,3 +452,12 @@ impl
> for Netcetera > for Netcetera
{ {
} }
impl
ConnectorIntegration<
api::PreAuthenticationVersionCall,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
> for Netcetera
{
}

View File

@ -211,6 +211,7 @@ impl api::IncomingWebhook for Threedsecureio {
} }
impl api::ConnectorPreAuthentication for Threedsecureio {} impl api::ConnectorPreAuthentication for Threedsecureio {}
impl api::ConnectorPreAuthenticationVersionCall for Threedsecureio {}
impl api::ExternalAuthentication for Threedsecureio {} impl api::ExternalAuthentication for Threedsecureio {}
impl api::ConnectorAuthentication for Threedsecureio {} impl api::ConnectorAuthentication for Threedsecureio {}
impl api::ConnectorPostAuthentication for Threedsecureio {} impl api::ConnectorPostAuthentication for Threedsecureio {}
@ -409,10 +410,6 @@ impl
data: data.clone(), data: data.clone(),
http_code: res.status_code, http_code: res.status_code,
}) })
// Ok(types::authentication::PreAuthNRouterData {
// response,
// ..data.clone()
// })
} }
fn get_error_response( fn get_error_response(
@ -527,3 +524,12 @@ impl
self.build_error_response(res, event_builder) self.build_error_response(res, event_builder)
} }
} }
impl
ConnectorIntegration<
api::PreAuthenticationVersionCall,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
> for Threedsecureio
{
}

View File

@ -140,12 +140,41 @@ pub async fn perform_pre_authentication(
) )
.await?; .await?;
let router_data = transformers::construct_pre_authentication_router_data( let authentication = if authentication_connector.is_separate_version_call_required() {
authentication_connector_name.clone(), let router_data: core_types::authentication::PreAuthNVersionCallRouterData =
card_number, transformers::construct_pre_authentication_router_data(
&three_ds_connector_account, authentication_connector_name.clone(),
business_profile.merchant_id.clone(), card_number.clone(),
)?; &three_ds_connector_account,
business_profile.merchant_id.clone(),
)?;
let router_data = utils::do_auth_connector_call(
state,
authentication_connector_name.clone(),
router_data,
)
.await?;
let updated_authentication =
utils::update_trackers(state, router_data, authentication, acquirer_details.clone())
.await?;
// from version call response, we will get to know the maximum supported 3ds version.
// If the version is not greater than or equal to 3DS 2.0, We should not do the successive pre authentication call.
if !updated_authentication.is_separate_authn_required() {
return Ok(updated_authentication);
}
updated_authentication
} else {
authentication
};
let router_data: core_types::authentication::PreAuthNRouterData =
transformers::construct_pre_authentication_router_data(
authentication_connector_name.clone(),
card_number,
&three_ds_connector_account,
business_profile.merchant_id.clone(),
)?;
let router_data = let router_data =
utils::do_auth_connector_call(state, authentication_connector_name, router_data).await?; utils::do_auth_connector_call(state, authentication_connector_name, router_data).await?;

View File

@ -109,12 +109,18 @@ pub fn construct_post_authentication_router_data(
) )
} }
pub fn construct_pre_authentication_router_data( pub fn construct_pre_authentication_router_data<F: Clone>(
authentication_connector: String, authentication_connector: String,
card_holder_account_number: cards::CardNumber, card_holder_account_number: cards::CardNumber,
merchant_connector_account: &payments_helpers::MerchantConnectorAccountType, merchant_connector_account: &payments_helpers::MerchantConnectorAccountType,
merchant_id: String, merchant_id: String,
) -> RouterResult<types::authentication::PreAuthNRouterData> { ) -> RouterResult<
types::RouterData<
F,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
>,
> {
let router_request = types::authentication::PreAuthNRequestData { let router_request = types::authentication::PreAuthNRequestData {
card_holder_account_number, card_holder_account_number,
}; };

View File

@ -2568,6 +2568,7 @@ macro_rules! default_imp_for_connector_authentication {
$( impl api::ExternalAuthentication for $path::$connector {} $( impl api::ExternalAuthentication for $path::$connector {}
impl api::ConnectorAuthentication for $path::$connector {} impl api::ConnectorAuthentication for $path::$connector {}
impl api::ConnectorPreAuthentication for $path::$connector {} impl api::ConnectorPreAuthentication for $path::$connector {}
impl api::ConnectorPreAuthenticationVersionCall for $path::$connector {}
impl api::ConnectorPostAuthentication for $path::$connector {} impl api::ConnectorPostAuthentication for $path::$connector {}
impl impl
services::ConnectorIntegration< services::ConnectorIntegration<
@ -2583,6 +2584,13 @@ macro_rules! default_imp_for_connector_authentication {
types::authentication::AuthenticationResponseData, types::authentication::AuthenticationResponseData,
> for $path::$connector > for $path::$connector
{} {}
impl
services::ConnectorIntegration<
api::PreAuthenticationVersionCall,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
> for $path::$connector
{}
impl impl
services::ConnectorIntegration< services::ConnectorIntegration<
api::PostAuthentication, api::PostAuthentication,
@ -2599,6 +2607,8 @@ impl<const T: u8> api::ExternalAuthentication for connector::DummyConnector<T> {
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]
impl<const T: u8> api::ConnectorPreAuthentication for connector::DummyConnector<T> {} impl<const T: u8> api::ConnectorPreAuthentication for connector::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]
impl<const T: u8> api::ConnectorPreAuthenticationVersionCall for connector::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> api::ConnectorAuthentication for connector::DummyConnector<T> {} impl<const T: u8> api::ConnectorAuthentication for connector::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]
impl<const T: u8> api::ConnectorPostAuthentication for connector::DummyConnector<T> {} impl<const T: u8> api::ConnectorPostAuthentication for connector::DummyConnector<T> {}
@ -2622,6 +2632,15 @@ impl<const T: u8>
{ {
} }
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]
impl<const T: u8>
services::ConnectorIntegration<
api::PreAuthenticationVersionCall,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
> for connector::DummyConnector<T>
{
}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> impl<const T: u8>
services::ConnectorIntegration< services::ConnectorIntegration<
api::PostAuthentication, api::PostAuthentication,

View File

@ -10,6 +10,9 @@ use crate::core::errors;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PreAuthentication; pub struct PreAuthentication;
#[derive(Debug, Clone)]
pub struct PreAuthenticationVersionCall;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Authentication; pub struct Authentication;
@ -94,6 +97,15 @@ pub trait ConnectorPreAuthentication:
{ {
} }
pub trait ConnectorPreAuthenticationVersionCall:
services::ConnectorIntegration<
PreAuthenticationVersionCall,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
>
{
}
pub trait ConnectorPostAuthentication: pub trait ConnectorPostAuthentication:
services::ConnectorIntegration< services::ConnectorIntegration<
PostAuthentication, PostAuthentication,
@ -107,6 +119,7 @@ pub trait ExternalAuthentication:
super::ConnectorCommon super::ConnectorCommon
+ ConnectorAuthentication + ConnectorAuthentication
+ ConnectorPreAuthentication + ConnectorPreAuthentication
+ ConnectorPreAuthenticationVersionCall
+ ConnectorPostAuthentication + ConnectorPostAuthentication
{ {
} }

View File

@ -125,6 +125,9 @@ pub struct ConnectorPostAuthenticationRequestData {
pub type PreAuthNRouterData = pub type PreAuthNRouterData =
RouterData<api::PreAuthentication, PreAuthNRequestData, AuthenticationResponseData>; RouterData<api::PreAuthentication, PreAuthNRequestData, AuthenticationResponseData>;
pub type PreAuthNVersionCallRouterData =
RouterData<api::PreAuthenticationVersionCall, PreAuthNRequestData, AuthenticationResponseData>;
pub type ConnectorAuthenticationRouterData = pub type ConnectorAuthenticationRouterData =
RouterData<api::Authentication, ConnectorAuthenticationRequestData, AuthenticationResponseData>; RouterData<api::Authentication, ConnectorAuthenticationRequestData, AuthenticationResponseData>;