Bug: Creation of Toggle and Configs for DynamicRouting & DynamicRoutingMetrics



### Toggle for Dynamic Routing:

There should be a 2 way toggle of the switch:
1. For Success-Based routing(whole integration in core that will affect payments).
2. For only enabling metrics of Success-Based routing (This can be used in future to show users the metrics first and then accordingly the core integration can be enabled).


-> Route 1: Something like GET `/routing/dynamic_routing/enable` or `/routing/dynamic_routing_metrics/enable`.

-> Once Toggled a default config should be created and stored in Routing table to be sent to Dynamo. 
-> Add a Boolean value in BusinessProfile table `is_dynamic_routing_enabled`.
-> The code should be under feature flag.

-> Route 2: Update Route (UPDATE `/routing/dynamic_routing/config`) to update the config for users with AdminApiKey auth.
diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json
index 3c2c811766b..8e6e58865fc 100644
--- a/api-reference-v2/openapi_spec.json
+++ b/api-reference-v2/openapi_spec.json
@@ -17247,7 +17247,8 @@
           "single",
           "priority",
           "volume_split",
-          "advanced"
+          "advanced",
+          "dynamic"
         ]
       },
       "RoutingConfigRequest": {
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index 2b185d202e1..be3e26b2639 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -2356,6 +2356,10 @@ pub struct BusinessProfileUpdate {
     /// Indicates if tax_calculator connector is enabled or not.
     /// If set to `true` tax_connector_id will be checked.
     pub is_tax_connector_enabled: Option<bool>,
+
+    /// Indicates if dynamic routing is enabled or not.
+    #[serde(default)]
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 #[cfg(feature = "v2")]
diff --git a/crates/api_models/src/events/routing.rs b/crates/api_models/src/events/routing.rs
index 9cfcafc8733..ffa5e008f0a 100644
--- a/crates/api_models/src/events/routing.rs
+++ b/crates/api_models/src/events/routing.rs
@@ -4,7 +4,9 @@ use crate::routing::{
     LinkedRoutingConfigRetrieveResponse, MerchantRoutingAlgorithm, ProfileDefaultRoutingConfig,
     RoutingAlgorithmId, RoutingConfigRequest, RoutingDictionaryRecord, RoutingKind,
     RoutingLinkWrapper, RoutingPayloadWrapper, RoutingRetrieveLinkQuery,
-    RoutingRetrieveLinkQueryWrapper, RoutingRetrieveQuery,
+    RoutingRetrieveLinkQueryWrapper, RoutingRetrieveQuery, SuccessBasedRoutingConfig,
+    SuccessBasedRoutingPayloadWrapper, SuccessBasedRoutingUpdateConfigQuery,
+    ToggleSuccessBasedRoutingQuery, ToggleSuccessBasedRoutingWrapper,
 };
 
 impl ApiEventMetric for RoutingKind {
@@ -76,3 +78,33 @@ impl ApiEventMetric for RoutingRetrieveLinkQueryWrapper {
         Some(ApiEventsType::Routing)
     }
 }
+
+impl ApiEventMetric for ToggleSuccessBasedRoutingQuery {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Routing)
+    }
+}
+
+impl ApiEventMetric for SuccessBasedRoutingConfig {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Routing)
+    }
+}
+
+impl ApiEventMetric for SuccessBasedRoutingPayloadWrapper {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Routing)
+    }
+}
+
+impl ApiEventMetric for ToggleSuccessBasedRoutingWrapper {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Routing)
+    }
+}
+
+impl ApiEventMetric for SuccessBasedRoutingUpdateConfigQuery {
+    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 bec917b06c8..5023d30f722 100644
--- a/crates/api_models/src/routing.rs
+++ b/crates/api_models/src/routing.rs
@@ -260,6 +260,7 @@ pub enum RoutingAlgorithmKind {
     Priority,
     VolumeSplit,
     Advanced,
+    Dynamic,
 }
 
 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -495,3 +496,138 @@ pub struct RoutingLinkWrapper {
     pub profile_id: common_utils::id_type::ProfileId,
     pub algorithm_id: RoutingAlgorithmId,
 }
+
+#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
+pub struct DynamicAlgorithmWithTimestamp<T> {
+    pub algorithm_id: Option<T>,
+    pub timestamp: i64,
+}
+
+#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
+pub struct DynamicRoutingAlgorithmRef {
+    pub success_based_algorithm:
+        Option<DynamicAlgorithmWithTimestamp<common_utils::id_type::RoutingId>>,
+}
+
+impl DynamicRoutingAlgorithmRef {
+    pub fn update_algorithm_id(&mut self, new_id: common_utils::id_type::RoutingId) {
+        self.success_based_algorithm = Some(DynamicAlgorithmWithTimestamp {
+            algorithm_id: Some(new_id),
+            timestamp: common_utils::date_time::now_unix_timestamp(),
+        })
+    }
+}
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
+pub struct ToggleSuccessBasedRoutingQuery {
+    pub status: bool,
+}
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
+pub struct SuccessBasedRoutingUpdateConfigQuery {
+    #[schema(value_type = String)]
+    pub algorithm_id: common_utils::id_type::RoutingId,
+    #[schema(value_type = String)]
+    pub profile_id: common_utils::id_type::ProfileId,
+}
+
+#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
+pub struct ToggleSuccessBasedRoutingWrapper {
+    pub profile_id: common_utils::id_type::ProfileId,
+    pub status: bool,
+}
+
+#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
+pub struct ToggleSuccessBasedRoutingPath {
+    #[schema(value_type = String)]
+    pub profile_id: common_utils::id_type::ProfileId,
+}
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
+pub struct SuccessBasedRoutingConfig {
+    pub params: Option<Vec<SuccessBasedRoutingConfigParams>>,
+    pub config: Option<SuccessBasedRoutingConfigBody>,
+}
+
+impl Default for SuccessBasedRoutingConfig {
+    fn default() -> Self {
+        Self {
+            params: Some(vec![SuccessBasedRoutingConfigParams::PaymentMethod]),
+            config: Some(SuccessBasedRoutingConfigBody {
+                min_aggregates_size: Some(2),
+                default_success_rate: Some(100.0),
+                max_aggregates_size: Some(3),
+                current_block_threshold: Some(CurrentBlockThreshold {
+                    duration_in_mins: Some(5),
+                    max_total_count: Some(2),
+                }),
+            }),
+        }
+    }
+}
+
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
+pub enum SuccessBasedRoutingConfigParams {
+    PaymentMethod,
+    PaymentMethodType,
+    Currency,
+    AuthenticationType,
+}
+
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
+pub struct SuccessBasedRoutingConfigBody {
+    pub min_aggregates_size: Option<u32>,
+    pub default_success_rate: Option<f64>,
+    pub max_aggregates_size: Option<u32>,
+    pub current_block_threshold: Option<CurrentBlockThreshold>,
+}
+
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
+pub struct CurrentBlockThreshold {
+    pub duration_in_mins: Option<u64>,
+    pub max_total_count: Option<u64>,
+}
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+pub struct SuccessBasedRoutingPayloadWrapper {
+    pub updated_config: SuccessBasedRoutingConfig,
+    pub algorithm_id: common_utils::id_type::RoutingId,
+    pub profile_id: common_utils::id_type::ProfileId,
+}
+
+impl SuccessBasedRoutingConfig {
+    pub fn update(&mut self, new: Self) {
+        if let Some(params) = new.params {
+            self.params = Some(params)
+        }
+        if let Some(new_config) = new.config {
+            self.config.as_mut().map(|config| config.update(new_config));
+        }
+    }
+}
+
+impl SuccessBasedRoutingConfigBody {
+    pub fn update(&mut self, new: Self) {
+        if let Some(min_aggregates_size) = new.min_aggregates_size {
+            self.min_aggregates_size = Some(min_aggregates_size)
+        }
+        if let Some(default_success_rate) = new.default_success_rate {
+            self.default_success_rate = Some(default_success_rate)
+        }
+        if let Some(max_aggregates_size) = new.max_aggregates_size {
+            self.max_aggregates_size = Some(max_aggregates_size)
+        }
+        if let Some(current_block_threshold) = new.current_block_threshold {
+            self.current_block_threshold
+                .as_mut()
+                .map(|threshold| threshold.update(current_block_threshold));
+        }
+    }
+}
+
+impl CurrentBlockThreshold {
+    pub fn update(&mut self, new: Self) {
+        if let Some(max_total_count) = new.max_total_count {
+            self.max_total_count = Some(max_total_count)
+        }
+    }
+}
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index 029add42ced..a72263b96a8 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -53,6 +53,7 @@ pub struct BusinessProfile {
     pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
     pub is_tax_connector_enabled: Option<bool>,
     pub version: common_enums::ApiVersion,
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 #[cfg(feature = "v1")]
@@ -129,6 +130,7 @@ pub struct BusinessProfileUpdateInternal {
     pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
     pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
     pub is_tax_connector_enabled: Option<bool>,
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 #[cfg(feature = "v1")]
@@ -164,6 +166,7 @@ impl BusinessProfileUpdateInternal {
             always_collect_shipping_details_from_wallet_connector,
             tax_connector_id,
             is_tax_connector_enabled,
+            dynamic_routing_algorithm,
         } = self;
         BusinessProfile {
             profile_id: source.profile_id,
@@ -217,6 +220,8 @@ impl BusinessProfileUpdateInternal {
             tax_connector_id: tax_connector_id.or(source.tax_connector_id),
             is_tax_connector_enabled: is_tax_connector_enabled.or(source.is_tax_connector_enabled),
             version: source.version,
+            dynamic_routing_algorithm: dynamic_routing_algorithm
+                .or(source.dynamic_routing_algorithm),
         }
     }
 }
@@ -266,6 +271,7 @@ pub struct BusinessProfile {
     pub default_fallback_routing: Option<pii::SecretSerdeValue>,
     pub id: common_utils::id_type::ProfileId,
     pub version: common_enums::ApiVersion,
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 impl BusinessProfile {
@@ -452,6 +458,7 @@ impl BusinessProfileUpdateInternal {
                 .or(source.payout_routing_algorithm_id),
             default_fallback_routing: default_fallback_routing.or(source.default_fallback_routing),
             version: source.version,
+            dynamic_routing_algorithm: None,
         }
     }
 }
@@ -502,6 +509,7 @@ impl From<BusinessProfileNew> for BusinessProfile {
             payout_routing_algorithm_id: new.payout_routing_algorithm_id,
             default_fallback_routing: new.default_fallback_routing,
             version: new.version,
+            dynamic_routing_algorithm: None,
         }
     }
 }
