Bug: [FEATURE] Adapt routing id and payout algorithm id in routing core



### Feature Description

In this PR we adapt the usage of routing_algorithm_id as well as payout_routing_algorithm_id in routing and payments core for v2.

### Possible Implementation

All the places that were being fetched as `serve_json::value` must be able to accept the id instead

### 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/crates/api_models/src/events/routing.rs b/crates/api_models/src/events/routing.rs
index 4c2c5ca2c0b..9cfcafc8733 100644
--- a/crates/api_models/src/events/routing.rs
+++ b/crates/api_models/src/events/routing.rs
@@ -3,7 +3,8 @@ use common_utils::events::{ApiEventMetric, ApiEventsType};
 use crate::routing::{
     LinkedRoutingConfigRetrieveResponse, MerchantRoutingAlgorithm, ProfileDefaultRoutingConfig,
     RoutingAlgorithmId, RoutingConfigRequest, RoutingDictionaryRecord, RoutingKind,
-    RoutingLinkWrapper, RoutingPayloadWrapper, RoutingRetrieveLinkQuery, RoutingRetrieveQuery,
+    RoutingLinkWrapper, RoutingPayloadWrapper, RoutingRetrieveLinkQuery,
+    RoutingRetrieveLinkQueryWrapper, RoutingRetrieveQuery,
 };
 
 impl ApiEventMetric for RoutingKind {
@@ -70,3 +71,8 @@ impl ApiEventMetric for RoutingLinkWrapper {
         Some(ApiEventsType::Routing)
     }
 }
