diff --git a/config/config.example.toml b/config/config.example.toml index 7e32b2f5d3..94f71fa3f7 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -339,7 +339,7 @@ sts_role_session_name = "" # An identifier for the assumed role session, used to #tokenization configuration which describe token lifetime and payment method for specific connector [tokenization] stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } } -checkout = { long_lived_token = false, payment_method = "wallet" } +checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_decrypt_flow = "network_tokenization" } mollie = { long_lived_token = false, payment_method = "card" } stax = { long_lived_token = true, payment_method = "card,bank_debit" } square = { long_lived_token = false, payment_method = "card" } diff --git a/config/development.toml b/config/development.toml index ebd4cb1c93..272b364171 100644 --- a/config/development.toml +++ b/config/development.toml @@ -415,7 +415,7 @@ debit = { currency = "USD" } [tokenization] stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } } -checkout = { long_lived_token = false, payment_method = "wallet" } +checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_decrypt_flow = "network_tokenization" } stax = { long_lived_token = true, payment_method = "card,bank_debit" } mollie = {long_lived_token = false, payment_method = "card"} square = {long_lived_token = false, payment_method = "card"} diff --git a/config/docker_compose.toml b/config/docker_compose.toml index a8cf5bfb05..e55353f890 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -229,7 +229,7 @@ consumer_group = "SCHEDULER_GROUP" #tokenization configuration which describe token lifetime and payment method for specific connector [tokenization] stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } } -checkout = { long_lived_token = false, payment_method = "wallet" } +checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_decrypt_flow = "network_tokenization" } mollie = {long_lived_token = false, payment_method = "card"} stax = { long_lived_token = true, payment_method = "card,bank_debit" } square = {long_lived_token = false, payment_method = "card"} diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index b7aa3d3ea5..3d93c2f188 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -287,6 +287,15 @@ pub struct PaymentMethodTokenFilter { pub payment_method: HashSet, pub payment_method_type: Option, pub long_lived_token: bool, + pub apple_pay_pre_decrypt_flow: Option, +} + +#[derive(Debug, Deserialize, Clone, Default)] +#[serde(deny_unknown_fields, rename_all = "snake_case")] +pub enum ApplePayPreDecryptFlow { + #[default] + ConnectorTokenization, + NetworkTokenization, } #[derive(Debug, Deserialize, Clone, Default)] diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index a07c88ea66..ff4934e1ef 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -44,7 +44,7 @@ use super::{errors::StorageErrorExt, payment_methods::surcharge_decision_configs #[cfg(feature = "frm")] use crate::core::fraud_check as frm_core; use crate::{ - configs::settings::PaymentMethodTypeTokenFilter, + configs::settings::{ApplePayPreDecryptFlow, PaymentMethodTypeTokenFilter}, core::{ errors::{self, CustomResult, RouterResponse, RouterResult}, payment_methods::PaymentMethodRetrieve, @@ -1582,6 +1582,7 @@ fn is_payment_method_tokenization_enabled_for_connector( connector_name: &str, payment_method: &storage::enums::PaymentMethod, payment_method_type: &Option, + apple_pay_flow: &Option, ) -> RouterResult { let connector_tokenization_filter = state.conf.tokenization.0.get(connector_name); @@ -1595,13 +1596,35 @@ fn is_payment_method_tokenization_enabled_for_connector( payment_method_type, connector_filter.payment_method_type.clone(), ) + && is_apple_pay_pre_decrypt_type_connector_tokenization( + payment_method_type, + apple_pay_flow, + connector_filter.apple_pay_pre_decrypt_flow.clone(), + ) }) .unwrap_or(false)) } +fn is_apple_pay_pre_decrypt_type_connector_tokenization( + payment_method_type: &Option, + apple_pay_flow: &Option, + apple_pay_pre_decrypt_flow_filter: Option, +) -> bool { + match (payment_method_type, apple_pay_flow) { + ( + Some(storage::enums::PaymentMethodType::ApplePay), + Some(enums::ApplePayFlow::Simplified), + ) => !matches!( + apple_pay_pre_decrypt_flow_filter, + Some(ApplePayPreDecryptFlow::NetworkTokenization) + ), + _ => true, + } +} + fn decide_apple_pay_flow( payment_method_type: &Option, - merchant_connector_account: &Option, + merchant_connector_account: Option<&helpers::MerchantConnectorAccountType>, ) -> Option { payment_method_type.and_then(|pmt| match pmt { api_models::enums::PaymentMethodType::ApplePay => { @@ -1612,9 +1635,9 @@ fn decide_apple_pay_flow( } fn check_apple_pay_metadata( - merchant_connector_account: &Option, + merchant_connector_account: Option<&helpers::MerchantConnectorAccountType>, ) -> Option { - merchant_connector_account.clone().and_then(|mca| { + merchant_connector_account.and_then(|mca| { let metadata = mca.get_metadata(); metadata.and_then(|apple_pay_metadata| { let parsed_metadata = apple_pay_metadata @@ -1785,19 +1808,18 @@ where .get_required_value("payment_method")?; let payment_method_type = &payment_data.payment_attempt.payment_method_type; + let apple_pay_flow = + decide_apple_pay_flow(payment_method_type, Some(merchant_connector_account)); + let is_connector_tokenization_enabled = is_payment_method_tokenization_enabled_for_connector( state, &connector, payment_method, payment_method_type, + &apple_pay_flow, )?; - let apple_pay_flow = decide_apple_pay_flow( - payment_method_type, - &Some(merchant_connector_account.clone()), - ); - add_apple_pay_flow_metrics( &apple_pay_flow, payment_data.payment_attempt.connector.clone(), diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 7b7d64a5f8..551f8cd5da 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -118,7 +118,7 @@ where let apple_pay_flow = payments::decide_apple_pay_flow( &payment_data.payment_attempt.payment_method_type, - &Some(merchant_connector_account.clone()), + Some(merchant_connector_account), ); router_data = types::RouterData { diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml index 066933317b..358a591a66 100644 --- a/loadtest/config/development.toml +++ b/loadtest/config/development.toml @@ -200,7 +200,7 @@ red_pagos = { country = "UY", currency = "UYU" } #tokenization configuration which describe token lifetime and payment method for specific connector [tokenization] stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } } -checkout = { long_lived_token = false, payment_method = "wallet" } +checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_decrypt_flow = "network_tokenization" } mollie = {long_lived_token = false, payment_method = "card"} braintree = { long_lived_token = false, payment_method = "card" } gocardless = {long_lived_token = true, payment_method = "bank_debit"}