Repository: juspay/hyperswitch
File: crates/router/src/core/payment_methods/cards.rs (Rust)

Code before:
                &platform
                    .get_processor()
                    .get_account()
                    .get_id()
                    .get_pre_routing_disabled_pm_pmt_key(),
            )
            .await
            .ok()
            .and_then(|cfg| serde_json::from_str::<MerchantPreRoutingConfig>(&cfg.config).ok())
            .unwrap_or_default();

        let skip_pre_routing: HashMap<_, _> = merchant_cfg
            .skip_rules
            .into_iter()
            .map(|rule| (rule.payment_method, rule.payment_method_type))
            .collect();

        let routing_enabled_pms = &router_consts::ROUTING_ENABLED_PAYMENT_METHODS;
        let routing_enabled_pm_types = &router_consts::ROUTING_ENABLED_PAYMENT_METHOD_TYPES;

        let mut chosen = api::SessionConnectorDatas::new(Vec::new());
        for intermediate in &response {
            let skip = skip_pre_routing
                .get(&intermediate.payment_method)
                .map(|ty| ty == &intermediate.payment_method_type)
                .unwrap_or(false);
            let pm_allowed = routing_enabled_pms.contains(&intermediate.payment_method);
            let pmt_allowed = routing_enabled_pm_types.contains(&intermediate.payment_method_type);

            if (pm_allowed || pmt_allowed) && !skip {
                let connector_data = helpers::get_connector_data_with_token(
                    &state,
                    intermediate.connector.to_string(),
                    None,
                    intermediate.payment_method_type,
                )
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("invalid connector name received")?;

                chosen.push(api::SessionConnectorData {
                    payment_method_sub_type: intermediate.payment_method_type,
                    payment_method_type: intermediate.payment_method,
                    connector: connector_data,
                    business_sub_label: None,
                });
            }
        }

        let sfr = SessionFlowRoutingInput {
            state: &state,
            country: billing_address.clone().and_then(|ad| ad.country),

Review comment (suggestion):
As per the config structure mentioned below there could be multiple `payment_method` and `payment_method_type` combination. Example (BankRedirect, Interac) and (BankRedirect, ach), in here since we are not iterating over all possible element for a payment method we would get a random payment method type.

We could either iter over the vec to collect all the disabled payment method types for a payment method and then do the validation or either modify the config structure to store multiple payment method type against a payment method.

example:
```
pub struct PreRoutingSkipRule {
    pub payment_method: common_enums::PaymentMethod,
    pub payment_method_type: vec<common_enums::PaymentMethodType>,
}
```

Code after:
        payment_attempt.as_ref().zip(payment_intent.as_ref())
    {
        let pre_routing_disabled_pm_pmt_key = &platform
            .get_processor()
            .get_account()
            .get_id()
            .get_pre_routing_disabled_pm_pmt_key();

        let skip_pre_routing =
            load_skip_pre_routing_config(&state, pre_routing_disabled_pm_pmt_key.to_string()).await;

        let routing_enabled_pms = &router_consts::ROUTING_ENABLED_PAYMENT_METHODS;
        let routing_enabled_pm_types = &router_consts::ROUTING_ENABLED_PAYMENT_METHOD_TYPES;

        let mut chosen = api::SessionConnectorDatas::new(Vec::new());
        for intermediate in &response {
            if perform_pre_routing(
                routing_enabled_pms,
                routing_enabled_pm_types,
                &intermediate.payment_method,
                &intermediate.payment_method_type,
                &skip_pre_routing,
            ) {
                let connector_data = helpers::get_connector_data_with_token(
                    &state,
                    intermediate.connector.to_string(),
                    None,
                    intermediate.payment_method_type,
                )
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("invalid connector name received")?;

                chosen.push(api::SessionConnectorData {
                    payment_method_sub_type: intermediate.payment_method_type,
                    payment_method_type: intermediate.payment_method,
                    connector: connector_data,
                    business_sub_label: None,
                });
            }
        }

        let sfr = SessionFlowRoutingInput {
            state: &state,
            country: billing_address.clone().and_then(|ad| ad.country),
            key_store: platform.get_processor().get_key_store(),
            merchant_account: platform.get_processor().get_account(),
            payment_attempt,
            payment_intent,
            chosen,
        };
        let (result, routing_approach) = routing::perform_session_flow_routing(