// File: crates/router/src/db.rs
// Module: router
// Public functions: 1

pub mod address;
pub mod api_keys;
pub mod authentication;
pub mod authorization;
pub mod blocklist;
pub mod blocklist_fingerprint;
pub mod blocklist_lookup;
pub mod business_profile;
pub mod callback_mapper;
pub mod capture;
pub mod configs;
pub mod customers;
pub mod dashboard_metadata;
pub mod dispute;
pub mod dynamic_routing_stats;
pub mod ephemeral_key;
pub mod events;
pub mod file;
pub mod fraud_check;
pub mod generic_link;
pub mod gsm;
pub mod health_check;
pub mod hyperswitch_ai_interaction;
pub mod invoice;
pub mod kafka_store;
pub mod locker_mock_up;
pub mod mandate;
pub mod merchant_account;
pub mod merchant_connector_account;
pub mod merchant_key_store;
pub mod organization;
pub mod payment_link;
pub mod payment_method_session;
pub mod refund;
pub mod relay;
pub mod reverse_lookup;
pub mod role;
pub mod routing_algorithm;
pub mod subscription;
pub mod unified_translations;
pub mod user;
pub mod user_authentication_method;
pub mod user_key_store;
pub mod user_role;

use ::payment_methods::state::PaymentMethodsStorageInterface;
use common_utils::id_type;
use diesel_models::{
    fraud_check::{FraudCheck, FraudCheckUpdate},
    organization::{Organization, OrganizationNew, OrganizationUpdate},
};
use error_stack::ResultExt;
#[cfg(feature = "payouts")]
use hyperswitch_domain_models::payouts::{
    payout_attempt::PayoutAttemptInterface, payouts::PayoutsInterface,
};
use hyperswitch_domain_models::{
    cards_info::CardsInfoInterface,
    payment_methods::PaymentMethodInterface,
    payments::{payment_attempt::PaymentAttemptInterface, payment_intent::PaymentIntentInterface},
};
#[cfg(not(feature = "payouts"))]
use hyperswitch_domain_models::{PayoutAttemptInterface, PayoutsInterface};
use masking::PeekInterface;
use redis_interface::errors::RedisError;
use router_env::logger;
use storage_impl::{
    errors::StorageError, redis::kv_store::RedisConnInterface, tokenization, MockDb,
};

pub use self::kafka_store::KafkaStore;
use self::{fraud_check::FraudCheckInterface, organization::OrganizationInterface};
pub use crate::{
    core::errors::{self, ProcessTrackerError},
    errors::CustomResult,
    services::{
        kafka::{KafkaError, KafkaProducer, MQResult},
        Store,
    },
    types::{
        domain,
        storage::{self},
        AccessToken,
    },
};

#[derive(PartialEq, Eq)]
pub enum StorageImpl {
    Postgresql,
    PostgresqlTest,
    Mock,
}

#[async_trait::async_trait]
pub trait StorageInterface:
    Send
    + Sync
    + dyn_clone::DynClone
    + address::AddressInterface
    + api_keys::ApiKeyInterface
    + blocklist_lookup::BlocklistLookupInterface
    + configs::ConfigInterface
    + capture::CaptureInterface
    + customers::CustomerInterface<Error = StorageError>
    + dashboard_metadata::DashboardMetadataInterface
    + dispute::DisputeInterface
    + ephemeral_key::EphemeralKeyInterface
    + ephemeral_key::ClientSecretInterface
    + events::EventInterface
    + file::FileMetadataInterface
    + FraudCheckInterface
    + locker_mock_up::LockerMockUpInterface
    + mandate::MandateInterface
    + merchant_account::MerchantAccountInterface
    + merchant_connector_account::ConnectorAccessToken
    + merchant_connector_account::MerchantConnectorAccountInterface
    + PaymentAttemptInterface<Error = StorageError>
    + PaymentIntentInterface<Error = StorageError>
    + PaymentMethodInterface<Error = StorageError>
    + blocklist::BlocklistInterface
    + blocklist_fingerprint::BlocklistFingerprintInterface
    + dynamic_routing_stats::DynamicRoutingStatsInterface
    + scheduler::SchedulerInterface
    + PayoutAttemptInterface<Error = StorageError>
    + PayoutsInterface<Error = StorageError>
    + refund::RefundInterface
    + reverse_lookup::ReverseLookupInterface
    + CardsInfoInterface<Error = StorageError>
    + merchant_key_store::MerchantKeyStoreInterface
    + MasterKeyInterface
    + payment_link::PaymentLinkInterface
    + RedisConnInterface
    + RequestIdStore
    + business_profile::ProfileInterface
    + routing_algorithm::RoutingAlgorithmInterface
    + gsm::GsmInterface
    + unified_translations::UnifiedTranslationsInterface
    + authorization::AuthorizationInterface
    + user::sample_data::BatchSampleDataInterface
    + health_check::HealthCheckDbInterface
    + user_authentication_method::UserAuthenticationMethodInterface
    + hyperswitch_ai_interaction::HyperswitchAiInteractionInterface
    + authentication::AuthenticationInterface
    + generic_link::GenericLinkInterface
    + relay::RelayInterface
    + user::theme::ThemeInterface
    + payment_method_session::PaymentMethodsSessionInterface
    + tokenization::TokenizationInterface
    + callback_mapper::CallbackMapperInterface
    + subscription::SubscriptionInterface
    + invoice::InvoiceInterface
    + 'static
{
    fn get_scheduler_db(&self) -> Box<dyn scheduler::SchedulerInterface>;
    fn get_payment_methods_store(&self) -> Box<dyn PaymentMethodsStorageInterface>;
    fn get_cache_store(&self) -> Box<dyn RedisConnInterface + Send + Sync + 'static>;
}

#[async_trait::async_trait]
pub trait GlobalStorageInterface:
    Send
    + Sync
    + dyn_clone::DynClone
    + user::UserInterface
    + user_role::UserRoleInterface
    + user_key_store::UserKeyStoreInterface
    + role::RoleInterface
    + RedisConnInterface
    + 'static
{
    fn get_cache_store(&self) -> Box<dyn RedisConnInterface + Send + Sync + 'static>;
}

#[async_trait::async_trait]
pub trait AccountsStorageInterface:
    Send
    + Sync
    + dyn_clone::DynClone
    + OrganizationInterface
    + merchant_account::MerchantAccountInterface
    + business_profile::ProfileInterface
    + merchant_connector_account::MerchantConnectorAccountInterface
    + merchant_key_store::MerchantKeyStoreInterface
    + dashboard_metadata::DashboardMetadataInterface
    + 'static
{
}

pub trait CommonStorageInterface:
    StorageInterface
    + GlobalStorageInterface
    + AccountsStorageInterface
    + PaymentMethodsStorageInterface
{
    fn get_storage_interface(&self) -> Box<dyn StorageInterface>;
    fn get_global_storage_interface(&self) -> Box<dyn GlobalStorageInterface>;
    fn get_accounts_storage_interface(&self) -> Box<dyn AccountsStorageInterface>;
}

pub trait MasterKeyInterface {
    fn get_master_key(&self) -> &[u8];
}

impl MasterKeyInterface for Store {
    fn get_master_key(&self) -> &[u8] {
        self.master_key().peek()
    }
}

/// Default dummy key for MockDb
impl MasterKeyInterface for MockDb {
    fn get_master_key(&self) -> &[u8] {
        &[
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
            25, 26, 27, 28, 29, 30, 31, 32,
        ]
    }
}

#[async_trait::async_trait]
impl StorageInterface for Store {
    fn get_scheduler_db(&self) -> Box<dyn scheduler::SchedulerInterface> {
        Box::new(self.clone())
    }
    fn get_payment_methods_store(&self) -> Box<dyn PaymentMethodsStorageInterface> {
        Box::new(self.clone())
    }

    fn get_cache_store(&self) -> Box<dyn RedisConnInterface + Send + Sync + 'static> {
        Box::new(self.clone())
    }
}

#[async_trait::async_trait]
impl GlobalStorageInterface for Store {
    fn get_cache_store(&self) -> Box<dyn RedisConnInterface + Send + Sync + 'static> {
        Box::new(self.clone())
    }
}

impl AccountsStorageInterface for Store {}

#[async_trait::async_trait]
impl StorageInterface for MockDb {
    fn get_scheduler_db(&self) -> Box<dyn scheduler::SchedulerInterface> {
        Box::new(self.clone())
    }
    fn get_payment_methods_store(&self) -> Box<dyn PaymentMethodsStorageInterface> {
        Box::new(self.clone())
    }

    fn get_cache_store(&self) -> Box<dyn RedisConnInterface + Send + Sync + 'static> {
        Box::new(self.clone())
    }
}