diff --git a/crates/diesel_models/src/enums.rs b/crates/diesel_models/src/enums.rs
index 8f9469c0288..68809d8d2fa 100644
--- a/crates/diesel_models/src/enums.rs
+++ b/crates/diesel_models/src/enums.rs
@@ -50,6 +50,7 @@ pub enum RoutingAlgorithmKind {
     Priority,
     VolumeSplit,
     Advanced,
+    Dynamic,
 }
 
 #[derive(
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 8e6c72eb5ba..1487616f458 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -209,6 +209,7 @@ diesel::table! {
         tax_connector_id -> Nullable<Varchar>,
         is_tax_connector_enabled -> Nullable<Bool>,
         version -> ApiVersion,
+        dynamic_routing_algorithm -> Nullable<Json>,
     }
 }
 
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index 2deaa3d4ee4..818e7ecf01e 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -216,6 +216,7 @@ diesel::table! {
         #[max_length = 64]
         id -> Varchar,
         version -> ApiVersion,
+        dynamic_routing_algorithm -> Nullable<Json>,
     }
 }
 
diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs
index c6b76680d48..b13d79175c2 100644
--- a/crates/hyperswitch_domain_models/src/business_profile.rs
+++ b/crates/hyperswitch_domain_models/src/business_profile.rs
@@ -54,6 +54,7 @@ pub struct BusinessProfile {
     pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
     pub is_tax_connector_enabled: bool,
     pub version: common_enums::ApiVersion,
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 #[cfg(feature = "v1")]
@@ -90,6 +91,7 @@ pub struct BusinessProfileSetter {
     pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
     pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
     pub is_tax_connector_enabled: bool,
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 #[cfg(feature = "v1")]
@@ -133,6 +135,7 @@ impl From<BusinessProfileSetter> for BusinessProfile {
             tax_connector_id: value.tax_connector_id,
             is_tax_connector_enabled: value.is_tax_connector_enabled,
             version: consts::API_VERSION,
+            dynamic_routing_algorithm: value.dynamic_routing_algorithm,
         }
     }
 }
