Bug: [BUG]: Success Rate rule being created/listed twice for a new profile



When creating an SR rule for a new profile, 2 rules with different algorithm ids are being listed in the get call for listing rules. This is happening only upon creating a new SR rule for a new profile (with no rules existing previously), and not in case of creating an SR rule when other rules already exist. 

<img width="1728" height="1002" alt="Image" src="https://github.com/user-attachments/assets/eeb0c631-57d2-4e97-8c96-929d705aa4ad" />
diff --git a/crates/api_models/src/events/routing.rs b/crates/api_models/src/events/routing.rs
index 9f09bac8274..b1129f96afb 100644
--- a/crates/api_models/src/events/routing.rs
+++ b/crates/api_models/src/events/routing.rs
@@ -2,7 +2,7 @@ use common_utils::events::{ApiEventMetric, ApiEventsType};
 
 use crate::routing::{
     ContractBasedRoutingPayloadWrapper, ContractBasedRoutingSetupPayloadWrapper,
-    DynamicRoutingUpdateConfigQuery, EliminationRoutingPayloadWrapper,
+    CreateDynamicRoutingWrapper, DynamicRoutingUpdateConfigQuery, EliminationRoutingPayloadWrapper,
     LinkedRoutingConfigRetrieveResponse, MerchantRoutingAlgorithm, ProfileDefaultRoutingConfig,
     RoutingAlgorithmId, RoutingConfigRequest, RoutingDictionaryRecord, RoutingKind,
     RoutingLinkWrapper, RoutingPayloadWrapper, RoutingRetrieveLinkQuery,
@@ -125,6 +125,12 @@ impl ApiEventMetric for ToggleDynamicRoutingWrapper {
     }
 }
 
+impl ApiEventMetric for CreateDynamicRoutingWrapper {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Routing)
+    }
+}
+
 impl ApiEventMetric for DynamicRoutingUpdateConfigQuery {
     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 ef5a9422e20..8216f58d4ec 100644
--- a/crates/api_models/src/routing.rs
+++ b/crates/api_models/src/routing.rs
@@ -836,6 +836,33 @@ impl DynamicRoutingAlgorithmRef {
         };
     }
 