#[async_trait::async_trait]
impl GlobalStorageInterface for MockDb {
    fn get_cache_store(&self) -> Box<dyn RedisConnInterface + Send + Sync + 'static> {
        Box::new(self.clone())
    }
}

impl AccountsStorageInterface for MockDb {}

impl CommonStorageInterface for MockDb {
    fn get_global_storage_interface(&self) -> Box<dyn GlobalStorageInterface> {
        Box::new(self.clone())
    }
    fn get_storage_interface(&self) -> Box<dyn StorageInterface> {
        Box::new(self.clone())
    }

    fn get_accounts_storage_interface(&self) -> Box<dyn AccountsStorageInterface> {
        Box::new(self.clone())
    }
}

impl CommonStorageInterface for Store {
    fn get_global_storage_interface(&self) -> Box<dyn GlobalStorageInterface> {
        Box::new(self.clone())
    }
    fn get_storage_interface(&self) -> Box<dyn StorageInterface> {
        Box::new(self.clone())
    }
    fn get_accounts_storage_interface(&self) -> Box<dyn AccountsStorageInterface> {
        Box::new(self.clone())
    }
}

pub trait RequestIdStore {
    fn add_request_id(&mut self, _request_id: String) {}
    fn get_request_id(&self) -> Option<String> {
        None
    }
}

impl RequestIdStore for MockDb {}

impl RequestIdStore for Store {
    fn add_request_id(&mut self, request_id: String) {
        self.request_id = Some(request_id)
    }

    fn get_request_id(&self) -> Option<String> {
        self.request_id.clone()
    }
}

pub async fn get_and_deserialize_key<T>(
    db: &dyn StorageInterface,
    key: &str,
    type_name: &'static str,
) -> CustomResult<T, RedisError>
where
    T: serde::de::DeserializeOwned,
{
    use common_utils::ext_traits::ByteSliceExt;

    let bytes = db.get_key(key).await?;
    bytes
        .parse_struct(type_name)
        .change_context(RedisError::JsonDeserializationFailed)
}

dyn_clone::clone_trait_object!(StorageInterface);
dyn_clone::clone_trait_object!(GlobalStorageInterface);
dyn_clone::clone_trait_object!(AccountsStorageInterface);

impl RequestIdStore for KafkaStore {
    fn add_request_id(&mut self, request_id: String) {
        self.diesel_store.add_request_id(request_id)
    }
}

#[async_trait::async_trait]
impl FraudCheckInterface for KafkaStore {
    async fn insert_fraud_check_response(
        &self,
        new: storage::FraudCheckNew,
    ) -> CustomResult<FraudCheck, StorageError> {
        let frm = self.diesel_store.insert_fraud_check_response(new).await?;
        if let Err(er) = self
            .kafka_producer
            .log_fraud_check(&frm, None, self.tenant_id.clone())
            .await
        {
            logger::error!(message = "Failed to log analytics event for fraud check", error_message = ?er);
        }
        Ok(frm)
    }
    async fn update_fraud_check_response_with_attempt_id(
        &self,
        this: FraudCheck,
        fraud_check: FraudCheckUpdate,
    ) -> CustomResult<FraudCheck, StorageError> {
        let frm = self
            .diesel_store
            .update_fraud_check_response_with_attempt_id(this, fraud_check)
            .await?;
        if let Err(er) = self
            .kafka_producer
            .log_fraud_check(&frm, None, self.tenant_id.clone())
            .await
        {
            logger::error!(message="Failed to log analytics event for fraud check {frm:?}", error_message=?er)
        }
        Ok(frm)
    }
    async fn find_fraud_check_by_payment_id(
        &self,
        payment_id: id_type::PaymentId,
        merchant_id: id_type::MerchantId,
    ) -> CustomResult<FraudCheck, StorageError> {
        let frm = self
            .diesel_store
            .find_fraud_check_by_payment_id(payment_id, merchant_id)
            .await?;
        if let Err(er) = self
            .kafka_producer
            .log_fraud_check(&frm, None, self.tenant_id.clone())
            .await
        {
            logger::error!(message="Failed to log analytics event for fraud check {frm:?}", error_message=?er)
        }
        Ok(frm)
    }
    async fn find_fraud_check_by_payment_id_if_present(
        &self,
        payment_id: id_type::PaymentId,
        merchant_id: id_type::MerchantId,
    ) -> CustomResult<Option<FraudCheck>, StorageError> {
        let frm = self
            .diesel_store
            .find_fraud_check_by_payment_id_if_present(payment_id, merchant_id)
            .await?;

        if let Some(fraud_check) = frm.clone() {
            if let Err(er) = self
                .kafka_producer
                .log_fraud_check(&fraud_check, None, self.tenant_id.clone())
                .await
            {
                logger::error!(message="Failed to log analytics event for frm {frm:?}", error_message=?er);
            }
        }
        Ok(frm)
    }
}

#[async_trait::async_trait]
impl OrganizationInterface for KafkaStore {
    async fn insert_organization(
        &self,
        organization: OrganizationNew,
    ) -> CustomResult<Organization, StorageError> {
        self.diesel_store.insert_organization(organization).await
    }
    async fn find_organization_by_org_id(
        &self,
        org_id: &id_type::OrganizationId,
    ) -> CustomResult<Organization, StorageError> {
        self.diesel_store.find_organization_by_org_id(org_id).await
    }

    async fn update_organization_by_org_id(
        &self,
        org_id: &id_type::OrganizationId,
        update: OrganizationUpdate,
    ) -> CustomResult<Organization, StorageError> {
        self.diesel_store
            .update_organization_by_org_id(org_id, update)
            .await
    }
}


// Function: generate_authorization_signature
// File: crates/hyperswitch_connectors/src/connectors/fiserv.rs
// Module: hyperswitch_connectors

pub fn generate_authorization_signature(
        &self,
        auth: fiserv::FiservAuthType,
        request_id: &str,
        payload: &str,
        timestamp: i128,
    ) -> CustomResult<String, errors::ConnectorError>


// Implementation: impl api::payments::MandateSetup for for Prophetpay
// File: crates/hyperswitch_connectors/src/connectors/prophetpay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::payments::MandateSetup for for Prophetpay


// File: crates/hyperswitch_interfaces/src/api/subscriptions_v2.rs
// Module: hyperswitch_interfaces

//! SubscriptionsV2
use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::{
        GetSubscriptionEstimateData, GetSubscriptionPlanPricesData, GetSubscriptionPlansData,
        SubscriptionCreateData, SubscriptionCustomerData,
    },
    router_flow_types::{
        subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans, SubscriptionCreate},
        CreateConnectorCustomer, GetSubscriptionEstimate,
    },
    router_request_types::{
        subscriptions::{
            GetSubscriptionEstimateRequest, GetSubscriptionPlanPricesRequest,
            GetSubscriptionPlansRequest, SubscriptionCreateRequest,
        },
        ConnectorCustomerData,
    },
    router_response_types::{
        subscriptions::{
            GetSubscriptionEstimateResponse, GetSubscriptionPlanPricesResponse,
            GetSubscriptionPlansResponse, SubscriptionCreateResponse,
        },
        PaymentsResponseData,
    },
};

use crate::connector_integration_v2::ConnectorIntegrationV2;

/// trait SubscriptionsV2
pub trait SubscriptionsV2:
    GetSubscriptionPlansV2
    + SubscriptionsCreateV2
    + SubscriptionConnectorCustomerV2
    + GetSubscriptionPlanPricesV2
    + GetSubscriptionEstimateV2
{
}

/// trait GetSubscriptionPlans for V2
pub trait GetSubscriptionPlansV2:
    ConnectorIntegrationV2<
    GetSubscriptionPlans,
    GetSubscriptionPlansData,
    GetSubscriptionPlansRequest,
    GetSubscriptionPlansResponse,
>
{
}

/// trait GetSubscriptionPlans for V2
pub trait GetSubscriptionPlanPricesV2:
    ConnectorIntegrationV2<
    GetSubscriptionPlanPrices,
    GetSubscriptionPlanPricesData,
    GetSubscriptionPlanPricesRequest,
    GetSubscriptionPlanPricesResponse,
>
{
}

/// trait SubscriptionsCreateV2
pub trait SubscriptionsCreateV2:
    ConnectorIntegrationV2<
    SubscriptionCreate,
    SubscriptionCreateData,
    SubscriptionCreateRequest,
    SubscriptionCreateResponse,
>
{
}

/// trait SubscriptionConnectorCustomerV2
pub trait SubscriptionConnectorCustomerV2:
    ConnectorIntegrationV2<
    CreateConnectorCustomer,
    SubscriptionCustomerData,
    ConnectorCustomerData,
    PaymentsResponseData,
