diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 50eedcfb5680..b4ac878d372c 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -3558,6 +3558,25 @@ pub async fn decide_multiplex_connector_for_normal_or_recurring_payment { + let skip_saving_wallet_at_connector_optional = + helpers::config_skip_saving_wallet_at_connector( + &*state.store, + &payment_data.payment_intent.merchant_id, + ) + .await?; + + if let Some(skip_saving_wallet_at_connector) = skip_saving_wallet_at_connector_optional + { + if let Some(payment_method_type) = payment_data.payment_attempt.payment_method_type + { + if skip_saving_wallet_at_connector.contains(&payment_method_type) { + logger::debug!("Override setup_future_usage from off_session to on_session based on the merchant's skip_saving_wallet_at_connector configuration to avoid creating a connector mandate."); + payment_data.payment_intent.setup_future_usage = + Some(enums::FutureUsage::OnSession); + } + } + }; + let first_choice = connectors .first() .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 7eada733aed5..1a2f0a5cbaa4 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -4793,3 +4793,26 @@ pub async fn get_payment_external_authentication_flow_during_confirm( pub fn get_redis_key_for_extended_card_info(merchant_id: &str, payment_id: &str) -> String { format!("{merchant_id}_{payment_id}_extended_card_info") } + +pub async fn config_skip_saving_wallet_at_connector( + db: &dyn StorageInterface, + merchant_id: &String, +) -> CustomResult>, errors::ApiErrorResponse> { + let config = db + .find_config_by_key_unwrap_or( + format!("skip_saving_wallet_at_connector_{}", merchant_id).as_str(), + Some("[]".to_string()), + ) + .await; + Ok(match config { + Ok(conf) => Some( + serde_json::from_str::>(&conf.config) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("skip_save_wallet_at_connector config parsing failed")?, + ), + Err(err) => { + logger::error!("{err}"); + None + } + }) +} diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index b014f42a5ce0..2d5d216a8569 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -515,35 +515,79 @@ where } }, None => { - let pm_metadata = create_payment_method_metadata(None, connector_token)?; - - locker_id = resp.payment_method.and_then(|pm| { - if pm == PaymentMethod::Card { - Some(resp.payment_method_id) - } else { - None + let customer_apple_pay_saved_pm_id_option = if payment_method_type + == Some(api_models::enums::PaymentMethodType::ApplePay) + { + match state + .store + .find_payment_method_by_customer_id_merchant_id_list( + &customer_id, + merchant_id, + None, + ) + .await + { + Ok(customer_payment_methods) => Ok(customer_payment_methods + .iter() + .find(|payment_method| { + payment_method.payment_method_type + == Some(api_models::enums::PaymentMethodType::ApplePay) + }) + .map(|pm| pm.payment_method_id.clone())), + Err(error) => { + if error.current_context().is_db_not_found() { + Ok(None) + } else { + Err(error) + .change_context( + errors::ApiErrorResponse::InternalServerError, + ) + .attach_printable( + "failed to find payment methods for a customer", + ) + } + } } - }); - - resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm"); - payment_methods::cards::create_payment_method( - db, - &payment_method_create_request, - &customer_id, - &resp.payment_method_id, - locker_id, - merchant_id, - pm_metadata, - customer_acceptance, - pm_data_encrypted, - key_store, - connector_mandate_details, - None, - network_transaction_id, - merchant_account.storage_scheme, - encrypted_payment_method_billing_address, - ) - .await?; + } else { + Ok(None) + }?; + + if let Some(customer_apple_pay_saved_pm_id) = + customer_apple_pay_saved_pm_id_option + { + resp.payment_method_id = customer_apple_pay_saved_pm_id; + } else { + let pm_metadata = + create_payment_method_metadata(None, connector_token)?; + + locker_id = resp.payment_method.and_then(|pm| { + if pm == PaymentMethod::Card { + Some(resp.payment_method_id) + } else { + None + } + }); + + resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm"); + payment_methods::cards::create_payment_method( + db, + &payment_method_create_request, + &customer_id, + &resp.payment_method_id, + locker_id, + merchant_id, + pm_metadata, + customer_acceptance, + pm_data_encrypted, + key_store, + connector_mandate_details, + None, + network_transaction_id, + merchant_account.storage_scheme, + encrypted_payment_method_billing_address, + ) + .await?; + }; } }