mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +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,7 +140,36 @@ 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() { | ||||||
|  |         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(), |             authentication_connector_name.clone(), | ||||||
|             card_number, |             card_number, | ||||||
|             &three_ds_connector_account, |             &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, |     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
	 Hrithikesh
					Hrithikesh