>
{
}
/// trait GetSubscriptionEstimate for V2
pub trait GetSubscriptionEstimateV2:
    ConnectorIntegrationV2<
    GetSubscriptionEstimate,
    GetSubscriptionEstimateData,
    GetSubscriptionEstimateRequest,
    GetSubscriptionEstimateResponse,
>
{
}


// Struct: GetSearchRequestWithIndex
// File: crates/api_models/src/analytics/search.rs
// Module: api_models
// Implementations: 0

pub struct GetSearchRequestWithIndex


// Function: get_authentication_connector_data
// File: crates/router/src/core/authentication/utils.rs
// Module: router

pub fn get_authentication_connector_data(
    state: &SessionState,
    key_store: &domain::MerchantKeyStore,
    business_profile: &domain::Profile,
    authentication_connector: Option<String>,
) -> RouterResult<(
    common_enums::AuthenticationConnectors,
    payments::helpers::MerchantConnectorAccountType,
)>


// Function: list_routing_configs_for_profile
// File: crates/router/src/routes/routing.rs
// Module: router

pub fn list_routing_configs_for_profile(
    state: web::Data<AppState>,
    req: HttpRequest,
    query: web::Query<RoutingRetrieveQuery>,
    transaction_type: Option<enums::TransactionType>,
) -> impl Responder


// Struct: HyperswitchAiDataRequest
// File: crates/hyperswitch_domain_models/src/chat.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct HyperswitchAiDataRequest


// Function: create_payment_method_card_core
// File: crates/router/src/core/payment_methods.rs
// Module: router

pub fn create_payment_method_card_core(
    state: &SessionState,
    req: api::PaymentMethodCreate,
    merchant_context: &domain::MerchantContext,
    profile: &domain::Profile,
    merchant_id: &id_type::MerchantId,
    customer_id: &id_type::GlobalCustomerId,
    payment_method_id: id_type::GlobalPaymentMethodId,
    payment_method_billing_address: Option<
        Encryptable<hyperswitch_domain_models::address::Address>,
    >,
) -> RouterResult<(api::PaymentMethodResponse, domain::PaymentMethod)>


// Module Structure
// File: crates/hyperswitch_connectors/src/connectors/gigadat.rs
// Module: hyperswitch_connectors

// Public submodules:
pub mod transformers;


// Implementation: impl api::ConnectorCustomer for for Dwolla
// File: crates/hyperswitch_connectors/src/connectors/dwolla.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::ConnectorCustomer for for Dwolla


// Implementation: impl api::PaymentSync for for Dwolla
// File: crates/hyperswitch_connectors/src/connectors/dwolla.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSync for for Dwolla


// Struct: MerchantConnectorAccountNew
// File: crates/diesel_models/src/merchant_connector_account.rs
// Module: diesel_models
// Implementations: 0

pub struct MerchantConnectorAccountNew


// Function: get_client_builder
// File: crates/external_services/src/http_client/client.rs
// Module: external_services

pub fn get_client_builder(
    proxy_config: &Proxy,
) -> CustomResult<reqwest::ClientBuilder, HttpClientError>


// Struct: AuthenticationDataWithMultipleProfiles
// File: crates/router/src/services/authentication.rs
// Module: router
// Implementations: 1
// Traits: AuthInfo

pub struct AuthenticationDataWithMultipleProfiles


                    .store
                    .update_dynamic_routing_stats(
                        payment_attempt.attempt_id.clone(),
                        &payment_attempt.merchant_id.to_owned(),
                        dynamic_routing_update,
                    )
                    .await
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("Unable to update dynamic routing stats to db")?;
            } else {
                let dynamic_routing_stats = DynamicRoutingStatsNew {
                    payment_id: payment_attempt.payment_id.to_owned(),
                    attempt_id: payment_attempt.attempt_id.clone(),
                    merchant_id: payment_attempt.merchant_id.to_owned(),
                    profile_id: payment_attempt.profile_id.to_owned(),
                    amount: payment_attempt.get_total_amount(),
                    success_based_routing_connector: first_merchant_success_based_connector_label
                        .to_string(),
                    payment_connector: payment_connector.to_string(),
                    payment_method_type: payment_attempt.payment_method_type,
                    currency: payment_attempt.currency,
                    payment_method: payment_attempt.payment_method,
                    capture_method: payment_attempt.capture_method,
                    authentication_type: payment_attempt.authentication_type,
                    payment_status: payment_attempt.status,
                    conclusive_classification: outcome,
                    created_at: common_utils::date_time::now(),
                    global_success_based_connector: Some(
                        first_global_success_based_connector.label.to_string(),
                    ),
                };

                state
                    .store
                    .insert_dynamic_routing_stat_entry(dynamic_routing_stats)
                    .await
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("Unable to push dynamic routing stats to db")?;
            };

            let label_with_status = routing_utils::UpdateLabelWithStatusEventRequest {
                label: routable_connector.clone().to_string(),
                status: payment_status_attribute == common_enums::AttemptStatus::Charged,
            };
            let event_request = routing_utils::UpdateSuccessRateWindowEventRequest {
                id: payment_attempt.profile_id.get_string_repr().to_string(),
                params: success_based_routing_config_params.clone(),
                labels_with_status: vec![label_with_status.clone()],
                global_labels_with_status: vec![label_with_status],
                config: success_based_routing_configs
                    .config
                    .as_ref()
                    .map(routing_utils::UpdateSuccessRateWindowConfig::from),
            };

            let routing_events_wrapper = routing_utils::RoutingEventsWrapper::new(
                state.tenant.tenant_id.clone(),
                state.request_id,
                payment_attempt.payment_id.get_string_repr().to_string(),
                profile_id.to_owned(),
                payment_attempt.merchant_id.to_owned(),
                "IntelligentRouter: UpdateSuccessRateWindow".to_string(),
                Some(event_request.clone()),
                true,
                false,
            );

            let closure = || async {
                let update_response_result = client
                    .update_success_rate(
                        profile_id.get_string_repr().into(),
                        success_based_routing_configs,
                        success_based_routing_config_params,
                        vec![routing_types::RoutableConnectorChoiceWithStatus::new(
                            routable_connector.clone(),
                            payment_status_attribute == common_enums::AttemptStatus::Charged,
                        )],
                        state.get_grpc_headers(),
                    )
                    .await
                    .change_context(errors::RoutingError::SuccessRateCalculationError)
                    .attach_printable(
                        "unable to update success based routing window in dynamic routing service",
                    );

                match update_response_result {
                    Ok(update_response) => {
                        let updated_resp =
                            routing_utils::UpdateSuccessRateWindowEventResponse::try_from(
                                &update_response,
                            )
                            .change_context(errors::RoutingError::RoutingEventsError { message: "Unable to convert to UpdateSuccessRateWindowEventResponse from UpdateSuccessRateWindowResponse".to_string(), status_code: 500 })?;
                        Ok(Some(updated_resp))
                    }
                    Err(err) => {
                        logger::error!(
                            "unable to update connector score in dynamic routing service: {:?}",
                            err.current_context()
                        );

                        Err(err)
                    }
                }
            };

            let events_response = routing_events_wrapper
                .construct_event_builder(
                    "SuccessRateCalculator.UpdateSuccessRateWindow".to_string(),
                    routing_events::RoutingEngine::IntelligentRouter,
                    routing_events::ApiMethod::Grpc,
                )
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "SR-Intelligent-Router: Failed to update success rate in Intelligent-Router",
                )?
                .trigger_event(state, closure)
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "SR-Intelligent-Router: Failed to update success rate in Intelligent-Router",
                )?;

            let _response: routing_utils::UpdateSuccessRateWindowEventResponse = events_response
                .response
                .ok_or(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "UpdateSuccessRateWindowEventResponse not found in RoutingEventResponse",
                )?;

            let mut routing_event = events_response
                .event
                .ok_or(errors::RoutingError::RoutingEventsError {
                    message:
                        "SR-Intelligent-Router: RoutingEvent not found in RoutingEventsResponse"
                            .to_string(),
                    status_code: 500,
                })
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "SR-Intelligent-Router: RoutingEvent not found in RoutingEventsResponse",
                )?;

            routing_event.set_status_code(200);
            routing_event.set_payment_connector(routable_connector); // we can do this inside the event wrap by implementing an interface on the req type
            state.event_handler().log_event(&routing_event);

            Ok(())
        } else {
            Ok(())
        }
    } else {
        Ok(())
    }
}

