mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +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,
|
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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@ -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?;
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user