@@ -178,6 +181,7 @@ pub struct BusinessProfileGeneralUpdate {
     pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
     pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
     pub is_tax_connector_enabled: Option<bool>,
+    pub dynamic_routing_algorithm: Option<serde_json::Value>,
 }
 
 #[cfg(feature = "v1")]
@@ -188,6 +192,9 @@ pub enum BusinessProfileUpdate {
         routing_algorithm: Option<serde_json::Value>,
         payout_routing_algorithm: Option<serde_json::Value>,
     },
+    DynamicRoutingAlgorithmUpdate {
+        dynamic_routing_algorithm: Option<serde_json::Value>,
+    },
     ExtendedCardInfoUpdate {
         is_extended_card_info_enabled: Option<bool>,
     },
@@ -230,6 +237,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                     always_collect_shipping_details_from_wallet_connector,
                     tax_connector_id,
                     is_tax_connector_enabled,
+                    dynamic_routing_algorithm,
                 } = *update;
 
                 Self {
@@ -263,6 +271,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                     always_collect_shipping_details_from_wallet_connector,
                     tax_connector_id,
                     is_tax_connector_enabled,
+                    dynamic_routing_algorithm,
                 }
             }
             BusinessProfileUpdate::RoutingAlgorithmUpdate {
@@ -298,6 +307,41 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 always_collect_shipping_details_from_wallet_connector: None,
                 tax_connector_id: None,
                 is_tax_connector_enabled: None,
+                dynamic_routing_algorithm: None,
+            },
+            BusinessProfileUpdate::DynamicRoutingAlgorithmUpdate {
+                dynamic_routing_algorithm,
+            } => Self {
+                profile_name: None,
+                modified_at: now,
+                return_url: None,
+                enable_payment_response_hash: None,
+                payment_response_hash_key: None,
+                redirect_to_merchant_with_http_post: None,
+                webhook_details: None,
+                metadata: None,
+                routing_algorithm: None,
+                intent_fulfillment_time: None,
+                frm_routing_algorithm: None,
+                payout_routing_algorithm: None,
+                is_recon_enabled: None,
+                applepay_verified_domains: None,
+                payment_link_config: None,
+                session_expiry: None,
+                authentication_connector_details: None,
+                payout_link_config: None,
+                is_extended_card_info_enabled: None,
+                extended_card_info_config: None,
+                is_connector_agnostic_mit_enabled: None,
+                use_billing_as_payment_method_billing: None,
+                collect_shipping_details_from_wallet_connector: None,
+                collect_billing_details_from_wallet_connector: None,
+                outgoing_webhook_custom_http_headers: None,
+                always_collect_billing_details_from_wallet_connector: None,
+                always_collect_shipping_details_from_wallet_connector: None,
+                tax_connector_id: None,
+                is_tax_connector_enabled: None,
+                dynamic_routing_algorithm,
             },
             BusinessProfileUpdate::ExtendedCardInfoUpdate {
                 is_extended_card_info_enabled,
@@ -331,6 +375,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 always_collect_shipping_details_from_wallet_connector: None,
                 tax_connector_id: None,
                 is_tax_connector_enabled: None,
+                dynamic_routing_algorithm: None,
             },
             BusinessProfileUpdate::ConnectorAgnosticMitUpdate {
                 is_connector_agnostic_mit_enabled,
@@ -364,6 +409,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 always_collect_shipping_details_from_wallet_connector: None,
                 tax_connector_id: None,
                 is_tax_connector_enabled: None,
+                dynamic_routing_algorithm: None,
             },
         }
     }
@@ -416,6 +462,7 @@ impl super::behaviour::Conversion for BusinessProfile {
             tax_connector_id: self.tax_connector_id,
             is_tax_connector_enabled: Some(self.is_tax_connector_enabled),
             version: self.version,
+            dynamic_routing_algorithm: self.dynamic_routing_algorithm,
         })
     }
 
@@ -480,6 +527,7 @@ impl super::behaviour::Conversion for BusinessProfile {
                 tax_connector_id: item.tax_connector_id,
                 is_tax_connector_enabled: item.is_tax_connector_enabled.unwrap_or(false),
                 version: item.version,
+                dynamic_routing_algorithm: item.dynamic_routing_algorithm,
             })
         }
         .await
@@ -984,6 +1032,7 @@ impl super::behaviour::Conversion for BusinessProfile {
             tax_connector_id: self.tax_connector_id,
             is_tax_connector_enabled: Some(self.is_tax_connector_enabled),
             version: self.version,
+            dynamic_routing_algorithm: None,
         })
     }
 
diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs
index 2926f47af9e..6c911fc9bbe 100644
--- a/crates/openapi/src/openapi.rs
+++ b/crates/openapi/src/openapi.rs
@@ -158,6 +158,8 @@ Never share your secret api keys. Keep them guarded and secure.
         routes::routing::routing_retrieve_linked_config,
         routes::routing::routing_retrieve_default_config_for_profiles,
         routes::routing::routing_update_default_config_for_profile,
+        routes::routing::toggle_success_based_routing,
+        routes::routing::success_based_routing_update_configs,
 
         // Routes for blocklist
         routes::blocklist::remove_entry_from_blocklist,
@@ -543,6 +545,13 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::routing::StraightThroughAlgorithm,
         api_models::routing::ConnectorVolumeSplit,
         api_models::routing::ConnectorSelection,
+        api_models::routing::ToggleSuccessBasedRoutingQuery,
+        api_models::routing::SuccessBasedRoutingConfig,
+        api_models::routing::SuccessBasedRoutingConfigParams,
+        api_models::routing::SuccessBasedRoutingConfigBody,
+        api_models::routing::CurrentBlockThreshold,
+        api_models::routing::SuccessBasedRoutingUpdateConfigQuery,
+        api_models::routing::ToggleSuccessBasedRoutingPath,
         api_models::routing::ast::RoutableChoiceKind,
         api_models::enums::RoutableConnectors,
         api_models::routing::ast::ProgramConnectorSelection,