/// update window for elimination based dynamic routing
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
#[instrument(skip_all)]
pub async fn update_window_for_elimination_routing(
    state: &SessionState,
    payment_attempt: &storage::PaymentAttempt,
    profile_id: &id_type::ProfileId,
    dynamic_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
    elimination_routing_configs_params_interpolator: DynamicRoutingConfigParamsInterpolator,
    gsm_error_category: common_enums::ErrorCategory,
) -> RouterResult<()> {
    if let Some(elimination_algo_ref) = dynamic_algo_ref.elimination_routing_algorithm {
        if elimination_algo_ref.enabled_feature != routing_types::DynamicRoutingFeatures::None {
            let client = &state
                .grpc_client
                .dynamic_routing
                .as_ref()
                .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
                    message: "dynamic routing gRPC client not found".to_string(),
                })?
                .elimination_based_client;

            let elimination_routing_config = fetch_dynamic_routing_configs::<
                routing_types::EliminationRoutingConfig,
            >(
                state,
                profile_id,
                elimination_algo_ref
                    .algorithm_id_with_timestamp
                    .algorithm_id
                    .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
                        message: "elimination routing algorithm_id not found".to_string(),
                    })
                    .attach_printable(
                        "elimination_routing_algorithm_id not found in business_profile",
                    )?,
            )
            .await
            .change_context(errors::ApiErrorResponse::GenericNotFoundError {
                message: "elimination based dynamic routing configs not found".to_string(),
            })
            .attach_printable("unable to retrieve success_rate based dynamic routing configs")?;

            let payment_connector = &payment_attempt.connector.clone().ok_or(
                errors::ApiErrorResponse::GenericNotFoundError {
                    message: "unable to derive payment connector from payment attempt".to_string(),
                },
            )?;

            let elimination_routing_config_params = elimination_routing_configs_params_interpolator
                .get_string_val(
                    elimination_routing_config
                        .params
                        .as_ref()
                        .ok_or(errors::RoutingError::EliminationBasedRoutingParamsNotFoundError)
                        .change_context(errors::ApiErrorResponse::InternalServerError)?,
                );

            let labels_with_bucket_name =
                vec![routing_types::RoutableConnectorChoiceWithBucketName::new(
                    routing_types::RoutableConnectorChoice {
                        choice_kind: api_models::routing::RoutableChoiceKind::FullStruct,
                        connector: common_enums::RoutableConnectors::from_str(
                            payment_connector.as_str(),
                        )
                        .change_context(errors::ApiErrorResponse::InternalServerError)
                        .attach_printable("unable to infer routable_connector from connector")?,
                        merchant_connector_id: payment_attempt.merchant_connector_id.clone(),
                    },
                    gsm_error_category.to_string(),
                )];

            let event_request = routing_utils::UpdateEliminationBucketEventRequest {
                id: profile_id.get_string_repr().to_string(),
                params: elimination_routing_config_params.clone(),
                labels_with_bucket_name: labels_with_bucket_name
                    .iter()
                    .map(|conn_choice| {
                        routing_utils::LabelWithBucketNameEventRequest::from(conn_choice)
                    })
                    .collect(),
                config: elimination_routing_config
                    .elimination_analyser_config
                    .as_ref()
                    .map(routing_utils::EliminationRoutingEventBucketConfig::from),
            };

            let routing_events_wrapper = routing_utils::RoutingEventsWrapper::new(
                state.tenant.tenant_id.clone(),
                state.request_id,
                payment_attempt.payment_id.get_string_repr().to_string(),
                profile_id.to_owned(),
                payment_attempt.merchant_id.to_owned(),
                "IntelligentRouter: UpdateEliminationBucket".to_string(),
                Some(event_request.clone()),
                true,
                false,
            );

            let closure = || async {
                let update_response_result = client
                .update_elimination_bucket_config(
                    profile_id.get_string_repr().to_string(),
                    elimination_routing_config_params,
                    labels_with_bucket_name,
                    elimination_routing_config.elimination_analyser_config,
                    state.get_grpc_headers(),
                )
                .await
                .change_context(errors::RoutingError::EliminationRoutingCalculationError)
                .attach_printable(
                    "unable to update elimination based routing buckets in dynamic routing service",
                );

                match update_response_result {
                    Ok(resp) => {
                        let updated_resp =
                            routing_utils::UpdateEliminationBucketEventResponse::try_from(&resp)
                            .change_context(errors::RoutingError::RoutingEventsError { message: "Unable to convert to UpdateEliminationBucketEventResponse from UpdateEliminationBucketResponse".to_string(), status_code: 500 })?;

                        Ok(Some(updated_resp))
                    }
                    Err(err) => {
                        logger::error!(
                            "unable to update elimination  score in dynamic routing service: {:?}",
                            err.current_context()
                        );

                        Err(err)
                    }
                }
            };

            let events_response = routing_events_wrapper.construct_event_builder( "EliminationAnalyser.UpdateEliminationBucket".to_string(),
            routing_events::RoutingEngine::IntelligentRouter,
            routing_events::ApiMethod::Grpc)
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Elimination-Intelligent-Router: Failed to update elimination bucket in Intelligent-Router")?
            .trigger_event(state, closure)
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Elimination-Intelligent-Router: Failed to update elimination bucket in Intelligent-Router")?;

            let _response: routing_utils::UpdateEliminationBucketEventResponse = events_response
                .response
                .ok_or(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "UpdateEliminationBucketEventResponse not found in RoutingEventResponse",
                )?;

            let mut routing_event = events_response
                .event
                .ok_or(errors::RoutingError::RoutingEventsError {
                    message:
                        "Elimination-Intelligent-Router: RoutingEvent not found in RoutingEventsResponse"
                            .to_string(),
                    status_code: 500,
                })
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Elimination-Intelligent-Router: RoutingEvent not found in RoutingEventsResponse")?;

            routing_event.set_status_code(200);
            routing_event.set_payment_connector(routing_types::RoutableConnectorChoice {
                choice_kind: api_models::routing::RoutableChoiceKind::FullStruct,
                connector: common_enums::RoutableConnectors::from_str(payment_connector.as_str())
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("unable to infer routable_connector from connector")?,
                merchant_connector_id: payment_attempt.merchant_connector_id.clone(),
            });
            state.event_handler().log_event(&routing_event);
            Ok(())
        } else {
            Ok(())
        }
    } else {
        Ok(())
    }
}

