Skip to content

Commit

Permalink
feat(router): add core changes for external authentication flow throu…
Browse files Browse the repository at this point in the history
…gh unified_authentication_service (#7063)

Co-authored-by: Sahkal Poddar <[email protected]>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Sahkal Poddar <[email protected]>
  • Loading branch information
4 people authored Jan 31, 2025
1 parent b5b5003 commit 1d5db2b
Show file tree
Hide file tree
Showing 20 changed files with 1,189 additions and 261 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ use hyperswitch_domain_models::{
access_token_auth::AccessTokenAuth,
payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
refunds::{Execute, RSync},
PostAuthenticate, PreAuthenticate,
Authenticate, PostAuthenticate, PreAuthenticate,
},
router_request_types::{
unified_authentication_service::{
UasAuthenticationResponseData, UasPostAuthenticationRequestData,
UasPreAuthenticationRequestData,
UasAuthenticationRequestData, UasAuthenticationResponseData,
UasPostAuthenticationRequestData, UasPreAuthenticationRequestData,
},
AccessTokenRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData,
PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData,
Expand Down Expand Up @@ -71,6 +71,7 @@ impl api::PaymentToken for UnifiedAuthenticationService {}
impl api::UnifiedAuthenticationService for UnifiedAuthenticationService {}
impl api::UasPreAuthentication for UnifiedAuthenticationService {}
impl api::UasPostAuthentication for UnifiedAuthenticationService {}
impl api::UasAuthentication for UnifiedAuthenticationService {}

impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
for UnifiedAuthenticationService
Expand Down Expand Up @@ -209,8 +210,16 @@ impl
)?;
let amount = utils::convert_amount(
self.amount_converter,
transaction_details.amount,
transaction_details.currency,
transaction_details
.amount
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "amount",
})?,
transaction_details
.currency
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "currency",
})?,
)?;

let connector_router_data =
Expand Down Expand Up @@ -366,6 +375,11 @@ impl
}
}

impl ConnectorIntegration<Authenticate, UasAuthenticationRequestData, UasAuthenticationResponseData>
for UnifiedAuthenticationService
{
}

impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData>
for UnifiedAuthenticationService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use common_utils::types::FloatMajorUnit;
use hyperswitch_domain_models::{
router_data::{ConnectorAuthType, RouterData},
router_request_types::unified_authentication_service::{
DynamicData, PostAuthenticationDetails, TokenDetails, UasAuthenticationResponseData,
DynamicData, PostAuthenticationDetails, PreAuthenticationDetails, TokenDetails,
UasAuthenticationResponseData,
},
types::{UasPostAuthenticationRouterData, UasPreAuthenticationRouterData},
};
Expand Down Expand Up @@ -238,7 +239,10 @@ impl TryFrom<&UnifiedAuthenticationServiceRouterData<&UasPreAuthenticationRouter
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "transaction_details",
})?
.currency,
.currency
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "currency",
})?,
date: None,
pan_source: None,
protection_type: None,
Expand Down Expand Up @@ -301,7 +305,18 @@ impl<F, T>
>,
) -> Result<Self, Self::Error> {
Ok(Self {
response: Ok(UasAuthenticationResponseData::PreAuthentication {}),
response: Ok(UasAuthenticationResponseData::PreAuthentication {
authentication_details: PreAuthenticationDetails {
threeds_server_transaction_id: None,
maximum_supported_3ds_version: None,
connector_authentication_id: None,
three_ds_method_data: None,
three_ds_method_url: None,
message_version: None,
connector_metadata: None,
directory_server_id: None,
},
}),
..item.data
})
}
Expand Down Expand Up @@ -337,7 +352,7 @@ pub struct UasTokenDetails {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UasDynamicData {
pub dynamic_data_value: Option<Secret<String>>,
pub dynamic_data_type: String,
pub dynamic_data_type: Option<String>,
pub ds_trans_id: Option<String>,
}

Expand Down Expand Up @@ -384,7 +399,7 @@ impl<F, T>
response: Ok(UasAuthenticationResponseData::PostAuthentication {
authentication_details: PostAuthenticationDetails {
eci: item.response.authentication_details.eci,
token_details: TokenDetails {
token_details: Some(TokenDetails {
payment_token: item
.response
.authentication_details
Expand All @@ -405,7 +420,7 @@ impl<F, T>
.authentication_details
.token_details
.token_expiration_year,
},
}),
dynamic_data_details: item
.response
.authentication_details
Expand All @@ -415,6 +430,7 @@ impl<F, T>
dynamic_data_type: dynamic_data.dynamic_data_type,
ds_trans_id: dynamic_data.ds_trans_id,
}),
trans_status: None,
},
}),
..item.data
Expand Down
81 changes: 77 additions & 4 deletions crates/hyperswitch_connectors/src/default_implementations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ use hyperswitch_domain_models::{
PreProcessing, Reject, SdkSessionUpdate,
},
webhooks::VerifyWebhookSource,
PostAuthenticate, PreAuthenticate,
Authenticate, PostAuthenticate, PreAuthenticate,
},
router_request_types::{
unified_authentication_service::{
UasAuthenticationResponseData, UasPostAuthenticationRequestData,
UasPreAuthenticationRequestData,
UasAuthenticationRequestData, UasAuthenticationResponseData,
UasPostAuthenticationRequestData, UasPreAuthenticationRequestData,
},
AcceptDisputeRequestData, AuthorizeSessionTokenData, CompleteAuthorizeData,
ConnectorCustomerData, DefendDisputeRequestData, MandateRevokeRequestData,
Expand Down Expand Up @@ -74,7 +74,7 @@ use hyperswitch_interfaces::{
PaymentSessionUpdate, PaymentsCompleteAuthorize, PaymentsPostProcessing,
PaymentsPreProcessing, TaxCalculation,
},
ConnectorIntegration, ConnectorMandateRevoke, ConnectorRedirectResponse,
ConnectorIntegration, ConnectorMandateRevoke, ConnectorRedirectResponse, UasAuthentication,
UasPostAuthentication, UasPreAuthentication, UnifiedAuthenticationService,
},
errors::ConnectorError,
Expand Down Expand Up @@ -2648,3 +2648,76 @@ default_imp_for_uas_post_authentication!(
connectors::Zen,
connectors::Zsl
);