diff --git a/crates/openapi/src/routes/routing.rs b/crates/openapi/src/routes/routing.rs
index 5e1e3f60c62..009708d860d 100644
--- a/crates/openapi/src/routes/routing.rs
+++ b/crates/openapi/src/routes/routing.rs
@@ -255,3 +255,56 @@ pub async fn routing_retrieve_default_config_for_profiles() {}
    security(("api_key" = []), ("jwt_key" = []))
 )]
 pub async fn routing_update_default_config_for_profile() {}
+
+#[cfg(feature = "v1")]
+/// Routing - Toggle success based dynamic routing for profile
+///
+/// Create a success based dynamic routing algorithm
+#[utoipa::path(
+    post,
+    path = "/account/:account_id/business_profile/:profile_id/dynamic_routing/success_based/toggle",
+    params(
+        ("account_id" = String, Path, description = "Merchant id"),
+        ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"),
+        ("status" = bool, Query, description = "Boolean value for mentioning the expected state of dynamic routing"),
+    ),
+    responses(
+        (status = 200, description = "Routing Algorithm created", body = RoutingDictionaryRecord),
+        (status = 400, description = "Request body is malformed"),
+        (status = 500, description = "Internal server error"),
+        (status = 404, description = "Resource missing"),
+        (status = 422, description = "Unprocessable request"),
+        (status = 403, description = "Forbidden"),
+    ),
+   tag = "Routing",
+   operation_id = "Toggle success based dynamic routing algprithm",
+   security(("api_key" = []), ("jwt_key" = []))
+)]
+pub async fn toggle_success_based_routing() {}
+
+#[cfg(feature = "v1")]
+/// Routing - Update config for success based dynamic routing
+///
+/// Update config for success based dynamic routing
+#[utoipa::path(
+    patch,
+    path = "/account/:account_id/business_profile/:profile_id/dynamic_routing/success_based/config/:algorithm_id",
+    request_body = SuccessBasedRoutingConfig,
+    params(
+        ("account_id" = String, Path, description = "Merchant id"),
+        ("profile_id" = String, Path, description = "The unique identifier for a profile"),
+        ("algorithm_id" = String, Path, description = "The unique identifier for routing algorithm"),
+    ),
+    responses(
+        (status = 200, description = "Routing Algorithm updated", body = RoutingDictionaryRecord),
+        (status = 400, description = "Request body is malformed"),
+        (status = 500, description = "Internal server error"),
+        (status = 404, description = "Resource missing"),
+        (status = 422, description = "Unprocessable request"),
+        (status = 403, description = "Forbidden"),
+    ),
+   tag = "Routing",
+   operation_id = "Update configs for success based dynamic routing algorithm",
+   security(("admin_api_key" = []))
+)]
+pub async fn success_based_routing_update_configs() {}
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index c0cb446b38f..eb357d80ad1 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -3471,6 +3471,7 @@ impl BusinessProfileCreateBridge for api::BusinessProfileCreate {
                     .always_collect_billing_details_from_wallet_connector,
                 always_collect_shipping_details_from_wallet_connector: self
                     .always_collect_shipping_details_from_wallet_connector,
+                dynamic_routing_algorithm: None,
             },
         ))
     }