/// metrics for contract based dynamic routing
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
#[instrument(skip_all)]
pub async fn push_metrics_with_update_window_for_contract_based_routing(
    state: &SessionState,
    payment_attempt: &storage::PaymentAttempt,
    routable_connectors: Vec<routing_types::RoutableConnectorChoice>,
    profile_id: &id_type::ProfileId,
    dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
    _dynamic_routing_config_params_interpolator: DynamicRoutingConfigParamsInterpolator,
) -> RouterResult<()> {
    if let Some(contract_routing_algo_ref) = dynamic_routing_algo_ref.contract_based_routing {
        if contract_routing_algo_ref.enabled_feature != routing_types::DynamicRoutingFeatures::None
        {
            let client = &state
                .grpc_client
                .dynamic_routing
                .as_ref()
                .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
                    message: "dynamic routing gRPC client not found".to_string(),
                })?
                .contract_based_client;

            let payment_connector = &payment_attempt.connector.clone().ok_or(
                errors::ApiErrorResponse::GenericNotFoundError {
                    message: "unable to derive payment connector from payment attempt".to_string(),
                },
            )?;

            let contract_based_routing_config =
                fetch_dynamic_routing_configs::<routing_types::ContractBasedRoutingConfig>(
                    state,
                    profile_id,
                    contract_routing_algo_ref
                        .algorithm_id_with_timestamp
                        .algorithm_id
                        .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
                            message: "contract_routing algorithm_id not found".to_string(),
                        })
                        .attach_printable(
                            "contract_based_routing_algorithm_id not found in business_profile",
                        )?,
                )
                .await
                .change_context(errors::ApiErrorResponse::GenericNotFoundError {
                    message: "contract based dynamic routing configs not found".to_string(),
                })
                .attach_printable("unable to retrieve contract based dynamic routing configs")?;

            let mut existing_label_info = None;

            contract_based_routing_config
                .label_info
                .as_ref()
                .map(|label_info_vec| {
                    for label_info in label_info_vec {
                        if Some(&label_info.mca_id)
                            == payment_attempt.merchant_connector_id.as_ref()
                        {
                            existing_label_info = Some(label_info.clone());
                        }
                    }
                });

            let final_label_info = existing_label_info
                .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
                    message: "LabelInformation from ContractBasedRoutingConfig not found"
                        .to_string(),
                })
                .attach_printable(
                    "unable to get LabelInformation from ContractBasedRoutingConfig",
                )?;

            logger::debug!(
                "contract based routing: matched LabelInformation - {:?}",
                final_label_info
            );

            let request_label_info = routing_types::LabelInformation {
                label: final_label_info.label.clone(),
                target_count: final_label_info.target_count,
                target_time: final_label_info.target_time,
                mca_id: final_label_info.mca_id.to_owned(),
            };

            let payment_status_attribute =
                get_desired_payment_status_for_dynamic_routing_metrics(payment_attempt.status);

            if payment_status_attribute == common_enums::AttemptStatus::Charged {
                let event_request = routing_utils::UpdateContractRequestEventRequest {
                    id: profile_id.get_string_repr().to_string(),
                    params: "".to_string(),
                    labels_information: vec![
                        routing_utils::ContractLabelInformationEventRequest::from(
                            &request_label_info,
                        ),
                    ],
                };

                let routing_events_wrapper = routing_utils::RoutingEventsWrapper::new(
                    state.tenant.tenant_id.clone(),
                    state.request_id,
                    payment_attempt.payment_id.get_string_repr().to_string(),
                    profile_id.to_owned(),
                    payment_attempt.merchant_id.to_owned(),
                    "IntelligentRouter: UpdateContractScore".to_string(),
                    Some(event_request.clone()),
                    true,
                    false,
                );

                let closure = || async {
                    let update_response_result = client
                    .update_contracts(
                        profile_id.get_string_repr().into(),
                        vec![request_label_info],
                        "".to_string(),
                        vec![],
                        1,
                        state.get_grpc_headers(),
                    )
                    .await
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable(
                        "unable to update contract based routing window in dynamic routing service",
                    );

                    match update_response_result {
                        Ok(resp) => {
                            let updated_resp =
                                routing_utils::UpdateContractEventResponse::try_from(&resp)
                                .change_context(errors::RoutingError::RoutingEventsError { message: "Unable to convert to UpdateContractEventResponse from UpdateContractResponse".to_string(), status_code: 500 })?;
                            Ok(Some(updated_resp))
                        }
                        Err(err) => {
                            logger::error!(
                                "unable to update elimination  score in dynamic routing service: {:?}",
                                err.current_context()
                            );

                            // have to refactor errors
                            Err(error_stack::report!(
                                errors::RoutingError::ContractScoreUpdationError
                            ))
                        }
                    }
                };

                let events_response = routing_events_wrapper.construct_event_builder( "ContractScoreCalculator.UpdateContract".to_string(),
                routing_events::RoutingEngine::IntelligentRouter,
                routing_events::ApiMethod::Grpc)
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("ContractRouting-Intelligent-Router: Failed to construct RoutingEventsBuilder")?
                .trigger_event(state, closure)
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("ContractRouting-Intelligent-Router: Failed to update contract scores in Intelligent-Router")?;

                let _response: routing_utils::UpdateContractEventResponse = events_response
                    .response
                    .ok_or(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable(
                        "UpdateContractEventResponse not found in RoutingEventResponse",
                    )?;

                let mut routing_event = events_response
                    .event
                    .ok_or(errors::RoutingError::RoutingEventsError {
                        message:
                            "ContractRouting-Intelligent-Router: RoutingEvent not found in RoutingEventsResponse"
                                .to_string(),
                        status_code: 500,
                    })
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("ContractRouting-Intelligent-Router: RoutingEvent not found in RoutingEventsResponse")?;

                routing_event.set_payment_connector(routing_types::RoutableConnectorChoice {
                    choice_kind: api_models::routing::RoutableChoiceKind::FullStruct,
                    connector: common_enums::RoutableConnectors::from_str(
                        final_label_info.label.as_str(),
                    )
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("unable to infer routable_connector from connector")?,
                    merchant_connector_id: Some(final_label_info.mca_id.clone()),
                });
                routing_event.set_status_code(200);
                state.event_handler().log_event(&routing_event);
            }

            let contract_based_connectors = routable_connectors
                .into_iter()
                .filter(|conn| {
                    conn.merchant_connector_id.clone() == Some(final_label_info.mca_id.clone())
                })
                .collect::<Vec<_>>();

            let contract_scores = client
                .calculate_contract_score(
                    profile_id.get_string_repr().into(),
                    contract_based_routing_config.clone(),
                    "".to_string(),
                    contract_based_connectors,
                    state.get_grpc_headers(),
                )
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "unable to calculate/fetch contract scores from dynamic routing service",
                )?;

            let first_contract_based_connector = &contract_scores
                .labels_with_score
                .first()
                .ok_or(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "unable to fetch the first connector from list of connectors obtained from dynamic routing service",
                )?;

            let (first_contract_based_connector, connector_score, current_payment_cnt) = (first_contract_based_connector.label
                .split_once(':')
                .ok_or(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(format!(
                    "unable to split connector_name and mca_id from the first connector {first_contract_based_connector:?} obtained from dynamic routing service",

                ))?
                .0, first_contract_based_connector.score, first_contract_based_connector.current_count );

            core_metrics::DYNAMIC_CONTRACT_BASED_ROUTING.add(
                1,
                router_env::metric_attributes!(
                    (
                        "tenant",
                        state.tenant.tenant_id.get_string_repr().to_owned(),
                    ),
                    (
                        "merchant_profile_id",
                        format!(
                            "{}:{}",
                            payment_attempt.merchant_id.get_string_repr(),
                            payment_attempt.profile_id.get_string_repr()
                        ),
                    ),
                    (
                        "contract_based_routing_connector",
                        first_contract_based_connector.to_string(),
                    ),
                    (
                        "contract_based_routing_connector_score",
                        connector_score.to_string(),
                    ),
                    (
                        "current_payment_count_contract_based_routing_connector",
                        current_payment_cnt.to_string(),
                    ),
                    ("payment_connector", payment_connector.to_string()),
                    (
                        "currency",
                        payment_attempt
                            .currency
                            .map_or_else(|| "None".to_string(), |currency| currency.to_string()),
                    ),
                    (
                        "payment_method",
                        payment_attempt.payment_method.map_or_else(
                            || "None".to_string(),
                            |payment_method| payment_method.to_string(),
                        ),
                    ),
                    (
                        "payment_method_type",
                        payment_attempt.payment_method_type.map_or_else(
                            || "None".to_string(),
                            |payment_method_type| payment_method_type.to_string(),
                        ),
                    ),
                    (
                        "capture_method",
                        payment_attempt.capture_method.map_or_else(
                            || "None".to_string(),
                            |capture_method| capture_method.to_string(),
                        ),
                    ),
                    (
                        "authentication_type",
                        payment_attempt.authentication_type.map_or_else(
                            || "None".to_string(),
                            |authentication_type| authentication_type.to_string(),
                        ),
                    ),
                    ("payment_status", payment_attempt.status.to_string()),
                ),
            );
            logger::debug!("successfully pushed contract_based_routing metrics");

            Ok(())
        } else {
            Ok(())
        }
    } else {
        Ok(())
    }
}

#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
fn get_desired_payment_status_for_dynamic_routing_metrics(
    attempt_status: common_enums::AttemptStatus,
) -> common_enums::AttemptStatus {
    match attempt_status {
        common_enums::AttemptStatus::Charged
        | common_enums::AttemptStatus::Authorized
        | common_enums::AttemptStatus::PartialCharged
        | common_enums::AttemptStatus::PartialChargedAndChargeable
        | common_enums::AttemptStatus::PartiallyAuthorized => common_enums::AttemptStatus::Charged,
        common_enums::AttemptStatus::Failure
        | common_enums::AttemptStatus::AuthorizationFailed
        | common_enums::AttemptStatus::AuthenticationFailed
        | common_enums::AttemptStatus::CaptureFailed
        | common_enums::AttemptStatus::RouterDeclined => common_enums::AttemptStatus::Failure,
        common_enums::AttemptStatus::Started
        | common_enums::AttemptStatus::AuthenticationPending
        | common_enums::AttemptStatus::AuthenticationSuccessful
        | common_enums::AttemptStatus::Authorizing
        | common_enums::AttemptStatus::CodInitiated
        | common_enums::AttemptStatus::Voided
        | common_enums::AttemptStatus::VoidedPostCharge
        | common_enums::AttemptStatus::VoidInitiated
        | common_enums::AttemptStatus::CaptureInitiated
        | common_enums::AttemptStatus::VoidFailed
        | common_enums::AttemptStatus::AutoRefunded
        | common_enums::AttemptStatus::Unresolved
        | common_enums::AttemptStatus::Pending
        | common_enums::AttemptStatus::IntegrityFailure
        | common_enums::AttemptStatus::PaymentMethodAwaited
        | common_enums::AttemptStatus::ConfirmationAwaited
        | common_enums::AttemptStatus::DeviceDataCollectionPending
        | common_enums::AttemptStatus::Expired => common_enums::AttemptStatus::Pending,
    }
}