+impl ApiEventMetric for RoutingRetrieveLinkQueryWrapper {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Routing)
+    }
+}
diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs
index aca7bfaebe3..04ca1fd4429 100644
--- a/crates/api_models/src/routing.rs
+++ b/crates/api_models/src/routing.rs
@@ -58,8 +58,6 @@ pub struct ProfileDefaultRoutingConfig {
 pub struct RoutingRetrieveQuery {
     pub limit: Option<u16>,
     pub offset: Option<u8>,
-
-    pub profile_id: Option<String>,
 }
 
 #[derive(Debug, serde::Deserialize, serde::Serialize)]
@@ -67,6 +65,11 @@ pub struct RoutingRetrieveLinkQuery {
     pub profile_id: Option<String>,
 }
 
+#[derive(Debug, serde::Deserialize, serde::Serialize)]
+pub struct RoutingRetrieveLinkQueryWrapper {
+    pub routing_query: RoutingRetrieveQuery,
+    pub profile_id: String,
+}
 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
 /// Response of the retrieved routing configs for a merchant account
 pub struct RoutingRetrieveResponse {
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index b6efa7ea272..bb4aa21cda6 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -1,8 +1,8 @@
 use std::collections::{HashMap, HashSet};
 
 use common_enums::AuthenticationConnectors;
-#[cfg(all(feature = "v2", feature = "business_profile_v2"))]
-use common_enums::OrderFulfillmentTimeOrigin;
+// #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
+// use common_enums::OrderFulfillmentTimeOrigin;
 use common_utils::{encryption::Encryption, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use masking::Secret;
@@ -231,6 +231,7 @@ pub struct BusinessProfile {
     pub redirect_to_merchant_with_http_post: bool,
     pub webhook_details: Option<WebhookDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
+    pub intent_fulfillment_time: Option<i64>,
     pub is_recon_enabled: bool,
     #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
     pub applepay_verified_domains: Option<Vec<String>>,
@@ -246,11 +247,11 @@ pub struct BusinessProfile {
     pub collect_billing_details_from_wallet_connector: Option<bool>,
     pub outgoing_webhook_custom_http_headers: Option<Encryption>,
     pub routing_algorithm_id: Option<String>,
-    pub order_fulfillment_time: Option<i64>,
-    pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
+    // pub order_fulfillment_time: Option<i64>,
+    // pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
     pub frm_routing_algorithm_id: Option<String>,
     pub payout_routing_algorithm_id: Option<String>,
-    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
+    // pub default_fallback_routing: Option<pii::SecretSerdeValue>,
 }
 
 #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
@@ -268,6 +269,7 @@ pub struct BusinessProfileNew {
     pub redirect_to_merchant_with_http_post: bool,
     pub webhook_details: Option<WebhookDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
+    pub intent_fulfillment_time: Option<i64>,
     pub is_recon_enabled: bool,
     #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
     pub applepay_verified_domains: Option<Vec<String>>,
@@ -283,11 +285,11 @@ pub struct BusinessProfileNew {
     pub collect_billing_details_from_wallet_connector: Option<bool>,
     pub outgoing_webhook_custom_http_headers: Option<Encryption>,
     pub routing_algorithm_id: Option<String>,
-    pub order_fulfillment_time: Option<i64>,
-    pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
+    // pub order_fulfillment_time: Option<i64>,
+    // pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
     pub frm_routing_algorithm_id: Option<String>,
     pub payout_routing_algorithm_id: Option<String>,
-    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
+    // pub default_fallback_routing: Option<pii::SecretSerdeValue>,
 }
 
 #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
@@ -302,6 +304,7 @@ pub struct BusinessProfileUpdateInternal {
     pub redirect_to_merchant_with_http_post: Option<bool>,
     pub webhook_details: Option<WebhookDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
+    pub intent_fulfillment_time: Option<i64>,
     pub is_recon_enabled: Option<bool>,
     #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
     pub applepay_verified_domains: Option<Vec<String>>,
@@ -317,11 +320,11 @@ pub struct BusinessProfileUpdateInternal {
     pub collect_billing_details_from_wallet_connector: Option<bool>,
     pub outgoing_webhook_custom_http_headers: Option<Encryption>,
     pub routing_algorithm_id: Option<String>,
-    pub order_fulfillment_time: Option<i64>,
-    pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
+    // pub order_fulfillment_time: Option<i64>,
+    // pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
     pub frm_routing_algorithm_id: Option<String>,
     pub payout_routing_algorithm_id: Option<String>,
-    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
+    // pub default_fallback_routing: Option<pii::SecretSerdeValue>,
 }
 
 #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
@@ -350,11 +353,12 @@ impl BusinessProfileUpdateInternal {
             collect_billing_details_from_wallet_connector,
             outgoing_webhook_custom_http_headers,
             routing_algorithm_id,
-            order_fulfillment_time,
-            order_fulfillment_time_origin,
+            intent_fulfillment_time,
+            // order_fulfillment_time,
+            // order_fulfillment_time_origin,
             frm_routing_algorithm_id,
             payout_routing_algorithm_id,
-            default_fallback_routing,
+            // default_fallback_routing,
         } = self;
         BusinessProfile {
             profile_id: source.profile_id,
@@ -396,13 +400,14 @@ impl BusinessProfileUpdateInternal {
             outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
                 .or(source.outgoing_webhook_custom_http_headers),
             routing_algorithm_id: routing_algorithm_id.or(source.routing_algorithm_id),
-            order_fulfillment_time: order_fulfillment_time.or(source.order_fulfillment_time),
-            order_fulfillment_time_origin: order_fulfillment_time_origin
-                .or(source.order_fulfillment_time_origin),
+            intent_fulfillment_time: intent_fulfillment_time.or(source.intent_fulfillment_time),
+            // order_fulfillment_time: order_fulfillment_time.or(source.order_fulfillment_time),
+            // order_fulfillment_time_origin: order_fulfillment_time_origin
+            //     .or(source.order_fulfillment_time_origin),
             frm_routing_algorithm_id: frm_routing_algorithm_id.or(source.frm_routing_algorithm_id),
             payout_routing_algorithm_id: payout_routing_algorithm_id
                 .or(source.payout_routing_algorithm_id),
-            default_fallback_routing: default_fallback_routing.or(source.default_fallback_routing),
+            // default_fallback_routing: default_fallback_routing.or(source.default_fallback_routing),
         }
     }
 }
@@ -441,11 +446,12 @@ impl From<BusinessProfileNew> for BusinessProfile {
                 .collect_billing_details_from_wallet_connector,
             outgoing_webhook_custom_http_headers: new.outgoing_webhook_custom_http_headers,
             routing_algorithm_id: new.routing_algorithm_id,
-            order_fulfillment_time: new.order_fulfillment_time,
-            order_fulfillment_time_origin: new.order_fulfillment_time_origin,
+            intent_fulfillment_time: new.intent_fulfillment_time,
+            // order_fulfillment_time: new.order_fulfillment_time,
+            // order_fulfillment_time_origin: new.order_fulfillment_time_origin,
             frm_routing_algorithm_id: new.frm_routing_algorithm_id,
             payout_routing_algorithm_id: new.payout_routing_algorithm_id,
-            default_fallback_routing: new.default_fallback_routing,
+            // default_fallback_routing: new.default_fallback_routing,
         }
     }
 }
diff --git a/crates/diesel_models/src/query/routing_algorithm.rs b/crates/diesel_models/src/query/routing_algorithm.rs
index 6598733f0e5..0f3b709d264 100644
--- a/crates/diesel_models/src/query/routing_algorithm.rs
+++ b/crates/diesel_models/src/query/routing_algorithm.rs
@@ -7,7 +7,7 @@ use crate::{
     enums,
     errors::DatabaseError,
     query::generics,
-    routing_algorithm::{RoutingAlgorithm, RoutingAlgorithmMetadata, RoutingProfileMetadata},
+    routing_algorithm::{RoutingAlgorithm, RoutingProfileMetadata},
     schema::routing_algorithm::dsl,
     PgPooledConn, StorageResult,
 };
@@ -112,10 +112,11 @@ impl RoutingAlgorithm {
         profile_id: &str,
         limit: i64,
         offset: i64,
-    ) -> StorageResult<Vec<RoutingAlgorithmMetadata>> {
+    ) -> StorageResult<Vec<RoutingProfileMetadata>> {
         Ok(Self::table()
             .select((
                 dsl::algorithm_id,
+                dsl::profile_id,
                 dsl::name,
                 dsl::description,
                 dsl::kind,
@@ -127,6 +128,7 @@ impl RoutingAlgorithm {
             .limit(limit)
             .offset(offset)
             .load_async::<(
+                String,
                 String,
                 String,
                 Option<String>,
@@ -141,6 +143,7 @@ impl RoutingAlgorithm {
             .map(
                 |(
                     algorithm_id,
+                    profile_id,
                     name,
                     description,
                     kind,
@@ -148,7 +151,7 @@ impl RoutingAlgorithm {
                     modified_at,
                     algorithm_for,
                 )| {
-                    RoutingAlgorithmMetadata {
+                    RoutingProfileMetadata {
                         algorithm_id,
                         name,
                         description,
@@ -156,6 +159,7 @@ impl RoutingAlgorithm {
                         created_at,
                         modified_at,
                         algorithm_for,
+                        profile_id,
                     }
                 },
             )
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index 8821c7c8976..b5a4ff384ad 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -188,6 +188,7 @@ diesel::table! {
         redirect_to_merchant_with_http_post -> Bool,
         webhook_details -> Nullable<Json>,
         metadata -> Nullable<Json>,
+        intent_fulfillment_time -> Nullable<Int8>,
         is_recon_enabled -> Bool,
         applepay_verified_domains -> Nullable<Array<Nullable<Text>>>,
         payment_link_config -> Nullable<Jsonb>,
@@ -203,13 +204,10 @@ diesel::table! {
         outgoing_webhook_custom_http_headers -> Nullable<Bytea>,
         #[max_length = 64]
         routing_algorithm_id -> Nullable<Varchar>,
-        order_fulfillment_time -> Nullable<Int8>,
-        order_fulfillment_time_origin -> Nullable<OrderFulfillmentTimeOrigin>,
         #[max_length = 64]
         frm_routing_algorithm_id -> Nullable<Varchar>,
         #[max_length = 64]
         payout_routing_algorithm_id -> Nullable<Varchar>,
-        default_fallback_routing -> Nullable<Jsonb>,
     }
 }
 
diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs
index 08903748c01..dcc6a88c824 100644
--- a/crates/hyperswitch_domain_models/src/business_profile.rs
+++ b/crates/hyperswitch_domain_models/src/business_profile.rs
@@ -1,5 +1,5 @@
-#[cfg(all(feature = "v2", feature = "business_profile_v2"))]
-use common_enums::OrderFulfillmentTimeOrigin;
+// #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
+// use common_enums::OrderFulfillmentTimeOrigin;
 use common_utils::{
     crypto::OptionalEncryptableValue,
     date_time,
@@ -420,6 +420,7 @@ pub struct BusinessProfile {
     pub redirect_to_merchant_with_http_post: bool,
     pub webhook_details: Option<WebhookDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
+    pub intent_fulfillment_time: Option<i64>,
     pub is_recon_enabled: bool,
     pub applepay_verified_domains: Option<Vec<String>>,
     pub payment_link_config: Option<BusinessPaymentLinkConfig>,
@@ -434,11 +435,11 @@ pub struct BusinessProfile {
     pub collect_billing_details_from_wallet_connector: Option<bool>,
     pub outgoing_webhook_custom_http_headers: OptionalEncryptableValue,
     pub routing_algorithm_id: Option<String>,
-    pub order_fulfillment_time: Option<i64>,
-    pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
+    // pub order_fulfillment_time: Option<i64>,
+    // pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
     pub frm_routing_algorithm_id: Option<String>,
     pub payout_routing_algorithm_id: Option<String>,
-    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
+    // pub default_fallback_routing: Option<pii::SecretSerdeValue>,
 }
 
 #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
@@ -451,6 +452,7 @@ pub struct BusinessProfileGeneralUpdate {
     pub redirect_to_merchant_with_http_post: Option<bool>,
     pub webhook_details: Option<WebhookDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
+    pub intent_fulfillment_time: Option<i64>,
     pub is_recon_enabled: Option<bool>,
     pub applepay_verified_domains: Option<Vec<String>>,
     pub payment_link_config: Option<BusinessPaymentLinkConfig>,
@@ -464,11 +466,11 @@ pub struct BusinessProfileGeneralUpdate {
     pub is_connector_agnostic_mit_enabled: Option<bool>,
     pub outgoing_webhook_custom_http_headers: OptionalEncryptableValue,
     pub routing_algorithm_id: Option<String>,
-    pub order_fulfillment_time: Option<i64>,
-    pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
+    // pub order_fulfillment_time: Option<i64>,
+    // pub order_fulfillment_time_origin: Option<OrderFulfillmentTimeOrigin>,
     pub frm_routing_algorithm_id: Option<String>,
     pub payout_routing_algorithm_id: Option<String>,
-    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
+    // pub default_fallback_routing: Option<pii::SecretSerdeValue>,
 }
 
 #[cfg(all(feature = "v2", feature = "business_profile_v2"))]
@@ -502,6 +504,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                     redirect_to_merchant_with_http_post,
                     webhook_details,
                     metadata,
+                    intent_fulfillment_time,
                     is_recon_enabled,
                     applepay_verified_domains,
                     payment_link_config,
@@ -515,11 +518,11 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                     is_connector_agnostic_mit_enabled,
                     outgoing_webhook_custom_http_headers,
                     routing_algorithm_id,
-                    order_fulfillment_time,
-                    order_fulfillment_time_origin,
+                    // order_fulfillment_time,
+                    // order_fulfillment_time_origin,
                     frm_routing_algorithm_id,
                     payout_routing_algorithm_id,
-                    default_fallback_routing,
+                    // default_fallback_routing,
                 } = *update;
                 Self {
                     profile_name,
@@ -530,6 +533,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                     redirect_to_merchant_with_http_post,
                     webhook_details,
                     metadata,
+                    intent_fulfillment_time,
                     is_recon_enabled,
                     applepay_verified_domains,
                     payment_link_config,
@@ -545,11 +549,11 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                     outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
                         .map(Encryption::from),
                     routing_algorithm_id,
-                    order_fulfillment_time,
-                    order_fulfillment_time_origin,
+                    // order_fulfillment_time,
+                    // order_fulfillment_time_origin,
                     frm_routing_algorithm_id,
                     payout_routing_algorithm_id,
-                    default_fallback_routing,
+                    // default_fallback_routing,
                 }
             }
             BusinessProfileUpdate::RoutingAlgorithmUpdate {
@@ -578,11 +582,12 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 collect_billing_details_from_wallet_connector: None,
                 outgoing_webhook_custom_http_headers: None,
                 routing_algorithm_id,
-                order_fulfillment_time: None,
-                order_fulfillment_time_origin: None,
+                intent_fulfillment_time: None,
+                // order_fulfillment_time: None,
+                // order_fulfillment_time_origin: None,
                 frm_routing_algorithm_id: None,
                 payout_routing_algorithm_id,
-                default_fallback_routing: None,
+                // default_fallback_routing: None,
             },
             BusinessProfileUpdate::ExtendedCardInfoUpdate {
                 is_extended_card_info_enabled,
@@ -609,11 +614,12 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 collect_billing_details_from_wallet_connector: None,
                 outgoing_webhook_custom_http_headers: None,
                 routing_algorithm_id: None,
-                order_fulfillment_time: None,
-                order_fulfillment_time_origin: None,
-                frm_routing_algorithm_id: None,
                 payout_routing_algorithm_id: None,
-                default_fallback_routing: None,
+                intent_fulfillment_time: None,
+                // order_fulfillment_time: None,
+                // order_fulfillment_time_origin: None,
+                frm_routing_algorithm_id: None,
+                // default_fallback_routing: None,
             },
             BusinessProfileUpdate::ConnectorAgnosticMitUpdate {
                 is_connector_agnostic_mit_enabled,
@@ -640,11 +646,12 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 collect_billing_details_from_wallet_connector: None,
                 outgoing_webhook_custom_http_headers: None,
                 routing_algorithm_id: None,
-                order_fulfillment_time: None,
-                order_fulfillment_time_origin: None,
-                frm_routing_algorithm_id: None,
                 payout_routing_algorithm_id: None,
-                default_fallback_routing: None,
+                intent_fulfillment_time: None,
+                // order_fulfillment_time: None,
+                // order_fulfillment_time_origin: None,
+                frm_routing_algorithm_id: None,
+                // default_fallback_routing: None,
             },
         }
     }
@@ -687,11 +694,12 @@ impl super::behaviour::Conversion for BusinessProfile {
                 .outgoing_webhook_custom_http_headers
                 .map(Encryption::from),
             routing_algorithm_id: self.routing_algorithm_id,
-            order_fulfillment_time: self.order_fulfillment_time,
-            order_fulfillment_time_origin: self.order_fulfillment_time_origin,
-            frm_routing_algorithm_id: self.frm_routing_algorithm_id,
             payout_routing_algorithm_id: self.payout_routing_algorithm_id,
-            default_fallback_routing: self.default_fallback_routing,
+            intent_fulfillment_time: self.intent_fulfillment_time,
+            // order_fulfillment_time: self.order_fulfillment_time,
+            // order_fulfillment_time_origin: self.order_fulfillment_time_origin,
+            frm_routing_algorithm_id: self.frm_routing_algorithm_id,
+            // default_fallback_routing: self.default_fallback_routing,
         })
     }
 
@@ -746,11 +754,13 @@ impl super::behaviour::Conversion for BusinessProfile {
                     })
                     .await?,
                 routing_algorithm_id: item.routing_algorithm_id,
-                order_fulfillment_time: item.order_fulfillment_time,
-                order_fulfillment_time_origin: item.order_fulfillment_time_origin,
+
+                intent_fulfillment_time: item.intent_fulfillment_time,
+                // order_fulfillment_time: item.order_fulfillment_time,
+                // order_fulfillment_time_origin: item.order_fulfillment_time_origin,
                 frm_routing_algorithm_id: item.frm_routing_algorithm_id,
                 payout_routing_algorithm_id: item.payout_routing_algorithm_id,
-                default_fallback_routing: item.default_fallback_routing,
+                // default_fallback_routing: item.default_fallback_routing,
             })
         }
         .await
@@ -790,11 +800,12 @@ impl super::behaviour::Conversion for BusinessProfile {
                 .outgoing_webhook_custom_http_headers
                 .map(Encryption::from),
             routing_algorithm_id: self.routing_algorithm_id,
-            order_fulfillment_time: self.order_fulfillment_time,
-            order_fulfillment_time_origin: self.order_fulfillment_time_origin,
+            intent_fulfillment_time: self.intent_fulfillment_time,
+            // order_fulfillment_time: self.order_fulfillment_time,
+            // order_fulfillment_time_origin: self.order_fulfillment_time_origin,
             frm_routing_algorithm_id: self.frm_routing_algorithm_id,
             payout_routing_algorithm_id: self.payout_routing_algorithm_id,
-            default_fallback_routing: self.default_fallback_routing,
+            // default_fallback_routing: self.default_fallback_routing,
         })
     }
 }
diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml
index 3e0470cc08d..01568aa8518 100644
--- a/crates/router/Cargo.toml
+++ b/crates/router/Cargo.toml
@@ -33,7 +33,7 @@ recon = ["email", "api_models/recon"]
 retry = []
 v2 = ["api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2"]
 v1 = ["api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1"]
-# business_profile_v2 = ["api_models/business_profile_v2", "diesel_models/business_profile_v2", "hyperswitch_domain_models/business_profile_v2"]
+business_profile_v2 = ["api_models/business_profile_v2", "diesel_models/business_profile_v2", "hyperswitch_domain_models/business_profile_v2"]
 customer_v2 = ["api_models/customer_v2", "diesel_models/customer_v2", "hyperswitch_domain_models/customer_v2", "storage_impl/customer_v2"]
 merchant_account_v2 = ["api_models/merchant_account_v2", "diesel_models/merchant_account_v2", "hyperswitch_domain_models/merchant_account_v2"]
 payment_v2 = ["api_models/payment_v2", "diesel_models/payment_v2", "hyperswitch_domain_models/payment_v2"]
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index 5c800a0dc24..2b3360f35da 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -21,6 +21,12 @@ 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::{
@@ -28,10 +34,7 @@ use crate::{
     core::{
         encryption::transfer_encryption_key,
         errors::{self, RouterResponse, RouterResult, StorageErrorExt},
-        payment_methods::{
-            cards::{self, create_encrypted_data},
-            transformers,
-        },
+        payment_methods::{cards, transformers},
         payments::helpers,
         pm_auth::helpers::PaymentAuthConnectorDataExt,
         routing::helpers as routing_helpers,
@@ -52,7 +55,6 @@ use crate::{
     },
     utils,
 };
-
 const IBAN_MAX_LENGTH: usize = 34;
 const BACS_SORT_CODE_LENGTH: usize = 6;
 const BACS_MAX_ACCOUNT_NUMBER_LENGTH: usize = 8;
@@ -3311,7 +3313,7 @@ pub async fn create_and_insert_business_profile(
 
 #[cfg(all(
     any(feature = "v1", feature = "v2"),
-    not(feature = "merchant_account_v2")
+    not(any(feature = "merchant_account_v2", feature = "business_profile_v2"))
 ))]
 pub async fn create_business_profile(
     state: SessionState,
@@ -3377,7 +3379,11 @@ pub async fn create_business_profile(
     ))
 }
 
-#[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
+#[cfg(all(
+    feature = "v2",
+    feature = "merchant_account_v2",
+    feature = "business_profile_v2"
+))]
 pub async fn create_business_profile(
     _state: SessionState,
     _request: api::BusinessProfileCreate,
@@ -3460,6 +3466,10 @@ pub async fn delete_business_profile(
     Ok(service_api::ApplicationResponse::Json(delete_result))
 }
 
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(feature = "business_profile_v2")
+))]
 pub async fn update_business_profile(
     state: SessionState,
     profile_id: &str,
@@ -3535,7 +3545,7 @@ pub async fn update_business_profile(
         .map(Secret::new);
     let outgoing_webhook_custom_http_headers = request
         .outgoing_webhook_custom_http_headers
-        .async_map(|headers| create_encrypted_data(&state, &key_store, headers))
+        .async_map(|headers| cards::create_encrypted_data(&state, &key_store, headers))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -3604,6 +3614,111 @@ pub async fn update_business_profile(
             .attach_printable("Failed to parse business profile details")?,
     ))
 }
