mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 04:04:43 +08:00
feat(router): skip apple pay session call if the browser is not Safari (#5136)
This commit is contained in:
@ -461,6 +461,7 @@ where
|
||||
&customer,
|
||||
session_surcharge_details,
|
||||
&business_profile,
|
||||
header_payload.clone(),
|
||||
))
|
||||
.await?
|
||||
}
|
||||
@ -1610,6 +1611,7 @@ where
|
||||
call_connector_action,
|
||||
connector_request,
|
||||
business_profile,
|
||||
header_payload.clone(),
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
@ -1673,6 +1675,7 @@ pub async fn call_multiple_connectors_service<F, Op, Req>(
|
||||
customer: &Option<domain::Customer>,
|
||||
session_surcharge_details: Option<api::SessionSurchargeDetails>,
|
||||
business_profile: &storage::business_profile::BusinessProfile,
|
||||
header_payload: HeaderPayload,
|
||||
) -> RouterResult<PaymentData<F>>
|
||||
where
|
||||
Op: Debug,
|
||||
@ -1736,6 +1739,7 @@ where
|
||||
CallConnectorAction::Trigger,
|
||||
None,
|
||||
business_profile,
|
||||
header_payload.clone(),
|
||||
);
|
||||
|
||||
join_handlers.push(res);
|
||||
|
||||
@ -47,6 +47,7 @@ pub trait Feature<F, T> {
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
business_profile: &storage::business_profile::BusinessProfile,
|
||||
header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
||||
@ -52,6 +52,7 @@ impl Feature<api::Approve, types::PaymentsApproveData>
|
||||
_call_connector_action: payments::CallConnectorAction,
|
||||
_connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
Err(ApiErrorResponse::NotImplemented {
|
||||
message: NotImplementedMessage::Reason("Flow not supported".to_string()),
|
||||
|
||||
@ -65,6 +65,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
api::Authorize,
|
||||
|
||||
@ -52,6 +52,7 @@ impl Feature<api::Void, types::PaymentsCancelData>
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
metrics::PAYMENT_CANCEL_COUNT.add(
|
||||
&metrics::CONTEXT,
|
||||
|
||||
@ -52,6 +52,7 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
api::Capture,
|
||||
|
||||
@ -66,6 +66,7 @@ impl Feature<api::CompleteAuthorize, types::CompleteAuthorizeData>
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
api::CompleteAuthorize,
|
||||
|
||||
@ -59,6 +59,7 @@ impl Feature<api::IncrementalAuthorization, types::PaymentsIncrementalAuthorizat
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
api::IncrementalAuthorization,
|
||||
|
||||
@ -55,6 +55,7 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
api::PSync,
|
||||
|
||||
@ -51,6 +51,7 @@ impl Feature<api::Reject, types::PaymentsRejectData>
|
||||
_call_connector_action: payments::CallConnectorAction,
|
||||
_connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
Err(ApiErrorResponse::NotImplemented {
|
||||
message: NotImplementedMessage::Reason("Flow not supported".to_string()),
|
||||
|
||||
@ -65,6 +65,7 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_connector_request: Option<services::Request>,
|
||||
business_profile: &storage::business_profile::BusinessProfile,
|
||||
header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
metrics::SESSION_TOKEN_CREATED.add(
|
||||
&metrics::CONTEXT,
|
||||
@ -77,6 +78,7 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
|
||||
Some(true),
|
||||
call_connector_action,
|
||||
business_profile,
|
||||
header_payload,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -155,6 +157,7 @@ async fn create_applepay_session_token(
|
||||
router_data: &types::PaymentsSessionRouterData,
|
||||
connector: &api::ConnectorData,
|
||||
business_profile: &storage::business_profile::BusinessProfile,
|
||||
header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<types::PaymentsSessionRouterData> {
|
||||
let delayed_response = is_session_response_delayed(state, connector);
|
||||
if delayed_response {
|
||||
@ -188,9 +191,10 @@ async fn create_applepay_session_token(
|
||||
// Get payment request data , apple pay session request and merchant keys
|
||||
let (
|
||||
payment_request_data,
|
||||
apple_pay_session_request,
|
||||
apple_pay_session_request_optional,
|
||||
apple_pay_merchant_cert,
|
||||
apple_pay_merchant_cert_key,
|
||||
apple_pay_merchant_identifier,
|
||||
merchant_business_country,
|
||||
) = match apple_pay_metadata {
|
||||
payment_types::ApplepaySessionTokenMetadata::ApplePayCombined(
|
||||
@ -213,7 +217,7 @@ async fn create_applepay_session_token(
|
||||
let merchant_business_country = session_token_data.merchant_business_country;
|
||||
|
||||
let apple_pay_session_request = get_session_request_for_simplified_apple_pay(
|
||||
merchant_identifier,
|
||||
merchant_identifier.clone(),
|
||||
session_token_data,
|
||||
);
|
||||
|
||||
@ -233,9 +237,10 @@ async fn create_applepay_session_token(
|
||||
|
||||
(
|
||||
payment_request_data,
|
||||
apple_pay_session_request,
|
||||
Ok(apple_pay_session_request),
|
||||
apple_pay_merchant_cert,
|
||||
apple_pay_merchant_cert_key,
|
||||
merchant_identifier,
|
||||
merchant_business_country,
|
||||
)
|
||||
}
|
||||
@ -255,6 +260,7 @@ async fn create_applepay_session_token(
|
||||
apple_pay_session_request,
|
||||
session_token_data.certificate.clone(),
|
||||
session_token_data.certificate_keys,
|
||||
session_token_data.merchant_identifier,
|
||||
merchant_business_country,
|
||||
)
|
||||
}
|
||||
@ -273,7 +279,11 @@ async fn create_applepay_session_token(
|
||||
apple_pay_metadata.payment_request_data,
|
||||
apple_pay_session_request,
|
||||
apple_pay_metadata.session_token_data.certificate.clone(),
|
||||
apple_pay_metadata.session_token_data.certificate_keys,
|
||||
apple_pay_metadata
|
||||
.session_token_data
|
||||
.certificate_keys
|
||||
.clone(),
|
||||
apple_pay_metadata.session_token_data.merchant_identifier,
|
||||
merchant_business_country,
|
||||
)
|
||||
}
|
||||
@ -323,48 +333,63 @@ async fn create_applepay_session_token(
|
||||
amount_info,
|
||||
payment_request_data,
|
||||
router_data.request.to_owned(),
|
||||
apple_pay_session_request.merchant_identifier.as_str(),
|
||||
apple_pay_merchant_identifier.as_str(),
|
||||
merchant_business_country,
|
||||
required_billing_contact_fields,
|
||||
required_shipping_contact_fields,
|
||||
)?;
|
||||
|
||||
let applepay_session_request = build_apple_pay_session_request(
|
||||
state,
|
||||
apple_pay_session_request,
|
||||
apple_pay_merchant_cert,
|
||||
apple_pay_merchant_cert_key,
|
||||
)?;
|
||||
let response = services::call_connector_api(
|
||||
state,
|
||||
applepay_session_request,
|
||||
"create_apple_pay_session_token",
|
||||
)
|
||||
.await;
|
||||
let apple_pay_session_response = match (
|
||||
header_payload.browser_name,
|
||||
header_payload.x_client_platform,
|
||||
) {
|
||||
(Some(common_enums::BrowserName::Safari), Some(common_enums::ClientPlatform::Web))
|
||||
| (None, None) => {
|
||||
let apple_pay_session_request = apple_pay_session_request_optional
|
||||
.attach_printable("Failed to obtain apple pay session request")?;
|
||||
let applepay_session_request = build_apple_pay_session_request(
|
||||
state,
|
||||
apple_pay_session_request,
|
||||
apple_pay_merchant_cert,
|
||||
apple_pay_merchant_cert_key,
|
||||
)?;
|
||||
|
||||
// logging the error if present in session call response
|
||||
log_session_response_if_error(&response);
|
||||
let response = services::call_connector_api(
|
||||
state,
|
||||
applepay_session_request,
|
||||
"create_apple_pay_session_token",
|
||||
)
|
||||
.await;
|
||||
|
||||
let apple_pay_session_response = response
|
||||
.ok()
|
||||
.and_then(|apple_pay_res| {
|
||||
apple_pay_res
|
||||
.map(|res| {
|
||||
let response: Result<
|
||||
payment_types::NoThirdPartySdkSessionResponse,
|
||||
Report<common_utils::errors::ParsingError>,
|
||||
> = res.response.parse_struct("NoThirdPartySdkSessionResponse");
|
||||
// logging the error if present in session call response
|
||||
log_session_response_if_error(&response);
|
||||
|
||||
// logging the parsing failed error
|
||||
if let Err(error) = response.as_ref() {
|
||||
logger::error!(?error);
|
||||
};
|
||||
|
||||
response.ok()
|
||||
})
|
||||
response
|
||||
.ok()
|
||||
})
|
||||
.flatten();
|
||||
.and_then(|apple_pay_res| {
|
||||
apple_pay_res
|
||||
.map(|res| {
|
||||
let response: Result<
|
||||
payment_types::NoThirdPartySdkSessionResponse,
|
||||
Report<common_utils::errors::ParsingError>,
|
||||
> = res.response.parse_struct("NoThirdPartySdkSessionResponse");
|
||||
|
||||
// logging the parsing failed error
|
||||
if let Err(error) = response.as_ref() {
|
||||
logger::error!(?error);
|
||||
};
|
||||
|
||||
response.ok()
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
_ => {
|
||||
logger::debug!("Skipping apple pay session call based on the browser name");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let session_response =
|
||||
apple_pay_session_response.map(payment_types::ApplePaySessionResponse::NoThirdPartySdk);
|
||||
@ -394,13 +419,17 @@ fn get_session_request_for_simplified_apple_pay(
|
||||
|
||||
fn get_session_request_for_manual_apple_pay(
|
||||
session_token_data: payment_types::SessionTokenInfo,
|
||||
) -> payment_types::ApplepaySessionRequest {
|
||||
payment_types::ApplepaySessionRequest {
|
||||
) -> RouterResult<payment_types::ApplepaySessionRequest> {
|
||||
let initiative_context = session_token_data
|
||||
.initiative_context
|
||||
.ok_or(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to get initiative_context for apple pay session call")?;
|
||||
Ok(payment_types::ApplepaySessionRequest {
|
||||
merchant_identifier: session_token_data.merchant_identifier.clone(),
|
||||
display_name: session_token_data.display_name.clone(),
|
||||
initiative: session_token_data.initiative.clone(),
|
||||
initiative_context: session_token_data.initiative_context,
|
||||
}
|
||||
initiative: session_token_data.initiative.to_string(),
|
||||
initiative_context,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_apple_pay_amount_info(
|
||||
@ -461,7 +490,7 @@ fn create_apple_pay_session_response(
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::ApplePay(Box::new(
|
||||
payment_types::ApplepaySessionTokenResponse {
|
||||
session_token_data: response,
|
||||
session_token_data: Some(response),
|
||||
payment_request_data: apple_pay_payment_request,
|
||||
connector: connector_name,
|
||||
delayed_session_token: delayed_response,
|
||||
@ -476,7 +505,18 @@ fn create_apple_pay_session_response(
|
||||
}),
|
||||
None => Ok(types::PaymentsSessionRouterData {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::NoSessionTokenReceived,
|
||||
session_token: payment_types::SessionToken::ApplePay(Box::new(
|
||||
payment_types::ApplepaySessionTokenResponse {
|
||||
session_token_data: None,
|
||||
payment_request_data: apple_pay_payment_request,
|
||||
connector: connector_name,
|
||||
delayed_session_token: delayed_response,
|
||||
sdk_next_action: { payment_types::SdkNextAction { next_action } },
|
||||
connector_reference_id: None,
|
||||
connector_sdk_public_key: None,
|
||||
connector_merchant_id: None,
|
||||
},
|
||||
)),
|
||||
}),
|
||||
..router_data.clone()
|
||||
}),
|
||||
@ -650,6 +690,7 @@ where
|
||||
_confirm: Option<bool>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
business_profile: &storage::business_profile::BusinessProfile,
|
||||
header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self>;
|
||||
}
|
||||
|
||||
@ -698,13 +739,21 @@ impl RouterDataSession for types::PaymentsSessionRouterData {
|
||||
_confirm: Option<bool>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
business_profile: &storage::business_profile::BusinessProfile,
|
||||
header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
match connector.get_token {
|
||||
api::GetToken::GpayMetadata => {
|
||||
create_gpay_session_token(state, self, connector, business_profile)
|
||||
}
|
||||
api::GetToken::ApplePayMetadata => {
|
||||
create_applepay_session_token(state, self, connector, business_profile).await
|
||||
create_applepay_session_token(
|
||||
state,
|
||||
self,
|
||||
connector,
|
||||
business_profile,
|
||||
header_payload,
|
||||
)
|
||||
.await
|
||||
}
|
||||
api::GetToken::PaypalSdkMetadata => {
|
||||
create_paypal_sdk_session_token(state, self, connector, business_profile)
|
||||
|
||||
@ -57,6 +57,7 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &storage::business_profile::BusinessProfile,
|
||||
_header_payload: api_models::payments::HeaderPayload,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
api::SetupMandate,
|
||||
|
||||
Reference in New Issue
Block a user