Bug: Add support to pass fallback_configs for PL routing in the /routing/evaulate request from hyperswitch




diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index 7feea3286ca..4bbffcde633 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -442,22 +442,24 @@ pub async fn perform_static_routing_v1(
     Vec<routing_types::RoutableConnectorChoice>,
     Option<common_enums::RoutingApproach>,
 )> {
-    let algorithm_id = if let Some(id) = algorithm_id {
-        id
-    } else {
+    let get_merchant_fallback_config = || async {
         #[cfg(feature = "v1")]
-        let fallback_config = routing::helpers::get_merchant_default_config(
+        return routing::helpers::get_merchant_default_config(
             &*state.clone().store,
             business_profile.get_id().get_string_repr(),
             &api_enums::TransactionType::from(transaction_data),
         )
         .await
-        .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
+        .change_context(errors::RoutingError::FallbackConfigFetchFailed);
         #[cfg(feature = "v2")]
-        let fallback_config = admin::ProfileWrapper::new(business_profile.clone())
+        return admin::ProfileWrapper::new(business_profile.clone())
             .get_default_fallback_list_of_connector_under_profile()
-            .change_context(errors::RoutingError::FallbackConfigFetchFailed)?;
-
+            .change_context(errors::RoutingError::FallbackConfigFetchFailed);
+    };
+    let algorithm_id = if let Some(id) = algorithm_id {
+        id
+    } else {
+        let fallback_config = get_merchant_fallback_config().await?;
         return Ok((fallback_config, None));
     };
     let cached_algorithm = ensure_algorithm_cached_v1(
@@ -507,7 +509,8 @@ pub async fn perform_static_routing_v1(
             state,
             backend_input.clone(),
             business_profile.get_id().get_string_repr().to_string(),
-            routing_events_wrapper
+            routing_events_wrapper,
+            get_merchant_fallback_config().await?,
         )
         .await
         .map_err(|e|
diff --git a/crates/router/src/core/payments/routing/utils.rs b/crates/router/src/core/payments/routing/utils.rs
index d2167f88498..d217cc04360 100644
--- a/crates/router/src/core/payments/routing/utils.rs
+++ b/crates/router/src/core/payments/routing/utils.rs
@@ -298,12 +298,21 @@ pub async fn perform_decision_euclid_routing(
     input: BackendInput,
     created_by: String,
     events_wrapper: RoutingEventsWrapper<RoutingEvaluateRequest>,
+    fallback_output: Vec<RoutableConnectorChoice>,
 ) -> RoutingResult<Vec<RoutableConnectorChoice>> {
     logger::debug!("decision_engine_euclid: evaluate api call for euclid routing evaluation");
 
     let mut events_wrapper = events_wrapper;
+    let fallback_output = fallback_output
+        .into_iter()
+        .map(|c| DeRoutableConnectorChoice {
+            gateway_name: c.connector,
+            gateway_id: c.merchant_connector_id,
+        })
+        .collect::<Vec<_>>();
 
-    let routing_request = convert_backend_input_to_routing_eval(created_by, input)?;
+    let routing_request =
+        convert_backend_input_to_routing_eval(created_by, input, fallback_output)?;
     events_wrapper.set_request_body(routing_request.clone());
 
     let event_response = EuclidApiClient::send_decision_engine_request(
@@ -515,6 +524,7 @@ pub struct ListRountingAlgorithmsRequest {
 pub fn convert_backend_input_to_routing_eval(
     created_by: String,
     input: BackendInput,
+    fallback_output: Vec<DeRoutableConnectorChoice>,
 ) -> RoutingResult<RoutingEvaluateRequest> {
     let mut params: HashMap<String, Option<ValueType>> = HashMap::new();
 
@@ -631,6 +641,7 @@ pub fn convert_backend_input_to_routing_eval(
     Ok(RoutingEvaluateRequest {
         created_by,
         parameters: params,
+        fallback_output,
     })
 }
 
@@ -677,6 +688,7 @@ impl DecisionEngineErrorsInterface for or_types::ErrorResponse {
 pub struct RoutingEvaluateRequest {
     pub created_by: String,
     pub parameters: HashMap<String, Option<ValueType>>,
+    pub fallback_output: Vec<DeRoutableConnectorChoice>,
 }
 
 #[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
@@ -690,7 +702,7 @@ pub struct RoutingEvaluateResponse {
 }
 
 /// Routable Connector chosen for a payment
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
 pub struct DeRoutableConnectorChoice {
     pub gateway_name: common_enums::RoutableConnectors,
     pub gateway_id: Option<id_type::MerchantConnectorAccountId>,

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

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

## Description
<!-- Describe your changes in detail -->
Decision engine does not have the concept of fallback connectors, so we recently added support to handle the default connectors by allowing them to be passed in the evaluate request. As part of this PR we are making the necessary changes to pass fallback connectors to decision engine

### Additional Changes

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

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

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


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

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


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->

On making a payment from hyperswitch, with the routing rules defined and activated already. We will be passing the fallback_output to the decision engine

<img width="1038" height="379" alt="Screenshot 2025-07-14 at 6 51 45 PM" src="https://github.com/user-attachments/assets/59540f64-00e6-475f-b528-a19ea0f71411" />



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

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