+#[cfg(all(feature = "v2", feature = "business_profile_v2"))]
+pub async fn update_business_profile(
+    _state: SessionState,
+    _profile_id: &str,
+    _merchant_id: &id_type::MerchantId,
+    _request: api::BusinessProfileUpdate,
+) -> RouterResponse<api::BusinessProfileResponse> {
+    todo!()
+}
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+#[derive(Clone, Debug)]
+pub struct BusinessProfileWrapper {
+    pub profile: domain::BusinessProfile,
+}
+
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+impl BusinessProfileWrapper {
+    pub fn new(profile: domain::BusinessProfile) -> Self {
+        Self { profile }
+    }
+    fn get_routing_config_cache_key(self) -> storage_impl::redis::cache::CacheKind<'static> {
+        let merchant_id = self.profile.merchant_id.clone();
+
+        let profile_id = self.profile.profile_id.clone();
+
+        storage_impl::redis::cache::CacheKind::Routing(
+            format!(
+                "routing_config_{}_{profile_id}",
+                merchant_id.get_string_repr()
+            )
+            .into(),
+        )
+    }
+
+    pub async fn update_business_profile_and_invalidate_routing_config_for_active_algorithm_id_update(
+        self,
+        db: &dyn StorageInterface,
+        key_manager_state: &KeyManagerState,
+        merchant_key_store: &domain::MerchantKeyStore,
+        algorithm_id: String,
+        transaction_type: &storage::enums::TransactionType,
+    ) -> RouterResult<()> {
+        let routing_cache_key = self.clone().get_routing_config_cache_key();
+
+        let (routing_algorithm_id, payout_routing_algorithm_id) = match transaction_type {
+            storage::enums::TransactionType::Payment => (Some(algorithm_id), None),
+            #[cfg(feature = "payouts")]
+            storage::enums::TransactionType::Payout => (None, Some(algorithm_id)),
+        };
+
+        let business_profile_update = domain::BusinessProfileUpdate::RoutingAlgorithmUpdate {
+            routing_algorithm_id,
+            payout_routing_algorithm_id,
+        };
+
+        let profile = self.profile;
+
+        db.update_business_profile_by_profile_id(
+            key_manager_state,
+            merchant_key_store,
+            profile,
+            business_profile_update,
+        )
+        .await
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to update routing algorithm ref in business profile")?;
+
+        storage_impl::redis::cache::publish_into_redact_channel(
+            db.get_cache_store().as_ref(),
+            [routing_cache_key],
+        )
+        .await
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to invalidate routing cache")?;
+        Ok(())
+    }
+
+    pub fn get_profile_id_and_routing_algorithm_id<F>(
+        &self,
+        transaction_data: &routing::TransactionData<'_, F>,
+    ) -> (Option<String>, 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(),
+            ),
+            #[cfg(feature = "payouts")]
+            routing::TransactionData::Payout(payout_data) => (
+                Some(payout_data.payout_attempt.profile_id.clone()),
+                self.profile.payout_routing_algorithm_id.clone(),
+            ),
+        }
+    }
+}
 
 pub async fn extended_card_info_toggle(
     state: SessionState,
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 145f8d63f83..db731848dbb 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -3305,15 +3305,9 @@ pub async fn call_surcharge_decision_management(
         .attach_printable("Could not decode the routing algorithm")?
         .unwrap_or_default();
 
+    // TODO: Move to business profile surcharge decision column
     #[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
-    let algorithm_ref: routing_types::RoutingAlgorithmRef = business_profile
-        .routing_algorithm
-        .clone()
-        .map(|val| val.parse_value("routing algorithm"))
-        .transpose()
-        .change_context(errors::ApiErrorResponse::InternalServerError)
-        .attach_printable("Could not decode the routing algorithm")?
-        .unwrap_or_default();
+    let algorithm_ref: routing_types::RoutingAlgorithmRef = todo!();
 
     let (surcharge_results, merchant_sucharge_configs) =
         perform_surcharge_decision_management_for_payment_method_list(
@@ -3371,16 +3365,9 @@ pub async fn call_surcharge_decision_management_for_saved_card(
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Could not decode the routing algorithm")?
         .unwrap_or_default();
-
+    // TODO: Move to business profile surcharge column
     #[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
-    let algorithm_ref: routing_types::RoutingAlgorithmRef = business_profile
-        .routing_algorithm
-        .clone()
-        .map(|val| val.parse_value("routing algorithm"))
-        .transpose()
-        .change_context(errors::ApiErrorResponse::InternalServerError)
-        .attach_printable("Could not decode the routing algorithm")?
-        .unwrap_or_default();
+    let algorithm_ref: routing_types::RoutingAlgorithmRef = todo!();
 
     let surcharge_results = perform_surcharge_decision_management_for_saved_cards(
         state,
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index 6b8c19925ee..60a5581d39b 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -647,15 +647,9 @@ where
         .attach_printable("Could not decode the routing algorithm")?
         .unwrap_or_default();
 
+    // TODO: Move to business profile surcharge column
     #[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
-    let algorithm_ref: api::routing::RoutingAlgorithmRef = _business_profile
-        .routing_algorithm
-        .clone()
-        .map(|val| val.parse_value("routing algorithm"))
-        .transpose()
-        .change_context(errors::ApiErrorResponse::InternalServerError)
-        .attach_printable("Could not decode the routing algorithm")?
-        .unwrap_or_default();
+    let algorithm_ref: api::routing::RoutingAlgorithmRef = todo!();
 
     let output = perform_decision_management(
         state,
@@ -800,15 +794,9 @@ where
             .attach_printable("Could not decode the routing algorithm")?
             .unwrap_or_default();
 
+        // TODO: Move to business profile surcharge column
         #[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
-        let algorithm_ref: api::routing::RoutingAlgorithmRef = _business_profile
-            .routing_algorithm
-            .clone()
-            .map(|val| val.parse_value("routing algorithm"))
-            .transpose()
-            .change_context(errors::ApiErrorResponse::InternalServerError)
-            .attach_printable("Could not decode the routing algorithm")?
-            .unwrap_or_default();
+        let algorithm_ref: api::routing::RoutingAlgorithmRef = todo!();
 
         let surcharge_results =
             surcharge_decision_configs::perform_surcharge_decision_management_for_session_flow(
@@ -3953,7 +3941,11 @@ where
     Ok(final_list)
 }
 
-#[allow(clippy::too_many_arguments)]
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
 pub async fn route_connector_v1<F>(
     state: &SessionState,
     merchant_account: &domain::MerchantAccount,
@@ -3967,35 +3959,124 @@ pub async fn route_connector_v1<F>(
 where
     F: Send + Clone,
 {
-    #[allow(unused_variables)]
-    let (profile_id, routing_algorithm) = match &transaction_data {
-        TransactionData::Payment(payment_data) => (
-            payment_data.payment_intent.profile_id.clone(),
-            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(),
-        ),
-    };
+    let (profile_id, routing_algorithm_id) =
+        super::admin::BusinessProfileWrapper::new(business_profile.clone())
+            .get_profile_id_and_routing_algorithm_id(&transaction_data);
 
-    let algorithm_ref = routing_algorithm
-        .map(|ra| ra.parse_value::<api::routing::RoutingAlgorithmRef>("RoutingAlgorithmRef"))
-        .transpose()
+    let connectors = routing::perform_static_routing_v1(
+        state,
+        merchant_account.get_id(),
+        routing_algorithm_id,
+        &transaction_data,
+    )
+    .await
+    .change_context(errors::ApiErrorResponse::InternalServerError)?;
+
+    let connectors = routing::perform_eligibility_analysis_with_fallback(
+        &state.clone(),
+        key_store,
+        connectors,
+        &transaction_data,
+        eligible_connectors,
+        profile_id,
+    )
+    .await
+    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .attach_printable("failed eligibility analysis and fallback")?;
+
+    #[cfg(feature = "payouts")]
+    let first_connector_choice = connectors
+        .first()
+        .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration)
+        .attach_printable("Empty connector list returned")?
+        .clone();
+
+    let connector_data = connectors
+        .into_iter()
+        .map(|conn| {
+            api::ConnectorData::get_connector_by_name(
+                &state.conf.connectors,
+                &conn.connector.to_string(),
+                api::GetToken::Connector,
+                conn.merchant_connector_id,
+            )
+        })
+        .collect::<CustomResult<Vec<_>, _>>()
         .change_context(errors::ApiErrorResponse::InternalServerError)
-        .attach_printable("Could not decode merchant routing algorithm ref")?
-        .unwrap_or_default();
+        .attach_printable("Invalid connector name received")?;
+
+    match transaction_data {
+        TransactionData::Payment(payment_data) => {
+            decide_multiplex_connector_for_normal_or_recurring_payment(
+                state,
+                payment_data,
+                routing_data,
+                connector_data,
+                mandate_type,
+                business_profile.is_connector_agnostic_mit_enabled.clone(),
+            )
+            .await
+        }
+
+        #[cfg(feature = "payouts")]
+        TransactionData::Payout(_) => {
+            routing_data.routed_through = Some(first_connector_choice.connector.to_string());
+
+            routing_data.merchant_connector_id = first_connector_choice.merchant_connector_id;
+
+            Ok(ConnectorCallType::Retryable(connector_data))
+        }
+    }
+}
+
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(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,
+    business_profile: &domain::BusinessProfile,
+    key_store: &domain::MerchantKeyStore,
+    transaction_data: TransactionData<'_, F>,
+    routing_data: &mut storage::RoutingData,
+    eligible_connectors: Option<Vec<enums::RoutableConnectors>>,
+    mandate_type: Option<api::MandateTransactionType>,
+) -> RouterResult<ConnectorCallType>
+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(),
+            ),
+            #[cfg(feature = "payouts")]
+            TransactionData::Payout(payout_data) => (
+                Some(payout_data.payout_attempt.profile_id.clone()),
+                business_profile.payout_routing_algorithm.clone(),
+            ),
+        };
+
+        let algorithm_ref = routing_algorithm
+            .map(|ra| ra.parse_value::<api::routing::RoutingAlgorithmRef>("RoutingAlgorithmRef"))
+            .transpose()
+            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .attach_printable("Could not decode merchant routing algorithm ref")?
+            .unwrap_or_default();
+        (profile_id, algorithm_ref.algorithm_id)
+    };
 
     let connectors = routing::perform_static_routing_v1(
         state,
         merchant_account.get_id(),
-        algorithm_ref,
+        routing_algorithm_id,
         &transaction_data,
     )
     .await
     .change_context(errors::ApiErrorResponse::InternalServerError)?;
-
     let connectors = routing::perform_eligibility_analysis_with_fallback(
         &state.clone(),
         key_store,
diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index a989e30d8ea..c029e2d289c 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -80,18 +80,37 @@ pub struct SessionRoutingPmTypeInput<'a> {
 
 type RoutingResult<O> = oss_errors::CustomResult<O, errors::RoutingError>;
 
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 #[derive(Debug, serde::Serialize, serde::Deserialize)]
 #[serde(untagged)]
 enum MerchantAccountRoutingAlgorithm {
     V1(routing_types::RoutingAlgorithmRef),
 }
 
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 impl Default for MerchantAccountRoutingAlgorithm {
     fn default() -> Self {
         Self::V1(routing_types::RoutingAlgorithmRef::default())
     }
 }
 
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
+#[serde(untagged)]
+enum MerchantAccountRoutingAlgorithm {
+    V1(Option<String>),
+}
+
 #[cfg(feature = "payouts")]
 pub fn make_dsl_input_for_payouts(
     payout_data: &payouts::PayoutData,
@@ -253,7 +272,7 @@ where
 pub async fn perform_static_routing_v1<F: Clone>(
     state: &SessionState,
     merchant_id: &common_utils::id_type::MerchantId,
-    algorithm_ref: routing_types::RoutingAlgorithmRef,
+    algorithm_id: Option<String>,
     transaction_data: &routing::TransactionData<'_, F>,
 ) -> RoutingResult<Vec<routing_types::RoutableConnectorChoice>> {
     let profile_id = match transaction_data {
@@ -266,7 +285,7 @@ pub async fn perform_static_routing_v1<F: Clone>(
         #[cfg(feature = "payouts")]
         routing::TransactionData::Payout(payout_data) => &payout_data.payout_attempt.profile_id,
     };
-    let algorithm_id = if let Some(id) = algorithm_ref.algorithm_id {
+    let algorithm_id = if let Some(id) = algorithm_id {
         id
     } else {
         let fallback_config = routing_helpers::get_merchant_default_config(
@@ -789,26 +808,36 @@ pub async fn perform_session_flow_routing(
 {
     let mut pm_type_map: FxHashMap<api_enums::PaymentMethodType, FxHashMap<String, api::GetToken>> =
         FxHashMap::default();
+    let profile_id = session_input
+        .payment_intent
+        .profile_id
+        .clone()
+        .get_required_value("profile_id")
+        .change_context(errors::RoutingError::ProfileIdMissing)?;
 
+    let business_profile = session_input
+        .state
+        .store
+        .find_business_profile_by_profile_id(
+            &session_input.state.into(),
+            session_input.key_store,
+            &profile_id,
+        )
+        .await
+        .change_context(errors::RoutingError::ProfileNotFound)?;
+    #[cfg(all(
+        feature = "v2",
+        feature = "routing_v2",
+        feature = "business_profile_v2"
+    ))]
+    let routing_algorithm =
+        MerchantAccountRoutingAlgorithm::V1(business_profile.routing_algorithm_id);
+
+    #[cfg(all(
+        any(feature = "v1", feature = "v2"),
+        not(any(feature = "routing_v2", feature = "business_profile_v2"))
+    ))]
     let routing_algorithm: MerchantAccountRoutingAlgorithm = {
-        let profile_id = session_input
-            .payment_intent
-            .profile_id
-            .clone()
-            .get_required_value("profile_id")
-            .change_context(errors::RoutingError::ProfileIdMissing)?;
-
-        let business_profile = session_input
-            .state
-            .store
-            .find_business_profile_by_profile_id(
-                &session_input.state.into(),
-                session_input.key_store,
-                &profile_id,
-            )
-            .await
-            .change_context(errors::RoutingError::ProfileNotFound)?;
-
         business_profile
             .routing_algorithm
             .clone()
@@ -940,45 +969,56 @@ async fn perform_session_routing_for_pm_type(
     transaction_type: &api_enums::TransactionType,
 ) -> 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 = match session_pm_input.routing_algorithm {
-        MerchantAccountRoutingAlgorithm::V1(algorithm_ref) => {
-            if let Some(ref algorithm_id) = algorithm_ref.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 {
-                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)?,
-                    transaction_type,
-                )
-                .await
-                .change_context(errors::RoutingError::FallbackConfigFetchFailed)?
+    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 {
+        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)?,
+            transaction_type,
+        )
+        .await
+        .change_context(errors::RoutingError::FallbackConfigFetchFailed)?
     };
 
     let mut final_selection = perform_cgraph_filtering(
diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs
index 3992438a747..9d819f8df9f 100644
--- a/crates/router/src/core/routing.rs
+++ b/crates/router/src/core/routing.rs
@@ -1,21 +1,19 @@
 pub mod helpers;
 pub mod transformers;
 
-#[cfg(all(feature = "v2", feature = "routing_v2"))]
-use api_models::routing::RoutingConfigRequest;
 use api_models::{
     enums,
-    routing::{self as routing_types, RoutingRetrieveLinkQuery, RoutingRetrieveQuery},
+    routing::{self as routing_types, RoutingRetrieveQuery},
 };
 use diesel_models::routing_algorithm::RoutingAlgorithm;
 use error_stack::ResultExt;
-#[cfg(all(feature = "v2", feature = "routing_v2"))]
-use masking::Secret;
 use rustc_hash::FxHashSet;
 
 use super::payments;
 #[cfg(feature = "payouts")]
 use super::payouts;
+#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "routing_v2")))]
+use crate::utils::ValueExt;
 use crate::{
     consts,
     core::{
@@ -28,10 +26,13 @@ use crate::{
         domain,
         transformers::{ForeignInto, ForeignTryFrom},
     },
-    utils::{self, OptionExt, ValueExt},
+    utils::{self, OptionExt},
 };
 #[cfg(all(feature = "v2", feature = "routing_v2"))]
-use crate::{core::errors::RouterResult, db::StorageInterface};
+use crate::{
+    core::{admin, errors::RouterResult},
+    db::StorageInterface,
+};
 pub enum TransactionData<'a, F>
 where
     F: Clone,
@@ -47,7 +48,7 @@ struct RoutingAlgorithmUpdate(RoutingAlgorithm);
 #[cfg(all(feature = "v2", feature = "routing_v2"))]
 impl RoutingAlgorithmUpdate {
     pub fn create_new_routing_algorithm(
-        request: &RoutingConfigRequest,
+        request: &routing_types::RoutingConfigRequest,
         merchant_id: &common_utils::id_type::MerchantId,
         profile_id: String,
         transaction_type: &enums::TransactionType,
@@ -82,32 +83,6 @@ impl RoutingAlgorithmUpdate {
             .change_context(errors::ApiErrorResponse::ResourceIdNotFound)?;
         Ok(Self(routing_algo))
     }
-
-    pub fn update_routing_ref_with_algorithm_id(
-        &self,
-        transaction_type: &enums::TransactionType,
-        routing_ref: &mut routing_types::RoutingAlgorithmRef,
-    ) -> RouterResult<()> {
-        utils::when(self.0.algorithm_for != *transaction_type, || {
-            Err(errors::ApiErrorResponse::PreconditionFailed {
-                message: format!(
-                    "Cannot use {}'s routing algorithm for {} operation",
-                    self.0.algorithm_for, transaction_type
-                ),
-            })
-        })?;
-
-        utils::when(
-            routing_ref.algorithm_id == Some(self.0.algorithm_id.clone()),
-            || {
-                Err(errors::ApiErrorResponse::PreconditionFailed {
-                    message: "Algorithm is already active".to_string(),
-                })
-            },
-        )?;
-        routing_ref.update_algorithm_id(self.0.algorithm_id.clone());
-        Ok(())
-    }
 }
 
 pub async fn retrieve_merchant_routing_dictionary(
@@ -140,11 +115,11 @@ pub async fn retrieve_merchant_routing_dictionary(
 }
 
 #[cfg(all(feature = "v2", feature = "routing_v2"))]
-pub async fn create_routing_config(
+pub async fn create_routing_algorithm_under_profile(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
-    request: RoutingConfigRequest,
+    request: routing_types::RoutingConfigRequest,
     transaction_type: &enums::TransactionType,
 ) -> RouterResponse<routing_types::RoutingDictionaryRecord> {
     metrics::ROUTING_CREATE_REQUEST_RECEIVED.add(&metrics::CONTEXT, 1, &[]);
@@ -170,7 +145,7 @@ pub async fn create_routing_config(
 
     let name_mca_id_set = helpers::ConnectNameAndMCAIdForProfile(
         all_mcas.filter_by_profile(&business_profile.profile_id, |mca| {
-            (&mca.connector_name, &mca.id)
+            (&mca.connector_name, mca.get_id())
         }),
     );
 
@@ -207,7 +182,7 @@ pub async fn create_routing_config(
 }
 
 #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "routing_v2")))]
-pub async fn create_routing_config(
+pub async fn create_routing_algorithm_under_profile(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -295,8 +270,12 @@ pub async fn create_routing_config(
     Ok(service_api::ApplicationResponse::Json(new_record))
 }
 
-#[cfg(all(feature = "v2", feature = "routing_v2"))]
-pub async fn link_routing_config(
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+pub async fn link_routing_config_under_profile(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -328,31 +307,47 @@ pub async fn link_routing_config(
     .await?
     .get_required_value("BusinessProfile")?;
 
-    let mut routing_ref = routing_types::RoutingAlgorithmRef::parse_routing_algorithm(
-        business_profile.routing_algorithm.clone().map(Secret::new),
-    )
-    .change_context(errors::ApiErrorResponse::InternalServerError)
-    .attach_printable("unable to deserialize routing algorithm ref from merchant account")?
-    .unwrap_or_default();
+    utils::when(
+        routing_algorithm.0.algorithm_for != *transaction_type,
+        || {
+            Err(errors::ApiErrorResponse::PreconditionFailed {
+                message: format!(
+                    "Cannot use {}'s routing algorithm for {} operation",
+                    routing_algorithm.0.algorithm_for, transaction_type
+                ),
+            })
+        },
+    )?;
 
-    routing_algorithm.update_routing_ref_with_algorithm_id(transaction_type, &mut routing_ref)?;
+    utils::when(
+        business_profile.routing_algorithm_id == Some(algorithm_id.clone())
+            || business_profile.payout_routing_algorithm_id == Some(algorithm_id.clone()),
+        || {
+            Err(errors::ApiErrorResponse::PreconditionFailed {
+                message: "Algorithm is already active".to_string(),
+            })
+        },
+    )?;
+    admin::BusinessProfileWrapper::new(business_profile)
+        .update_business_profile_and_invalidate_routing_config_for_active_algorithm_id_update(
+            db,
+            key_manager_state,
+            &key_store,
+            algorithm_id,
+            transaction_type,
+        )
+        .await?;
 
-    helpers::update_business_profile_active_algorithm_ref(
-        db,
-        key_manager_state,
-        &key_store,
-        business_profile,
-        routing_ref,
-        transaction_type,
-    )
-    .await?;
     metrics::ROUTING_LINK_CONFIG_SUCCESS_RESPONSE.add(&metrics::CONTEXT, 1, &[]);
     Ok(service_api::ApplicationResponse::Json(
         routing_algorithm.0.foreign_into(),
     ))
 }
 
-#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "routing_v2")))]
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 pub async fn link_routing_config(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
@@ -428,8 +423,8 @@ pub async fn link_routing_config(
     ))
 }
 
-#[cfg(all(feature = "v2", feature = "routing_v2"))]
-pub async fn retrieve_routing_config(
+#[cfg(all(feature = "v2", feature = "routing_v2",))]
+pub async fn retrieve_active_routing_config(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -462,7 +457,7 @@ pub async fn retrieve_routing_config(
 }
 
 #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "routing_v2")))]
-pub async fn retrieve_routing_config(
+pub async fn retrieve_active_routing_config(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -499,8 +494,12 @@ pub async fn retrieve_routing_config(
     Ok(service_api::ApplicationResponse::Json(response))
 }
 
-#[cfg(all(feature = "v2", feature = "routing_v2"))]
-pub async fn unlink_routing_config(
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+pub async fn unlink_routing_config_under_profile(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -521,27 +520,13 @@ pub async fn unlink_routing_config(
     .await?
     .get_required_value("BusinessProfile")?;
 
-    let routing_algo_ref = routing_types::RoutingAlgorithmRef::parse_routing_algorithm(
-        match transaction_type {
-            enums::TransactionType::Payment => business_profile.routing_algorithm.clone(),
-            #[cfg(feature = "payouts")]
-            enums::TransactionType::Payout => business_profile.payout_routing_algorithm.clone(),
-        }
-        .map(Secret::new),
-    )
-    .change_context(errors::ApiErrorResponse::InternalServerError)
-    .attach_printable("unable to deserialize routing algorithm ref from merchant account")?
-    .unwrap_or_default();
-
-    if let Some(algorithm_id) = routing_algo_ref.algorithm_id {
-        let timestamp = common_utils::date_time::now_unix_timestamp();
-        let routing_algorithm: routing_types::RoutingAlgorithmRef =
-            routing_types::RoutingAlgorithmRef {
-                algorithm_id: None,
-                timestamp,
-                config_algo_id: routing_algo_ref.config_algo_id.clone(),
-                surcharge_config_algo_id: routing_algo_ref.surcharge_config_algo_id,
-            };
+    let routing_algo_id = match transaction_type {
+        enums::TransactionType::Payment => business_profile.routing_algorithm_id.clone(),
+        #[cfg(feature = "payouts")]
+        enums::TransactionType::Payout => business_profile.payout_routing_algorithm_id.clone(),
+    };
+
+    if let Some(algorithm_id) = routing_algo_id {
         let record = RoutingAlgorithmUpdate::fetch_routing_algo(
             merchant_account.get_id(),
             &algorithm_id,
@@ -549,16 +534,15 @@ pub async fn unlink_routing_config(
         )
         .await?;
         let response = record.0.foreign_into();
-        helpers::update_business_profile_active_algorithm_ref(
-            db,
-            key_manager_state,
-            &key_store,
-            business_profile,
-            routing_algorithm,
-            transaction_type,
-        )
-        .await?;
-
+        admin::BusinessProfileWrapper::new(business_profile)
+            .update_business_profile_and_invalidate_routing_config_for_active_algorithm_id_update(
+                db,
+                key_manager_state,
+                &key_store,
+                algorithm_id,
+                transaction_type,
+            )
+            .await?;
         metrics::ROUTING_UNLINK_CONFIG_SUCCESS_RESPONSE.add(&metrics::CONTEXT, 1, &[]);
         Ok(service_api::ApplicationResponse::Json(response))
     } else {
@@ -568,7 +552,10 @@ pub async fn unlink_routing_config(
     }
 }
 
-#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "routing_v2")))]
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 pub async fn unlink_routing_config(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
@@ -726,11 +713,63 @@ pub async fn retrieve_default_routing_config(
     })
 }
 
+#[cfg(all(
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+pub async fn retrieve_routing_config_under_profile(
+    state: SessionState,
+    merchant_account: domain::MerchantAccount,
+    key_store: domain::MerchantKeyStore,
+    query_params: RoutingRetrieveQuery,
+    profile_id: String,
+    transaction_type: &enums::TransactionType,
+) -> RouterResponse<routing_types::LinkedRoutingConfigRetrieveResponse> {
+    metrics::ROUTING_RETRIEVE_LINK_CONFIG.add(&metrics::CONTEXT, 1, &[]);
+    let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
+
+    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")?;
+
+    let record = db
+        .list_routing_algorithm_metadata_by_profile_id(
+            &business_profile.profile_id,
+            i64::from(query_params.limit.unwrap_or_default()),
+            i64::from(query_params.offset.unwrap_or_default()),
+        )
+        .await
+        .to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?;
+
+    let active_algorithms = record
+        .into_iter()
+        .filter(|routing_rec| &routing_rec.algorithm_for == transaction_type)
+        .map(|routing_algo| routing_algo.foreign_into())
+        .collect::<Vec<_>>();
+
+    metrics::ROUTING_RETRIEVE_LINK_CONFIG_SUCCESS_RESPONSE.add(&metrics::CONTEXT, 1, &[]);
+    Ok(service_api::ApplicationResponse::Json(
+        routing_types::LinkedRoutingConfigRetrieveResponse::ProfileBased(active_algorithms),
+    ))
+}
+
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 pub async fn retrieve_linked_routing_config(
     state: SessionState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
-    query_params: RoutingRetrieveLinkQuery,
+    query_params: routing_types::RoutingRetrieveLinkQuery,
     transaction_type: &enums::TransactionType,
 ) -> RouterResponse<routing_types::LinkedRoutingConfigRetrieveResponse> {
     metrics::ROUTING_RETRIEVE_LINK_CONFIG.add(&metrics::CONTEXT, 1, &[]);
diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs
index e388be764d2..9255c2bad0b 100644
--- a/crates/router/src/core/routing/helpers.rs
+++ b/crates/router/src/core/routing/helpers.rs
@@ -173,7 +173,6 @@ pub async fn update_merchant_active_algorithm_ref(
     Ok(())
 }
 
-#[cfg(all(any(feature = "v1", feature = "v2"), feature = "merchant_account_v2"))]
 #[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
 pub async fn update_merchant_active_algorithm_ref(
     _state: &SessionState,
@@ -181,9 +180,14 @@ pub async fn update_merchant_active_algorithm_ref(
     _config_key: cache::CacheKind<'_>,
     _algorithm_id: routing_types::RoutingAlgorithmRef,
 ) -> RouterResult<()> {
+    // TODO: handle updating the active routing algorithm for v2 in merchant account
     todo!()
 }
 
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 pub async fn update_business_profile_active_algorithm_ref(
     db: &dyn StorageInterface,
     key_manager_state: &KeyManagerState,
@@ -246,7 +250,7 @@ pub struct RoutingAlgorithmHelpers<'h> {
 }
 
 #[derive(Clone, Debug)]
-pub struct ConnectNameAndMCAIdForProfile<'a>(pub FxHashSet<(&'a String, &'a String)>);
+pub struct ConnectNameAndMCAIdForProfile<'a>(pub FxHashSet<(&'a String, String)>);
 #[derive(Clone, Debug)]
 pub struct ConnectNameForProfile<'a>(pub FxHashSet<&'a String>);
 
@@ -314,7 +318,7 @@ impl<'h> RoutingAlgorithmHelpers<'h> {
     ) -> RouterResult<()> {
         if let Some(ref mca_id) = choice.merchant_connector_id {
             error_stack::ensure!(
-                    self.name_mca_id_set.0.contains(&(&choice.connector.to_string(), mca_id)),
+                    self.name_mca_id_set.0.contains(&(&choice.connector.to_string(), mca_id.clone())),
                     errors::ApiErrorResponse::InvalidRequestData {
                         message: format!(
                             "connector with name '{}' and merchant connector account id '{}' not found for the given profile",
diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs
index b997aad1080..31b9ffcd7f8 100644
--- a/crates/router/src/db/kafka_store.rs
+++ b/crates/router/src/db/kafka_store.rs
@@ -2399,7 +2399,7 @@ impl RoutingAlgorithmInterface for KafkaStore {
         profile_id: &str,
         limit: i64,
         offset: i64,
-    ) -> CustomResult<Vec<storage::RoutingAlgorithmMetadata>, errors::StorageError> {
+    ) -> CustomResult<Vec<storage::RoutingProfileMetadata>, errors::StorageError> {
         self.diesel_store
             .list_routing_algorithm_metadata_by_profile_id(profile_id, limit, offset)
             .await
diff --git a/crates/router/src/db/routing_algorithm.rs b/crates/router/src/db/routing_algorithm.rs
index b5e877b5295..ad4b3bd9192 100644
--- a/crates/router/src/db/routing_algorithm.rs
+++ b/crates/router/src/db/routing_algorithm.rs
@@ -41,7 +41,7 @@ pub trait RoutingAlgorithmInterface {
         profile_id: &str,
         limit: i64,
         offset: i64,
-    ) -> StorageResult<Vec<routing_storage::RoutingAlgorithmMetadata>>;
+    ) -> StorageResult<Vec<routing_storage::RoutingProfileMetadata>>;
 
     async fn list_routing_algorithm_metadata_by_merchant_id(
         &self,
@@ -127,7 +127,7 @@ impl RoutingAlgorithmInterface for Store {
         profile_id: &str,
         limit: i64,
         offset: i64,
-    ) -> StorageResult<Vec<routing_storage::RoutingAlgorithmMetadata>> {
+    ) -> StorageResult<Vec<routing_storage::RoutingProfileMetadata>> {
         let conn = connection::pg_connection_write(self).await?;
         routing_storage::RoutingAlgorithm::list_metadata_by_profile_id(
             &conn, profile_id, limit, offset,
@@ -212,7 +212,7 @@ impl RoutingAlgorithmInterface for MockDb {
         _profile_id: &str,
         _limit: i64,
         _offset: i64,
-    ) -> StorageResult<Vec<routing_storage::RoutingAlgorithmMetadata>> {
+    ) -> StorageResult<Vec<routing_storage::RoutingProfileMetadata>> {
         Err(errors::StorageError::MockDbError)?
     }
 
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 3c891d8a537..a6ce8c568b1 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -1455,7 +1455,12 @@ impl PayoutLink {
 }
 
 pub struct BusinessProfile;
-#[cfg(all(feature = "olap", feature = "v2", feature = "routing_v2"))]
+#[cfg(all(
+    feature = "olap",
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
 impl BusinessProfile {
     pub fn server(state: AppState) -> Scope {
         web::scope("/v2/profiles")
@@ -1493,23 +1498,36 @@ impl BusinessProfile {
                             },
                         )),
                     )
-                    .service(web::resource("/deactivate_routing_algorithm").route(
-                        web::patch().to(|state, req, path| {
-                            routing::routing_unlink_config(
+                    .service(
+                        web::resource("/deactivate_routing_algorithm").route(web::patch().to(
+                            |state, req, path| {
+                                routing::routing_unlink_config(
+                                    state,
+                                    req,
+                                    path,
+                                    &TransactionType::Payment,
+                                )
+                            },
+                        )),
+                    )
+                    .service(web::resource("/routing_algorithm").route(web::get().to(
+                        |state, req, query_params, path| {
+                            routing::routing_retrieve_linked_config(
                                 state,
                                 req,
+                                query_params,
                                 path,
                                 &TransactionType::Payment,
                             )
-                        }),
-                    )),
+                        },
+                    ))),
             )
     }
 }
 #[cfg(all(
     feature = "olap",
     any(feature = "v1", feature = "v2"),
-    not(feature = "routing_v2")
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
 ))]
 impl BusinessProfile {
     pub fn server(state: AppState) -> Scope {
diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs
index 3705b0313d7..485a55baa50 100644
--- a/crates/router/src/routes/routing.rs
+++ b/crates/router/src/routes/routing.rs
@@ -4,10 +4,7 @@
 //! of Routing configs.
 
 use actix_web::{web, HttpRequest, Responder};
-use api_models::{
-    enums, routing as routing_types,
-    routing::{RoutingRetrieveLinkQuery, RoutingRetrieveQuery},
-};
+use api_models::{enums, routing as routing_types, routing::RoutingRetrieveQuery};
 use router_env::{
     tracing::{self, instrument},
     Flow,
@@ -33,7 +30,7 @@ pub async fn routing_create_config(
         &req,
         json_payload.into_inner(),
         |state, auth: auth::AuthenticationData, payload, _| {
-            routing::create_routing_config(
+            routing::create_routing_algorithm_under_profile(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -115,7 +112,7 @@ pub async fn routing_link_config(
         &req,
         wrapper,
         |state, auth: auth::AuthenticationData, wrapper, _| {
-            routing::link_routing_config(
+            routing::link_routing_config_under_profile(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -152,7 +149,7 @@ pub async fn routing_retrieve_config(
         &req,
         algorithm_id,
         |state, auth: auth::AuthenticationData, algorithm_id, _| {
-            routing::retrieve_routing_config(
+            routing::retrieve_active_routing_config(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -222,7 +219,7 @@ pub async fn routing_unlink_config(
         &req,
         path.into_inner(),
         |state, auth: auth::AuthenticationData, path, _| {
-            routing::unlink_routing_config(
+            routing::unlink_routing_config_under_profile(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -535,12 +532,16 @@ pub async fn retrieve_decision_manager_config(
     .await
 }
 
-#[cfg(feature = "olap")]
+#[cfg(all(
+    feature = "olap",
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "routing_v2", feature = "business_profile_v2"))
+))]
 #[instrument(skip_all)]
 pub async fn routing_retrieve_linked_config(
     state: web::Data<AppState>,
     req: HttpRequest,
-    query: web::Query<RoutingRetrieveLinkQuery>,
+    query: web::Query<routing_types::RoutingRetrieveLinkQuery>,
     transaction_type: &enums::TransactionType,
 ) -> impl Responder {
     use crate::services::authentication::AuthenticationData;
@@ -572,6 +573,54 @@ pub async fn routing_retrieve_linked_config(
     .await
 }
 
+#[cfg(all(
+    feature = "olap",
+    feature = "v2",
+    feature = "routing_v2",
+    feature = "business_profile_v2"
+))]
+#[instrument(skip_all)]
+pub async fn routing_retrieve_linked_config(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    query: web::Query<RoutingRetrieveQuery>,
+    path: web::Path<String>,
+    transaction_type: &enums::TransactionType,
+) -> impl Responder {
+    use crate::services::authentication::AuthenticationData;
+    let flow = Flow::RoutingRetrieveActiveConfig;
+    let wrapper = routing_types::RoutingRetrieveLinkQueryWrapper {
+        routing_query: query.into_inner(),
+        profile_id: path.into_inner(),
+    };
+    Box::pin(oss_api::server_wrap(
+        flow,
+        state,
+        &req,
+        wrapper,
+        |state, auth: AuthenticationData, wrapper, _| {
+            routing::retrieve_routing_config_under_profile(
+                state,
+                auth.merchant_account,
+                auth.key_store,
+                wrapper.routing_query,
+                wrapper.profile_id,
+                transaction_type,
+            )
+        },
+        #[cfg(not(feature = "release"))]
+        auth::auth_type(
+            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::JWTAuth(Permission::RoutingRead),
+            req.headers(),
+        ),
+        #[cfg(feature = "release")]
+        &auth::JWTAuth(Permission::RoutingRead),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
 #[cfg(feature = "olap")]
 #[instrument(skip_all)]
 pub async fn routing_retrieve_default_config_for_profiles(
diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs
index 1217ae66bd7..56a6c4ec2b2 100644
--- a/crates/router/src/types/api/admin.rs
+++ b/crates/router/src/types/api/admin.rs
@@ -109,7 +109,10 @@ impl ForeignTryFrom<domain::MerchantAccount> for MerchantAccountResponse {
         })
     }
 }
-
+#[cfg(all(
+    any(feature = "v1", feature = "v2"),
+    not(any(feature = "business_profile_v2", feature = "merchant_account_v2",))
+))]
 impl ForeignTryFrom<domain::BusinessProfile> for BusinessProfileResponse {
     type Error = error_stack::Report<errors::ParsingError>;
 
@@ -163,7 +166,71 @@ impl ForeignTryFrom<domain::BusinessProfile> for BusinessProfileResponse {
     }
 }
 
-#[cfg(all(feature = "v2", feature = "merchant_account_v2"))]
+#[cfg(all(
+    feature = "v2",
+    feature = "merchant_account_v2",
+    feature = "business_profile_v2"
+))]
+impl ForeignTryFrom<domain::BusinessProfile> for BusinessProfileResponse {
+    type Error = error_stack::Report<errors::ParsingError>;
+
+    fn foreign_try_from(item: domain::BusinessProfile) -> Result<Self, Self::Error> {
+        let outgoing_webhook_custom_http_headers = item
+            .outgoing_webhook_custom_http_headers
+            .map(|headers| {
+                headers
+                    .into_inner()
+                    .expose()
+                    .parse_value::<HashMap<String, Secret<String>>>(
+                        "HashMap<String, Secret<String>>",
+                    )
+            })
+            .transpose()?;
+
+        Ok(Self {
+            merchant_id: item.merchant_id,
+            profile_id: item.profile_id,
+            profile_name: item.profile_name,
+            return_url: item.return_url,
+            enable_payment_response_hash: item.enable_payment_response_hash,
+            payment_response_hash_key: item.payment_response_hash_key,
+            redirect_to_merchant_with_http_post: item.redirect_to_merchant_with_http_post,
+            webhook_details: item.webhook_details.map(ForeignInto::foreign_into),
+            metadata: item.metadata,
+            // TODO: Remove routing algorithm from api models of business profile
+            routing_algorithm: todo!(),
+            intent_fulfillment_time: item.intent_fulfillment_time,
+            // TODO: Remove frm algorithm from api models of business profile
+            frm_routing_algorithm: todo!(),
+            #[cfg(feature = "payouts")]
+            // TODO: Remove payout algorithm from api models of business profile
+            payout_routing_algorithm: todo!(),
+            applepay_verified_domains: item.applepay_verified_domains,
+            payment_link_config: item.payment_link_config.map(ForeignInto::foreign_into),
+            session_expiry: item.session_expiry,
+            authentication_connector_details: item
+                .authentication_connector_details
+                .map(ForeignInto::foreign_into),
+            payout_link_config: item.payout_link_config.map(ForeignInto::foreign_into),
+            use_billing_as_payment_method_billing: item.use_billing_as_payment_method_billing,
+            extended_card_info_config: item
+                .extended_card_info_config
+                .map(|config| config.expose().parse_value("ExtendedCardInfoConfig"))
+                .transpose()?,
+            collect_shipping_details_from_wallet_connector: item
+                .collect_shipping_details_from_wallet_connector,
+            collect_billing_details_from_wallet_connector: item
+                .collect_billing_details_from_wallet_connector,
+            is_connector_agnostic_mit_enabled: item.is_connector_agnostic_mit_enabled,
+            outgoing_webhook_custom_http_headers,
+        })
+    }
+}
+#[cfg(all(
+    feature = "v2",
+    feature = "merchant_account_v2",
+    feature = "business_profile_v2"
+))]
 pub async fn create_business_profile(
     _state: &SessionState,
     _request: BusinessProfileCreate,
@@ -174,7 +241,7 @@ pub async fn create_business_profile(
 
 #[cfg(all(
     any(feature = "v1", feature = "v2"),
-    not(feature = "merchant_account_v2")
+    not(any(feature = "merchant_account_v2", feature = "business_profile_v2"))
 ))]
 pub async fn create_business_profile(
     state: &SessionState,
@@ -241,10 +308,7 @@ pub async fn create_business_profile(
             .unwrap_or(merchant_account.redirect_to_merchant_with_http_post),
         webhook_details: webhook_details.or(merchant_account.webhook_details),
         metadata: request.metadata,
-        routing_algorithm: Some(serde_json::json!({
-            "algorithm_id": null,
-            "timestamp": 0
-        })),
+        routing_algorithm: None,
         intent_fulfillment_time: request
             .intent_fulfillment_time
             .map(i64::from)
diff --git a/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/down.sql b/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/down.sql
index 5645d4c7399..3d35becdfab 100644
--- a/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/down.sql
+++ b/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/down.sql
@@ -3,16 +3,16 @@
 -- stored in these columns.
 ALTER TABLE business_profile
     ADD COLUMN routing_algorithm JSON DEFAULT NULL,
-    ADD COLUMN intent_fulfillment_time BIGINT DEFAULT NULL,
+    -- ADD COLUMN intent_fulfillment_time BIGINT DEFAULT NULL,
     ADD COLUMN frm_routing_algorithm JSONB DEFAULT NULL,
-    ADD COLUMN payout_routing_algorithm JSONB DEFAULT NULL;
+     ADD COLUMN payout_routing_algorithm JSONB DEFAULT NULL;
 
 ALTER TABLE business_profile
     DROP COLUMN routing_algorithm_id,
-    DROP COLUMN order_fulfillment_time,
-    DROP COLUMN order_fulfillment_time_origin,
+    -- DROP COLUMN order_fulfillment_time,
+    -- DROP COLUMN order_fulfillment_time_origin,
     DROP COLUMN frm_routing_algorithm_id,
-    DROP COLUMN payout_routing_algorithm_id,
-    DROP COLUMN default_fallback_routing;
+    DROP COLUMN payout_routing_algorithm_id;
+    -- DROP COLUMN default_fallback_routing;
 
-DROP TYPE "OrderFulfillmentTimeOrigin";
+-- DROP TYPE "OrderFulfillmentTimeOrigin";
diff --git a/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/up.sql b/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/up.sql
index f1cff174468..2b98bef00d4 100644
--- a/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/up.sql
+++ b/v2_migrations/2024-07-31-100300_business_profile_add_v2_columns_drop_v1_columns/up.sql
@@ -1,17 +1,17 @@
-CREATE TYPE "OrderFulfillmentTimeOrigin" AS ENUM ('create', 'confirm');
+-- CREATE TYPE "OrderFulfillmentTimeOrigin" AS ENUM ('create', 'confirm');
 
 ALTER TABLE business_profile
     ADD COLUMN routing_algorithm_id VARCHAR(64) DEFAULT NULL,
-    ADD COLUMN order_fulfillment_time BIGINT DEFAULT NULL,
-    ADD COLUMN order_fulfillment_time_origin "OrderFulfillmentTimeOrigin" DEFAULT NULL,
-    ADD COLUMN frm_routing_algorithm_id VARCHAR(64) DEFAULT NULL,
-    ADD COLUMN payout_routing_algorithm_id VARCHAR(64) DEFAULT NULL,
-    ADD COLUMN default_fallback_routing JSONB DEFAULT NULL;
+    -- ADD COLUMN order_fulfillment_time BIGINT DEFAULT NULL,
+    -- ADD COLUMN order_fulfillment_time_origin "OrderFulfillmentTimeOrigin" DEFAULT NULL,
+     ADD COLUMN frm_routing_algorithm_id VARCHAR(64) DEFAULT NULL,
+     ADD COLUMN payout_routing_algorithm_id VARCHAR(64) DEFAULT NULL;
+    -- ADD COLUMN default_fallback_routing JSONB DEFAULT NULL;
 
 -- Note: This query should not be run on higher environments as this leads to data loss.
 -- The application will work fine even without these queries being run.
 ALTER TABLE business_profile
     DROP COLUMN routing_algorithm,
-    DROP COLUMN intent_fulfillment_time,
-    DROP COLUMN frm_routing_algorithm,
-    DROP COLUMN payout_routing_algorithm;
+    -- DROP COLUMN intent_fulfillment_time,
+     DROP COLUMN frm_routing_algorithm,
+     DROP COLUMN payout_routing_algorithm;

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

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

## Description
In this PR we adapt the usage of routing_algorithm_id as well as payout_routing_algorithm_id in routing and payments core for v2. Also refactored the routing_algorithm list, to list all the algorithms(history) on the basis of a single  profile.

### 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?
 
 - List all the routing rules for under a profile 
```
curl --location 'http://localhost:8080/v2/profile/pro_VirB3AxB3qItFTnLsuA2/routing_algorithm' \
--header 'api-key: dev_jsssWAg0XyxGK0ycPunkFjlItYNs30X1IVOr1MIF7lwrDQgBBk7npwdkZB4t7EQd'
```
## 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