+    pub fn update_feature(
+        &mut self,
+        enabled_feature: DynamicRoutingFeatures,
+        dynamic_routing_type: DynamicRoutingType,
+    ) {
+        match dynamic_routing_type {
+            DynamicRoutingType::SuccessRateBasedRouting => {
+                self.success_based_algorithm = Some(SuccessBasedAlgorithm {
+                    algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp::new(None),
+                    enabled_feature,
+                })
+            }
+            DynamicRoutingType::EliminationRouting => {
+                self.elimination_routing_algorithm = Some(EliminationRoutingAlgorithm {
+                    algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp::new(None),
+                    enabled_feature,
+                })
+            }
+            DynamicRoutingType::ContractBasedRouting => {
+                self.contract_based_routing = Some(ContractRoutingAlgorithm {
+                    algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp::new(None),
+                    enabled_feature,
+                })
+            }
+        };
+    }
+
     pub fn disable_algorithm_id(&mut self, dynamic_routing_type: DynamicRoutingType) {
         match dynamic_routing_type {
             DynamicRoutingType::SuccessRateBasedRouting => {
@@ -871,6 +898,11 @@ pub struct ToggleDynamicRoutingQuery {
     pub enable: DynamicRoutingFeatures,
 }
 
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
+pub struct CreateDynamicRoutingQuery {
+    pub enable: DynamicRoutingFeatures,
+}
+
 #[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, ToSchema)]
 pub struct DynamicRoutingVolumeSplitQuery {
     pub split: u8,
@@ -907,6 +939,20 @@ pub struct ToggleDynamicRoutingPath {
     pub profile_id: common_utils::id_type::ProfileId,
 }
 
+#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
+pub struct CreateDynamicRoutingWrapper {
+    pub profile_id: common_utils::id_type::ProfileId,
+    pub feature_to_enable: DynamicRoutingFeatures,
+    pub payload: DynamicRoutingPayload,
+}
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
+#[serde(tag = "type", content = "data", rename_all = "snake_case")]
+pub enum DynamicRoutingPayload {
+    SuccessBasedRoutingPayload(SuccessBasedRoutingConfig),
+    EliminationRoutingPayload(EliminationRoutingConfig),
+}
+
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
 pub struct RoutingVolumeSplitResponse {
     pub split: u8,
diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs
index 2e6f8b09775..6094c9826a1 100644
--- a/crates/router/src/core/routing.rs
+++ b/crates/router/src/core/routing.rs
@@ -1598,6 +1598,7 @@ pub async fn update_default_routing_config_for_profile(
 
 // Toggle the specific routing type as well as add the default configs in RoutingAlgorithm table
 // and update the same in business profile table.
+
 #[cfg(all(feature = "v1", feature = "dynamic_routing"))]
 pub async fn toggle_specific_dynamic_routing(
     state: SessionState,
@@ -1647,16 +1648,88 @@ pub async fn toggle_specific_dynamic_routing(
             // 1. If present with same feature then return response as already enabled
             // 2. Else update the feature and persist the same on db
             // 3. If not present in db then create a new default entry
-            helpers::enable_dynamic_routing_algorithm(
+            Box::pin(helpers::enable_dynamic_routing_algorithm(
                 &state,
                 merchant_context.get_merchant_key_store().clone(),
                 business_profile,
                 feature_to_enable,
                 dynamic_routing_algo_ref,
                 dynamic_routing_type,
+                None,
+            ))
+            .await
+        }
+        routing::DynamicRoutingFeatures::None => {
+            // disable specific dynamic routing for the requested profile
+            helpers::disable_dynamic_routing_algorithm(
+                &state,
+                merchant_context.get_merchant_key_store().clone(),
+                business_profile,
+                dynamic_routing_algo_ref,
+                dynamic_routing_type,
             )
             .await
         }
+    }
+}
+
+#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
+pub async fn create_specific_dynamic_routing(
+    state: SessionState,
+    merchant_context: domain::MerchantContext,
+    feature_to_enable: routing::DynamicRoutingFeatures,
+    profile_id: common_utils::id_type::ProfileId,
+    dynamic_routing_type: routing::DynamicRoutingType,
+    payload: routing_types::DynamicRoutingPayload,
+) -> RouterResponse<routing_types::RoutingDictionaryRecord> {
+    metrics::ROUTING_CREATE_REQUEST_RECEIVED.add(
+        1,
+        router_env::metric_attributes!(
+            ("profile_id", profile_id.clone()),
+            ("algorithm_type", dynamic_routing_type.to_string())
+        ),
+    );
+    let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
+
+    let business_profile: domain::Profile = core_utils::validate_and_get_business_profile(
+        db,
+        key_manager_state,
+        merchant_context.get_merchant_key_store(),
+        Some(&profile_id),
+        merchant_context.get_merchant_account().get_id(),
+    )
+    .await?
+    .get_required_value("Profile")
+    .change_context(errors::ApiErrorResponse::ProfileNotFound {
+        id: profile_id.get_string_repr().to_owned(),
+    })?;
+
+    let 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();
+
+    match feature_to_enable {
+        routing::DynamicRoutingFeatures::Metrics
+        | routing::DynamicRoutingFeatures::DynamicConnectorSelection => {
+            Box::pin(helpers::enable_dynamic_routing_algorithm(
+                &state,
+                merchant_context.get_merchant_key_store().clone(),
+                business_profile,
+                feature_to_enable,
+                dynamic_routing_algo_ref,
+                dynamic_routing_type,
+                Some(payload),
+            ))
+            .await
+        }
         routing::DynamicRoutingFeatures::None => {
             // disable specific dynamic routing for the requested profile
             helpers::disable_dynamic_routing_algorithm(
diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs
index b04df149228..290feb9e306 100644
--- a/crates/router/src/core/routing/helpers.rs
+++ b/crates/router/src/core/routing/helpers.rs
@@ -1979,6 +1979,7 @@ pub async fn enable_dynamic_routing_algorithm(
     feature_to_enable: routing_types::DynamicRoutingFeatures,
     dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
     dynamic_routing_type: routing_types::DynamicRoutingType,
+    payload: Option<routing_types::DynamicRoutingPayload>,
 ) -> RouterResult<ApplicationResponse<routing_types::RoutingDictionaryRecord>> {
     let mut dynamic_routing = dynamic_routing_algo_ref.clone();
     match dynamic_routing_type {
@@ -1994,6 +1995,7 @@ pub async fn enable_dynamic_routing_algorithm(
                 dynamic_routing.clone(),
                 dynamic_routing_type,
                 dynamic_routing.success_based_algorithm,
+                payload,
             )
             .await
         }
@@ -2006,6 +2008,7 @@ pub async fn enable_dynamic_routing_algorithm(
                 dynamic_routing.clone(),
                 dynamic_routing_type,
                 dynamic_routing.elimination_routing_algorithm,
+                payload,
             )
             .await
         }
@@ -2018,6 +2021,7 @@ pub async fn enable_dynamic_routing_algorithm(
     }
 }
 
+#[allow(clippy::too_many_arguments)]
 #[cfg(all(feature = "v1", feature = "dynamic_routing"))]
 pub async fn enable_specific_routing_algorithm<A>(
     state: &SessionState,
@@ -2027,10 +2031,24 @@ pub async fn enable_specific_routing_algorithm<A>(
     mut dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
     dynamic_routing_type: routing_types::DynamicRoutingType,
     algo_type: Option<A>,
+    payload: Option<routing_types::DynamicRoutingPayload>,
 ) -> RouterResult<ApplicationResponse<routing_types::RoutingDictionaryRecord>>
 where
     A: routing_types::DynamicRoutingAlgoAccessor + Clone + Debug,
 {
+    //Check for payload
+    if let Some(payload) = payload {
+        return create_specific_dynamic_routing_setup(
+            state,
+            key_store,
+            business_profile,
+            feature_to_enable,
+            dynamic_routing_algo_ref,
+            dynamic_routing_type,
+            payload,
+        )
+        .await;
+    }
     // Algorithm wasn't created yet
     let Some(mut algo_type) = algo_type else {
         return default_specific_dynamic_routing_setup(
@@ -2112,6 +2130,7 @@ pub async fn default_specific_dynamic_routing_setup(
     let merchant_id = business_profile.merchant_id.clone();
     let algorithm_id = common_utils::generate_routing_id_of_default_length();
     let timestamp = common_utils::date_time::now();
+
     let algo = match dynamic_routing_type {
         routing_types::DynamicRoutingType::SuccessRateBasedRouting => {
             let default_success_based_routing_config =
@@ -2142,6 +2161,7 @@ pub async fn default_specific_dynamic_routing_setup(
                 } else {
                     routing_types::EliminationRoutingConfig::default()
                 };
+
             routing_algorithm::RoutingAlgorithm {
                 algorithm_id: algorithm_id.clone(),
                 profile_id: profile_id.clone(),
@@ -2173,6 +2193,7 @@ pub async fn default_specific_dynamic_routing_setup(
             business_profile.get_id(),
             dynamic_routing_type,
             &mut dynamic_routing_algo_ref,
+            None,
         )
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -2208,6 +2229,122 @@ pub async fn default_specific_dynamic_routing_setup(
     Ok(ApplicationResponse::Json(new_record))
 }
 
+#[cfg(all(feature = "dynamic_routing", feature = "v1"))]
+#[instrument(skip_all)]
+pub async fn create_specific_dynamic_routing_setup(
+    state: &SessionState,
+    key_store: domain::MerchantKeyStore,
+    business_profile: domain::Profile,
+    feature_to_enable: routing_types::DynamicRoutingFeatures,
+    mut dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
+    dynamic_routing_type: routing_types::DynamicRoutingType,
+    payload: routing_types::DynamicRoutingPayload,
+) -> RouterResult<ApplicationResponse<routing_types::RoutingDictionaryRecord>> {
+    let db = state.store.as_ref();
+    let key_manager_state = &state.into();
+    let profile_id = business_profile.get_id().clone();
+    let merchant_id = business_profile.merchant_id.clone();
+    let algorithm_id = common_utils::generate_routing_id_of_default_length();
+    let timestamp = common_utils::date_time::now();
+
+    let algo = match dynamic_routing_type {
+        routing_types::DynamicRoutingType::SuccessRateBasedRouting => {
+            let success_config = match &payload {
+                routing_types::DynamicRoutingPayload::SuccessBasedRoutingPayload(config) => config,
+                _ => {
+                    return Err((errors::ApiErrorResponse::InvalidRequestData {
+                        message: "Invalid payload type for Success Rate Based Routing".to_string(),
+                    })
+                    .into())
+                }
+            };
+
+            routing_algorithm::RoutingAlgorithm {
+                algorithm_id: algorithm_id.clone(),
+                profile_id: profile_id.clone(),
+                merchant_id,
+                name: SUCCESS_BASED_DYNAMIC_ROUTING_ALGORITHM.to_string(),
+                description: None,
+                kind: diesel_models::enums::RoutingAlgorithmKind::Dynamic,
+                algorithm_data: serde_json::json!(success_config),
+                created_at: timestamp,
+                modified_at: timestamp,
+                algorithm_for: common_enums::TransactionType::Payment,
+                decision_engine_routing_id: None,
+            }
+        }
+        routing_types::DynamicRoutingType::EliminationRouting => {
+            let elimination_config = match &payload {
+                routing_types::DynamicRoutingPayload::EliminationRoutingPayload(config) => config,
+                _ => {
+                    return Err((errors::ApiErrorResponse::InvalidRequestData {
+                        message: "Invalid payload type for Elimination Routing".to_string(),
+                    })
+                    .into())
+                }
+            };
+
+            routing_algorithm::RoutingAlgorithm {
+                algorithm_id: algorithm_id.clone(),
+                profile_id: profile_id.clone(),
+                merchant_id,
+                name: ELIMINATION_BASED_DYNAMIC_ROUTING_ALGORITHM.to_string(),
+                description: None,
+                kind: diesel_models::enums::RoutingAlgorithmKind::Dynamic,
+                algorithm_data: serde_json::json!(elimination_config),
+                created_at: timestamp,
+                modified_at: timestamp,
+                algorithm_for: common_enums::TransactionType::Payment,
+                decision_engine_routing_id: None,
+            }
+        }
+
+        routing_types::DynamicRoutingType::ContractBasedRouting => {
+            return Err((errors::ApiErrorResponse::InvalidRequestData {
+                message: "Contract routing cannot be set as default".to_string(),
+            })
+            .into())
+        }
+    };
+
+    if state.conf.open_router.dynamic_routing_enabled {
+        enable_decision_engine_dynamic_routing_setup(
+            state,
+            business_profile.get_id(),
+            dynamic_routing_type,
+            &mut dynamic_routing_algo_ref,
+            Some(payload),
+        )
+        .await
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Unable to setup decision engine dynamic routing")?;
+    }
+
+    let record = db
+        .insert_routing_algorithm(algo)
+        .await
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Unable to insert record in routing algorithm table")?;
+
+    dynamic_routing_algo_ref.update_feature(feature_to_enable, dynamic_routing_type);
+    update_business_profile_active_dynamic_algorithm_ref(
+        db,
+        key_manager_state,
+        &key_store,
+        business_profile,
+        dynamic_routing_algo_ref,
+    )
+    .await?;
+
+    let new_record = record.foreign_into();
+
+    core_metrics::ROUTING_CREATE_SUCCESS_RESPONSE.add(
+        1,
+        router_env::metric_attributes!(("profile_id", profile_id.clone())),
+    );
+    Ok(ApplicationResponse::Json(new_record))
+}
+
 #[derive(Debug, Clone)]
 pub struct DynamicRoutingConfigParamsInterpolator {
     pub payment_method: Option<common_enums::PaymentMethod>,
@@ -2289,20 +2426,30 @@ pub async fn enable_decision_engine_dynamic_routing_setup(
     profile_id: &id_type::ProfileId,
     dynamic_routing_type: routing_types::DynamicRoutingType,
     dynamic_routing_algo_ref: &mut routing_types::DynamicRoutingAlgorithmRef,
+    payload: Option<routing_types::DynamicRoutingPayload>,
 ) -> RouterResult<()> {
     logger::debug!(
         "performing call with open_router for profile {}",
         profile_id.get_string_repr()
     );
 
-    let default_engine_config_request = match dynamic_routing_type {
+    let decision_engine_config_request = match dynamic_routing_type {
         routing_types::DynamicRoutingType::SuccessRateBasedRouting => {
-            let default_success_based_routing_config =
-                routing_types::SuccessBasedRoutingConfig::open_router_config_default();
+            let success_based_routing_config = payload
+                .and_then(|p| match p {
+                    routing_types::DynamicRoutingPayload::SuccessBasedRoutingPayload(config) => {
+                        Some(config)
+                    }
+                    _ => None,
+                })
+                .unwrap_or_else(
+                    routing_types::SuccessBasedRoutingConfig::open_router_config_default,
+                );
+
             open_router::DecisionEngineConfigSetupRequest {
                 merchant_id: profile_id.get_string_repr().to_string(),
                 config: open_router::DecisionEngineConfigVariant::SuccessRate(
-                    default_success_based_routing_config
+                    success_based_routing_config
                         .get_decision_engine_configs()
                         .change_context(errors::ApiErrorResponse::GenericNotFoundError {
                             message: "Decision engine config not found".to_string(),
@@ -2312,12 +2459,21 @@ pub async fn enable_decision_engine_dynamic_routing_setup(
             }
         }
         routing_types::DynamicRoutingType::EliminationRouting => {
-            let default_elimination_based_routing_config =
-                routing_types::EliminationRoutingConfig::open_router_config_default();
+            let elimination_based_routing_config = payload
+                .and_then(|p| match p {
+                    routing_types::DynamicRoutingPayload::EliminationRoutingPayload(config) => {
+                        Some(config)
+                    }
+                    _ => None,
+                })
+                .unwrap_or_else(
+                    routing_types::EliminationRoutingConfig::open_router_config_default,
+                );
+
             open_router::DecisionEngineConfigSetupRequest {
                 merchant_id: profile_id.get_string_repr().to_string(),
                 config: open_router::DecisionEngineConfigVariant::Elimination(
-                    default_elimination_based_routing_config
+                    elimination_based_routing_config
                         .get_decision_engine_configs()
                         .change_context(errors::ApiErrorResponse::GenericNotFoundError {
                             message: "Decision engine config not found".to_string(),
@@ -2342,7 +2498,7 @@ pub async fn enable_decision_engine_dynamic_routing_setup(
         state,
         services::Method::Post,
         DECISION_ENGINE_RULE_CREATE_ENDPOINT,
-        Some(default_engine_config_request),
+        Some(decision_engine_config_request),
         None,
         None,
     )
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 01455e9e17b..62260dc49cc 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -2189,6 +2189,10 @@ impl Profile {
                                 web::resource("/toggle")
                                     .route(web::post().to(routing::toggle_success_based_routing)),
                             )
+                            .service(
+                                web::resource("/create")
+                                    .route(web::post().to(routing::create_success_based_routing)),
+                            )
                             .service(web::resource("/config/{algorithm_id}").route(
                                 web::patch().to(|state, req, path, payload| {
                                     routing::success_based_routing_update_configs(
@@ -2211,6 +2215,10 @@ impl Profile {
                                 web::resource("/toggle")
                                     .route(web::post().to(routing::toggle_elimination_routing)),
                             )
+                            .service(
+                                web::resource("/create")
+                                    .route(web::post().to(routing::create_elimination_routing)),
+                            )
                             .service(web::resource("config/{algorithm_id}").route(
                                 web::patch().to(|state, req, path, payload| {
                                     routing::elimination_routing_update_configs(
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index 62d65211053..dcc5cf0752d 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -79,6 +79,7 @@ impl From<Flow> for ApiIdentifier {
             | Flow::DecisionManagerDeleteConfig
             | Flow::DecisionManagerRetrieveConfig
             | Flow::ToggleDynamicRouting
+            | Flow::CreateDynamicRoutingConfig
             | Flow::UpdateDynamicRoutingConfigs
             | Flow::DecisionManagerUpsertConfig
             | Flow::RoutingEvaluateRule
diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs
index 53f6a75c5c1..ec118bea8da 100644
--- a/crates/router/src/routes/routing.rs
+++ b/crates/router/src/routes/routing.rs
@@ -1240,6 +1240,60 @@ pub async fn toggle_success_based_routing(
     .await
 }
 
+#[cfg(all(feature = "olap", feature = "v1", feature = "dynamic_routing"))]
+#[instrument(skip_all)]
+pub async fn create_success_based_routing(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    query: web::Query<api_models::routing::CreateDynamicRoutingQuery>,
+    path: web::Path<routing_types::ToggleDynamicRoutingPath>,
+    success_based_config: web::Json<routing_types::SuccessBasedRoutingConfig>,
+) -> impl Responder {
+    let flow = Flow::CreateDynamicRoutingConfig;
+    let wrapper = routing_types::CreateDynamicRoutingWrapper {
+        feature_to_enable: query.into_inner().enable,
+        profile_id: path.into_inner().profile_id,
+        payload: api_models::routing::DynamicRoutingPayload::SuccessBasedRoutingPayload(
+            success_based_config.into_inner(),
+        ),
+    };
+    Box::pin(oss_api::server_wrap(
+        flow,
+        state,
+        &req,
+        wrapper.clone(),
+        |state,
+         auth: auth::AuthenticationData,
+         wrapper: routing_types::CreateDynamicRoutingWrapper,
+         _| {
+            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
+                domain::Context(auth.merchant_account, auth.key_store),
+            ));
+            routing::create_specific_dynamic_routing(
+                state,
+                merchant_context,
+                wrapper.feature_to_enable,
+                wrapper.profile_id,
+                api_models::routing::DynamicRoutingType::SuccessRateBasedRouting,
+                wrapper.payload,
+            )
+        },
+        auth::auth_type(
+            &auth::HeaderAuth(auth::ApiKeyAuth {
+                is_connected_allowed: false,
+                is_platform_allowed: false,
+            }),
+            &auth::JWTAuthProfileFromRoute {
+                profile_id: wrapper.profile_id,
+                required_permission: Permission::ProfileRoutingWrite,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
 #[cfg(all(feature = "olap", feature = "v1", feature = "dynamic_routing"))]
 #[instrument(skip_all)]
 pub async fn success_based_routing_update_configs(
@@ -1480,6 +1534,60 @@ pub async fn toggle_elimination_routing(
     .await
 }
 
+#[cfg(all(feature = "olap", feature = "v1", feature = "dynamic_routing"))]
+#[instrument(skip_all)]
+pub async fn create_elimination_routing(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    query: web::Query<api_models::routing::CreateDynamicRoutingQuery>,
+    path: web::Path<routing_types::ToggleDynamicRoutingPath>,
+    elimination_config: web::Json<routing_types::EliminationRoutingConfig>,
+) -> impl Responder {
+    let flow = Flow::CreateDynamicRoutingConfig;
+    let wrapper = routing_types::CreateDynamicRoutingWrapper {
+        feature_to_enable: query.into_inner().enable,
+        profile_id: path.into_inner().profile_id,
+        payload: api_models::routing::DynamicRoutingPayload::EliminationRoutingPayload(
+            elimination_config.into_inner(),
+        ),
+    };
+    Box::pin(oss_api::server_wrap(
+        flow,
+        state,
+        &req,
+        wrapper.clone(),
+        |state,
+         auth: auth::AuthenticationData,
+         wrapper: routing_types::CreateDynamicRoutingWrapper,
+         _| {
+            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
+                domain::Context(auth.merchant_account, auth.key_store),
+            ));
+            routing::create_specific_dynamic_routing(
+                state,
+                merchant_context,
+                wrapper.feature_to_enable,
+                wrapper.profile_id,
+                api_models::routing::DynamicRoutingType::EliminationRouting,
+                wrapper.payload,
+            )
+        },
+        auth::auth_type(
+            &auth::HeaderAuth(auth::ApiKeyAuth {
+                is_connected_allowed: false,
+                is_platform_allowed: false,
+            }),
+            &auth::JWTAuthProfileFromRoute {
+                profile_id: wrapper.profile_id,
+                required_permission: Permission::ProfileRoutingWrite,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
 #[cfg(all(feature = "olap", feature = "v1"))]
 #[instrument(skip_all)]
 pub async fn set_dynamic_routing_volume_split(
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index e6651c3c520..722d9bde9aa 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -261,6 +261,8 @@ pub enum Flow {
     RoutingUpdateDefaultConfig,
     /// Routing delete config
     RoutingDeleteConfig,
+    /// Create dynamic routing
+    CreateDynamicRoutingConfig,
     /// Toggle dynamic routing
     ToggleDynamicRouting,
     /// Update dynamic routing config

### **Summary**

This PR introduces the **`/create`** endpoints for dynamic routing algorithm types (Success-Based and Elimination), allowing merchants to initialize and register dynamic routing logic via a new payload-capable flow. The implementation includes support for optional configuration payloads and integration with the existing routing setup framework.

---

### **Key Changes**

**New Features**

* **New endpoint**:

  * `POST /{profile_id}/dynamic_routing/success_based/create`
  * `POST /{profile_id}/dynamic_routing/elimination/create`
* **Payload Support**: Optional payloads for `SuccessBasedRoutingConfig` and `EliminationRoutingConfig` can now be passed to configure algorithms during creation.
* **`CreateDynamicRoutingWrapper`** added to handle request data (profile ID, feature flag, optional payload).
* **`DynamicRoutingPayload` enum** introduced with tagged serialization for extensibility.

**Core Logic Additions**

* **`create_specific_dynamic_routing`** method introduced to encapsulate algorithm creation logic based on feature + payload.
* **`enable_dynamic_routing_algorithm`** and **`enable_specific_routing_algorithm`** now accept optional payloads to use custom configs during setup.
* **New helper**: `create_specific_dynamic_routing_setup()` handles inserting the provided configuration payload into the DB, avoiding fallback to defaults.


**Flow and API Updates**

* `Flow::CreateDynamicRouting` added for observability and authorization context.
* `ApiEventMetric` trait implemented for `CreateDynamicRoutingWrapper`.

---

**Curls and Responses**

1. Flow for success_based

(i)Request : Success Based


```
curl --location 'http://localhost:8080/account/merchant_1755085769/business_profile/pro_W03vsc3viNBMsEb2BAGF/dynamic_routing/success_based/create?enable=dynamic_connector_selection' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QHVD0EjpDPHoROKdB1NLfap0tBhRrH2QiQ5NQfIpHB' \
--data '{
        "decision_engine_configs": {
        "defaultLatencyThreshold": 90,
        "defaultBucketSize": 200,
        "defaultHedgingPercent": 5,
        "subLevelInputConfig": [
            {
                "paymentMethodType": "card",
                "paymentMethod": "credit",
                "bucketSize": 250,
                "hedgingPercent": 1
            }
        ]
    }

}'
```

Response:

```
{
    "id": "routing_STHAfh9Dyiy3BPLIUQAS",
    "profile_id": "pro_W03vsc3viNBMsEb2BAGF",
    "name": "Success rate based dynamic routing algorithm",
    "kind": "dynamic",
    "description": "",
    "created_at": 1755086316,
    "modified_at": 1755086316,
    "algorithm_for": "payment",
    "decision_engine_routing_id": null
}
```

(ii)Request : Activate 

```
curl --location 'http://localhost:8080/routing/routing_STHAfh9Dyiy3BPLIUQAS/activate' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QHVD0EjpDPHoROKdB1NLfap0tBhRrH2QiQ5NQfIpHB' \
--data '{}'
```

Response:

```
{
    "id": "routing_STHAfh9Dyiy3BPLIUQAS",
    "profile_id": "pro_W03vsc3viNBMsEb2BAGF",
    "name": "Success rate based dynamic routing algorithm",
    "kind": "dynamic",
    "description": "",
    "created_at": 1755086316,
    "modified_at": 1755086316,
    "algorithm_for": "payment",
    "decision_engine_routing_id": null
}
```

(iii)Request: volume_split

```
curl --location --request POST 'http://localhost:8080/account/merchant_1755085769/business_profile/pro_W03vsc3viNBMsEb2BAGF/dynamic_routing/set_volume_split?split=100' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QH*****DPHoROKdB1NLfap0tBhRrH2QiQ5NQfIpHB'
```

Response:
```

{
    "routing_type": "dynamic",
    "split": 100
}
```

(iv)Request: Payment

```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QHVD0EjpDPHoROKdB1NLfap0tBhRrH2QiQ5NQfIpHB' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "amount_to_capture": 6540,
    "confirm": true,
    "profile_id": "pro_W03vsc3viNBMsEb2BAGF",
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "no_three_ds",
    "setup_future_usage": "on_session", 
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "customer@gmail.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "customer_id": "customer123",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": { 
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123"
        }
    },
    
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 6540,
            "account_name": "transaction_processing"
        }
    ],
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "128.0.0.1"
    },
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "125.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    
    "connector_metadata": {
        "noon": {
            "order_category": "pay"
        }
    },
    "payment_link": false,
    "payment_link_config": {
        "theme": "",
        "logo": "",
        "seller_name": "",
        "sdk_layout": "",
        "display_sdk_only": false,
        "enabled_saved_payment_method": false
    },
    

    "payment_type": "normal", 
    "request_incremental_authorization": false,
    "merchant_order_reference_id": "test_ord",
    "session_expiry": 900 

    
}'
```





2. Flow of elimination

Resquest : Elimination

```
curl --location 'http://localhost:8080/account/merchant_1755085769/business_profile/pro_W03vsc3viNBMsEb2BAGF/dynamic_routing/elimination/create?enable=dynamic_connector_selection' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QHVD0EjpDPHoROKdB1NLfap0tBhRrH2QiQ5NQfIpHB' \
--data '{
    "decision_engine_configs": {
        "threshold": 0.35
    }
}'

```
Response:

```
{
    "id": "routing_TNPpQ8FtYXyVmBx408it",
    "profile_id": "pro_W03vsc3viNBMsEb2BAGF",
    "name": "Elimination based dynamic routing algorithm",
    "kind": "dynamic",
    "description": "",
    "created_at": 1755086640,
    "modified_at": 1755086640,
    "algorithm_for": "payment",
    "decision_engine_routing_id": null
}

```
Request : activate

```
curl --location 'http://localhost:8080/routing/routing_TNPpQ8FtYXyVmBx408it/activate' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QHVD0EjpDPHoROKdB1NLfap0tBhRrH2QiQ5NQfIpHB' \
--data '{}'

```
Response:

```
{
    "id": "routing_TNPpQ8FtYXyVmBx408it",
    "profile_id": "pro_W03vsc3viNBMsEb2BAGF",
    "name": "Elimination based dynamic routing algorithm",
    "kind": "dynamic",
    "description": "",
    "created_at": 1755086640,
    "modified_at": 1755086640,
    "algorithm_for": "payment",
    "decision_engine_routing_id": null
}
```

Request: volume_split

```
curl --location --request POST 'http://localhost:8080/account/merchant_1755085769/business_profile/pro_W03vsc3viNBMsEb2BAGF/dynamic_routing/set_volume_split?split=100' \
--header 'api-key: dev_bhW5F52tburClYJFA3MhY5QHVD0EjpDPHoROKd*****p0tBhRrH2QiQ5NQfIpHB'
```

Response:

```
{
    "routing_type": "dynamic",
    "split": 100
}

```
(iv) Request: Payment