Bug: [REFACTOR] Refactor Update and Retrieve Default Fallback behaviour in payments routing



### Feature Description

 Refactor Update and Retrieve Default Fallback usages in payments core for routing

### Possible Implementation

 Refactor Update and Retrieve Default Fallback usages in payments core for routing, and pass business_profile in the parameters instead of profile_id

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/Cargo.lock b/Cargo.lock
index cf7718d8875..0a0448cae47 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -454,6 +454,7 @@ dependencies = [
  "nutype",
  "reqwest",
  "router_derive",
+ "rustc-hash",
  "serde",
  "serde_json",
  "strum 0.26.2",
diff --git a/crates/api_models/Cargo.toml b/crates/api_models/Cargo.toml
index e342fb3db91..0134c6c6fc9 100644
--- a/crates/api_models/Cargo.toml
+++ b/crates/api_models/Cargo.toml
@@ -39,6 +39,7 @@ strum = { version = "0.26", features = ["derive"] }
 time = { version = "0.3.35", features = ["serde", "serde-well-known", "std"] }
 url = { version = "2.5.0", features = ["serde"] }
 utoipa = { version = "4.2.0", features = ["preserve_order", "preserve_path_order"] }
+rustc-hash = "1.1.0"
 nutype = { version = "0.4.2", features = ["serde"] }
 
 # First party crates
diff --git a/crates/api_models/src/customers.rs b/crates/api_models/src/customers.rs
index c4261d624f1..1f890b1bf89 100644
--- a/crates/api_models/src/customers.rs
+++ b/crates/api_models/src/customers.rs
@@ -5,8 +5,8 @@ use common_utils::{
     pii::{self, EmailStrategy},
     types::{keymanager::ToEncryptable, Description},
 };
-use euclid::dssa::graph::euclid_graph_prelude::FxHashMap;
 use masking::{ExposeInterface, Secret, SwitchStrategy};
+use rustc_hash::FxHashMap;
 use serde::{Deserialize, Serialize};
 use utoipa::ToSchema;
 
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 88c915f0e73..b18481b03da 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -15,9 +15,9 @@ use common_utils::{
     types::{keymanager::ToEncryptable, MinorUnit, StringMajorUnit},
 };
 use error_stack::ResultExt;
-use euclid::dssa::graph::euclid_graph_prelude::FxHashMap;
 use masking::{ExposeInterface, PeekInterface, Secret, SwitchStrategy, WithType};
 use router_derive::Setter;
+use rustc_hash::FxHashMap;
 use serde::{
     de::{self, Unexpected, Visitor},
     ser::Serializer,
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index 1f5fb068408..f49fce8e7f6 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -7,7 +7,7 @@ use api_models::{
 use base64::Engine;
 use common_utils::{
     date_time,
-    ext_traits::{AsyncExt, Encode, ValueExt},
+    ext_traits::{AsyncExt, Encode, OptionExt, ValueExt},
     id_type, pii, type_name,
     types::keymanager::{self as km_types, KeyManagerState},
 };
@@ -21,12 +21,6 @@ use regex::Regex;
 use router_env::metrics::add_attributes;
 use uuid::Uuid;
 
-#[cfg(all(
-    feature = "v2",
-    feature = "routing_v2",
-    feature = "business_profile_v2"
-))]
-use crate::core::routing;
 #[cfg(any(feature = "v1", feature = "v2"))]
 use crate::types::transformers::ForeignFrom;
 use crate::{
@@ -37,8 +31,7 @@ use crate::{
         payment_methods::{cards, transformers},
         payments::helpers,
         pm_auth::helpers::PaymentAuthConnectorDataExt,
-        routing::helpers as routing_helpers,
-        utils as core_utils,
+        routing, utils as core_utils,
     },
     db::StorageInterface,
     routes::{metrics, SessionState},
@@ -55,6 +48,7 @@ use crate::{
     },
     utils,
 };
+
 const IBAN_MAX_LENGTH: usize = 34;
 const BACS_SORT_CODE_LENGTH: usize = 6;
 const BACS_MAX_ACCOUNT_NUMBER_LENGTH: usize = 8;
@@ -1871,23 +1865,40 @@ impl<'a> ConnectorTypeAndConnectorName<'a> {
         Ok(routable_connector)
     }
 }
-
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2",))
+))]
 struct MerchantDefaultConfigUpdate<'a> {
     routable_connector: &'a Option<api_enums::RoutableConnectors>,
     merchant_connector_id: &'a String,
     store: &'a dyn StorageInterface,
     merchant_id: &'a id_type::MerchantId,
-    default_routing_config: &'a Vec<api_models::routing::RoutableConnectorChoice>,
-    default_routing_config_for_profile: &'a Vec<api_models::routing::RoutableConnectorChoice>,
     profile_id: &'a String,
     transaction_type: &'a api_enums::TransactionType,
 }