@@ -3818,6 +3819,7 @@ impl BusinessProfileUpdateBridge for api::BusinessProfileUpdate {
                     .always_collect_shipping_details_from_wallet_connector,
                 tax_connector_id: self.tax_connector_id,
                 is_tax_connector_enabled: self.is_tax_connector_enabled,
+                dynamic_routing_algorithm: self.dynamic_routing_algorithm,
             },
         )))
     }
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index df2f8746e11..35cc811af65 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -922,12 +922,12 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest, PaymentData<F>> for Paymen
             Some(helpers::PaymentExternalAuthenticationFlow::PostAuthenticationFlow {
                 authentication_id,
             }) => {
-                let authentication = authentication::perform_post_authentication(
+                let authentication = Box::pin(authentication::perform_post_authentication(
                     state,
                     key_store,
                     business_profile.clone(),
                     authentication_id.clone(),
-                )
+                ))
                 .await?;
                 //If authentication is not successful, skip the payment connector flows and mark the payment as failure
                 if authentication.authentication_status
diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs
index fd58a2c571a..2ce75065673 100644
--- a/crates/router/src/core/routing.rs
+++ b/crates/router/src/core/routing.rs
@@ -2,12 +2,13 @@ pub mod helpers;
 pub mod transformers;
 
 use api_models::{
-    enums, mandates as mandates_api,
+    enums, mandates as mandates_api, routing,
     routing::{self as routing_types, RoutingRetrieveQuery},
 };
 use diesel_models::routing_algorithm::RoutingAlgorithm;
 use error_stack::ResultExt;
 use hyperswitch_domain_models::{mandates, payment_address};
+use router_env::metrics::add_attributes;
 use rustc_hash::FxHashSet;
 
 #[cfg(feature = "payouts")]
@@ -411,42 +412,89 @@ pub async fn link_routing_config(
 
     core_utils::validate_profile_id_from_auth_layer(authentication_profile_id, &business_profile)?;
 
-    let mut routing_ref: routing_types::RoutingAlgorithmRef = business_profile
-        .routing_algorithm
-        .clone()
-        .map(|val| val.parse_value("RoutingAlgorithmRef"))
-        .transpose()
-        .change_context(errors::ApiErrorResponse::InternalServerError)
-        .attach_printable("unable to deserialize routing algorithm ref from merchant account")?
-        .unwrap_or_default();
-
-    utils::when(routing_algorithm.algorithm_for != *transaction_type, || {
-        Err(errors::ApiErrorResponse::PreconditionFailed {
-            message: format!(
-                "Cannot use {}'s routing algorithm for {} operation",
-                routing_algorithm.algorithm_for, transaction_type
-            ),
-        })
-    })?;
+    match routing_algorithm.kind {
+        diesel_models::enums::RoutingAlgorithmKind::Dynamic => {
+            let mut dynamic_routing_ref: routing_types::DynamicRoutingAlgorithmRef =
+                business_profile
+                    .dynamic_routing_algorithm
+                    .clone()
+                    .map(|val| val.parse_value("DynamicRoutingAlgorithmRef"))
+                    .transpose()
+                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .attach_printable(
+                        "unable to deserialize Dynamic routing algorithm ref from business profile",
+                    )?
+                    .unwrap_or_default();
+
+            utils::when(
+                matches!(
+                    dynamic_routing_ref.success_based_algorithm,
+                    Some(routing_types::DynamicAlgorithmWithTimestamp {
+                        algorithm_id: Some(ref id),
+                        timestamp: _
+                    }) if id == &algorithm_id
+                ),
+                || {
+                    Err(errors::ApiErrorResponse::PreconditionFailed {
+                        message: "Algorithm is already active".to_string(),
+                    })
+                },
+            )?;
 
-    utils::when(
-        routing_ref.algorithm_id == Some(algorithm_id.clone()),
-        || {
-            Err(errors::ApiErrorResponse::PreconditionFailed {
-                message: "Algorithm is already active".to_string(),
-            })
-        },
-    )?;
-    routing_ref.update_algorithm_id(algorithm_id);
-    helpers::update_business_profile_active_algorithm_ref(
-        db,
-        key_manager_state,
-        &key_store,
-        business_profile,
-        routing_ref,
-        transaction_type,
-    )
-    .await?;
+            dynamic_routing_ref.update_algorithm_id(algorithm_id);
+            helpers::update_business_profile_active_dynamic_algorithm_ref(
+                db,
+                key_manager_state,
+                &key_store,
+                business_profile,
+                dynamic_routing_ref,
+            )
+            .await?;
+        }
+        diesel_models::enums::RoutingAlgorithmKind::Single
+        | diesel_models::enums::RoutingAlgorithmKind::Priority
+        | diesel_models::enums::RoutingAlgorithmKind::Advanced
+        | diesel_models::enums::RoutingAlgorithmKind::VolumeSplit => {
+            let mut routing_ref: routing_types::RoutingAlgorithmRef = business_profile
+                .routing_algorithm
+                .clone()
+                .map(|val| val.parse_value("RoutingAlgorithmRef"))
+                .transpose()
+                .change_context(errors::ApiErrorResponse::InternalServerError)
+                .attach_printable(
+                    "unable to deserialize routing algorithm ref from business profile",
+                )?
+                .unwrap_or_default();
+
+            utils::when(routing_algorithm.algorithm_for != *transaction_type, || {
+                Err(errors::ApiErrorResponse::PreconditionFailed {
+                    message: format!(
+                        "Cannot use {}'s routing algorithm for {} operation",
+                        routing_algorithm.algorithm_for, transaction_type
+                    ),
+                })
+            })?;
+
+            utils::when(
+                routing_ref.algorithm_id == Some(algorithm_id.clone()),
+                || {
+                    Err(errors::ApiErrorResponse::PreconditionFailed {
+                        message: "Algorithm is already active".to_string(),
+                    })
+                },
+            )?;
+            routing_ref.update_algorithm_id(algorithm_id);
+            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(
@@ -1111,3 +1159,192 @@ pub async fn update_default_routing_config_for_profile(
         },
     ))
 }
+
+#[cfg(feature = "v1")]
+pub async fn toggle_success_based_routing(
+    state: SessionState,
+    merchant_account: domain::MerchantAccount,
+    key_store: domain::MerchantKeyStore,
+    status: bool,
+    profile_id: common_utils::id_type::ProfileId,
+) -> RouterResponse<routing_types::RoutingDictionaryRecord> {
+    metrics::ROUTING_CREATE_REQUEST_RECEIVED.add(
+        &metrics::CONTEXT,
+        1,
+        &add_attributes([("profile_id", profile_id.get_string_repr().to_owned())]),
+    );
+    let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
+
+    let business_profile: domain::BusinessProfile = 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.get_string_repr().to_owned(),
+    })?;
+
+    let mut success_based_dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef =
+        business_profile
+            .dynamic_routing_algorithm
+            .clone()
+            .map(|val| val.parse_value("DynamicRoutingAlgorithmRef"))
+            .transpose()
+            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .attach_printable(
+                "unable to deserialize dynamic routing algorithm ref from business profile",
+            )?
+            .unwrap_or_default();
+
+    if status {
+        let default_success_based_routing_config = routing::SuccessBasedRoutingConfig::default();
+        let algorithm_id = common_utils::generate_routing_id_of_default_length();
+        let timestamp = common_utils::date_time::now();
+        let algo = RoutingAlgorithm {
+            algorithm_id: algorithm_id.clone(),
+            profile_id: business_profile.get_id().to_owned(),
+            merchant_id: merchant_account.get_id().to_owned(),
+            name: "Dynamic routing algorithm".to_string(),
+            description: None,
+            kind: diesel_models::enums::RoutingAlgorithmKind::Dynamic,
+            algorithm_data: serde_json::json!(default_success_based_routing_config),
+            created_at: timestamp,
+            modified_at: timestamp,
+            algorithm_for: common_enums::TransactionType::Payment,
+        };
+
+        let record = db
+            .insert_routing_algorithm(algo)
+            .await
+            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .attach_printable("Unable to insert record in routing algorithm table")?;
+
+        success_based_dynamic_routing_algo_ref.update_algorithm_id(algorithm_id);
+        helpers::update_business_profile_active_dynamic_algorithm_ref(
+            db,
+            key_manager_state,
+            &key_store,
+            business_profile,
+            success_based_dynamic_routing_algo_ref,
+        )
+        .await?;
+
+        let new_record = record.foreign_into();
+
+        metrics::ROUTING_CREATE_SUCCESS_RESPONSE.add(
+            &metrics::CONTEXT,
+            1,
+            &add_attributes([("profile_id", profile_id.get_string_repr().to_owned())]),
+        );
+        Ok(service_api::ApplicationResponse::Json(new_record))
+    } else {
+        let timestamp = common_utils::date_time::now_unix_timestamp();
+        match success_based_dynamic_routing_algo_ref.success_based_algorithm {
+            Some(algorithm_ref) => {
+                if let Some(algorithm_id) = algorithm_ref.algorithm_id {
+                    let dynamic_routing_algorithm = routing_types::DynamicRoutingAlgorithmRef {
+                        success_based_algorithm: Some(
+                            routing_types::DynamicAlgorithmWithTimestamp {
+                                algorithm_id: None,
+                                timestamp,
+                            },
+                        ),
+                    };
+
+                    let record = db
+                        .find_routing_algorithm_by_profile_id_algorithm_id(
+                            business_profile.get_id(),
+                            &algorithm_id,
+                        )
+                        .await
+                        .to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?;
+                    let response = record.foreign_into();
+                    helpers::update_business_profile_active_dynamic_algorithm_ref(
+                        db,
+                        key_manager_state,
+                        &key_store,
+                        business_profile,
+                        dynamic_routing_algorithm,
+                    )
+                    .await?;
+
+                    metrics::ROUTING_UNLINK_CONFIG_SUCCESS_RESPONSE.add(
+                        &metrics::CONTEXT,
+                        1,
+                        &add_attributes([("profile_id", profile_id.get_string_repr().to_owned())]),
+                    );
+
+                    Ok(service_api::ApplicationResponse::Json(response))
+                } else {
+                    Err(errors::ApiErrorResponse::PreconditionFailed {
+                        message: "Algorithm is already inactive".to_string(),
+                    })?
+                }
+            }
+            None => Err(errors::ApiErrorResponse::PreconditionFailed {
+                message: "Algorithm is already inactive".to_string(),
+            })?,
+        }
+    }
+}
+
+#[cfg(feature = "v1")]
+pub async fn success_based_routing_update_configs(
+    state: SessionState,
+    request: routing_types::SuccessBasedRoutingConfig,
+    algorithm_id: common_utils::id_type::RoutingId,
+    profile_id: common_utils::id_type::ProfileId,
+) -> RouterResponse<routing_types::RoutingDictionaryRecord> {
+    metrics::ROUTING_UPDATE_CONFIG_FOR_PROFILE.add(
+        &metrics::CONTEXT,
+        1,
+        &add_attributes([("profile_id", profile_id.get_string_repr().to_owned())]),
+    );
+    let db = state.store.as_ref();
+    let dynamic_routing_algo_to_update = db
+        .find_routing_algorithm_by_profile_id_algorithm_id(&profile_id, &algorithm_id)
+        .await
+        .to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?;
+
+    let mut config_to_update: routing::SuccessBasedRoutingConfig = dynamic_routing_algo_to_update
+        .algorithm_data
+        .parse_value::<routing::SuccessBasedRoutingConfig>("SuccessBasedRoutingConfig")
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("unable to deserialize algorithm data from routing table into SuccessBasedRoutingConfig")?;
+
+    config_to_update.update(request);
+
+    let algorithm_id = common_utils::generate_routing_id_of_default_length();
+    let timestamp = common_utils::date_time::now();
+    let algo = RoutingAlgorithm {
+        algorithm_id,
+        profile_id: dynamic_routing_algo_to_update.profile_id,
+        merchant_id: dynamic_routing_algo_to_update.merchant_id,
+        name: dynamic_routing_algo_to_update.name,
+        description: dynamic_routing_algo_to_update.description,
+        kind: dynamic_routing_algo_to_update.kind,
+        algorithm_data: serde_json::json!(config_to_update),
+        created_at: timestamp,
+        modified_at: timestamp,
+        algorithm_for: dynamic_routing_algo_to_update.algorithm_for,
+    };
+    let record = db
+        .insert_routing_algorithm(algo)
+        .await
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Unable to insert record in routing algorithm table")?;
+
+    let new_record = record.foreign_into();
+
+    metrics::ROUTING_UPDATE_CONFIG_FOR_PROFILE_SUCCESS_RESPONSE.add(
+        &metrics::CONTEXT,
+        1,
+        &add_attributes([("profile_id", profile_id.get_string_repr().to_owned())]),
+    );
+    Ok(service_api::ApplicationResponse::Json(new_record))
+}
diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs
index bd4107a48d0..f818dc05f5b 100644
--- a/crates/router/src/core/routing/helpers.rs
+++ b/crates/router/src/core/routing/helpers.rs
@@ -236,6 +236,33 @@ pub async fn update_business_profile_active_algorithm_ref(
     Ok(())
 }
 