#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
impl ForeignFrom<common_enums::AttemptStatus> for open_router::TxnStatus {
    fn foreign_from(attempt_status: common_enums::AttemptStatus) -> Self {
        match attempt_status {
            common_enums::AttemptStatus::Started => Self::Started,
            common_enums::AttemptStatus::AuthenticationFailed => Self::AuthenticationFailed,
            common_enums::AttemptStatus::RouterDeclined => Self::JuspayDeclined,
            common_enums::AttemptStatus::AuthenticationPending => Self::PendingVbv,
            common_enums::AttemptStatus::AuthenticationSuccessful => Self::VBVSuccessful,
            common_enums::AttemptStatus::Authorized
            | common_enums::AttemptStatus::PartiallyAuthorized => Self::Authorized,
            common_enums::AttemptStatus::AuthorizationFailed => Self::AuthorizationFailed,
            common_enums::AttemptStatus::Charged => Self::Charged,
            common_enums::AttemptStatus::Authorizing => Self::Authorizing,
            common_enums::AttemptStatus::CodInitiated => Self::CODInitiated,
            common_enums::AttemptStatus::Voided | common_enums::AttemptStatus::Expired => {
                Self::Voided
            }
            common_enums::AttemptStatus::VoidedPostCharge => Self::VoidedPostCharge,
            common_enums::AttemptStatus::VoidInitiated => Self::VoidInitiated,
            common_enums::AttemptStatus::CaptureInitiated => Self::CaptureInitiated,
            common_enums::AttemptStatus::CaptureFailed => Self::CaptureFailed,
            common_enums::AttemptStatus::VoidFailed => Self::VoidFailed,
            common_enums::AttemptStatus::AutoRefunded => Self::AutoRefunded,
            common_enums::AttemptStatus::PartialCharged => Self::PartialCharged,
            common_enums::AttemptStatus::PartialChargedAndChargeable => Self::ToBeCharged,
            common_enums::AttemptStatus::Unresolved => Self::Pending,
            common_enums::AttemptStatus::Pending
            | common_enums::AttemptStatus::IntegrityFailure => Self::Pending,
            common_enums::AttemptStatus::Failure => Self::Failure,
            common_enums::AttemptStatus::PaymentMethodAwaited => Self::Pending,
            common_enums::AttemptStatus::ConfirmationAwaited => Self::Pending,
            common_enums::AttemptStatus::DeviceDataCollectionPending => Self::Pending,
        }
    }
}

#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
fn get_dynamic_routing_based_metrics_outcome_for_payment(
    payment_status_attribute: common_enums::AttemptStatus,
    payment_connector: String,
    first_success_based_connector: String,
) -> common_enums::SuccessBasedRoutingConclusiveState {
    match payment_status_attribute {
        common_enums::AttemptStatus::Charged
            if *first_success_based_connector == *payment_connector =>
        {
            common_enums::SuccessBasedRoutingConclusiveState::TruePositive
        }
        common_enums::AttemptStatus::Failure
            if *first_success_based_connector == *payment_connector =>
        {
            common_enums::SuccessBasedRoutingConclusiveState::FalsePositive
        }
        common_enums::AttemptStatus::Failure
            if *first_success_based_connector != *payment_connector =>
        {
            common_enums::SuccessBasedRoutingConclusiveState::TrueNegative
        }
        common_enums::AttemptStatus::Charged
            if *first_success_based_connector != *payment_connector =>
        {
            common_enums::SuccessBasedRoutingConclusiveState::FalseNegative
        }
        _ => common_enums::SuccessBasedRoutingConclusiveState::NonDeterministic,
    }
}

#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
pub async fn disable_dynamic_routing_algorithm(
    state: &SessionState,
    key_store: domain::MerchantKeyStore,
    business_profile: domain::Profile,
    dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
    dynamic_routing_type: routing_types::DynamicRoutingType,
) -> 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 (algorithm_id, mut dynamic_routing_algorithm, cache_entries_to_redact) =
        match dynamic_routing_type {
            routing_types::DynamicRoutingType::SuccessRateBasedRouting => {
                let Some(algorithm_ref) = dynamic_routing_algo_ref.success_based_algorithm else {
                    Err(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Success rate based routing is already disabled".to_string(),
                    })?
                };
                let Some(algorithm_id) = algorithm_ref.algorithm_id_with_timestamp.algorithm_id
                else {
                    Err(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Algorithm is already inactive".to_string(),
                    })?
                };

                let cache_key = format!(
                    "{}_{}",
                    business_profile.get_id().get_string_repr(),
                    algorithm_id.get_string_repr()
                );
                let cache_entries_to_redact =
                    vec![cache::CacheKind::SuccessBasedDynamicRoutingCache(
                        cache_key.into(),
                    )];
                (
                    algorithm_id,
                    routing_types::DynamicRoutingAlgorithmRef {
                        success_based_algorithm: Some(routing_types::SuccessBasedAlgorithm {
                            algorithm_id_with_timestamp:
                                routing_types::DynamicAlgorithmWithTimestamp::new(None),
                            enabled_feature: routing_types::DynamicRoutingFeatures::None,
                        }),
                        elimination_routing_algorithm: dynamic_routing_algo_ref
                            .elimination_routing_algorithm,
                        contract_based_routing: dynamic_routing_algo_ref.contract_based_routing,
                        dynamic_routing_volume_split: dynamic_routing_algo_ref
                            .dynamic_routing_volume_split,
                        is_merchant_created_in_decision_engine: dynamic_routing_algo_ref
                            .is_merchant_created_in_decision_engine,
                    },
                    cache_entries_to_redact,
                )
            }
            routing_types::DynamicRoutingType::EliminationRouting => {
                let Some(algorithm_ref) = dynamic_routing_algo_ref.elimination_routing_algorithm
                else {
                    Err(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Elimination routing is already disabled".to_string(),
                    })?
                };
                let Some(algorithm_id) = algorithm_ref.algorithm_id_with_timestamp.algorithm_id
                else {
                    Err(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Algorithm is already inactive".to_string(),
                    })?
                };
                let cache_key = format!(
                    "{}_{}",
                    business_profile.get_id().get_string_repr(),
                    algorithm_id.get_string_repr()
                );
                let cache_entries_to_redact =
                    vec![cache::CacheKind::EliminationBasedDynamicRoutingCache(
                        cache_key.into(),
                    )];
                (
                    algorithm_id,
                    routing_types::DynamicRoutingAlgorithmRef {
                        success_based_algorithm: dynamic_routing_algo_ref.success_based_algorithm,
                        dynamic_routing_volume_split: dynamic_routing_algo_ref
                            .dynamic_routing_volume_split,
                        elimination_routing_algorithm: Some(
                            routing_types::EliminationRoutingAlgorithm {
                                algorithm_id_with_timestamp:
                                    routing_types::DynamicAlgorithmWithTimestamp::new(None),
                                enabled_feature: routing_types::DynamicRoutingFeatures::None,
                            },
                        ),
                        contract_based_routing: dynamic_routing_algo_ref.contract_based_routing,
                        is_merchant_created_in_decision_engine: dynamic_routing_algo_ref
                            .is_merchant_created_in_decision_engine,
                    },
                    cache_entries_to_redact,
                )
            }
            routing_types::DynamicRoutingType::ContractBasedRouting => {
                let Some(algorithm_ref) = dynamic_routing_algo_ref.contract_based_routing else {
                    Err(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Contract routing is already disabled".to_string(),
                    })?
                };
                let Some(algorithm_id) = algorithm_ref.algorithm_id_with_timestamp.algorithm_id
                else {
                    Err(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Algorithm is already inactive".to_string(),
                    })?
                };
                let cache_key = format!(
                    "{}_{}",
                    business_profile.get_id().get_string_repr(),
                    algorithm_id.get_string_repr()
                );
                let cache_entries_to_redact =
                    vec![cache::CacheKind::ContractBasedDynamicRoutingCache(
                        cache_key.into(),
                    )];
                (
                    algorithm_id,
                    routing_types::DynamicRoutingAlgorithmRef {
                        success_based_algorithm: dynamic_routing_algo_ref.success_based_algorithm,
                        elimination_routing_algorithm: dynamic_routing_algo_ref
                            .elimination_routing_algorithm,
                        dynamic_routing_volume_split: dynamic_routing_algo_ref
                            .dynamic_routing_volume_split,
                        contract_based_routing: Some(routing_types::ContractRoutingAlgorithm {
                            algorithm_id_with_timestamp:
                                routing_types::DynamicAlgorithmWithTimestamp::new(None),
                            enabled_feature: routing_types::DynamicRoutingFeatures::None,
                        }),
                        is_merchant_created_in_decision_engine: dynamic_routing_algo_ref
                            .is_merchant_created_in_decision_engine,
                    },
                    cache_entries_to_redact,
                )
            }
        };

    // Call to DE here
    if state.conf.open_router.dynamic_routing_enabled {
        disable_decision_engine_dynamic_routing_setup(
            state,
            business_profile.get_id(),
            dynamic_routing_type,
            &mut dynamic_routing_algorithm,
        )
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("unable to disable dynamic routing setup in decision engine")?;
    }

    // redact cache for dynamic routing config
    let _ = cache::redact_from_redis_and_publish(
        state.store.get_cache_store().as_ref(),
        cache_entries_to_redact,
    )
    .await
    .change_context(errors::ApiErrorResponse::InternalServerError)
    .attach_printable(
        "unable to publish into the redact channel for evicting the dynamic routing config cache",
    )?;

    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();
    update_business_profile_active_dynamic_algorithm_ref(
        db,
        key_manager_state,
        &key_store,
        business_profile,
        dynamic_routing_algorithm,
    )
    .await?;

    core_metrics::ROUTING_UNLINK_CONFIG_SUCCESS_RESPONSE.add(
        1,
        router_env::metric_attributes!(("profile_id", profile_id)),
    );

    Ok(ApplicationResponse::Json(response))
}

