mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
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:
@ -273,6 +273,15 @@ pub enum AuthenticationConnectors {
|
||||
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")]
|
||||
#[derive(
|
||||
Clone,
|
||||
|
||||
@ -204,6 +204,7 @@ impl api::IncomingWebhook for Gpayments {
|
||||
impl api::ExternalAuthentication for Gpayments {}
|
||||
impl api::ConnectorAuthentication for Gpayments {}
|
||||
impl api::ConnectorPreAuthentication for Gpayments {}
|
||||
impl api::ConnectorPreAuthenticationVersionCall for Gpayments {}
|
||||
impl api::ConnectorPostAuthentication for Gpayments {}
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
@ -221,6 +222,14 @@ impl
|
||||
> for Gpayments
|
||||
{
|
||||
}
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
api::PreAuthenticationVersionCall,
|
||||
types::authentication::PreAuthNRequestData,
|
||||
types::authentication::AuthenticationResponseData,
|
||||
> for Gpayments
|
||||
{
|
||||
}
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
api::PostAuthentication,
|
||||
|
||||
@ -228,6 +228,7 @@ fn build_endpoint(
|
||||
}
|
||||
|
||||
impl api::ConnectorPreAuthentication for Netcetera {}
|
||||
impl api::ConnectorPreAuthenticationVersionCall for Netcetera {}
|
||||
impl api::ExternalAuthentication for Netcetera {}
|
||||
impl api::ConnectorAuthentication for Netcetera {}
|
||||
impl api::ConnectorPostAuthentication for Netcetera {}
|
||||
@ -451,3 +452,12 @@ impl
|
||||
> for Netcetera
|
||||
{
|
||||
}
|
||||
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
api::PreAuthenticationVersionCall,
|
||||
types::authentication::PreAuthNRequestData,
|
||||
types::authentication::AuthenticationResponseData,
|
||||
> for Netcetera
|
||||
{
|
||||
}
|
||||
|
||||
@ -211,6 +211,7 @@ impl api::IncomingWebhook for Threedsecureio {
|
||||
}
|
||||
|
||||
impl api::ConnectorPreAuthentication for Threedsecureio {}
|
||||
impl api::ConnectorPreAuthenticationVersionCall for Threedsecureio {}
|
||||
impl api::ExternalAuthentication for Threedsecureio {}
|
||||
impl api::ConnectorAuthentication for Threedsecureio {}
|
||||
impl api::ConnectorPostAuthentication for Threedsecureio {}
|
||||
@ -409,10 +410,6 @@ impl
|
||||
data: data.clone(),
|
||||
http_code: res.status_code,
|
||||
})
|
||||
// Ok(types::authentication::PreAuthNRouterData {
|
||||
// response,
|
||||
// ..data.clone()
|
||||
// })
|
||||
}
|
||||
|
||||
fn get_error_response(
|
||||
@ -527,3 +524,12 @@ impl
|
||||
self.build_error_response(res, event_builder)
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
api::PreAuthenticationVersionCall,
|
||||
types::authentication::PreAuthNRequestData,
|
||||
types::authentication::AuthenticationResponseData,
|
||||
> for Threedsecureio
|
||||
{
|
||||
}
|
||||
|
||||
@ -140,7 +140,36 @@ pub async fn perform_pre_authentication(
|
||||
)
|
||||
.await?;
|
||||
|
||||
let router_data = transformers::construct_pre_authentication_router_data(
|
||||
let authentication = if authentication_connector.is_separate_version_call_required() {
|
||||
let router_data: core_types::authentication::PreAuthNVersionCallRouterData =
|
||||
transformers::construct_pre_authentication_router_data(
|
||||
authentication_connector_name.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,
|
||||
|
||||
@ -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,
|
||||
card_holder_account_number: cards::CardNumber,
|
||||
merchant_connector_account: &payments_helpers::MerchantConnectorAccountType,
|
||||
merchant_id: String,
|
||||
) -> RouterResult<types::authentication::PreAuthNRouterData> {
|
||||
) -> RouterResult<
|
||||
types::RouterData<
|
||||
F,
|
||||
types::authentication::PreAuthNRequestData,
|
||||
types::authentication::AuthenticationResponseData,
|
||||
>,
|
||||
> {
|
||||
let router_request = types::authentication::PreAuthNRequestData {
|
||||
card_holder_account_number,
|
||||
};
|
||||
|
||||
@ -2568,6 +2568,7 @@ macro_rules! default_imp_for_connector_authentication {
|
||||
$( impl api::ExternalAuthentication for $path::$connector {}
|
||||
impl api::ConnectorAuthentication for $path::$connector {}
|
||||
impl api::ConnectorPreAuthentication for $path::$connector {}
|
||||
impl api::ConnectorPreAuthenticationVersionCall for $path::$connector {}
|
||||
impl api::ConnectorPostAuthentication for $path::$connector {}
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
@ -2583,6 +2584,13 @@ macro_rules! default_imp_for_connector_authentication {
|
||||
types::authentication::AuthenticationResponseData,
|
||||
> for $path::$connector
|
||||
{}
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::PreAuthenticationVersionCall,
|
||||
types::authentication::PreAuthNRequestData,
|
||||
types::authentication::AuthenticationResponseData,
|
||||
> for $path::$connector
|
||||
{}
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::PostAuthentication,
|
||||
@ -2599,6 +2607,8 @@ impl<const T: u8> api::ExternalAuthentication for connector::DummyConnector<T> {
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8> api::ConnectorPreAuthentication for connector::DummyConnector<T> {}
|
||||
#[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> {}
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8> api::ConnectorPostAuthentication for connector::DummyConnector<T> {}
|
||||
@ -2622,6 +2632,15 @@ impl<const T: u8>
|
||||
{
|
||||
}
|
||||
#[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>
|
||||
services::ConnectorIntegration<
|
||||
api::PostAuthentication,
|
||||
|
||||
@ -10,6 +10,9 @@ use crate::core::errors;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PreAuthentication;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PreAuthenticationVersionCall;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
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:
|
||||
services::ConnectorIntegration<
|
||||
PostAuthentication,
|
||||
@ -107,6 +119,7 @@ pub trait ExternalAuthentication:
|
||||
super::ConnectorCommon
|
||||
+ ConnectorAuthentication
|
||||
+ ConnectorPreAuthentication
|
||||
+ ConnectorPreAuthenticationVersionCall
|
||||
+ ConnectorPostAuthentication
|
||||
{
|
||||
}
|
||||
|
||||
@ -125,6 +125,9 @@ pub struct ConnectorPostAuthenticationRequestData {
|
||||
pub type PreAuthNRouterData =
|
||||
RouterData<api::PreAuthentication, PreAuthNRequestData, AuthenticationResponseData>;
|
||||
|
||||
pub type PreAuthNVersionCallRouterData =
|
||||
RouterData<api::PreAuthenticationVersionCall, PreAuthNRequestData, AuthenticationResponseData>;
|
||||
|
||||
pub type ConnectorAuthenticationRouterData =
|
||||
RouterData<api::Authentication, ConnectorAuthenticationRequestData, AuthenticationResponseData>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user