+#[cfg(feature = "v1")]
+pub async fn update_business_profile_active_dynamic_algorithm_ref(
+    db: &dyn StorageInterface,
+    key_manager_state: &KeyManagerState,
+    merchant_key_store: &domain::MerchantKeyStore,
+    current_business_profile: domain::BusinessProfile,
+    dynamic_routing_algorithm: routing_types::DynamicRoutingAlgorithmRef,
+) -> RouterResult<()> {
+    let ref_val = dynamic_routing_algorithm
+        .encode_to_value()
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to convert dynamic routing ref to value")?;
+    let business_profile_update = domain::BusinessProfileUpdate::DynamicRoutingAlgorithmUpdate {
+        dynamic_routing_algorithm: Some(ref_val),
+    };
+    db.update_business_profile_by_profile_id(
+        key_manager_state,
+        merchant_key_store,
+        current_business_profile,
+        business_profile_update,
+    )
+    .await
+    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .attach_printable("Failed to update dynamic routing algorithm ref in business profile")?;
+    Ok(())
+}
+
 #[cfg(feature = "v2")]
 #[derive(Clone, Debug)]
 pub struct RoutingAlgorithmHelpers<'h> {
diff --git a/crates/router/src/core/routing/transformers.rs b/crates/router/src/core/routing/transformers.rs
index 6bffde12a9b..652422086b7 100644
--- a/crates/router/src/core/routing/transformers.rs
+++ b/crates/router/src/core/routing/transformers.rs
@@ -72,6 +72,7 @@ impl ForeignFrom<storage_enums::RoutingAlgorithmKind> for RoutingAlgorithmKind {
             storage_enums::RoutingAlgorithmKind::Priority => Self::Priority,
             storage_enums::RoutingAlgorithmKind::VolumeSplit => Self::VolumeSplit,
             storage_enums::RoutingAlgorithmKind::Advanced => Self::Advanced,
+            storage_enums::RoutingAlgorithmKind::Dynamic => Self::Dynamic,
         }
     }
 }