#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
pub async fn enable_dynamic_routing_algorithm(
    state: &SessionState,
    key_store: domain::MerchantKeyStore,
    business_profile: domain::Profile,
    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 {
        routing_types::DynamicRoutingType::SuccessRateBasedRouting => {
            dynamic_routing
                .disable_algorithm_id(routing_types::DynamicRoutingType::ContractBasedRouting);

            enable_specific_routing_algorithm(
                state,
                key_store,
                business_profile,
                feature_to_enable,
                dynamic_routing.clone(),
                dynamic_routing_type,
                dynamic_routing.success_based_algorithm,
                payload,
            )
            .await
        }
        routing_types::DynamicRoutingType::EliminationRouting => {
            enable_specific_routing_algorithm(
                state,
                key_store,
                business_profile,
                feature_to_enable,
                dynamic_routing.clone(),
                dynamic_routing_type,
                dynamic_routing.elimination_routing_algorithm,
                payload,
            )
            .await
        }
        routing_types::DynamicRoutingType::ContractBasedRouting => {
            Err((errors::ApiErrorResponse::InvalidRequestData {
                message: "Contract routing cannot be set as default".to_string(),
            })
            .into())
        }
    }
}

#[allow(clippy::too_many_arguments)]
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
pub async fn enable_specific_routing_algorithm<A>(
    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,
    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(
            state,
            key_store,
            business_profile,
            feature_to_enable,
            dynamic_routing_algo_ref,
            dynamic_routing_type,
        )
        .await;
    };

    // Algorithm was in disabled state
    let Some(algo_type_algorithm_id) = algo_type
        .clone()
        .get_algorithm_id_with_timestamp()
        .algorithm_id
    else {
        return default_specific_dynamic_routing_setup(
            state,
            key_store,
            business_profile,
            feature_to_enable,
            dynamic_routing_algo_ref,
            dynamic_routing_type,
        )
        .await;
    };
    let db = state.store.as_ref();
    let profile_id = business_profile.get_id().clone();


// Function: extract_domain
// File: crates/router/src/types/domain/user.rs
// Module: router

pub fn extract_domain(&self) -> UserResult<&str>


// Struct: AdyenSplitData
// File: crates/common_types/src/domain.rs
// Module: common_types
// Implementations: 0

// Documentation: Fee information for Split Payments to be charged on the payment being collected for Adyen

pub struct AdyenSplitData


// Struct: PaymentMethodsUpdateForm
// File: crates/router/src/core/payment_methods/migration.rs
// Module: router
// Implementations: 1

pub struct PaymentMethodsUpdateForm


// Function: new
// File: crates/hyperswitch_connectors/src/connectors/stripebilling.rs
// Module: hyperswitch_connectors

pub fn new() -> &'static Self


// Struct: BusinessGenericLinkConfig
// File: crates/api_models/src/admin.rs
// Module: api_models
// Implementations: 1

pub struct BusinessGenericLinkConfig


// Function: get_secret
// File: crates/router/src/types/domain/user.rs
// Module: router

pub fn get_secret(self) -> Secret<String, pii::EmailStrategy>


// Struct: MandateResponse
// File: crates/hyperswitch_connectors/src/connectors/gocardless/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct MandateResponse


// Struct: RefundCount
// File: crates/api_models/src/analytics/refunds.rs
// Module: api_models
// Implementations: 0

pub struct RefundCount


// Struct: Browser
// File: crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Browser


// Function: validate_payout_list_request_for_joins
// File: crates/router/src/core/payouts/validator.rs
// Module: router

pub fn validate_payout_list_request_for_joins(
    limit: u32,
) -> CustomResult<(), errors::ApiErrorResponse>


// Struct: ContractBasedRoutingSetupPayloadWrapper
// File: crates/api_models/src/routing.rs
// Module: api_models
// Implementations: 0

pub struct ContractBasedRoutingSetupPayloadWrapper


// Struct: DuitNowQrCodeResponse
// File: crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct DuitNowQrCodeResponse


// Implementation: impl Payment for for Payone
// File: crates/hyperswitch_connectors/src/connectors/payone.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl Payment for for Payone


// Implementation: impl Novalnet
// File: crates/hyperswitch_connectors/src/connectors/novalnet.rs
// Module: hyperswitch_connectors
// Methods: 1 total (1 public)

impl Novalnet


// Implementation: impl api::ConnectorAccessToken for for Coinbase
// File: crates/hyperswitch_connectors/src/connectors/coinbase.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::ConnectorAccessToken for for Coinbase


// Implementation: impl api::PayoutCreate for for Ebanx
// File: crates/hyperswitch_connectors/src/connectors/ebanx.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PayoutCreate for for Ebanx


// Function: is_pre_processing_required_before_authorize
// File: crates/common_enums/src/connector_enums.rs
// Module: common_enums

pub fn is_pre_processing_required_before_authorize(self) -> bool


// Function: supports_access_token_for_payout
// File: crates/common_enums/src/connector_enums.rs
// Module: common_enums

pub fn supports_access_token_for_payout(self, payout_method: Option<PayoutType>) -> bool


// Function: update
// File: crates/diesel_models/src/query/process_tracker.rs
// Module: diesel_models

pub fn update(
        self,
        conn: &PgPooledConn,
        process: ProcessTrackerUpdate,
    ) -> StorageResult<Self>


// Module Structure
// File: crates/diesel_models/src/user.rs
// Module: diesel_models

// Public submodules:
pub mod dashboard_metadata;
pub mod sample_data;
pub mod theme;


// Implementation: impl PaymentSync for for Netcetera
// File: crates/hyperswitch_connectors/src/connectors/netcetera.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl PaymentSync for for Netcetera


// Struct: GooglePayData
// File: crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct GooglePayData


// File: crates/router/src/core/payments/flows/session_update_flow.rs
// Module: router

use async_trait::async_trait;

use super::ConstructFlowSpecificData;
use crate::{
    core::{
        errors::{ConnectorErrorExt, RouterResult},
        payments::{self, access_token, helpers, transformers, Feature, PaymentData},
    },
    routes::SessionState,
    services,
    types::{self, api, domain},
};

#[async_trait]
impl
    ConstructFlowSpecificData<
        api::SdkSessionUpdate,
        types::SdkPaymentsSessionUpdateData,
        types::PaymentsResponseData,
    > for PaymentData<api::SdkSessionUpdate>
{
    #[cfg(feature = "v1")]
    async fn construct_router_data<'a>(
        &self,
        state: &SessionState,
        connector_id: &str,
        merchant_context: &domain::MerchantContext,
        customer: &Option<domain::Customer>,
        merchant_connector_account: &helpers::MerchantConnectorAccountType,
        _merchant_recipient_data: Option<types::MerchantRecipientData>,
        _header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
    ) -> RouterResult<types::SdkSessionUpdateRouterData> {
        Box::pin(
            transformers::construct_router_data_to_update_calculated_tax::<
                api::SdkSessionUpdate,
                types::SdkPaymentsSessionUpdateData,
            >(
                state,
                self.clone(),
                connector_id,
                merchant_context,
                customer,
                merchant_connector_account,
            ),
        )
        .await
    }

    #[cfg(feature = "v2")]
    async fn construct_router_data<'a>(
        &self,
        state: &SessionState,
        connector_id: &str,
        merchant_context: &domain::MerchantContext,
        customer: &Option<domain::Customer>,
        merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
        _merchant_recipient_data: Option<types::MerchantRecipientData>,
        _header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
    ) -> RouterResult<types::SdkSessionUpdateRouterData> {
        todo!()
    }
}