macro_rules! default_imp_for_uas_authentication {
($($path:ident::$connector:ident),*) => {
$( impl UasAuthentication for $path::$connector {}
impl
ConnectorIntegration<
Authenticate,
UasAuthenticationRequestData,
UasAuthenticationResponseData
> for $path::$connector
{}
)*
};
}

default_imp_for_uas_authentication!(
connectors::Airwallex,
connectors::Amazonpay,
connectors::Bambora,
connectors::Bamboraapac,
connectors::Bankofamerica,
connectors::Billwerk,
connectors::Bitpay,
connectors::Bluesnap,
connectors::Boku,
connectors::Cashtocode,
connectors::Coinbase,
connectors::Cryptopay,
connectors::CtpMastercard,
connectors::Cybersource,
connectors::Datatrans,
connectors::Deutschebank,
connectors::Digitalvirgo,
connectors::Dlocal,
connectors::Elavon,
connectors::Fiserv,
connectors::Fiservemea,
connectors::Fiuu,
connectors::Forte,
connectors::Globepay,
connectors::Gocardless,
connectors::Helcim,
connectors::Inespay,
connectors::Jpmorgan,
connectors::Nomupay,
connectors::Novalnet,
connectors::Nexinets,
connectors::Nexixpay,
connectors::Payeezy,
connectors::Payu,
connectors::Powertranz,
connectors::Prophetpay,
connectors::Mollie,
connectors::Multisafepay,
connectors::Paybox,
connectors::Placetopay,
connectors::Rapyd,
connectors::Razorpay,
connectors::Redsys,
connectors::Shift4,
connectors::Stax,
connectors::Square,
connectors::Taxjar,
connectors::Thunes,
connectors::Tsys,
connectors::Wellsfargo,
connectors::Worldline,
connectors::Worldpay,
connectors::Volt,
connectors::Xendit,
connectors::Zen,
connectors::Zsl
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ pub struct PreAuthenticate;

#[derive(Debug, Clone)]
pub struct PostAuthenticate;

#[derive(Debug, Clone)]
pub struct Authenticate;
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
use api_models::payments::DeviceChannel;
use masking::Secret;

#[derive(Clone, serde::Deserialize, Debug, serde::Serialize)]
use crate::{address::Address, payment_method_data::PaymentMethodData};

#[derive(Clone, Debug)]
pub struct UasPreAuthenticationRequestData {
pub service_details: Option<CtpServiceDetails>,
pub transaction_details: Option<TransactionDetails>,
pub payment_details: Option<PaymentDetails>,
}

#[derive(Clone, serde::Deserialize, Debug, serde::Serialize)]
#[derive(Clone, Debug)]
pub struct UasAuthenticationRequestData {
pub payment_method_data: PaymentMethodData,
pub billing_address: Address,
pub shipping_address: Option<Address>,
pub browser_details: Option<super::BrowserInformation>,
pub transaction_details: TransactionDetails,
pub pre_authentication_data: super::authentication::PreAuthenticationData,
pub return_url: Option<String>,
pub sdk_information: Option<api_models::payments::SdkInformation>,
pub email: Option<common_utils::pii::Email>,
pub threeds_method_comp_ind: api_models::payments::ThreeDsCompletionIndicator,
pub three_ds_requestor_url: String,
pub webhook_url: String,
}

#[derive(Clone, Debug)]
pub struct CtpServiceDetails {
pub service_session_ids: Option<ServiceSessionIds>,
pub payment_details: Option<PaymentDetails>,
}

#[derive(Debug, Clone)]
pub struct PaymentDetails {
pub pan: cards::CardNumber,
pub digital_card_id: Option<String>,
pub payment_data_type: Option<String>,
pub encrypted_src_card_details: Option<String>,
pub card_expiry_date: Secret<String>,
pub cardholder_name: Option<Secret<String>>,
pub card_token_number: Secret<String>,
pub account_type: Option<common_enums::CardNetwork>,
}

#[derive(Clone, serde::Deserialize, Debug, serde::Serialize)]
Expand All @@ -20,26 +53,57 @@ pub struct ServiceSessionIds {

#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct TransactionDetails {
pub amount: common_utils::types::MinorUnit,
pub currency: common_enums::Currency,
pub amount: Option<common_utils::types::MinorUnit>,
pub currency: Option<common_enums::Currency>,
pub device_channel: Option<DeviceChannel>,
pub message_category: Option<super::authentication::MessageCategory>,
}

#[derive(Clone, Debug)]
pub struct UasPostAuthenticationRequestData {}
pub struct UasPostAuthenticationRequestData {
pub threeds_server_transaction_id: Option<String>,
}

#[derive(Debug, Clone)]
pub enum UasAuthenticationResponseData {
PreAuthentication {},
PreAuthentication {
authentication_details: PreAuthenticationDetails,
},
Authentication {
authentication_details: AuthenticationDetails,
},
PostAuthentication {
authentication_details: PostAuthenticationDetails,
},
}

#[derive(Debug, Clone)]
pub struct PreAuthenticationDetails {
pub threeds_server_transaction_id: Option<String>,
pub maximum_supported_3ds_version: Option<common_utils::types::SemanticVersion>,
pub connector_authentication_id: Option<String>,
pub three_ds_method_data: Option<String>,
pub three_ds_method_url: Option<String>,
pub message_version: Option<common_utils::types::SemanticVersion>,
pub connector_metadata: Option<serde_json::Value>,
pub directory_server_id: Option<String>,
}

#[derive(Debug, Clone)]
pub struct AuthenticationDetails {
pub authn_flow_type: super::authentication::AuthNFlowType,
pub authentication_value: Option<String>,
pub trans_status: common_enums::TransactionStatus,
pub connector_metadata: Option<serde_json::Value>,
pub ds_trans_id: Option<String>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct PostAuthenticationDetails {
pub eci: Option<String>,
pub token_details: TokenDetails,
pub token_details: Option<TokenDetails>,
pub dynamic_data_details: Option<DynamicData>,
pub trans_status: Option<common_enums::TransactionStatus>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
Expand All @@ -53,6 +117,6 @@ pub struct TokenDetails {
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct DynamicData {
pub dynamic_data_value: Option<Secret<String>>,
pub dynamic_data_type: String,
pub dynamic_data_type: Option<String>,
pub ds_trans_id: Option<String>,
}
16 changes: 9 additions & 7 deletions crates/hyperswitch_domain_models/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ pub use diesel_models::types::OrderDetailsWithAmount;
use crate::{
router_data::{AccessToken, RouterData},
router_flow_types::{
mandate_revoke::MandateRevoke, AccessTokenAuth, Authorize, AuthorizeSessionToken,
CalculateTax, Capture, CompleteAuthorize, CreateConnectorCustomer, Execute,
IncrementalAuthorization, PSync, PaymentMethodToken, PostAuthenticate, PostSessionTokens,
PreAuthenticate, PreProcessing, RSync, Session, SetupMandate, Void,
mandate_revoke::MandateRevoke, AccessTokenAuth, Authenticate, Authorize,
AuthorizeSessionToken, CalculateTax, Capture, CompleteAuthorize, CreateConnectorCustomer,
Execute, IncrementalAuthorization, PSync, PaymentMethodToken, PostAuthenticate,
PostSessionTokens, PreAuthenticate, PreProcessing, RSync, Session, SetupMandate, Void,
},
router_request_types::{
unified_authentication_service::{
UasAuthenticationResponseData, UasPostAuthenticationRequestData,
UasPreAuthenticationRequestData,
UasAuthenticationRequestData, UasAuthenticationResponseData,
UasPostAuthenticationRequestData, UasPreAuthenticationRequestData,
},
AccessTokenRequestData, AuthorizeSessionTokenData, CompleteAuthorizeData,
ConnectorCustomerData, MandateRevokeRequestData, PaymentMethodTokenizationData,
Expand Down Expand Up @@ -57,7 +57,6 @@ pub type PaymentsSessionRouterData = RouterData<Session, PaymentsSessionData, Pa

pub type UasPostAuthenticationRouterData =
RouterData<PostAuthenticate, UasPostAuthenticationRequestData, UasAuthenticationResponseData>;

pub type UasPreAuthenticationRouterData =
RouterData<PreAuthenticate, UasPreAuthenticationRequestData, UasAuthenticationResponseData>;

Expand All @@ -71,3 +70,6 @@ pub type PaymentsIncrementalAuthorizationRouterData = RouterData<

#[cfg(feature = "payouts")]
pub type PayoutsRouterData<F> = RouterData<F, PayoutsData, PayoutsResponseData>;

pub type UasAuthenticationRouterData =
RouterData<Authenticate, UasAuthenticationRequestData, UasAuthenticationResponseData>;
Loading

0 comments on commit 1d5db2b

Please sign in to comment.