-
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2",))
+))]
 impl<'a> MerchantDefaultConfigUpdate<'a> {
-    async fn update_merchant_default_config(&self) -> RouterResult<()> {
-        let mut default_routing_config = self.default_routing_config.to_owned();
-        let mut default_routing_config_for_profile =
-            self.default_routing_config_for_profile.to_owned();
+    async fn retrieve_and_update_default_fallback_routing_algorithm_if_routable_connector_exists(
+        &self,
+    ) -> RouterResult<()> {
+        let mut default_routing_config = routing::helpers::get_merchant_default_config(
+            self.store,
+            self.merchant_id.get_string_repr(),
+            self.transaction_type,
+        )
+        .await?;
+
+        let mut default_routing_config_for_profile = routing::helpers::get_merchant_default_config(
+            self.store,
+            self.profile_id,
+            self.transaction_type,
+        )
+        .await?;
+
         if let Some(routable_connector_val) = self.routable_connector {
             let choice = routing_types::RoutableConnectorChoice {
                 choice_kind: routing_types::RoutableChoiceKind::FullStruct,
@@ -1896,7 +1907,7 @@ impl<'a> MerchantDefaultConfigUpdate<'a> {
             };
             if !default_routing_config.contains(&choice) {
                 default_routing_config.push(choice.clone());
-                routing_helpers::update_merchant_default_config(
+                routing::helpers::update_merchant_default_config(
                     self.store,
                     self.merchant_id.get_string_repr(),
                     default_routing_config.clone(),
@@ -1906,7 +1917,7 @@ impl<'a> MerchantDefaultConfigUpdate<'a> {
             }
             if !default_routing_config_for_profile.contains(&choice.clone()) {
                 default_routing_config_for_profile.push(choice);
-                routing_helpers::update_merchant_default_config(
+                routing::helpers::update_merchant_default_config(
                     self.store,
                     self.profile_id,
                     default_routing_config_for_profile.clone(),
@@ -1918,7 +1929,53 @@ impl<'a> MerchantDefaultConfigUpdate<'a> {
         Ok(())
     }
 }
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2",
+))]
+struct DefaultFallbackRoutingConfigUpdate<'a> {
+    routable_connector: &'a Option<api_enums::RoutableConnectors>,
+    merchant_connector_id: &'a String,
+    store: &'a dyn StorageInterface,
+    business_profile: domain::BusinessProfile,
+    key_store: hyperswitch_domain_models::merchant_key_store::MerchantKeyStore,
+    key_manager_state: &'a KeyManagerState,
+}
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+impl<'a> DefaultFallbackRoutingConfigUpdate<'a> {
+    async fn retrieve_and_update_default_fallback_routing_algorithm_if_routable_connector_exists(
+        &self,
+    ) -> RouterResult<()> {
+        let profile_wrapper = BusinessProfileWrapper::new(self.business_profile.clone());
+        let default_routing_config_for_profile =
+            &mut profile_wrapper.get_default_fallback_list_of_connector_under_profile()?;
+        if let Some(routable_connector_val) = self.routable_connector {
+            let choice = routing_types::RoutableConnectorChoice {
+                choice_kind: routing_types::RoutableChoiceKind::FullStruct,
+                connector: *routable_connector_val,
+                merchant_connector_id: Some(self.merchant_connector_id.clone()),
+            };
+            if !default_routing_config_for_profile.contains(&choice.clone()) {
+                default_routing_config_for_profile.push(choice);
 
+                profile_wrapper
+                    .update_default_fallback_routing_of_connectors_under_profile(
+                        self.store,
+                        &default_routing_config_for_profile,
+                        self.key_manager_state,
+                        &self.key_store,
+                    )
+                    .await?
+            }
+        }
+        Ok(())
+    }
+}
 #[cfg(any(feature = "v1", feature = "v2", feature = "olap"))]
 #[async_trait::async_trait]
 trait MerchantConnectorAccountUpdateBridge {
@@ -2219,14 +2276,13 @@ trait MerchantConnectorAccountCreateBridge {
         key_manager_state: &KeyManagerState,
     ) -> RouterResult<domain::MerchantConnectorAccount>;
 
-    async fn validate_and_get_profile_id(
+    async fn validate_and_get_business_profile(
         self,
         merchant_account: &domain::MerchantAccount,
         db: &dyn StorageInterface,
         key_manager_state: &KeyManagerState,
         key_store: &domain::MerchantKeyStore,
-        should_validate: bool,
-    ) -> RouterResult<String>;
+    ) -> RouterResult<domain::BusinessProfile>;
 }
 
 #[cfg(all(
@@ -2360,27 +2416,28 @@ impl MerchantConnectorAccountCreateBridge for api::MerchantConnectorCreate {
         })
     }
 
-    async fn validate_and_get_profile_id(
+    async fn validate_and_get_business_profile(
         self,
         merchant_account: &domain::MerchantAccount,
         db: &dyn StorageInterface,
         key_manager_state: &KeyManagerState,
         key_store: &domain::MerchantKeyStore,
-        should_validate: bool,
-    ) -> RouterResult<String> {
+    ) -> RouterResult<domain::BusinessProfile> {
         let profile_id = self.profile_id;
         // Check whether this business profile belongs to the merchant
-        if should_validate {
-            let _ = core_utils::validate_and_get_business_profile(
-                db,
-                key_manager_state,
-                key_store,
-                Some(&profile_id),
-                merchant_account.get_id(),
-            )
-            .await?;
-        }
-        Ok(profile_id.clone())
+
+        let business_profile = core_utils::validate_and_get_business_profile(
+            db,
+            key_manager_state,
+            key_store,
+            Some(&profile_id),
+            merchant_account.get_id(),
+        )
+        .await?
+        .get_required_value("BusinessProfile")
+        .change_context(errors::ApiErrorResponse::BusinessProfileNotFound { id: profile_id })?;
+
+        Ok(business_profile)
     }
 }
 
@@ -2533,28 +2590,31 @@ impl MerchantConnectorAccountCreateBridge for api::MerchantConnectorCreate {
     /// If profile_id is not passed, use default profile if available, or
     /// If business_details (business_country and business_label) are passed, get the business_profile
     /// or return a `MissingRequiredField` error
-    async fn validate_and_get_profile_id(
+    async fn validate_and_get_business_profile(
         self,
         merchant_account: &domain::MerchantAccount,
         db: &dyn StorageInterface,
         key_manager_state: &KeyManagerState,
         key_store: &domain::MerchantKeyStore,
-        should_validate: bool,
-    ) -> RouterResult<String> {
+    ) -> RouterResult<domain::BusinessProfile> {
         match self.profile_id.or(merchant_account.default_profile.clone()) {
             Some(profile_id) => {
                 // Check whether this business profile belongs to the merchant
-                if should_validate {
-                    let _ = core_utils::validate_and_get_business_profile(
-                        db,
-                        key_manager_state,
-                        key_store,
-                        Some(&profile_id),
-                        merchant_account.get_id(),
-                    )
-                    .await?;
-                }
-                Ok(profile_id.clone())
+
+                let business_profile = core_utils::validate_and_get_business_profile(
+                    db,
+                    key_manager_state,
+                    key_store,
+                    Some(&profile_id),
+                    merchant_account.get_id(),
+                )
+                .await?
+                .get_required_value("BusinessProfile")
+                .change_context(
+                    errors::ApiErrorResponse::BusinessProfileNotFound { id: profile_id },
+                )?;
+
+                Ok(business_profile)
             }
             None => match self.business_country.zip(self.business_label) {
                 Some((business_country, business_label)) => {
@@ -2571,7 +2631,7 @@ impl MerchantConnectorAccountCreateBridge for api::MerchantConnectorCreate {
                             errors::ApiErrorResponse::BusinessProfileNotFound { id: profile_name },
                         )?;
 
-                    Ok(business_profile.profile_id)
+                    Ok(business_profile)
                 }
                 _ => Err(report!(errors::ApiErrorResponse::MissingRequiredField {
                     field_name: "profile_id or business_country, business_label"
@@ -2627,15 +2687,9 @@ pub async fn create_connector(
         &merchant_account,
     )?;
 
-    let profile_id = req
+    let business_profile = req
         .clone()
-        .validate_and_get_profile_id(
-            &merchant_account,
-            store,
-            key_manager_state,
-            &key_store,
-            true,
-        )
+        .validate_and_get_business_profile(&merchant_account, store, key_manager_state, &key_store)
         .await?;
 
     let pm_auth_config_validation = PMAuthConfigValidation {
@@ -2643,20 +2697,12 @@ pub async fn create_connector(
         pm_auth_config: &req.pm_auth_config,
         db: store,
         merchant_id,
-        profile_id: &profile_id.clone(),
+        profile_id: &business_profile.profile_id,
         key_store: &key_store,
         key_manager_state,
     };
     pm_auth_config_validation.validate_pm_auth_config().await?;
 
-    let business_profile = state
-        .store
-        .find_business_profile_by_profile_id(key_manager_state, &key_store, &profile_id)
-        .await
-        .to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
-            id: profile_id.to_owned(),
-        })?;
-
     let connector_type_and_connector_enum = ConnectorTypeAndConnectorName {
         connector_type: &req.connector_type,
         connector_name: &req.connector_name,
@@ -2687,22 +2733,6 @@ pub async fn create_connector(
         )
         .await?;
 
-    let transaction_type = req.get_transaction_type();
-
-    let mut default_routing_config = routing_helpers::get_merchant_default_config(
-        &*state.store,
-        merchant_id.get_string_repr(),
-        &transaction_type,
-    )
-    .await?;
-
-    let mut default_routing_config_for_profile = routing_helpers::get_merchant_default_config(
-        &*state.clone().store,
-        &profile_id,
-        &transaction_type,
-    )
-    .await?;
-
     let mca = state
         .store
         .insert_merchant_connector_account(
@@ -2713,27 +2743,44 @@ pub async fn create_connector(
         .await
         .to_duplicate_response(
             errors::ApiErrorResponse::DuplicateMerchantConnectorAccount {
-                profile_id: profile_id.clone(),
+                profile_id: business_profile.profile_id.clone(),
                 connector_label: merchant_connector_account
                     .connector_label
                     .unwrap_or_default(),
             },
         )?;
 
+    #[cfg(all(
+        any(feature = "v1", feature = "v2"),
+        not(any(feature = "routing_v2", feature = "business_profile_v2",))
+    ))]
     //update merchant default config
     let merchant_default_config_update = MerchantDefaultConfigUpdate {
         routable_connector: &routable_connector,
         merchant_connector_id: &mca.get_id(),
         store,
         merchant_id,
-        default_routing_config: &mut default_routing_config,
-        default_routing_config_for_profile: &mut default_routing_config_for_profile,
-        profile_id: &profile_id,
-        transaction_type: &transaction_type,
+        profile_id: &business_profile.profile_id,
+        transaction_type: &req.get_transaction_type(),
+    };
+
+    #[cfg(all(
+        feature = "v2",
+        feature = "routing_v2",
+        feature = "business_profile_v2",
+    ))]
+    //update merchant default config
+    let merchant_default_config_update = DefaultFallbackRoutingConfigUpdate {
+        routable_connector: &routable_connector,
+        merchant_connector_id: &mca.get_id(),
+        store,
+        business_profile,
+        key_store,
+        key_manager_state,
     };
 
     merchant_default_config_update
-        .update_merchant_default_config()
+        .retrieve_and_update_default_fallback_routing_algorithm_if_routable_connector_exists()
         .await?;
 
     metrics::MCA_CREATE.add(
@@ -3928,31 +3975,23 @@ impl BusinessProfileWrapper {
         Ok(())
     }
 
-    pub fn get_profile_id_and_routing_algorithm_id<F>(
-        &self,
-        transaction_data: &routing::TransactionData<'_, F>,
-    ) -> (Option<String>, Option<String>)
+    pub fn get_routing_algorithm_id<'a, F>(
+        &'a self,
+        transaction_data: &'a routing::TransactionData<'_, F>,
+    ) -> Option<String>
     where
         F: Send + Clone,
     {
         match transaction_data {
-            routing::TransactionData::Payment(payment_data) => (
-                payment_data.payment_intent.profile_id.clone(),
-                self.profile.routing_algorithm_id.clone(),
-            ),
+            routing::TransactionData::Payment(_) => self.profile.routing_algorithm_id.clone(),
             #[cfg(feature = "payouts")]
-            routing::TransactionData::Payout(payout_data) => (
-                Some(payout_data.payout_attempt.profile_id.clone()),
-                self.profile.payout_routing_algorithm_id.clone(),
-            ),
+            routing::TransactionData::Payout(_) => self.profile.payout_routing_algorithm_id.clone(),
         }
     }
     pub fn get_default_fallback_list_of_connector_under_profile(
         &self,
     ) -> RouterResult<Vec<routing_types::RoutableConnectorChoice>> {
-        use common_utils::ext_traits::OptionExt;
         use masking::ExposeOptionInterface;
-
         self.profile
             .default_fallback_routing
             .clone()
@@ -3975,7 +4014,7 @@ impl BusinessProfileWrapper {
         })
     }
 
-    pub async fn update_default_routing_for_profile(
+    pub async fn update_default_fallback_routing_of_connectors_under_profile(
         self,
         db: &dyn StorageInterface,
         updated_config: &Vec<routing_types::RoutableConnectorChoice>,
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 3ce9c9ab5af..402e5b4b0a1 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -2435,10 +2435,17 @@ pub async fn list_payment_methods(
     )
     .await?;
 
+    let profile_id = profile_id
+        .clone()
+        .get_required_value("profile_id")
+        .change_context(errors::ApiErrorResponse::GenericNotFoundError {
+            message: "Profile id not found".to_string(),
+        })?;
+
     // filter out payment connectors based on profile_id
     let filtered_mcas = helpers::filter_mca_based_on_profile_and_connector_type(
         all_mcas.clone(),
-        profile_id.as_ref(),
+        &profile_id,
         ConnectorType::PaymentProcessor,
     );
 
@@ -2447,12 +2454,6 @@ pub async fn list_payment_methods(
     let mut response: Vec<ResponsePaymentMethodIntermediate> = vec![];
     // Key creation for storing PM_FILTER_CGRAPH
     let key = {
-        let profile_id = profile_id
-            .clone()
-            .get_required_value("profile_id")
-            .change_context(errors::ApiErrorResponse::GenericNotFoundError {
-                message: "Profile id not found".to_string(),
-            })?;
         format!(
             "pm_filters_cgraph_{}_{}",
             merchant_account.get_id().get_string_repr(),
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index a8ec32cb55b..31838c34a85 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -3494,6 +3494,7 @@ where
                         .merchant_connector_id
                         .clone()
                         .as_ref(),
+                    business_profile.clone(),
                 )
                 .await?;
 
@@ -3526,15 +3527,13 @@ where
         .attach_printable("Failed execution of straight through routing")?;
 
         if check_eligibility {
-            let profile_id = payment_data.payment_intent.profile_id.clone();
-
             connectors = routing::perform_eligibility_analysis_with_fallback(
                 &state.clone(),
                 key_store,
                 connectors,
                 &TransactionData::Payment(payment_data),
                 eligible_connectors,
-                profile_id,
+                business_profile,
             )
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -3575,15 +3574,13 @@ where
         .attach_printable("Failed execution of straight through routing")?;
 
         if check_eligibility {
-            let profile_id = payment_data.payment_intent.profile_id.clone();
-
             connectors = routing::perform_eligibility_analysis_with_fallback(
                 &state,
                 key_store,
                 connectors,
                 &TransactionData::Payment(payment_data),
                 eligible_connectors,
-                profile_id,
+                business_profile,
             )
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -3949,6 +3946,7 @@ where
     feature = "routing_v2",
     feature = "business_profile_v2"
 ))]
+#[allow(clippy::too_many_arguments)]
 pub async fn route_connector_v1<F>(
     state: &SessionState,
     merchant_account: &domain::MerchantAccount,
@@ -3962,14 +3960,14 @@ pub async fn route_connector_v1<F>(
 where
     F: Send + Clone,
 {
-    let (profile_id, routing_algorithm_id) =
-        super::admin::BusinessProfileWrapper::new(business_profile.clone())
-            .get_profile_id_and_routing_algorithm_id(&transaction_data);
+    let profile_wrapper = super::admin::BusinessProfileWrapper::new(business_profile.clone());
+    let routing_algorithm_id = profile_wrapper.get_routing_algorithm_id(&transaction_data);
 
     let connectors = routing::perform_static_routing_v1(
         state,
         merchant_account.get_id(),
         routing_algorithm_id,
+        business_profile,
         &transaction_data,
     )
     .await
@@ -3981,7 +3979,7 @@ where
         connectors,
         &transaction_data,
         eligible_connectors,
-        profile_id,
+        business_profile,
     )
     .await
     .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -4050,17 +4048,12 @@ pub async fn route_connector_v1<F>(
 where
     F: Send + Clone,
 {
-    let (profile_id, routing_algorithm_id) = {
-        let (profile_id, routing_algorithm) = match &transaction_data {
-            TransactionData::Payment(payment_data) => (
-                payment_data.payment_intent.profile_id.clone(),
-                business_profile.routing_algorithm.clone(),
-            ),
+    let routing_algorithm_id = {
+        let routing_algorithm = match &transaction_data {
+            TransactionData::Payment(_) => business_profile.routing_algorithm.clone(),
+
             #[cfg(feature = "payouts")]
-            TransactionData::Payout(payout_data) => (
-                Some(payout_data.payout_attempt.profile_id.clone()),
-                business_profile.payout_routing_algorithm.clone(),
-            ),
+            TransactionData::Payout(_) => business_profile.payout_routing_algorithm.clone(),
         };
 
         let algorithm_ref = routing_algorithm
@@ -4069,13 +4062,14 @@ where
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Could not decode merchant routing algorithm ref")?
             .unwrap_or_default();
-        (profile_id, algorithm_ref.algorithm_id)
+        algorithm_ref.algorithm_id
     };
 
     let connectors = routing::perform_static_routing_v1(
         state,
         merchant_account.get_id(),
         routing_algorithm_id,
+        business_profile,
         &transaction_data,
     )
     .await
@@ -4086,7 +4080,7 @@ where
         connectors,
         &transaction_data,
         eligible_connectors,
-        profile_id,
+        business_profile,
     )
     .await
     .change_context(errors::ApiErrorResponse::InternalServerError)
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index b2ecae090c2..c1b8aedb651 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -45,6 +45,12 @@ use super::{
     operations::{BoxedOperation, Operation, PaymentResponse},
     CustomerDetails, PaymentData,
 };
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+use crate::core::admin as core_admin;
 use crate::{
     configs::settings::{ConnectorRequestReferenceIdConfig, TempLockerEnableConfig},
     connector,
@@ -124,15 +130,12 @@ pub fn create_certificate(
 
 pub fn filter_mca_based_on_profile_and_connector_type(
     merchant_connector_accounts: Vec<domain::MerchantConnectorAccount>,
-    profile_id: Option<&String>,
+    profile_id: &String,
     connector_type: ConnectorType,
 ) -> Vec<domain::MerchantConnectorAccount> {
     merchant_connector_accounts
         .into_iter()
-        .filter(|mca| {
-            profile_id.map_or(true, |id| &mca.profile_id == id)
-                && mca.connector_type == connector_type
-        })
+        .filter(|mca| &mca.profile_id == profile_id && mca.connector_type == connector_type)
         .collect()
 }
 
@@ -4269,18 +4272,12 @@ pub async fn get_apple_pay_retryable_connectors<F>(
     key_store: &domain::MerchantKeyStore,
     pre_routing_connector_data_list: &[api::ConnectorData],
     merchant_connector_id: Option<&String>,
+    business_profile: domain::BusinessProfile,
 ) -> CustomResult<Option<Vec<api::ConnectorData>>, errors::ApiErrorResponse>
 where
     F: Send + Clone,
 {
-    let profile_id = &payment_data
-        .payment_intent
-        .profile_id
-        .clone()
-        .get_required_value("profile_id")
-        .change_context(errors::ApiErrorResponse::MissingRequiredField {
-            field_name: "profile_id",
-        })?;
+    let profile_id = &business_profile.profile_id;
 
     let pre_decided_connector_data_first = pre_routing_connector_data_list
         .first()
@@ -4318,7 +4315,7 @@ where
         let profile_specific_merchant_connector_account_list =
             filter_mca_based_on_profile_and_connector_type(
                 merchant_connector_account_list,
-                Some(profile_id),
+                profile_id,
                 ConnectorType::PaymentProcessor,
             );
 
@@ -4349,7 +4346,10 @@ where
                 }
             }
         }
-
+        #[cfg(all(
+            any(feature = "v1", feature = "v2"),
+            not(any(feature = "routing_v2", feature = "business_profile_v2"))
+        ))]
         let fallback_connetors_list = crate::core::routing::helpers::get_merchant_default_config(
             &*state.clone().store,
             profile_id,
@@ -4359,6 +4359,16 @@ where
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Failed to get merchant default fallback connectors config")?;
 
+        #[cfg(all(
+            feature = "v2",
+            feature = "routing_v2",
+            feature = "business_profile_v2"
+        ))]
+        let fallback_connetors_list = core_admin::BusinessProfileWrapper::new(business_profile)
+            .get_default_fallback_list_of_connector_under_profile()
+            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .attach_printable("Failed to get merchant default fallback connectors config")?;
+
         let mut routing_connector_data_list = Vec::new();
 
         pre_routing_connector_data_list.iter().for_each(|pre_val| {
diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs
index 371b028154e..af5f234e2ce 100644
--- a/crates/router/src/core/payments/operations/payment_session.rs
+++ b/crates/router/src/core/payments/operations/payment_session.rs
@@ -378,7 +378,7 @@ where
 
         let filtered_connector_accounts = helpers::filter_mca_based_on_profile_and_connector_type(
             all_connector_accounts,
-            Some(&profile_id),
+            &profile_id,
             common_enums::ConnectorType::PaymentProcessor,
         );
 
diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index c029e2d289c..30c1edb6e04 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -34,12 +34,18 @@ use rand::{
 use rustc_hash::FxHashMap;
 use storage_impl::redis::cache::{CacheKey, CGRAPH_CACHE, ROUTING_CACHE};
 
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+use crate::core::admin;
 #[cfg(feature = "payouts")]
 use crate::core::payouts;
 use crate::{
     core::{
         errors, errors as oss_errors, payments as payments_oss,
-        routing::{self, helpers as routing_helpers},
+        routing::{self},
     },
     logger,
     types::{
@@ -75,7 +81,7 @@ pub struct SessionRoutingPmTypeInput<'a> {
     routing_algorithm: &'a MerchantAccountRoutingAlgorithm,
     backend_input: dsl_inputs::BackendInput,
     allowed_connectors: FxHashMap<String, api::GetToken>,
-    profile_id: Option<String>,
+    profile_id: String,
 }
 
 type RoutingResult<O> = oss_errors::CustomResult<O, errors::RoutingError>;
@@ -273,28 +279,31 @@ pub async fn perform_static_routing_v1<F: Clone>(
     state: &SessionState,
     merchant_id: &common_utils::id_type::MerchantId,
     algorithm_id: Option<String>,
+    business_profile: &domain::BusinessProfile,
     transaction_data: &routing::TransactionData<'_, F>,
 ) -> RoutingResult<Vec<routing_types::RoutableConnectorChoice>> {
-    let profile_id = match transaction_data {
-        routing::TransactionData::Payment(payment_data) => payment_data
-            .payment_intent
-            .profile_id
-            .as_ref()
-            .get_required_value("profile_id")
-            .change_context(errors::RoutingError::ProfileIdMissing)?,
-        #[cfg(feature = "payouts")]
-        routing::TransactionData::Payout(payout_data) => &payout_data.payout_attempt.profile_id,
-    };
     let algorithm_id = if let Some(id) = algorithm_id {
         id
     } else {
-        let fallback_config = routing_helpers::get_merchant_default_config(
+        #[cfg(all(
+            any(feature = "v1", feature = "v2"),
+            not(any(feature = "routing_v2", feature = "business_profile_v2"))
+        ))]
+        let fallback_config = routing::helpers::get_merchant_default_config(
             &*state.clone().store,
-            profile_id,
+            &business_profile.profile_id,
             &api_enums::TransactionType::from(transaction_data),
         )
         .await
         .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
+        #[cfg(all(
+            feature = "v2",
+            feature = "routing_v2",
+            feature = "business_profile_v2"
+        ))]
+        let fallback_config = admin::BusinessProfileWrapper::new(business_profile.clone())
+            .get_default_fallback_list_of_connector_under_profile()
+            .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
 
         return Ok(fallback_config);
     };
@@ -302,7 +311,7 @@ pub async fn perform_static_routing_v1<F: Clone>(
         state,
         merchant_id,
         &algorithm_id,
-        Some(profile_id).cloned(),
+        business_profile.profile_id.clone(),
         &api_enums::TransactionType::from(transaction_data),
     )
     .await?;
@@ -333,15 +342,10 @@ async fn ensure_algorithm_cached_v1(
     state: &SessionState,
     merchant_id: &common_utils::id_type::MerchantId,
     algorithm_id: &str,
-    profile_id: Option<String>,
+    profile_id: String,
     transaction_type: &api_enums::TransactionType,
 ) -> RoutingResult<Arc<CachedAlgorithm>> {
     let key = {
-        let profile_id = profile_id
-            .clone()
-            .get_required_value("profile_id")
-            .change_context(errors::RoutingError::ProfileIdMissing)?;
-
         match transaction_type {
             common_enums::TransactionType::Payment => {
                 format!(
@@ -421,15 +425,12 @@ pub async fn refresh_routing_cache_v1(
     state: &SessionState,
     key: String,
     algorithm_id: &str,
-    profile_id: Option<String>,
+    profile_id: String,
 ) -> RoutingResult<Arc<CachedAlgorithm>> {
     let algorithm = {
         let algorithm = state
             .store
-            .find_routing_algorithm_by_profile_id_algorithm_id(
-                &profile_id.unwrap_or_default(),
-                algorithm_id,
-            )
+            .find_routing_algorithm_by_profile_id_algorithm_id(&profile_id, algorithm_id)
             .await
             .change_context(errors::RoutingError::DslMissingInDb)?;
         let algorithm: routing_types::RoutingAlgorithm = algorithm
@@ -506,16 +507,12 @@ pub fn perform_volume_split(
 pub async fn get_merchant_cgraph<'a>(
     state: &SessionState,
     key_store: &domain::MerchantKeyStore,
-    profile_id: Option<String>,
+    profile_id: String,
     transaction_type: &api_enums::TransactionType,
 ) -> RoutingResult<Arc<hyperswitch_constraint_graph::ConstraintGraph<euclid_dir::DirValue>>> {
     let merchant_id = &key_store.merchant_id;
 
     let key = {
-        let profile_id = profile_id
-            .clone()
-            .get_required_value("profile_id")
-            .change_context(errors::RoutingError::ProfileIdMissing)?;
         match transaction_type {
             api_enums::TransactionType::Payment => {
                 format!("cgraph_{}_{}", merchant_id.get_string_repr(), profile_id)
@@ -549,7 +546,7 @@ pub async fn refresh_cgraph_cache<'a>(
     state: &SessionState,
     key_store: &domain::MerchantKeyStore,
     key: String,
-    profile_id: Option<String>,
+    profile_id: String,
     transaction_type: &api_enums::TransactionType,
 ) -> RoutingResult<Arc<hyperswitch_constraint_graph::ConstraintGraph<euclid_dir::DirValue>>> {
     let mut merchant_connector_accounts = state
@@ -588,7 +585,7 @@ pub async fn refresh_cgraph_cache<'a>(
     let merchant_connector_accounts =
         payments_oss::helpers::filter_mca_based_on_profile_and_connector_type(
             merchant_connector_accounts,
-            profile_id.as_ref(),
+            &profile_id,
             connector_type,
         );
 
@@ -648,7 +645,7 @@ async fn perform_cgraph_filtering(
     chosen: Vec<routing_types::RoutableConnectorChoice>,
     backend_input: dsl_inputs::BackendInput,
     eligible_connectors: Option<&Vec<api_enums::RoutableConnectors>>,
-    profile_id: Option<String>,
+    profile_id: String,
     transaction_type: &api_enums::TransactionType,
 ) -> RoutingResult<Vec<routing_types::RoutableConnectorChoice>> {
     let context = euclid_graph::AnalysisContext::from_dir_values(
@@ -692,7 +689,7 @@ pub async fn perform_eligibility_analysis<F: Clone>(
     chosen: Vec<routing_types::RoutableConnectorChoice>,
     transaction_data: &routing::TransactionData<'_, F>,
     eligible_connectors: Option<&Vec<api_enums::RoutableConnectors>>,
-    profile_id: Option<String>,
+    profile_id: String,
 ) -> RoutingResult<Vec<routing_types::RoutableConnectorChoice>> {
     let backend_input = match transaction_data {
         routing::TransactionData::Payment(payment_data) => make_dsl_input(payment_data)?,
@@ -717,9 +714,13 @@ pub async fn perform_fallback_routing<F: Clone>(
     key_store: &domain::MerchantKeyStore,
     transaction_data: &routing::TransactionData<'_, F>,
     eligible_connectors: Option<&Vec<api_enums::RoutableConnectors>>,
-    profile_id: Option<String>,
+    business_profile: &domain::BusinessProfile,
 ) -> RoutingResult<Vec<routing_types::RoutableConnectorChoice>> {
-    let fallback_config = routing_helpers::get_merchant_default_config(
+    #[cfg(all(
+        any(feature = "v1", feature = "v2"),
+        not(any(feature = "routing_v2", feature = "business_profile_v2"))
+    ))]
+    let fallback_config = routing::helpers::get_merchant_default_config(
         &*state.store,
         match transaction_data {
             routing::TransactionData::Payment(payment_data) => payment_data
@@ -735,7 +736,14 @@ pub async fn perform_fallback_routing<F: Clone>(
     )
     .await
     .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
-
+    #[cfg(all(
+        feature = "v2",
+        feature = "routing_v2",
+        feature = "business_profile_v2"
+    ))]
+    let fallback_config = admin::BusinessProfileWrapper::new(business_profile.clone())
+        .get_default_fallback_list_of_connector_under_profile()
+        .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
     let backend_input = match transaction_data {
         routing::TransactionData::Payment(payment_data) => make_dsl_input(payment_data)?,
         #[cfg(feature = "payouts")]
@@ -748,7 +756,7 @@ pub async fn perform_fallback_routing<F: Clone>(
         fallback_config,
         backend_input,
         eligible_connectors,
-        profile_id,
+        business_profile.profile_id.clone(),
         &api_enums::TransactionType::from(transaction_data),
     )
     .await
@@ -760,7 +768,7 @@ pub async fn perform_eligibility_analysis_with_fallback<F: Clone>(
     chosen: Vec<routing_types::RoutableConnectorChoice>,
     transaction_data: &routing::TransactionData<'_, F>,
     eligible_connectors: Option<Vec<api_enums::RoutableConnectors>>,
-    profile_id: Option<String>,
+    business_profile: &domain::BusinessProfile,
 ) -> RoutingResult<Vec<routing_types::RoutableConnectorChoice>> {
     let mut final_selection = perform_eligibility_analysis(
         state,
@@ -768,7 +776,7 @@ pub async fn perform_eligibility_analysis_with_fallback<F: Clone>(
         chosen,
         transaction_data,
         eligible_connectors.as_ref(),
-        profile_id.clone(),
+        business_profile.profile_id.clone(),
     )
     .await?;
 
@@ -777,7 +785,7 @@ pub async fn perform_eligibility_analysis_with_fallback<F: Clone>(
         key_store,
         transaction_data,
         eligible_connectors.as_ref(),
-        profile_id,
+        business_profile,
     )
     .await;
 
@@ -831,7 +839,7 @@ pub async fn perform_session_flow_routing(
         feature = "business_profile_v2"
     ))]
     let routing_algorithm =
-        MerchantAccountRoutingAlgorithm::V1(business_profile.routing_algorithm_id);
+        MerchantAccountRoutingAlgorithm::V1(business_profile.routing_algorithm_id.clone());
 
     #[cfg(all(
         any(feature = "v1", feature = "v2"),
@@ -929,11 +937,14 @@ pub async fn perform_session_flow_routing(
             routing_algorithm: &routing_algorithm,
             backend_input: backend_input.clone(),
             allowed_connectors,
-
-            profile_id: session_input.payment_intent.profile_id.clone(),
+            profile_id: profile_id.clone(),
         };
-        let routable_connector_choice_option =
-            perform_session_routing_for_pm_type(&session_pm_input, transaction_type).await?;
+        let routable_connector_choice_option = perform_session_routing_for_pm_type(
+            &session_pm_input,
+            transaction_type,
+            &business_profile,
+        )
+        .await?;
 
         if let Some(routable_connector_choice) = routable_connector_choice_option {
             let mut session_routing_choice: Vec<routing_types::SessionRoutingChoice> = Vec::new();
@@ -964,26 +975,20 @@ pub async fn perform_session_flow_routing(
     Ok(result)
 }
 
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 async fn perform_session_routing_for_pm_type(
     session_pm_input: &SessionRoutingPmTypeInput<'_>,
     transaction_type: &api_enums::TransactionType,
+    _business_profile: &domain::BusinessProfile,
 ) -> RoutingResult<Option<Vec<api_models::routing::RoutableConnectorChoice>>> {
     let merchant_id = &session_pm_input.key_store.merchant_id;
-    #[cfg(all(
-        any(feature = "v1", feature = "v2"),
-        not(any(feature = "routing_v2", feature = "business_profile_v2"))
-    ))]
+
     let algorithm_id = match session_pm_input.routing_algorithm {
         MerchantAccountRoutingAlgorithm::V1(algorithm_ref) => &algorithm_ref.algorithm_id,
     };
-    #[cfg(all(
-        feature = "v2",
-        feature = "routing_v2",
-        feature = "business_profile_v2"
-    ))]
-    let algorithm_id = match session_pm_input.routing_algorithm {
-        MerchantAccountRoutingAlgorithm::V1(algorithm_id) => algorithm_id,
-    };
 
     let chosen_connectors = if let Some(ref algorithm_id) = algorithm_id {
         let cached_algorithm = ensure_algorithm_cached_v1(
@@ -1008,13 +1013,9 @@ async fn perform_session_routing_for_pm_type(
             )?,
         }
     } else {
-        routing_helpers::get_merchant_default_config(
+        routing::helpers::get_merchant_default_config(
             &*session_pm_input.state.clone().store,
-            session_pm_input
-                .profile_id
-                .as_ref()
-                .get_required_value("profile_id")
-                .change_context(errors::RoutingError::ProfileIdMissing)?,
+            &session_pm_input.profile_id,
             transaction_type,
         )
         .await
@@ -1033,13 +1034,9 @@ async fn perform_session_routing_for_pm_type(
     .await?;
 
     if final_selection.is_empty() {
-        let fallback = routing_helpers::get_merchant_default_config(
+        let fallback = routing::helpers::get_merchant_default_config(
             &*session_pm_input.state.clone().store,
-            session_pm_input
-                .profile_id
-                .as_ref()
-                .get_required_value("profile_id")
-                .change_context(errors::RoutingError::ProfileIdMissing)?,
+            &session_pm_input.profile_id,
             transaction_type,
         )
         .await
@@ -1064,6 +1061,83 @@ async fn perform_session_routing_for_pm_type(
     }
 }
 
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+async fn perform_session_routing_for_pm_type(
+    session_pm_input: &SessionRoutingPmTypeInput<'_>,
+    transaction_type: &api_enums::TransactionType,
+    business_profile: &domain::BusinessProfile,
+) -> RoutingResult<Option<Vec<api_models::routing::RoutableConnectorChoice>>> {
+    let merchant_id = &session_pm_input.key_store.merchant_id;
+
+    let MerchantAccountRoutingAlgorithm::V1(algorithm_id) = session_pm_input.routing_algorithm;
+
+    let profile_wrapper = admin::BusinessProfileWrapper::new(business_profile.clone());
+    let chosen_connectors = if let Some(ref algorithm_id) = algorithm_id {
+        let cached_algorithm = ensure_algorithm_cached_v1(
+            &session_pm_input.state.clone(),
+            merchant_id,
+            algorithm_id,
+            session_pm_input.profile_id.clone(),
+            transaction_type,
+        )
+        .await?;
+
+        match cached_algorithm.as_ref() {
+            CachedAlgorithm::Single(conn) => vec![(**conn).clone()],
+            CachedAlgorithm::Priority(plist) => plist.clone(),
+            CachedAlgorithm::VolumeSplit(splits) => {
+                perform_volume_split(splits.to_vec(), Some(session_pm_input.attempt_id))
+                    .change_context(errors::RoutingError::ConnectorSelectionFailed)?
+            }
+            CachedAlgorithm::Advanced(interpreter) => execute_dsl_and_get_connector_v1(
+                session_pm_input.backend_input.clone(),
+                interpreter,
+            )?,
+        }
+    } else {
+        profile_wrapper
+            .get_default_fallback_list_of_connector_under_profile()
+            .change_context(errors::RoutingError::FallbackConfigFetchFailed)?
+    };
+
+    let mut final_selection = perform_cgraph_filtering(
+        &session_pm_input.state.clone(),
+        session_pm_input.key_store,
+        chosen_connectors,
+        session_pm_input.backend_input.clone(),
+        None,
+        session_pm_input.profile_id.clone(),
+        transaction_type,
+    )
+    .await?;
+
+    if final_selection.is_empty() {
+        let fallback = profile_wrapper
+            .get_default_fallback_list_of_connector_under_profile()
+            .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
+
+        final_selection = perform_cgraph_filtering(
+            &session_pm_input.state.clone(),
+            session_pm_input.key_store,
+            fallback,
+            session_pm_input.backend_input.clone(),
+            None,
+            session_pm_input.profile_id.clone(),
+            transaction_type,
+        )
+        .await?;
+    }
+
+    if final_selection.is_empty() {
+        Ok(None)
+    } else {
+        Ok(Some(final_selection))
+    }
+}
 pub fn make_dsl_input_for_surcharge(
     payment_attempt: &oss_storage::PaymentAttempt,
     payment_intent: &oss_storage::PaymentIntent,
diff --git a/crates/router/src/core/payout_link.rs b/crates/router/src/core/payout_link.rs
index 0e480605112..d18afe02056 100644
--- a/crates/router/src/core/payout_link.rs
+++ b/crates/router/src/core/payout_link.rs
@@ -300,7 +300,7 @@ pub async fn filter_payout_methods(
     // Filter MCAs based on profile_id and connector_type
     let filtered_mcas = helpers::filter_mca_based_on_profile_and_connector_type(
         all_mcas,
-        Some(&payout.profile_id),
+        &payout.profile_id,
         common_enums::ConnectorType::PayoutProcessor,
     );
     let address = payout
diff --git a/crates/router/src/core/payouts/helpers.rs b/crates/router/src/core/payouts/helpers.rs
index 67e35e7dff6..4f9e3f9529e 100644
--- a/crates/router/src/core/payouts/helpers.rs
+++ b/crates/router/src/core/payouts/helpers.rs
@@ -33,6 +33,7 @@ use crate::{
             route_connector_v1, routing, CustomerDetails,
         },
         routing::TransactionData,
+        utils as core_utils,
     },
     db::StorageInterface,
     routes::{metrics, SessionState},
@@ -745,6 +746,17 @@ pub async fn decide_payout_connector(
         return Ok(api::ConnectorCallType::PreDetermined(connector_data));
     }
 
+    // Validate and get the business_profile from payout_attempt
+    let business_profile = core_utils::validate_and_get_business_profile(
+        state.store.as_ref(),
+        &(state).into(),
+        key_store,
+        Some(&payout_attempt.profile_id),
+        merchant_account.get_id(),
+    )
+    .await?
+    .get_required_value("BusinessProfile")?;
+
     // 2. Check routing algorithm passed in the request
     if let Some(routing_algorithm) = request_straight_through {
         let (mut connectors, check_eligibility) =
@@ -759,7 +771,7 @@ pub async fn decide_payout_connector(
                 connectors,
                 &TransactionData::<()>::Payout(payout_data),
                 eligible_connectors,
-                Some(payout_attempt.profile_id.clone()),
+                &business_profile,
             )
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -807,7 +819,7 @@ pub async fn decide_payout_connector(
                 connectors,
                 &TransactionData::<()>::Payout(payout_data),
                 eligible_connectors,
-                Some(payout_attempt.profile_id.clone()),
+                &business_profile,
             )
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs
index 0c50a01e36d..2b7f2d18306 100644
--- a/crates/router/src/core/routing.rs
+++ b/crates/router/src/core/routing.rs
@@ -706,7 +706,7 @@ pub async fn update_default_fallback_routing(
         },
     )?;
     profile_wrapper
-        .update_default_routing_for_profile(
+        .update_default_fallback_routing_of_connectors_under_profile(
             db,
             &updated_list_of_connectors,
             key_manager_state,
@@ -949,7 +949,7 @@ pub async fn retrieve_linked_routing_config(
         routing_types::LinkedRoutingConfigRetrieveResponse::ProfileBased(active_algorithms),
     ))
 }
-
+// List all the default fallback algorithms under all the profile under a merchant
 pub async fn retrieve_default_routing_config_for_profiles(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
diff --git a/crates/storage_impl/src/payouts/payouts.rs b/crates/storage_impl/src/payouts/payouts.rs
index 94405a0249b..680d535a652 100644
--- a/crates/storage_impl/src/payouts/payouts.rs
+++ b/crates/storage_impl/src/payouts/payouts.rs
@@ -6,17 +6,21 @@ use async_bb8_diesel::{AsyncConnection, AsyncRunQueryDsl};
 use common_utils::errors::ReportSwitchExt;
 use common_utils::ext_traits::Encode;
 #[cfg(feature = "olap")]
-use diesel::{associations::HasTable, ExpressionMethods, QueryDsl};
+use diesel::{
+    associations::HasTable, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl,
+};
 #[cfg(all(
     feature = "olap",
     any(feature = "v1", feature = "v2"),
     not(feature = "customer_v2")
 ))]
-use diesel::{JoinOnDsl, NullableExpressionMethods};
+use diesel_models::payout_attempt::PayoutAttempt as DieselPayoutAttempt;
 #[cfg(feature = "olap")]
 use diesel_models::{
-    customers::Customer as DieselCustomer, enums as storage_enums, query::generics::db_metrics,
-    schema::payouts::dsl as po_dsl,
+    customers::Customer as DieselCustomer,
+    enums as storage_enums,
+    query::generics::db_metrics,
+    schema::{customers::dsl as cust_dsl, payout_attempt::dsl as poa_dsl, payouts::dsl as po_dsl},
 };
 use diesel_models::{
     enums::MerchantStorageScheme,
@@ -26,15 +30,6 @@ use diesel_models::{
         PayoutsUpdate as DieselPayoutsUpdate,
     },
 };
-#[cfg(all(
-    feature = "olap",
-    any(feature = "v1", feature = "v2"),
-    not(feature = "customer_v2")
-))]
-use diesel_models::{
-    payout_attempt::PayoutAttempt as DieselPayoutAttempt,
-    schema::{customers::dsl as cust_dsl, payout_attempt::dsl as poa_dsl},
-};
 use error_stack::ResultExt;
 #[cfg(feature = "olap")]
 use hyperswitch_domain_models::payouts::PayoutFetchConstraints;

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
This PR refactors the  fallback routing behaviour in payments routing for v2. Update the function to accept business_profile as a parameter instead of profile_id.


### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
For v2:
- create a MA and add 2 MCAs, it will be added for default fallback in the order they were cretaed 
- make a payment , it should go through the mca that was added first based on default fallback


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [ ] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