#[async_trait]
impl Feature<api::SdkSessionUpdate, types::SdkPaymentsSessionUpdateData>
    for types::RouterData<
        api::SdkSessionUpdate,
        types::SdkPaymentsSessionUpdateData,
        types::PaymentsResponseData,
    >
{
    async fn decide_flows<'a>(
        self,
        state: &SessionState,
        connector: &api::ConnectorData,
        call_connector_action: payments::CallConnectorAction,
        connector_request: Option<services::Request>,
        _business_profile: &domain::Profile,
        _header_payload: hyperswitch_domain_models::payments::HeaderPayload,
        _return_raw_connector_response: Option<bool>,
    ) -> RouterResult<Self> {
        let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
            api::SdkSessionUpdate,
            types::SdkPaymentsSessionUpdateData,
            types::PaymentsResponseData,
        > = connector.connector.get_connector_integration();

        let resp = services::execute_connector_processing_step(
            state,
            connector_integration,
            &self,
            call_connector_action,
            connector_request,
            None,
        )
        .await
        .to_payment_failed_response()?;
        Ok(resp)
    }

    async fn add_access_token<'a>(
        &self,
        state: &SessionState,
        connector: &api::ConnectorData,
        merchant_context: &domain::MerchantContext,
        creds_identifier: Option<&str>,
    ) -> RouterResult<types::AddAccessTokenResult> {
        Box::pin(access_token::add_access_token(
            state,
            connector,
            merchant_context,
            self,
            creds_identifier,
        ))
        .await
    }

    async fn build_flow_specific_connector_request(
        &mut self,
        state: &SessionState,
        connector: &api::ConnectorData,
        call_connector_action: payments::CallConnectorAction,
    ) -> RouterResult<(Option<services::Request>, bool)> {
        let request = match call_connector_action {
            payments::CallConnectorAction::Trigger => {
                let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
                    api::SdkSessionUpdate,
                    types::SdkPaymentsSessionUpdateData,
                    types::PaymentsResponseData,
                > = connector.connector.get_connector_integration();

                connector_integration
                    .build_request(self, &state.conf.connectors)
                    .to_payment_failed_response()?
            }
            _ => None,
        };

        Ok((request, true))
    }
}


// File: crates/analytics/src/disputes/metrics/dispute_status_metric.rs
// Module: analytics

use std::collections::HashSet;

use api_models::analytics::{
    disputes::{DisputeDimensions, DisputeFilters, DisputeMetricsBucketIdentifier},
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::DisputeMetricRow;
use crate::{
    enums::AuthInfo,
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, SeriesBucket, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
};
#[derive(Default)]
pub(super) struct DisputeStatusMetric {}

#[async_trait::async_trait]
impl<T> super::DisputeMetric<T> for DisputeStatusMetric
where
    T: AnalyticsDataSource + super::DisputeMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        dimensions: &[DisputeDimensions],
        auth: &AuthInfo,
        filters: &DisputeFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(DisputeMetricsBucketIdentifier, DisputeMetricRow)>>
    where
        T: AnalyticsDataSource + super::DisputeMetricAnalytics,
    {
        let mut query_builder = QueryBuilder::new(AnalyticsCollection::Dispute);

        for dim in dimensions {
            query_builder.add_select_column(dim).switch()?;
        }

        query_builder.add_select_column("dispute_status").switch()?;

        query_builder
            .add_select_column(Aggregate::Count {
                field: None,
                alias: Some("count"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Min {
                field: "created_at",
                alias: Some("start_bucket"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Max {
                field: "created_at",
                alias: Some("end_bucket"),
            })
            .switch()?;

        filters.set_filter_clause(&mut query_builder).switch()?;

        auth.set_filter_clause(&mut query_builder).switch()?;

        time_range.set_filter_clause(&mut query_builder).switch()?;

        for dim in dimensions {
            query_builder.add_group_by_clause(dim).switch()?;
        }

        query_builder
            .add_group_by_clause("dispute_status")
            .switch()?;

        if let Some(granularity) = granularity {
            granularity
                .set_group_by_clause(&mut query_builder)
                .switch()?;
        }

        query_builder
            .execute_query::<DisputeMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    DisputeMetricsBucketIdentifier::new(
                        i.dispute_stage.as_ref().map(|i| i.0),
                        i.connector.clone(),
                        i.currency.as_ref().map(|i| i.0),
                        TimeRange {
                            start_time: match (granularity, i.start_bucket) {
                                (Some(g), Some(st)) => g.clip_to_start(st)?,
                                _ => time_range.start_time,
                            },
                            end_time: granularity.as_ref().map_or_else(
                                || Ok(time_range.end_time),
                                |g| i.end_bucket.map(|et| g.clip_to_end(et)).transpose(),
                            )?,
                        },
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(DisputeMetricsBucketIdentifier, DisputeMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


// Function: get_total_blocked_amount
// File: crates/router/src/core/payments/types.rs
// Module: router

pub fn get_total_blocked_amount(&self) -> common_types::MinorUnit


// Implementation: impl ApiKey
// File: crates/diesel_models/src/query/api_keys.rs
// Module: diesel_models
// Methods: 5 total (0 public)

impl ApiKey


// Implementation: impl GetPaymentMethodType for for BankRedirectData
// File: crates/hyperswitch_domain_models/src/payment_method_data.rs
// Module: hyperswitch_domain_models
// Methods: 1 total (0 public)

impl GetPaymentMethodType for for BankRedirectData


// Struct: PaysafeApplePayDecryptedDataWrapper
// File: crates/hyperswitch_connectors/src/connectors/paysafe/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaysafeApplePayDecryptedDataWrapper


// Implementation: impl Nexixpay
// File: crates/hyperswitch_connectors/src/connectors/nexixpay.rs
// Module: hyperswitch_connectors
// Methods: 1 total (1 public)

impl Nexixpay


// Function: get_webhook_object_from_body
// File: crates/hyperswitch_connectors/src/connectors/stripebilling/transformers.rs
// Module: hyperswitch_connectors

pub fn get_webhook_object_from_body(body: &[u8]) -> CustomResult<Self, errors::ConnectorError>


// Function: pg_connection_read
// File: crates/storage_impl/src/connection.rs
// Module: storage_impl

pub fn pg_connection_read<T: crate::DatabaseStore>(
    store: &T,
) -> errors::CustomResult<
    PooledConnection<'_, async_bb8_diesel::ConnectionManager<PgConnection>>,
    crate::errors::StorageError,
>


// Struct: SuccessBasedAlgorithm
// File: crates/api_models/src/routing.rs
// Module: api_models
// Implementations: 3
// Traits: DynamicRoutingAlgoAccessor

pub struct SuccessBasedAlgorithm


// Implementation: impl BlackList for for SinglePurposeToken
// File: crates/router/src/services/authentication/blacklist.rs
// Module: router
// Methods: 1 total (0 public)

impl BlackList for for SinglePurposeToken


// Function: filter_network_tokenization_supported_connectors
// File: crates/router/src/core/payments.rs
// Module: router

pub fn filter_network_tokenization_supported_connectors(
    connectors: Vec<api::ConnectorRoutingData>,
    network_tokenization_supported_connectors: &HashSet<enums::Connector>,
) -> Vec<api::ConnectorRoutingData>


// Struct: CheckoutWebhookEventTypeBody
// File: crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CheckoutWebhookEventTypeBody


// File: crates/router/src/types/api/files_v2.rs
// Module: router

pub use hyperswitch_domain_models::router_flow_types::files::{Retrieve, Upload};
pub use hyperswitch_interfaces::api::files_v2::{FileUploadV2, RetrieveFileV2, UploadFileV2};


// Function: from_storage
// File: crates/router/src/services/kafka/refund.rs
// Module: router

pub fn from_storage(refund: &'a Refund) -> Self


// Implementation: impl MerchantAccount
// File: crates/diesel_models/src/merchant_account.rs
// Module: diesel_models
// Methods: 2 total (2 public)

impl MerchantAccount


// Struct: ChargebeeAuthType
// File: crates/hyperswitch_connectors/src/connectors/chargebee/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ChargebeeAuthType


// Struct: VaultRetrieveResponse
// File: crates/router/src/types/payment_methods.rs
// Module: router
// Implementations: 0

pub struct VaultRetrieveResponse


// Implementation: impl api::PaymentAuthorize for for Amazonpay
// File: crates/hyperswitch_connectors/src/connectors/amazonpay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentAuthorize for for Amazonpay


// Struct: Algorithm
// File: crates/router/src/core/three_ds_decision_rule.rs
// Module: router
// Implementations: 0

pub struct Algorithm


// Struct: CybersourcePaymentsResponse
// File: crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CybersourcePaymentsResponse


// Implementation: impl api::PaymentToken for for Deutschebank
// File: crates/hyperswitch_connectors/src/connectors/deutschebank.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentToken for for Deutschebank