Skip to content

Commit

Permalink
feat(router): send three_ds_requestor_url in authentication_respons…
Browse files Browse the repository at this point in the history
…e for external 3ds flow (#4828)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
1 parent ccee1a9 commit 67f017f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 18 deletions.
2 changes: 2 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4595,6 +4595,8 @@ pub struct PaymentsExternalAuthenticationResponse {
pub three_dsserver_trans_id: Option<String>,
/// Contains the JWS object created by the ACS for the ARes message
pub acs_signed_content: Option<String>,
/// Three DS Requestor URL
pub three_ds_requestor_url: String,
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
Expand Down
6 changes: 4 additions & 2 deletions crates/router/src/core/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ use crate::{
#[allow(clippy::too_many_arguments)]
pub async fn perform_authentication(
state: &AppState,
merchant_id: String,
authentication_connector: String,
payment_method_data: payments::PaymentMethodData,
payment_method: common_enums::PaymentMethod,
billing_address: payments::Address,
shipping_address: Option<payments::Address>,
browser_details: Option<core_types::BrowserInformation>,
business_profile: storage::BusinessProfile,
merchant_connector_account: payments_core::helpers::MerchantConnectorAccountType,
amount: Option<common_utils::types::MinorUnit>,
currency: Option<Currency>,
Expand All @@ -38,8 +38,10 @@ pub async fn perform_authentication(
threeds_method_comp_ind: payments::ThreeDsCompletionIndicator,
email: Option<common_utils::pii::Email>,
webhook_url: String,
three_ds_requestor_url: String,
) -> CustomResult<api::authentication::AuthenticationResponse, ApiErrorResponse> {
let router_data = transformers::construct_authentication_router_data(
merchant_id,
authentication_connector.clone(),
payment_method_data,
payment_method,
Expand All @@ -50,14 +52,14 @@ pub async fn perform_authentication(
currency,
message_category,
device_channel,
business_profile,
merchant_connector_account,
authentication_data.clone(),
return_url,
sdk_information,
threeds_method_comp_ind,
email,
webhook_url,
three_ds_requestor_url,
)?;
let response =
utils::do_auth_connector_call(state, authentication_connector.clone(), router_data).await?;
Expand Down
18 changes: 4 additions & 14 deletions crates/router/src/core/authentication/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_AUTHENTICATION_FLOW: &str =

#[allow(clippy::too_many_arguments)]
pub fn construct_authentication_router_data(
merchant_id: String,
authentication_connector: String,
payment_method_data: payments::PaymentMethodData,
payment_method: PaymentMethod,
Expand All @@ -36,26 +37,15 @@ pub fn construct_authentication_router_data(
currency: Option<common_enums::Currency>,
message_category: types::api::authentication::MessageCategory,
device_channel: payments::DeviceChannel,
business_profile: storage::BusinessProfile,
merchant_connector_account: payments_helpers::MerchantConnectorAccountType,
authentication_data: storage::Authentication,
return_url: Option<String>,
sdk_information: Option<payments::SdkInformation>,
threeds_method_comp_ind: payments::ThreeDsCompletionIndicator,
email: Option<common_utils::pii::Email>,
webhook_url: String,
three_ds_requestor_url: String,
) -> RouterResult<types::authentication::ConnectorAuthenticationRouterData> {
let authentication_details: api_models::admin::AuthenticationConnectorDetails =
business_profile
.authentication_connector_details
.clone()
.get_required_value("authentication_details")
.attach_printable("authentication_details not configured by the merchant")?
.parse_value("AuthenticationDetails")
.change_context(errors::ApiErrorResponse::UnprocessableEntity {
message: "Invalid data format found for authentication_details".into(),
})
.attach_printable("Error while parsing authentication_details from merchant_account")?;
let router_request = types::authentication::ConnectorAuthenticationRequestData {
payment_method_data: From::from(payment_method_data),
billing_address,
Expand All @@ -71,14 +61,14 @@ pub fn construct_authentication_router_data(
return_url,
sdk_information,
email,
three_ds_requestor_url: authentication_details.three_ds_requestor_url,
three_ds_requestor_url,
threeds_method_comp_ind,
webhook_url,
};
construct_router_data(
authentication_connector,
payment_method,
business_profile.merchant_id.clone(),
merchant_id.clone(),
types::PaymentAddress::default(),
router_request,
&merchant_connector_account,
Expand Down
18 changes: 17 additions & 1 deletion crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3918,8 +3918,23 @@ pub async fn payment_external_authentication(
id: profile_id.to_string(),
})?;

let authentication_details: api_models::admin::AuthenticationConnectorDetails =
business_profile
.authentication_connector_details
.clone()
.get_required_value("authentication_connector_details")
.attach_printable("authentication_connector_details not configured by the merchant")?
.parse_value("AuthenticationConnectorDetails")
.change_context(errors::ApiErrorResponse::UnprocessableEntity {
message: "Invalid data format found for authentication_connector_details".into(),
})
.attach_printable(
"Error while parsing authentication_connector_details from business_profile",
)?;

let authentication_response = Box::pin(authentication_core::perform_authentication(
&state,
business_profile.merchant_id,
authentication_connector,
payment_method_details.0,
payment_method_details.1,
Expand All @@ -3931,7 +3946,6 @@ pub async fn payment_external_authentication(
})?,
shipping_address.as_ref().map(|address| address.into()),
browser_info,
business_profile,
merchant_connector_account,
Some(amount),
Some(currency),
Expand All @@ -3943,6 +3957,7 @@ pub async fn payment_external_authentication(
req.threeds_method_comp_ind,
optional_customer.and_then(|customer| customer.email.map(pii::Email::from)),
webhook_url,
authentication_details.three_ds_requestor_url.clone(),
))
.await?;
Ok(services::ApplicationResponse::Json(
Expand All @@ -3957,6 +3972,7 @@ pub async fn payment_external_authentication(
acs_trans_id: authentication_response.acs_trans_id,
three_dsserver_trans_id: authentication_response.three_dsserver_trans_id,
acs_signed_content: authentication_response.acs_signed_content,
three_ds_requestor_url: authentication_details.three_ds_requestor_url,
},
))
}
Expand Down
7 changes: 6 additions & 1 deletion openapi/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -14594,7 +14594,8 @@
"PaymentsExternalAuthenticationResponse": {
"type": "object",
"required": [
"trans_status"
"trans_status",
"three_ds_requestor_url"
],
"properties": {
"trans_status": {
Expand Down Expand Up @@ -14629,6 +14630,10 @@
"type": "string",
"description": "Contains the JWS object created by the ACS for the ARes message",
"nullable": true
},
"three_ds_requestor_url": {
"type": "string",
"description": "Three DS Requestor URL"
}
}
},
Expand Down

0 comments on commit 67f017f

Please sign in to comment.