@@ -83,6 +84,7 @@ impl ForeignFrom<RoutingAlgorithmKind> for storage_enums::RoutingAlgorithmKind {
             RoutingAlgorithmKind::Priority => Self::Priority,
             RoutingAlgorithmKind::VolumeSplit => Self::VolumeSplit,
             RoutingAlgorithmKind::Advanced => Self::Advanced,
+            RoutingAlgorithmKind::Dynamic => Self::Dynamic,
         }
     }
 }
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 210ded9c25d..0c6e6762854 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -1614,6 +1614,23 @@ impl BusinessProfile {
             )
             .service(
                 web::scope("/{profile_id}")
+                    .service(
+                        web::scope("/dynamic_routing").service(
+                            web::scope("/success_based")
+                                .service(
+                                    web::resource("/toggle").route(
+                                        web::post().to(routing::toggle_success_based_routing),
+                                    ),
+                                )
+                                .service(web::resource("/config/{algorithm_id}").route(
+                                    web::patch().to(|state, req, path, payload| {
+                                        routing::success_based_routing_update_configs(
+                                            state, req, path, payload,
+                                        )
+                                    }),
+                                )),
+                        ),
+                    )
                     .service(
                         web::resource("")
                             .route(web::get().to(business_profile_retrieve))
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index 13148801aa9..9593e0344c9 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -65,6 +65,8 @@ impl From<Flow> for ApiIdentifier {
             | Flow::RoutingDeleteConfig
             | Flow::DecisionManagerDeleteConfig
             | Flow::DecisionManagerRetrieveConfig
+            | Flow::ToggleDynamicRouting
+            | Flow::UpdateDynamicRoutingConfigs
             | Flow::DecisionManagerUpsertConfig => Self::Routing,
 
             Flow::RetrieveForexFlow => Self::Forex,
diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs
index b1831068991..5870b5ba77d 100644
--- a/crates/router/src/routes/routing.rs
+++ b/crates/router/src/routes/routing.rs
@@ -977,3 +977,88 @@ pub async fn routing_update_default_config_for_profile(
     ))
     .await
 }
+
+#[cfg(all(feature = "olap", feature = "v1"))]
+#[instrument(skip_all)]
+pub async fn toggle_success_based_routing(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    query: web::Query<api_models::routing::ToggleSuccessBasedRoutingQuery>,
+    path: web::Path<routing_types::ToggleSuccessBasedRoutingPath>,
+) -> impl Responder {
+    let flow = Flow::ToggleDynamicRouting;
+    let wrapper = routing_types::ToggleSuccessBasedRoutingWrapper {
+        status: query.into_inner().status,
+        profile_id: path.into_inner().profile_id,
+    };
+    Box::pin(oss_api::server_wrap(
+        flow,
+        state,
+        &req,
+        wrapper.clone(),
+        |state,
+         auth: auth::AuthenticationData,
+         wrapper: routing_types::ToggleSuccessBasedRoutingWrapper,
+         _| {
+            routing::toggle_success_based_routing(
+                state,
+                auth.merchant_account,
+                auth.key_store,
+                wrapper.status,
+                wrapper.profile_id,
+            )
+        },
+        #[cfg(not(feature = "release"))]
+        auth::auth_type(
+            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::JWTAuthProfileFromRoute {
+                profile_id: wrapper.profile_id,
+                required_permission: Permission::RoutingWrite,
+                minimum_entity_level: EntityType::Merchant,
+            },
+            req.headers(),
+        ),
+        #[cfg(feature = "release")]
+        &auth::JWTAuthProfileFromRoute {
+            profile_id: wrapper.profile_id,
+            required_permission: Permission::RoutingWrite,
+            minimum_entity_level: EntityType::Merchant,
+        },
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
+#[cfg(all(feature = "olap", feature = "v1"))]
+#[instrument(skip_all)]
+pub async fn success_based_routing_update_configs(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    path: web::Path<routing_types::SuccessBasedRoutingUpdateConfigQuery>,
+    json_payload: web::Json<routing_types::SuccessBasedRoutingConfig>,
+) -> impl Responder {
+    let flow = Flow::UpdateDynamicRoutingConfigs;
+    let routing_payload_wrapper = routing_types::SuccessBasedRoutingPayloadWrapper {
+        updated_config: json_payload.into_inner(),
+        algorithm_id: path.clone().algorithm_id,
+        profile_id: path.clone().profile_id,
+    };
+    Box::pin(oss_api::server_wrap(
+        flow,
+        state,
+        &req,
+        routing_payload_wrapper,
+        |state, _, wrapper: routing_types::SuccessBasedRoutingPayloadWrapper, _| async {
+            Box::pin(routing::success_based_routing_update_configs(
+                state,
+                wrapper.updated_config,
+                wrapper.algorithm_id,
+                wrapper.profile_id,
+            ))
+            .await
+        },
+        &auth::AdminApiAuth,
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs
index 3d915f838ee..9d90ef530ae 100644
--- a/crates/router/src/types/api/admin.rs
+++ b/crates/router/src/types/api/admin.rs
@@ -347,6 +347,7 @@ pub async fn create_business_profile_from_merchant_account(
                 .map(Into::into),
             tax_connector_id: request.tax_connector_id,
             is_tax_connector_enabled: request.is_tax_connector_enabled,
+            dynamic_routing_algorithm: None,
         },
     ))
 }
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index 79ab704fbbe..329fe5e55fc 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -242,6 +242,10 @@ pub enum Flow {
     RoutingUpdateDefaultConfig,
     /// Routing delete config
     RoutingDeleteConfig,
+    /// Toggle dynamic routing
+    ToggleDynamicRouting,
+    /// Update dynamic routing config
+    UpdateDynamicRoutingConfigs,
     /// Add record to blocklist
     AddToBlocklist,
     /// Delete record from blocklist
diff --git a/migrations/2024-09-05-155712_add_new_variant_in_routing_algorithm_kind_type/down.sql b/migrations/2024-09-05-155712_add_new_variant_in_routing_algorithm_kind_type/down.sql
new file mode 100644
index 00000000000..9ca7ff5389e
--- /dev/null
+++ b/migrations/2024-09-05-155712_add_new_variant_in_routing_algorithm_kind_type/down.sql
@@ -0,0 +1,6 @@
+-- This file should undo anything in `up.sql`
+DELETE FROM pg_enum
+WHERE enumlabel = 'dynamic'
+AND enumtypid = (
+  SELECT oid FROM pg_type WHERE typname = 'RoutingAlgorithmKind'
+);
diff --git a/migrations/2024-09-05-155712_add_new_variant_in_routing_algorithm_kind_type/up.sql b/migrations/2024-09-05-155712_add_new_variant_in_routing_algorithm_kind_type/up.sql
new file mode 100644
index 00000000000..ebe6188c7db
--- /dev/null
+++ b/migrations/2024-09-05-155712_add_new_variant_in_routing_algorithm_kind_type/up.sql
@@ -0,0 +1,2 @@
+-- Your SQL goes here
+ALTER TYPE "RoutingAlgorithmKind" ADD VALUE 'dynamic';
diff --git a/migrations/2024-09-05-160455_add_new_col_is_dynamic_routing_algorithm_in_business_profile/down.sql b/migrations/2024-09-05-160455_add_new_col_is_dynamic_routing_algorithm_in_business_profile/down.sql
new file mode 100644
index 00000000000..61c22e45eae
--- /dev/null
+++ b/migrations/2024-09-05-160455_add_new_col_is_dynamic_routing_algorithm_in_business_profile/down.sql
@@ -0,0 +1,3 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE business_profile
+DROP COLUMN dynamic_routing_algorithm;
diff --git a/migrations/2024-09-05-160455_add_new_col_is_dynamic_routing_algorithm_in_business_profile/up.sql b/migrations/2024-09-05-160455_add_new_col_is_dynamic_routing_algorithm_in_business_profile/up.sql
new file mode 100644
index 00000000000..2482fc9f591
--- /dev/null
+++ b/migrations/2024-09-05-160455_add_new_col_is_dynamic_routing_algorithm_in_business_profile/up.sql
@@ -0,0 +1,3 @@
+-- Your SQL goes here
+ALTER TABLE business_profile
+ADD COLUMN dynamic_routing_algorithm JSON DEFAULT NULL;

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

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

## Description
<!-- Describe your changes in detail -->
### Toggle Success based dynamic routing
This PR will toggle success based dynamic routing for a profile, and the flow looks something like this:
1. A default config will be created for the profile, which will look something like this.
```
        api_models::routing::SuccessBasedRoutingConfig {
                        params: Some(vec![SuccessBasedRoutingConfigParams::PaymentMethod]),
            config: Some(SuccessBasedRoutingConfigBody {
                min_aggregates_size: Some(2),
                default_success_rate: Some(100.0),
                max_aggregates_size: Some(3),
                current_block_threshold: Some(CurrentBlockThreshold {
                    duration_in_mins: Some(5),
                    max_total_count: Some(2),
                }),
            }),
        };
```

2. `is_dynamic_routing_enabled` will be set to true in the business profile table and the routing algo id will be set.

The curls will be something like this:
1. Toggle(enable) Dynamic Routing.
```
curl --location --request POST 'http://localhost:8080/account/merchant_1726160910/business_profile/pro_7Oo0CzTQoOwE5HfwKf6v/dynamic_routing/success_based/toggle?status=true' \
--header 'api-key: xxxxxx'
```

### Update success based dynamic routing configs
This route will update the default configs for success based dynamic routing for a particular profile. Basically it will create a new routing rule and assign the id in business_profile.
The authentication is `admin_api_key`
```
curl --location --request PATCH 'http://localhost:8080/account/merchant_1726160910/business_profile/pro_7Oo0CzTQoOwE5HfwKf6v/dynamic_routing/success_based/config/routing_LYmOkYZuaVkL6ZEXaAjA' \
--header 'Content-Type: application/json' \
--header 'api-key: test_admin' \
--data '{
  "params": [
    "Currency"
  ],
  "config": {
    "min_aggregates_size": 1,
    "current_block_threshold": {
        "max_total_count": 22
    }
  }
}'
```

### Additional Changes

- [x] This PR modifies the API contract
- [x] 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`
4. `crates/router/src/configs`
5. `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).
-->
Baby steps for Dynamic Routing 

## How did you test it?
1. Request:
```
curl --location --request POST 'http://localhost:8080/account/merchant_1726160910/business_profile/pro_7Oo0CzTQoOwE5HfwKf6v/dynamic_routing/success_based/toggle?status=false' \
--header 'api-key:xxxxx'
```
Response:
```
{
    "id": "routing_sSePmUaucfVIcaSeZPK4",
    "profile_id": "pro_ejL5TRsd1mjCulBMXFIR",
    "name": "Dynamic routing algorithm",
    "kind": "dynamic",
    "description": "",
    "created_at": 1725635764,
    "modified_at": 1725635764,
    "algorithm_for": "payment"
}
```
Things to check for:
-> Check the BusinessProfile table for the `profile_id` and then whether the `dynamic_routing_algorithm` is present with the routing algo id we got in the response.
-> Toggle off the above curl by sending the `status` flag as `false` and then check the `step 1.` field for dynamic routing id to only have `timestamp` and no `routing_algorithm_Id`.

2. Request:
```
curl --location --request PATCH 'http://localhost:8080/account/merchant_1726160910/business_profile/pro_7Oo0CzTQoOwE5HfwKf6v/dynamic_routing/success_based/config/routing_LYmOkYZuaVkL6ZEXaAjA' \
--header 'Content-Type: application/json' \
--header 'api-key: test_admin' \
--data '{
  "params": [
    "Currency"
  ],
  "config": {
    "min_aggregates_size": 1,
    "current_block_threshold": {
        "max_total_count": 22
    }
  }
}'
```
Response:
```
{
    "id": "routing_LYmOkYZuaVkL6ZEXaAjA",
    "profile_id": "pro_ejL5TRsd1mjCulBMXFIR",
    "name": "Dynamic routing algorithm",
    "kind": "dynamic",
    "description": "",
    "created_at": 1725635764,
    "modified_at": 1725635764,
    "algorithm_for": "payment"
}
```
Things to check for:
-> Check the `RoutingAlgorithm` table for the `routing_algo_id`. Have a look for the fields above which we are updating like 
`"max_total_count": 22` should be present.

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

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