// File: crates/hyperswitch_connectors/src/connectors/sift/transformers.rs
// Module: hyperswitch_connectors
// Public structs: 8

use common_enums::enums;
use common_utils::types::StringMinorUnit;
use hyperswitch_domain_models::{
    payment_method_data::PaymentMethodData,
    router_data::{ConnectorAuthType, RouterData},
    router_flow_types::refunds::{Execute, RSync},
    router_request_types::ResponseId,
    router_response_types::{PaymentsResponseData, RefundsResponseData},
    types::{PaymentsAuthorizeRouterData, RefundsRouterData},
};
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};

use crate::types::{RefundsResponseRouterData, ResponseRouterData};

//TODO: Fill the struct with respective fields
pub struct SiftRouterData<T> {
    pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
    pub router_data: T,
}

impl<T> From<(StringMinorUnit, T)> for SiftRouterData<T> {
    fn from((amount, item): (StringMinorUnit, T)) -> Self {
        //Todo :  use utils to convert the amount to the type of amount that a connector accepts
        Self {
            amount,
            router_data: item,
        }
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Serialize, PartialEq)]
pub struct SiftPaymentsRequest {
    amount: StringMinorUnit,
    card: SiftCard,
}

#[derive(Default, Debug, Serialize, Eq, PartialEq)]
pub struct SiftCard {
    number: cards::CardNumber,
    expiry_month: Secret<String>,
    expiry_year: Secret<String>,
    cvc: Secret<String>,
    complete: bool,
}

impl TryFrom<&SiftRouterData<&PaymentsAuthorizeRouterData>> for SiftPaymentsRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &SiftRouterData<&PaymentsAuthorizeRouterData>) -> Result<Self, Self::Error> {
        match item.router_data.request.payment_method_data.clone() {
            PaymentMethodData::Card(_) => Err(errors::ConnectorError::NotImplemented(
                "Card payment method not implemented".to_string(),
            )
            .into()),
            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
        }
    }
}

//TODO: Fill the struct with respective fields
// Auth Struct
pub struct SiftAuthType {
    pub(super) api_key: Secret<String>,
}

impl TryFrom<&ConnectorAuthType> for SiftAuthType {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        match auth_type {
            ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
                api_key: api_key.to_owned(),
            }),
            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
        }
    }
}
// PaymentsResponse
//TODO: Append the remaining status flags
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum SiftPaymentStatus {
    Succeeded,
    Failed,
    #[default]
    Processing,
}

impl From<SiftPaymentStatus> for common_enums::AttemptStatus {
    fn from(item: SiftPaymentStatus) -> Self {
        match item {
            SiftPaymentStatus::Succeeded => Self::Charged,
            SiftPaymentStatus::Failed => Self::Failure,
            SiftPaymentStatus::Processing => Self::Authorizing,
        }
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SiftPaymentsResponse {
    status: SiftPaymentStatus,
    id: String,
}

impl<F, T> TryFrom<ResponseRouterData<F, SiftPaymentsResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, SiftPaymentsResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            status: common_enums::AttemptStatus::from(item.response.status),
            response: Ok(PaymentsResponseData::TransactionResponse {
                resource_id: ResponseId::ConnectorTransactionId(item.response.id),
                redirection_data: Box::new(None),
                mandate_reference: Box::new(None),
                connector_metadata: None,
                network_txn_id: None,
                connector_response_reference_id: None,
                incremental_authorization_allowed: None,
                charges: None,
            }),
            ..item.data
        })
    }
}

//TODO: Fill the struct with respective fields
// REFUND :
// Type definition for RefundRequest
#[derive(Default, Debug, Serialize)]
pub struct SiftRefundRequest {
    pub amount: StringMinorUnit,
}

impl<F> TryFrom<&SiftRouterData<&RefundsRouterData<F>>> for SiftRefundRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &SiftRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
        Ok(Self {
            amount: item.amount.to_owned(),
        })
    }
}

// Type definition for Refund Response

#[allow(dead_code)]
#[derive(Debug, Copy, Serialize, Default, Deserialize, Clone)]
pub enum RefundStatus {
    Succeeded,
    Failed,
    #[default]
    Processing,
}

impl From<RefundStatus> for enums::RefundStatus {
    fn from(item: RefundStatus) -> Self {
        match item {
            RefundStatus::Succeeded => Self::Success,
            RefundStatus::Failed => Self::Failure,
            RefundStatus::Processing => Self::Pending,
            //TODO: Review mapping
        }
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct RefundResponse {
    id: String,
    status: RefundStatus,
}

impl TryFrom<RefundsResponseRouterData<Execute, RefundResponse>> for RefundsRouterData<Execute> {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<Execute, RefundResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.id.to_string(),
                refund_status: enums::RefundStatus::from(item.response.status),
            }),
            ..item.data
        })
    }
}

impl TryFrom<RefundsResponseRouterData<RSync, RefundResponse>> for RefundsRouterData<RSync> {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<RSync, RefundResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.id.to_string(),
                refund_status: enums::RefundStatus::from(item.response.status),
            }),
            ..item.data
        })
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
pub struct SiftErrorResponse {
    pub status_code: u16,
    pub code: String,
    pub message: String,
    pub reason: Option<String>,
    pub network_advice_code: Option<String>,
    pub network_decline_code: Option<String>,
    pub network_error_message: Option<String>,
}


// Struct: MbWayInfo
// File: crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct MbWayInfo


// Struct: PaypalPaymentErrorResponse
// File: crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaypalPaymentErrorResponse


// Struct: V2ApiKeyAuth
// File: crates/router/src/services/authentication.rs
// Module: router
// Implementations: 0

pub struct V2ApiKeyAuth


// Struct: BarclaycardPaymentsRequest
// File: crates/hyperswitch_connectors/src/connectors/barclaycard/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct BarclaycardPaymentsRequest


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

// Public submodules:
pub mod transformers;


// Module Structure
// File: crates/router/src/core/proxy.rs
// Module: router

// Public submodules:
pub mod utils;


// Implementation: impl FraudCheckTransaction for for Signifyd
// File: crates/hyperswitch_connectors/src/connectors/signifyd.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl FraudCheckTransaction for for Signifyd


// Implementation: impl Responder
// File: crates/router/src/routes/gsm.rs
// Module: router
// Methods: 0 total (0 public)

impl Responder


// Function: master_key
// File: crates/storage_impl/src/lib.rs
// Module: storage_impl

pub fn master_key(&self) -> &StrongSecret<Vec<u8>>


            common_enums::CardNetwork::AmericanExpress,
            common_enums::CardNetwork::JCB,
            common_enums::CardNetwork::DinersClub,
            common_enums::CardNetwork::UnionPay,
            common_enums::CardNetwork::Discover,
            common_enums::CardNetwork::CartesBancaires,
            common_enums::CardNetwork::Interac,
        ];

        let mut novalnet_supported_payment_methods = SupportedPaymentMethods::new();

        novalnet_supported_payment_methods.add(
            enums::PaymentMethod::Card,
            enums::PaymentMethodType::Credit,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::Supported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: Some(
                    api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                        api_models::feature_matrix::CardSpecificFeatures {
                            three_ds: common_enums::FeatureStatus::Supported,
                            no_three_ds: common_enums::FeatureStatus::Supported,
                            supported_card_networks: supported_card_network.clone(),
                        }
                    }),
                ),
            },
        );

        novalnet_supported_payment_methods.add(
            enums::PaymentMethod::Card,
            enums::PaymentMethodType::Debit,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::Supported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: Some(
                    api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                        api_models::feature_matrix::CardSpecificFeatures {
                            three_ds: common_enums::FeatureStatus::Supported,
                            no_three_ds: common_enums::FeatureStatus::Supported,
                            supported_card_networks: supported_card_network.clone(),
                        }
                    }),
                ),
            },
        );

        novalnet_supported_payment_methods.add(
            enums::PaymentMethod::Wallet,
            enums::PaymentMethodType::GooglePay,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::Supported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: None, // three-ds needed for googlepay
            },
        );

        novalnet_supported_payment_methods.add(
            enums::PaymentMethod::Wallet,
            enums::PaymentMethodType::ApplePay,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::Supported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: None,
            },
        );

        novalnet_supported_payment_methods.add(
            enums::PaymentMethod::Wallet,
            enums::PaymentMethodType::Paypal,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::Supported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: None,
            },
        );

        novalnet_supported_payment_methods
    });

static NOVALNET_CONNECTOR_INFO: ConnectorInfo = ConnectorInfo {
    display_name: "Novalnet",
    description: "Novalnet provides tailored, data-driven payment solutions that maximize acceptance, boost conversions, and deliver seamless customer experiences worldwide.",
    connector_type: enums::HyperswitchConnectorCategory::PaymentGateway,
    integration_status: enums::ConnectorIntegrationStatus::Live,
};

static NOVALNET_SUPPORTED_WEBHOOK_FLOWS: [enums::EventClass; 4] = [
    enums::EventClass::Payments,
    enums::EventClass::Refunds,
    enums::EventClass::Disputes,
    enums::EventClass::Mandates,
];

impl ConnectorSpecifications for Novalnet {
    fn get_connector_about(&self) -> Option<&'static ConnectorInfo> {
        Some(&NOVALNET_CONNECTOR_INFO)
    }

    fn get_supported_payment_methods(&self) -> Option<&'static SupportedPaymentMethods> {
        Some(&*NOVALNET_SUPPORTED_PAYMENT_METHODS)
    }

    fn get_supported_webhook_flows(&self) -> Option<&'static [enums::EventClass]> {
        Some(&NOVALNET_SUPPORTED_WEBHOOK_FLOWS)
    }
}


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

impl ConnectorValidation for for Nexixpay


// Implementation: impl Refund
// File: crates/diesel_models/src/query/refund.rs
// Module: diesel_models
// Methods: 3 total (0 public)

impl Refund


            query = query.filter(pi_dsl::profile_id.eq_any(profile_id));
        }

        query = query.filter(pi_dsl::created_at.ge(time_range.start_time));

        query = match time_range.end_time {
            Some(ending_at) => query.filter(pi_dsl::created_at.le(ending_at)),
            None => query,
        };

        logger::debug!(filter = %diesel::debug_query::<diesel::pg::Pg,_>(&query).to_string());

        db_metrics::track_database_call::<<DieselPaymentIntent as HasTable>::Table, _, _>(
            query.get_results_async::<(common_enums::IntentStatus, i64)>(conn),
            db_metrics::DatabaseOperation::Filter,
        )
        .await
        .map_err(|er| {
            StorageError::DatabaseError(
                error_stack::report!(diesel_models::errors::DatabaseError::from(er))
                    .attach_printable("Error filtering payment records"),
            )
            .into()
        })
    }

    #[cfg(all(feature = "v1", feature = "olap"))]
    #[instrument(skip_all)]
    async fn get_filtered_payment_intents_attempt(
        &self,
        state: &KeyManagerState,
        merchant_id: &common_utils::id_type::MerchantId,
        constraints: &PaymentIntentFetchConstraints,
        merchant_key_store: &MerchantKeyStore,
        storage_scheme: MerchantStorageScheme,
    ) -> error_stack::Result<Vec<(PaymentIntent, PaymentAttempt)>, StorageError> {
        use futures::{future::try_join_all, FutureExt};

        use crate::DataModelExt;

        let conn = connection::pg_connection_read(self).await?;
        let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
        let mut query = DieselPaymentIntent::table()
            .filter(pi_dsl::merchant_id.eq(merchant_id.to_owned()))
            .inner_join(
                payment_attempt_schema::table.on(pa_dsl::attempt_id.eq(pi_dsl::active_attempt_id)),
            )
            .filter(pa_dsl::merchant_id.eq(merchant_id.to_owned())) // Ensure merchant_ids match, as different merchants can share payment/attempt IDs.
            .into_boxed();

        query = match constraints {
            PaymentIntentFetchConstraints::Single { payment_intent_id } => {
                query.filter(pi_dsl::payment_id.eq(payment_intent_id.to_owned()))
            }
            PaymentIntentFetchConstraints::List(params) => {
                query = match params.order {
                    Order {
                        on: SortOn::Amount,
                        by: SortBy::Asc,
                    } => query.order(pi_dsl::amount.asc()),
                    Order {
                        on: SortOn::Amount,
                        by: SortBy::Desc,
                    } => query.order(pi_dsl::amount.desc()),
                    Order {
                        on: SortOn::Created,
                        by: SortBy::Asc,
                    } => query.order(pi_dsl::created_at.asc()),
                    Order {
                        on: SortOn::Created,
                        by: SortBy::Desc,
                    } => query.order(pi_dsl::created_at.desc()),
                };

                if let Some(limit) = params.limit {
                    query = query.limit(limit.into());
                }

                if let Some(customer_id) = &params.customer_id {
                    query = query.filter(pi_dsl::customer_id.eq(customer_id.clone()));
                }

                if let Some(merchant_order_reference_id) = &params.merchant_order_reference_id {
                    query = query.filter(
                        pi_dsl::merchant_order_reference_id.eq(merchant_order_reference_id.clone()),
                    )
                }

                if let Some(profile_id) = &params.profile_id {
                    query = query.filter(pi_dsl::profile_id.eq_any(profile_id.clone()));
                }

                query = match (params.starting_at, &params.starting_after_id) {
                    (Some(starting_at), _) => query.filter(pi_dsl::created_at.ge(starting_at)),
                    (None, Some(starting_after_id)) => {
                        // TODO: Fetch partial columns for this query since we only need some columns
                        let starting_at = self
                            .find_payment_intent_by_payment_id_merchant_id(
                                state,
                                starting_after_id,
                                merchant_id,
                                merchant_key_store,
                                storage_scheme,
                            )
                            .await?
                            .created_at;
                        query.filter(pi_dsl::created_at.ge(starting_at))
                    }
                    (None, None) => query,
                };

                query = match (params.ending_at, &params.ending_before_id) {
                    (Some(ending_at), _) => query.filter(pi_dsl::created_at.le(ending_at)),
                    (None, Some(ending_before_id)) => {
                        // TODO: Fetch partial columns for this query since we only need some columns
                        let ending_at = self
                            .find_payment_intent_by_payment_id_merchant_id(
                                state,
                                ending_before_id,
                                merchant_id,
                                merchant_key_store,
                                storage_scheme,
                            )
                            .await?
                            .created_at;
                        query.filter(pi_dsl::created_at.le(ending_at))
                    }
                    (None, None) => query,
                };

                query = query.offset(params.offset.into());

                query = match params.amount_filter {
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.between(start, end)),
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: None,
                    }) => query.filter(pi_dsl::amount.ge(start)),
                    Some(AmountFilter {
                        start_amount: None,
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.le(end)),
                    _ => query,
                };

                query = match &params.currency {
                    Some(currency) => query.filter(pi_dsl::currency.eq_any(currency.clone())),
                    None => query,
                };

                let connectors = params
                    .connector
                    .as_ref()
                    .map(|c| c.iter().map(|c| c.to_string()).collect::<Vec<String>>());

                query = match connectors {
                    Some(connectors) => query.filter(pa_dsl::connector.eq_any(connectors)),
                    None => query,
                };

                query = match &params.status {
                    Some(status) => query.filter(pi_dsl::status.eq_any(status.clone())),
                    None => query,
                };

                query = match &params.payment_method {
                    Some(payment_method) => {
                        query.filter(pa_dsl::payment_method.eq_any(payment_method.clone()))
                    }
                    None => query,
                };

                query = match &params.payment_method_type {
                    Some(payment_method_type) => query
                        .filter(pa_dsl::payment_method_type.eq_any(payment_method_type.clone())),
                    None => query,
                };

                query = match &params.authentication_type {
                    Some(authentication_type) => query
                        .filter(pa_dsl::authentication_type.eq_any(authentication_type.clone())),
                    None => query,
                };

                query = match &params.merchant_connector_id {
                    Some(merchant_connector_id) => query.filter(
                        pa_dsl::merchant_connector_id.eq_any(merchant_connector_id.clone()),
                    ),
                    None => query,
                };

                if let Some(card_network) = &params.card_network {
                    query = query.filter(pa_dsl::card_network.eq_any(card_network.clone()));
                }

                if let Some(card_discovery) = &params.card_discovery {
                    query = query.filter(pa_dsl::card_discovery.eq_any(card_discovery.clone()));
                }

                query
            }
        };

        logger::debug!(filter = %diesel::debug_query::<diesel::pg::Pg,_>(&query).to_string());

        query
            .get_results_async::<(
                DieselPaymentIntent,
                diesel_models::payment_attempt::PaymentAttempt,
            )>(conn)
            .await
            .map(|results| {
                try_join_all(results.into_iter().map(|(pi, pa)| {
                    PaymentIntent::convert_back(
                        state,
                        pi,
                        merchant_key_store.key.get_inner(),
                        merchant_id.to_owned().into(),
                    )
                    .map(|payment_intent| {
                        payment_intent.map(|payment_intent| {
                            (payment_intent, PaymentAttempt::from_storage_model(pa))
                        })
                    })
                }))
                .map(|join_result| join_result.change_context(StorageError::DecryptionError))
            })
            .map_err(|er| {
                StorageError::DatabaseError(
                    error_stack::report!(diesel_models::errors::DatabaseError::from(er))
                        .attach_printable("Error filtering payment records"),
                )
            })?
            .await
    }

    #[cfg(all(feature = "v2", feature = "olap"))]
    #[instrument(skip_all)]
    async fn get_filtered_payment_intents_attempt(
        &self,
        state: &KeyManagerState,
        merchant_id: &common_utils::id_type::MerchantId,
        constraints: &PaymentIntentFetchConstraints,
        merchant_key_store: &MerchantKeyStore,
        storage_scheme: MerchantStorageScheme,
    ) -> error_stack::Result<Vec<(PaymentIntent, Option<PaymentAttempt>)>, StorageError> {
        use diesel::NullableExpressionMethods as _;
        use futures::{future::try_join_all, FutureExt};

        let conn = connection::pg_connection_read(self).await?;
        let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
        let mut query = DieselPaymentIntent::table()
            .filter(pi_dsl::merchant_id.eq(merchant_id.to_owned()))
            .left_join(
                payment_attempt_schema::table
                    .on(pi_dsl::active_attempt_id.eq(pa_dsl::id.nullable())),
            )
            // Filtering on merchant_id for payment_attempt is not required for v2 as payment_attempt_ids are globally unique
            .into_boxed();

        query = match constraints {
            PaymentIntentFetchConstraints::List(params) => {
                query = match params.order {
                    Order {
                        on: SortOn::Amount,
                        by: SortBy::Asc,
                    } => query.order(pi_dsl::amount.asc()),
                    Order {
                        on: SortOn::Amount,
                        by: SortBy::Desc,
                    } => query.order(pi_dsl::amount.desc()),
                    Order {
                        on: SortOn::Created,
                        by: SortBy::Asc,
                    } => query.order(pi_dsl::created_at.asc()),
                    Order {
                        on: SortOn::Created,
                        by: SortBy::Desc,
                    } => query.order(pi_dsl::created_at.desc()),
                };

                if let Some(limit) = params.limit {
                    query = query.limit(limit.into());
                }

                if let Some(customer_id) = &params.customer_id {
                    query = query.filter(pi_dsl::customer_id.eq(customer_id.clone()));
                }

                if let Some(merchant_order_reference_id) = &params.merchant_order_reference_id {
                    query = query.filter(
                        pi_dsl::merchant_reference_id.eq(merchant_order_reference_id.clone()),
                    )
                }

                if let Some(profile_id) = &params.profile_id {
                    query = query.filter(pi_dsl::profile_id.eq(profile_id.clone()));
                }

                query = match (params.starting_at, &params.starting_after_id) {
                    (Some(starting_at), _) => query.filter(pi_dsl::created_at.ge(starting_at)),
                    (None, Some(starting_after_id)) => {
                        // TODO: Fetch partial columns for this query since we only need some columns
                        let starting_at = self
                            .find_payment_intent_by_id(
                                state,
                                starting_after_id,
                                merchant_key_store,
                                storage_scheme,
                            )
                            .await?
                            .created_at;
                        query.filter(pi_dsl::created_at.ge(starting_at))
                    }
                    (None, None) => query,
                };

                query = match (params.ending_at, &params.ending_before_id) {
                    (Some(ending_at), _) => query.filter(pi_dsl::created_at.le(ending_at)),
                    (None, Some(ending_before_id)) => {
                        // TODO: Fetch partial columns for this query since we only need some columns
                        let ending_at = self
                            .find_payment_intent_by_id(
                                state,
                                ending_before_id,
                                merchant_key_store,
                                storage_scheme,
                            )
                            .await?
                            .created_at;
                        query.filter(pi_dsl::created_at.le(ending_at))
                    }
                    (None, None) => query,
                };

                query = query.offset(params.offset.into());

                query = match params.amount_filter {
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.between(start, end)),
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: None,
                    }) => query.filter(pi_dsl::amount.ge(start)),
                    Some(AmountFilter {
                        start_amount: None,
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.le(end)),
                    _ => query,
                };

                query = match &params.currency {
                    Some(currency) => query.filter(pi_dsl::currency.eq_any(currency.clone())),
                    None => query,
                };

                query = match &params.connector {
                    Some(connector) => query.filter(pa_dsl::connector.eq_any(connector.clone())),
                    None => query,
                };

                query = match &params.status {
                    Some(status) => query.filter(pi_dsl::status.eq_any(status.clone())),
                    None => query,
                };

                query = match &params.payment_method_type {
                    Some(payment_method_type) => query
                        .filter(pa_dsl::payment_method_type_v2.eq_any(payment_method_type.clone())),
                    None => query,
                };

                query = match &params.payment_method_subtype {
                    Some(payment_method_subtype) => query.filter(
                        pa_dsl::payment_method_subtype.eq_any(payment_method_subtype.clone()),
                    ),
                    None => query,
                };

                query = match &params.authentication_type {
                    Some(authentication_type) => query
                        .filter(pa_dsl::authentication_type.eq_any(authentication_type.clone())),
                    None => query,
                };

                query = match &params.merchant_connector_id {
                    Some(merchant_connector_id) => query.filter(
                        pa_dsl::merchant_connector_id.eq_any(merchant_connector_id.clone()),
                    ),
                    None => query,
                };

                if let Some(card_network) = &params.card_network {
                    query = query.filter(pa_dsl::card_network.eq_any(card_network.clone()));
                }

                if let Some(payment_id) = &params.payment_id {
                    query = query.filter(pi_dsl::id.eq(payment_id.clone()));
                }

                query
            }
        };

        logger::debug!(filter = %diesel::debug_query::<diesel::pg::Pg,_>(&query).to_string());

        query
            .get_results_async::<(
                DieselPaymentIntent,
                Option<diesel_models::payment_attempt::PaymentAttempt>,
            )>(conn)
            .await
            .change_context(StorageError::DecryptionError)
            .async_and_then(|output| async {
                try_join_all(output.into_iter().map(
                    |(pi, pa): (_, Option<diesel_models::payment_attempt::PaymentAttempt>)| async {
                        let payment_intent = PaymentIntent::convert_back(
                            state,
                            pi,
                            merchant_key_store.key.get_inner(),
                            merchant_id.to_owned().into(),
                        );
                        let payment_attempt = pa
                            .async_map(|val| {
                                PaymentAttempt::convert_back(
                                    state,
                                    val,
                                    merchant_key_store.key.get_inner(),
                                    merchant_id.to_owned().into(),
                                )
                            })
                            .map(|val| val.transpose());

                        let output = futures::try_join!(payment_intent, payment_attempt);
                        output.change_context(StorageError::DecryptionError)
                    },
                ))
                .await
            })
            .await
            .change_context(StorageError::DecryptionError)
    }

    #[cfg(all(feature = "v2", feature = "olap"))]
    #[instrument(skip_all)]
    async fn get_filtered_active_attempt_ids_for_total_count(
        &self,
        merchant_id: &common_utils::id_type::MerchantId,
        constraints: &PaymentIntentFetchConstraints,
        _storage_scheme: MerchantStorageScheme,
    ) -> error_stack::Result<Vec<Option<String>>, StorageError> {
        let conn = connection::pg_connection_read(self).await?;
        let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
        let mut query = DieselPaymentIntent::table()
            .select(pi_dsl::active_attempt_id)
            .filter(pi_dsl::merchant_id.eq(merchant_id.to_owned()))
            .order(pi_dsl::created_at.desc())
            .into_boxed();

        query = match constraints {
            PaymentIntentFetchConstraints::List(params) => {
                if let Some(customer_id) = &params.customer_id {
                    query = query.filter(pi_dsl::customer_id.eq(customer_id.clone()));
                }
                if let Some(merchant_order_reference_id) = &params.merchant_order_reference_id {
                    query = query.filter(
                        pi_dsl::merchant_reference_id.eq(merchant_order_reference_id.clone()),
                    )
                }
                if let Some(profile_id) = &params.profile_id {
                    query = query.filter(pi_dsl::profile_id.eq(profile_id.clone()));
                }

                query = match params.starting_at {
                    Some(starting_at) => query.filter(pi_dsl::created_at.ge(starting_at)),
                    None => query,
                };

                query = match params.ending_at {
                    Some(ending_at) => query.filter(pi_dsl::created_at.le(ending_at)),
                    None => query,
                };

                query = match params.amount_filter {
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.between(start, end)),
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: None,
                    }) => query.filter(pi_dsl::amount.ge(start)),
                    Some(AmountFilter {
                        start_amount: None,
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.le(end)),
                    _ => query,
                };

                query = match &params.currency {
                    Some(currency) => query.filter(pi_dsl::currency.eq_any(currency.clone())),
                    None => query,
                };

                query = match &params.status {
                    Some(status) => query.filter(pi_dsl::status.eq_any(status.clone())),
                    None => query,
                };

                if let Some(payment_id) = &params.payment_id {
                    query = query.filter(pi_dsl::id.eq(payment_id.clone()));
                }

                query
            }
        };

        db_metrics::track_database_call::<<DieselPaymentIntent as HasTable>::Table, _, _>(
            query.get_results_async::<Option<String>>(conn),
            db_metrics::DatabaseOperation::Filter,
        )
        .await
        .map_err(|er| {
            StorageError::DatabaseError(
                error_stack::report!(diesel_models::errors::DatabaseError::from(er))
                    .attach_printable("Error filtering payment records"),
            )
            .into()
        })
    }

    #[cfg(all(feature = "v1", feature = "olap"))]
    #[instrument(skip_all)]
    async fn get_filtered_active_attempt_ids_for_total_count(
        &self,
        merchant_id: &common_utils::id_type::MerchantId,
        constraints: &PaymentIntentFetchConstraints,
        _storage_scheme: MerchantStorageScheme,
    ) -> error_stack::Result<Vec<String>, StorageError> {
        let conn = connection::pg_connection_read(self).await?;
        let conn = async_bb8_diesel::Connection::as_async_conn(&conn);
        let mut query = DieselPaymentIntent::table()
            .select(pi_dsl::active_attempt_id)
            .filter(pi_dsl::merchant_id.eq(merchant_id.to_owned()))
            .order(pi_dsl::created_at.desc())
            .into_boxed();

        query = match constraints {
            PaymentIntentFetchConstraints::Single { payment_intent_id } => {
                query.filter(pi_dsl::payment_id.eq(payment_intent_id.to_owned()))
            }
            PaymentIntentFetchConstraints::List(params) => {
                if let Some(customer_id) = &params.customer_id {
                    query = query.filter(pi_dsl::customer_id.eq(customer_id.clone()));
                }
                if let Some(merchant_order_reference_id) = &params.merchant_order_reference_id {
                    query = query.filter(
                        pi_dsl::merchant_order_reference_id.eq(merchant_order_reference_id.clone()),
                    )
                }
                if let Some(profile_id) = &params.profile_id {
                    query = query.filter(pi_dsl::profile_id.eq_any(profile_id.clone()));
                }

                query = match params.starting_at {
                    Some(starting_at) => query.filter(pi_dsl::created_at.ge(starting_at)),
                    None => query,
                };

                query = match params.ending_at {
                    Some(ending_at) => query.filter(pi_dsl::created_at.le(ending_at)),
                    None => query,
                };

                query = match params.amount_filter {
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.between(start, end)),
                    Some(AmountFilter {
                        start_amount: Some(start),
                        end_amount: None,
                    }) => query.filter(pi_dsl::amount.ge(start)),
                    Some(AmountFilter {
                        start_amount: None,
                        end_amount: Some(end),
                    }) => query.filter(pi_dsl::amount.le(end)),
                    _ => query,
                };

                query = match &params.currency {
                    Some(currency) => query.filter(pi_dsl::currency.eq_any(currency.clone())),
                    None => query,
                };

                query = match &params.status {
                    Some(status) => query.filter(pi_dsl::status.eq_any(status.clone())),
                    None => query,
                };

                query
            }
        };

        db_metrics::track_database_call::<<DieselPaymentIntent as HasTable>::Table, _, _>(
            query.get_results_async::<String>(conn),
            db_metrics::DatabaseOperation::Filter,
        )
        .await
        .map_err(|er| {
            StorageError::DatabaseError(
                error_stack::report!(diesel_models::errors::DatabaseError::from(er))
                    .attach_printable("Error filtering payment records"),
            )
            .into()
        })
    }
}


// Struct: EventContext
// File: crates/events/src/lib.rs
// Module: events
// Implementations: 1

pub struct EventContext<T, A>


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

impl api::PaymentAuthorize for for CtpMastercard


maud::html! {
            (maud::DOCTYPE)
            html {
                head {
                    meta name="viewport" content="width=device-width, initial-scale=1";
                }
                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {

                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }

                        (PreEscaped(r#""#))

                        (PreEscaped(r#"

                            "#))

                        h3 style="text-align: center;" { "Please wait while we process your payment..." }
                    }

                (PreEscaped(r#""#))
                (PreEscaped(format!("<form id=\"cardinal_collection_form\" method=\"POST\" target=\"collectionIframe\" action=\"{ddc_url}\">
                <input id=\"cardinal_collection_form_input\" type=\"hidden\" name=\"JWT\" value=\"{access_token}\">
              </form>")))
              (PreEscaped(r#""#))
              (PreEscaped(format!("
                ")))
            }}
        }
        RedirectForm::CybersourceConsumerAuth {
            access_token,
            step_up_url,
        } => {
            maud::html! {
            (maud::DOCTYPE)
            html {
                head {
                    meta name="viewport" content="width=device-width, initial-scale=1";
                }
                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {

                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }

                        (PreEscaped(r#""#))

                        (PreEscaped(r#"

                            "#))

                        h3 style="text-align: center;" { "Please wait while we process your payment..." }
                    }

                // This is the iframe recommended by cybersource but the redirection happens inside this iframe once otp
                // is received and we lose control of the redirection on user client browser, so to avoid that we have removed this iframe and directly consumed it.
                // (PreEscaped(r#""#))
                (PreEscaped(format!("<form id=\"step-up-form\" method=\"POST\" action=\"{step_up_url}\">
                <input type=\"hidden\" name=\"JWT\" value=\"{access_token}\">
              </form>")))
              (PreEscaped(format!("")))
            }}
        }
        RedirectForm::DeutschebankThreeDSChallengeFlow { acs_url, creq } => {
            maud::html! {
                (maud::DOCTYPE)
                html {
                    head {
                        meta name="viewport" content="width=device-width, initial-scale=1";
                    }

                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {
                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }

                        (PreEscaped(r#""#))

                        (PreEscaped(r#"


// Struct: ErrorInformation
// File: crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ErrorInformation


// File: crates/router/src/events/event_logger.rs
// Module: router
// Public structs: 1

use std::collections::HashMap;

use events::{EventsError, Message, MessagingInterface};
use masking::ErasedMaskSerialize;
use time::PrimitiveDateTime;

use super::EventType;
use crate::services::{kafka::KafkaMessage, logger};

#[derive(Clone, Debug, Default)]
pub struct EventLogger {}

impl EventLogger {
    #[track_caller]
    pub(super) fn log_event<T: KafkaMessage>(&self, event: &T) {
        logger::info!(event = ?event.masked_serialize().unwrap_or_else(|e| serde_json::json!({"error": e.to_string()})), event_type =? event.event_type(), event_id =? event.key(), log_type =? "event");
    }
}

impl MessagingInterface for EventLogger {
    type MessageClass = EventType;

    fn send_message<T>(
        &self,
        data: T,
        metadata: HashMap<String, String>,
        _timestamp: PrimitiveDateTime,
    ) -> error_stack::Result<(), EventsError>
    where
        T: Message<Class = Self::MessageClass> + ErasedMaskSerialize,
    {
        logger::info!(event =? data.masked_serialize().unwrap_or_else(|e| serde_json::json!({"error": e.to_string()})), event_type =? data.get_message_class(), event_id =? data.identifier(), log_type =? "event", metadata = ?metadata);
        Ok(())
    }
}


// File: crates/router/src/core/webhooks/types.rs
// Module: router
// Public functions: 1
// Public structs: 2

use api_models::{webhook_events, webhooks};
use common_utils::{crypto::SignMessage, ext_traits::Encode};
use error_stack::ResultExt;
use masking::Secret;
use serde::Serialize;

use crate::{
    core::errors,
    headers, logger,
    services::request::Maskable,
    types::storage::{self, enums},
};

#[derive(Debug)]
pub enum ScheduleWebhookRetry {
    WithProcessTracker(Box<storage::ProcessTracker>),
    NoSchedule,
}

pub struct OutgoingWebhookPayloadWithSignature {
    pub payload: Secret<String>,
    pub signature: Option<String>,
}

pub trait OutgoingWebhookType:
    Serialize + From<webhooks::OutgoingWebhook> + Sync + Send + std::fmt::Debug + 'static
{
    fn get_outgoing_webhooks_signature(
        &self,
        payment_response_hash_key: Option<impl AsRef<[u8]>>,
    ) -> errors::CustomResult<OutgoingWebhookPayloadWithSignature, errors::WebhooksFlowError>;

    fn add_webhook_header(header: &mut Vec<(String, Maskable<String>)>, signature: String);
}

impl OutgoingWebhookType for webhooks::OutgoingWebhook {
    fn get_outgoing_webhooks_signature(
        &self,
        payment_response_hash_key: Option<impl AsRef<[u8]>>,
    ) -> errors::CustomResult<OutgoingWebhookPayloadWithSignature, errors::WebhooksFlowError> {
        let webhook_signature_payload = self
            .encode_to_string_of_json()
            .change_context(errors::WebhooksFlowError::OutgoingWebhookEncodingFailed)
            .attach_printable("failed encoding outgoing webhook payload")?;

        let signature = payment_response_hash_key
            .map(|key| {
                common_utils::crypto::HmacSha512::sign_message(
                    &common_utils::crypto::HmacSha512,
                    key.as_ref(),
                    webhook_signature_payload.as_bytes(),
                )
            })
            .transpose()
            .change_context(errors::WebhooksFlowError::OutgoingWebhookSigningFailed)
            .attach_printable("Failed to sign the message")?
            .map(hex::encode);

        Ok(OutgoingWebhookPayloadWithSignature {
            payload: webhook_signature_payload.into(),
            signature,
        })
    }

    fn add_webhook_header(header: &mut Vec<(String, Maskable<String>)>, signature: String) {
        header.push((headers::X_WEBHOOK_SIGNATURE.to_string(), signature.into()))
    }
}

#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub(crate) struct OutgoingWebhookTrackingData {
    pub(crate) merchant_id: common_utils::id_type::MerchantId,
    pub(crate) business_profile_id: common_utils::id_type::ProfileId,
    pub(crate) event_type: enums::EventType,
    pub(crate) event_class: enums::EventClass,
    pub(crate) primary_object_id: String,
    pub(crate) primary_object_type: enums::EventObjectType,
    pub(crate) initial_attempt_id: Option<String>,
}

pub struct WebhookResponse {
    pub response: reqwest::Response,
}

impl WebhookResponse {
    pub async fn get_outgoing_webhook_response_content(
        self,
    ) -> webhook_events::OutgoingWebhookResponseContent {
        let status_code = self.response.status();
        let response_headers = self
            .response
            .headers()
            .iter()
            .map(|(name, value)| {
                (
                    name.as_str().to_owned(),
                    value
                        .to_str()
                        .map(|s| Secret::from(String::from(s)))
                        .unwrap_or_else(|error| {
                            logger::warn!(
                                "Response header {} contains non-UTF-8 characters: {error:?}",
                                name.as_str()
                            );
                            Secret::from(String::from("Non-UTF-8 header value"))
                        }),
                )
            })
            .collect::<Vec<_>>();
        let response_body = self
            .response
            .text()
            .await
            .map(Secret::from)
            .unwrap_or_else(|error| {
                logger::warn!("Response contains non-UTF-8 characters: {error:?}");
                Secret::from(String::from("Non-UTF-8 response body"))
            });
        webhook_events::OutgoingWebhookResponseContent {
            body: Some(response_body),
            headers: Some(response_headers),
            status_code: Some(status_code.as_u16()),
            error_message: None,
        }
    }
}


// Struct: ErrorDetail
// File: crates/hyperswitch_connectors/src/connectors/bambora/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ErrorDetail


// File: crates/openapi/src/routes/routing.rs
// Module: openapi
// Public functions: 20

#[cfg(feature = "v1")]
/// Routing - Create
///
/// Create a routing config
#[utoipa::path(
    post,
    path = "/routing",
    request_body = RoutingConfigRequest,
    responses(
        (status = 200, description = "Routing config created", body = RoutingDictionaryRecord),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Create a routing config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_create_config() {}

#[cfg(feature = "v2")]
/// Routing - Create
///
/// Create a routing algorithm
#[utoipa::path(
    post,
    path = "/v2/routing-algorithms",
    request_body = RoutingConfigRequest,
    responses(
        (status = 200, description = "Routing Algorithm created", body = RoutingDictionaryRecord),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Create a routing algorithm",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_create_config() {}

#[cfg(feature = "v1")]
/// Routing - Activate config
///
/// Activate a routing config
#[utoipa::path(
    post,
    path = "/routing/{routing_algorithm_id}/activate",
    params(
        ("routing_algorithm_id" = String, Path, description = "The unique identifier for a config"),
    ),
    responses(
        (status = 200, description = "Routing config activated", body = RoutingDictionaryRecord),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 400, description = "Bad request")
    ),
   tag = "Routing",
   operation_id = "Activate a routing config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_link_config() {}

#[cfg(feature = "v1")]
/// Routing - Retrieve
///
/// Retrieve a routing algorithm
#[utoipa::path(
    get,
    path = "/routing/{routing_algorithm_id}",
    params(
        ("routing_algorithm_id" = String, Path, description = "The unique identifier for a config"),
    ),
    responses(
        (status = 200, description = "Successfully fetched routing config", body = MerchantRoutingAlgorithm),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 403, description = "Forbidden")
    ),
   tag = "Routing",
   operation_id = "Retrieve a routing config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_retrieve_config() {}

#[cfg(feature = "v2")]
/// Routing - Retrieve
///
/// Retrieve a routing algorithm with its algorithm id
#[utoipa::path(
    get,
    path = "/v2/routing-algorithms/{id}",
    params(
        ("id" = String, Path, description = "The unique identifier for a routing algorithm"),
    ),
    responses(
        (status = 200, description = "Successfully fetched routing algorithm", body = MerchantRoutingAlgorithm),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 403, description = "Forbidden")
    ),
   tag = "Routing",
   operation_id = "Retrieve a routing algorithm with its algorithm id",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_retrieve_config() {}

#[cfg(feature = "v1")]
/// Routing - List
///
/// List all routing configs
#[utoipa::path(
    get,
    path = "/routing",
    params(
        ("limit" = Option<u16>, Query, description = "The number of records to be returned"),
        ("offset" = Option<u8>, Query, description = "The record offset from which to start gathering of results"),
        ("profile_id" = Option<String>, Query, description = "The unique identifier for a merchant profile"),
    ),
    responses(
        (status = 200, description = "Successfully fetched routing configs", body = RoutingKind),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing")
    ),
   tag = "Routing",
   operation_id = "List routing configs",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn list_routing_configs() {}

#[cfg(feature = "v1")]
/// Routing - Deactivate
///
/// Deactivates a routing config
#[utoipa::path(
    post,
    path = "/routing/deactivate",
    request_body = RoutingConfigRequest,
    responses(
        (status = 200, description = "Successfully deactivated routing config", body = RoutingDictionaryRecord),
        (status = 500, description = "Internal server error"),
        (status = 400, description = "Malformed request"),
        (status = 403, description = "Malformed request"),
        (status = 422, description = "Unprocessable request")
    ),
   tag = "Routing",
   operation_id = "Deactivate a routing config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_unlink_config() {}

#[cfg(feature = "v1")]
/// Routing - Update Default Config
///
/// Update default fallback config
#[utoipa::path(
    post,
    path = "/routing/default",
    request_body = Vec<RoutableConnectorChoice>,
    responses(
        (status = 200, description = "Successfully updated default config", body = Vec<RoutableConnectorChoice>),
        (status = 500, description = "Internal server error"),
        (status = 400, description = "Malformed request"),
        (status = 422, description = "Unprocessable request")
    ),
   tag = "Routing",
   operation_id = "Update default fallback config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_update_default_config() {}

#[cfg(feature = "v1")]
/// Routing - Retrieve Default Config
///
/// Retrieve default fallback config
#[utoipa::path(
    get,
    path = "/routing/default",
    responses(
        (status = 200, description = "Successfully retrieved default config", body = Vec<RoutableConnectorChoice>),
        (status = 500, description = "Internal server error")
    ),
   tag = "Routing",
   operation_id = "Retrieve default fallback config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_retrieve_default_config() {}

#[cfg(feature = "v1")]
/// Routing - Retrieve Config
///
/// Retrieve active config
#[utoipa::path(
    get,
    path = "/routing/active",
    params(
        ("profile_id" = Option<String>, Query, description = "The unique identifier for a merchant profile"),
    ),
    responses(
        (status = 200, description = "Successfully retrieved active config", body = LinkedRoutingConfigRetrieveResponse),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 403, description = "Forbidden")
    ),
   tag = "Routing",
   operation_id = "Retrieve active config",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_retrieve_linked_config() {}

#[cfg(feature = "v1")]
/// Routing - Retrieve Default For Profile
///
/// Retrieve default config for profiles
#[utoipa::path(
    get,
    path = "/routing/default/profile",
    responses(
        (status = 200, description = "Successfully retrieved default config", body = ProfileDefaultRoutingConfig),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing")
    ),
   tag = "Routing",
   operation_id = "Retrieve default configs for all profiles",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_retrieve_default_config_for_profiles() {}

#[cfg(feature = "v1")]
/// Routing - Update Default For Profile
///
/// Update default config for profiles
#[utoipa::path(
    post,
    path = "/routing/default/profile/{profile_id}",
    request_body = Vec<RoutableConnectorChoice>,
    params(
        ("profile_id" = String, Path, description = "The unique identifier for a profile"),
    ),
    responses(
        (status = 200, description = "Successfully updated default config for profile", body = ProfileDefaultRoutingConfig),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 400, description = "Malformed request"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Update default configs for all profiles",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn routing_update_default_config_for_profile() {}

#[cfg(feature = "v1")]
/// Routing - Toggle success based dynamic routing for profile
///
/// Create a success based dynamic routing algorithm
#[utoipa::path(
    post,
    path = "/account/{account_id}/business_profile/{profile_id}/dynamic_routing/success_based/toggle",
    params(
        ("account_id" = String, Path, description = "Merchant id"),
        ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"),
        ("enable" = DynamicRoutingFeatures, Query, description = "Feature to enable for success based routing"),
    ),
    responses(
        (status = 200, description = "Routing Algorithm created", body = RoutingDictionaryRecord),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Toggle success based dynamic routing algorithm",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn toggle_success_based_routing() {}

#[cfg(feature = "v1")]
/// Routing - Update success based dynamic routing config for profile
///
/// Update success based dynamic routing algorithm
#[utoipa::path(
    patch,
    path = "/account/{account_id}/business_profile/{profile_id}/dynamic_routing/success_based/config/{algorithm_id}",
    params(
        ("account_id" = String, Path, description = "Merchant id"),
        ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"),
        ("algorithm_id" = String, Path, description = "Success based routing algorithm id which was last activated to update the config"),
    ),
    request_body = SuccessBasedRoutingConfig,
    responses(
        (status = 200, description = "Routing Algorithm updated", body = RoutingDictionaryRecord),
        (status = 400, description = "Update body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Update success based dynamic routing configs",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn success_based_routing_update_configs() {}

#[cfg(feature = "v1")]
/// Routing - Toggle elimination routing for profile
///
/// Create a elimination based dynamic routing algorithm
#[utoipa::path(
    post,
    path = "/account/{account_id}/business_profile/{profile_id}/dynamic_routing/elimination/toggle",
    params(
        ("account_id" = String, Path, description = "Merchant id"),
        ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"),
        ("enable" = DynamicRoutingFeatures, Query, description = "Feature to enable for elimination based routing"),
    ),
    responses(
        (status = 200, description = "Routing Algorithm created", body = RoutingDictionaryRecord),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Toggle elimination routing algorithm",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn toggle_elimination_routing() {}

#[cfg(feature = "v1")]
/// Routing - Toggle Contract routing for profile
///
/// Create a Contract based dynamic routing algorithm
#[utoipa::path(
    post,
    path = "/account/{account_id}/business_profile/{profile_id}/dynamic_routing/contracts/toggle",
    params(
        ("account_id" = String, Path, description = "Merchant id"),
        ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"),
        ("enable" = DynamicRoutingFeatures, Query, description = "Feature to enable for contract based routing"),
    ),
    request_body = ContractBasedRoutingConfig,
    responses(
        (status = 200, description = "Routing Algorithm created", body = RoutingDictionaryRecord),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Toggle contract routing algorithm",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn contract_based_routing_setup_config() {}

#[cfg(feature = "v1")]
/// Routing - Update contract based dynamic routing config for profile
///
/// Update contract based dynamic routing algorithm
#[utoipa::path(
    patch,
    path = "/account/{account_id}/business_profile/{profile_id}/dynamic_routing/contracts/config/{algorithm_id}",
    params(
        ("account_id" = String, Path, description = "Merchant id"),
        ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"),
        ("algorithm_id" = String, Path, description = "Contract based routing algorithm id which was last activated to update the config"),
    ),
    request_body = ContractBasedRoutingConfig,
    responses(
        (status = 200, description = "Routing Algorithm updated", body = RoutingDictionaryRecord),
        (status = 400, description = "Update body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Update contract based dynamic routing configs",
   security(("api_key" = []), ("jwt_key" = []))
)]
pub async fn contract_based_routing_update_configs() {}

#[cfg(feature = "v1")]
/// Routing - Evaluate
///
/// Evaluate routing rules
#[utoipa::path(
    post,
    path = "/routing/evaluate",
    request_body = OpenRouterDecideGatewayRequest,
    responses(
        (status = 200, description = "Routing rules evaluated successfully", body = DecideGatewayResponse),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Evaluate routing rules",
   security(("api_key" = []))
)]
pub async fn call_decide_gateway_open_router() {}

#[cfg(feature = "v1")]
/// Routing - Feedback
///
/// Update gateway scores for dynamic routing
#[utoipa::path(
    post,
    path = "/routing/feedback",
    request_body = UpdateScorePayload,
    responses(
        (status = 200, description = "Gateway score updated successfully", body = UpdateScoreResponse),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Update gateway scores",
   security(("api_key" = []))
)]
pub async fn call_update_gateway_score_open_router() {}

#[cfg(feature = "v1")]
/// Routing - Rule Evaluate
///
/// Evaluate routing rules
#[utoipa::path(
    post,
    path = "/routing/rule/evaluate",
    request_body = RoutingEvaluateRequest,
    responses(
        (status = 200, description = "Routing rules evaluated successfully", body = RoutingEvaluateResponse),
        (status = 400, description = "Request body is malformed"),
        (status = 500, description = "Internal server error"),
        (status = 404, description = "Resource missing"),
        (status = 422, description = "Unprocessable request"),
        (status = 403, description = "Forbidden"),
    ),
   tag = "Routing",
   operation_id = "Evaluate routing rules (alternative)",
   security(("api_key" = []))
)]
pub async fn evaluate_routing_rule() {}


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

impl api::ConnectorAccessToken for for Payme


// Function: headers
// File: crates/common_utils/src/request.rs
// Module: common_utils

pub fn headers(mut self, headers: Vec<(String, Maskable<String>)


// Function: get_ephemeral_or_other_auth
// File: crates/router/src/services/authentication.rs
// Module: router

pub fn get_ephemeral_or_other_auth<T>(
    headers: &HeaderMap,
    is_merchant_flow: bool,
    payload: Option<&impl ClientSecretFetch>,
    api_auth: ApiKeyAuth,
) -> RouterResult<(
    Box<dyn AuthenticateAndFetch<AuthenticationData, T>>,
    api::AuthFlow,
    bool,
)>
where
    T: SessionStateInfo + Sync + Send,
    ApiKeyAuth: AuthenticateAndFetch<AuthenticationData, T>,
    PublishableKeyAuth: AuthenticateAndFetch<AuthenticationData, T>,
    EphemeralKeyAuth: AuthenticateAndFetch<AuthenticationData, T>,


// Struct: NoonOrderNvp
// File: crates/hyperswitch_connectors/src/connectors/noon/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 1

pub struct NoonOrderNvp


// Struct: PaymentIntentMetricsBucketValue
// File: crates/api_models/src/analytics/payment_intents.rs
// Module: api_models
// Implementations: 0

pub struct PaymentIntentMetricsBucketValue


// Struct: PlaidRecipientCreateAddress
// File: crates/pm_auth/src/connector/plaid/transformers.rs
// Module: pm_auth
// Implementations: 0

pub struct PlaidRecipientCreateAddress


// Struct: ClientRiskInformation
// File: crates/hyperswitch_connectors/src/connectors/barclaycard/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ClientRiskInformation


// Function: generate_recon_token
// File: crates/router/src/core/recon.rs
// Module: router

pub fn generate_recon_token(
    state: SessionState,
    user_with_role: authentication::UserFromTokenWithRoleInfo,
) -> RouterResponse<recon_api::ReconTokenResponse>


// Function: get_org_auth_event_metrics
// File: crates/router/src/analytics.rs
// Module: router

// Documentation: Panics if `json_payload` array does not contain one `GetAuthEventMetricRequest` element.

pub fn get_org_auth_event_metrics(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<[GetAuthEventMetricRequest; 1]>,
    ) -> impl Responder


// Function: create_profile
// File: crates/router/src/core/admin.rs
// Module: router

pub fn create_profile(
    state: SessionState,
    request: api::ProfileCreate,
    merchant_context: domain::MerchantContext,
) -> RouterResponse<api_models::admin::ProfileResponse>


// Implementation: impl DynamicRoutingStatsNew
// File: crates/diesel_models/src/query/dynamic_routing_stats.rs
// Module: diesel_models
// Methods: 1 total (0 public)

impl DynamicRoutingStatsNew


// File: crates/hyperswitch_domain_models/src/bulk_tokenization.rs
// Module: hyperswitch_domain_models
// Public structs: 4

use api_models::{payment_methods as payment_methods_api, payments as payments_api};
use cards::CardNumber;
use common_enums as enums;
use common_utils::{
    errors,
    ext_traits::OptionExt,
    id_type, pii,
    transformers::{ForeignFrom, ForeignTryFrom},
};
use error_stack::report;

use crate::{
    address::{Address, AddressDetails, PhoneDetails},
    router_request_types::CustomerDetails,
};

#[derive(Debug)]
pub struct CardNetworkTokenizeRequest {
    pub data: TokenizeDataRequest,
    pub customer: CustomerDetails,
    pub billing: Option<Address>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub payment_method_issuer: Option<String>,
}

#[derive(Debug)]
pub enum TokenizeDataRequest {
    Card(TokenizeCardRequest),
    ExistingPaymentMethod(TokenizePaymentMethodRequest),
}

#[derive(Clone, Debug)]
pub struct TokenizeCardRequest {
    pub raw_card_number: CardNumber,
    pub card_expiry_month: masking::Secret<String>,
    pub card_expiry_year: masking::Secret<String>,
    pub card_cvc: Option<masking::Secret<String>>,
    pub card_holder_name: Option<masking::Secret<String>>,
    pub nick_name: Option<masking::Secret<String>>,
    pub card_issuing_country: Option<String>,
    pub card_network: Option<enums::CardNetwork>,
    pub card_issuer: Option<String>,
    pub card_type: Option<payment_methods_api::CardType>,
}

#[derive(Clone, Debug)]
pub struct TokenizePaymentMethodRequest {
    pub payment_method_id: String,
    pub card_cvc: Option<masking::Secret<String>>,
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize)]
pub struct CardNetworkTokenizeRecord {
    // Card details
    pub raw_card_number: Option<CardNumber>,
    pub card_expiry_month: Option<masking::Secret<String>>,
    pub card_expiry_year: Option<masking::Secret<String>>,
    pub card_cvc: Option<masking::Secret<String>>,
    pub card_holder_name: Option<masking::Secret<String>>,
    pub nick_name: Option<masking::Secret<String>>,
    pub card_issuing_country: Option<String>,
    pub card_network: Option<enums::CardNetwork>,
    pub card_issuer: Option<String>,
    pub card_type: Option<payment_methods_api::CardType>,

    // Payment method details
    pub payment_method_id: Option<String>,
    pub payment_method_type: Option<payment_methods_api::CardType>,
    pub payment_method_issuer: Option<String>,

    // Customer details
    pub customer_id: id_type::CustomerId,
    #[serde(rename = "name")]
    pub customer_name: Option<masking::Secret<String>>,
    #[serde(rename = "email")]
    pub customer_email: Option<pii::Email>,
    #[serde(rename = "phone")]
    pub customer_phone: Option<masking::Secret<String>>,
    #[serde(rename = "phone_country_code")]
    pub customer_phone_country_code: Option<String>,
    #[serde(rename = "tax_registration_id")]
    pub customer_tax_registration_id: Option<masking::Secret<String>>,
    // Billing details
    pub billing_address_city: Option<String>,
    pub billing_address_country: Option<enums::CountryAlpha2>,
    pub billing_address_line1: Option<masking::Secret<String>>,
    pub billing_address_line2: Option<masking::Secret<String>>,
    pub billing_address_line3: Option<masking::Secret<String>>,
    pub billing_address_zip: Option<masking::Secret<String>>,
    pub billing_address_state: Option<masking::Secret<String>>,
    pub billing_address_first_name: Option<masking::Secret<String>>,
    pub billing_address_last_name: Option<masking::Secret<String>>,
    pub billing_phone_number: Option<masking::Secret<String>>,
    pub billing_phone_country_code: Option<String>,
    pub billing_email: Option<pii::Email>,

    // Other details
    pub line_number: Option<u64>,
    pub merchant_id: Option<id_type::MerchantId>,
}

impl ForeignFrom<&CardNetworkTokenizeRecord> for payments_api::CustomerDetails {
    fn foreign_from(record: &CardNetworkTokenizeRecord) -> Self {
        Self {
            id: record.customer_id.clone(),
            name: record.customer_name.clone(),
            email: record.customer_email.clone(),
            phone: record.customer_phone.clone(),
            phone_country_code: record.customer_phone_country_code.clone(),
            tax_registration_id: record.customer_tax_registration_id.clone(),
        }
    }
}

impl ForeignFrom<&CardNetworkTokenizeRecord> for payments_api::Address {
    fn foreign_from(record: &CardNetworkTokenizeRecord) -> Self {
        Self {
            address: Some(payments_api::AddressDetails {
                first_name: record.billing_address_first_name.clone(),
                last_name: record.billing_address_last_name.clone(),
                line1: record.billing_address_line1.clone(),
                line2: record.billing_address_line2.clone(),
                line3: record.billing_address_line3.clone(),
                city: record.billing_address_city.clone(),
                zip: record.billing_address_zip.clone(),
                state: record.billing_address_state.clone(),
                country: record.billing_address_country,
                origin_zip: None,
            }),
            phone: Some(payments_api::PhoneDetails {
                number: record.billing_phone_number.clone(),
                country_code: record.billing_phone_country_code.clone(),
            }),
            email: record.billing_email.clone(),
        }
    }
}

impl ForeignTryFrom<CardNetworkTokenizeRecord> for payment_methods_api::CardNetworkTokenizeRequest {
    type Error = error_stack::Report<errors::ValidationError>;
    fn foreign_try_from(record: CardNetworkTokenizeRecord) -> Result<Self, Self::Error> {
        let billing = Some(payments_api::Address::foreign_from(&record));
        let customer = payments_api::CustomerDetails::foreign_from(&record);
        let merchant_id = record.merchant_id.get_required_value("merchant_id")?;

        match (
            record.raw_card_number,
            record.card_expiry_month,
            record.card_expiry_year,
            record.payment_method_id,
        ) {
            (Some(raw_card_number), Some(card_expiry_month), Some(card_expiry_year), None) => {
                Ok(Self {
                    merchant_id,
                    data: payment_methods_api::TokenizeDataRequest::Card(
                        payment_methods_api::TokenizeCardRequest {
                            raw_card_number,
                            card_expiry_month,
                            card_expiry_year,
                            card_cvc: record.card_cvc,
                            card_holder_name: record.card_holder_name,
                            nick_name: record.nick_name,
                            card_issuing_country: record.card_issuing_country,
                            card_network: record.card_network,
                            card_issuer: record.card_issuer,
                            card_type: record.card_type.clone(),
                        },
                    ),
                    billing,
                    customer,
                    metadata: None,
                    payment_method_issuer: record.payment_method_issuer,
                })
            }
            (None, None, None, Some(payment_method_id)) => Ok(Self {
                merchant_id,
                data: payment_methods_api::TokenizeDataRequest::ExistingPaymentMethod(
                    payment_methods_api::TokenizePaymentMethodRequest {
                        payment_method_id,
                        card_cvc: record.card_cvc,
                    },
                ),
                billing,
                customer,
                metadata: None,
                payment_method_issuer: record.payment_method_issuer,
            }),
            _ => Err(report!(errors::ValidationError::InvalidValue {
                message: "Invalid record in bulk tokenization - expected one of card details or payment method details".to_string()
            })),
        }
    }
}

impl ForeignFrom<&TokenizeCardRequest> for payment_methods_api::MigrateCardDetail {
    fn foreign_from(card: &TokenizeCardRequest) -> Self {
        Self {
            card_number: masking::Secret::new(card.raw_card_number.get_card_no()),
            card_exp_month: card.card_expiry_month.clone(),
            card_exp_year: card.card_expiry_year.clone(),
            card_holder_name: card.card_holder_name.clone(),
            nick_name: card.nick_name.clone(),
            card_issuing_country: card.card_issuing_country.clone(),
            card_network: card.card_network.clone(),
            card_issuer: card.card_issuer.clone(),
            card_type: card
                .card_type
                .as_ref()
                .map(|card_type| card_type.to_string()),
        }
    }
}

impl ForeignTryFrom<CustomerDetails> for payments_api::CustomerDetails {
    type Error = error_stack::Report<errors::ValidationError>;
    fn foreign_try_from(customer: CustomerDetails) -> Result<Self, Self::Error> {
        Ok(Self {
            id: customer.customer_id.get_required_value("customer_id")?,
            name: customer.name,
            email: customer.email,
            phone: customer.phone,
            phone_country_code: customer.phone_country_code,
            tax_registration_id: customer.tax_registration_id,
        })
    }
}

impl ForeignFrom<payment_methods_api::CardNetworkTokenizeRequest> for CardNetworkTokenizeRequest {
    fn foreign_from(req: payment_methods_api::CardNetworkTokenizeRequest) -> Self {
        Self {
            data: TokenizeDataRequest::foreign_from(req.data),
            customer: CustomerDetails::foreign_from(req.customer),
            billing: req.billing.map(ForeignFrom::foreign_from),
            metadata: req.metadata,
            payment_method_issuer: req.payment_method_issuer,
        }
    }
}

impl ForeignFrom<payment_methods_api::TokenizeDataRequest> for TokenizeDataRequest {
    fn foreign_from(req: payment_methods_api::TokenizeDataRequest) -> Self {
        match req {
            payment_methods_api::TokenizeDataRequest::Card(card) => {
                Self::Card(TokenizeCardRequest {
                    raw_card_number: card.raw_card_number,
                    card_expiry_month: card.card_expiry_month,
                    card_expiry_year: card.card_expiry_year,
                    card_cvc: card.card_cvc,
                    card_holder_name: card.card_holder_name,
                    nick_name: card.nick_name,
                    card_issuing_country: card.card_issuing_country,
                    card_network: card.card_network,
                    card_issuer: card.card_issuer,
                    card_type: card.card_type,
                })
            }
            payment_methods_api::TokenizeDataRequest::ExistingPaymentMethod(pm) => {
                Self::ExistingPaymentMethod(TokenizePaymentMethodRequest {
                    payment_method_id: pm.payment_method_id,
                    card_cvc: pm.card_cvc,
                })
            }
        }
    }
}

impl ForeignFrom<payments_api::CustomerDetails> for CustomerDetails {
    fn foreign_from(req: payments_api::CustomerDetails) -> Self {
        Self {
            customer_id: Some(req.id),
            name: req.name,
            email: req.email,
            phone: req.phone,
            phone_country_code: req.phone_country_code,
            tax_registration_id: req.tax_registration_id,
        }
    }
}

impl ForeignFrom<payments_api::Address> for Address {
    fn foreign_from(req: payments_api::Address) -> Self {
        Self {
            address: req.address.map(ForeignFrom::foreign_from),
            phone: req.phone.map(ForeignFrom::foreign_from),
            email: req.email,
        }
    }
}

impl ForeignFrom<payments_api::AddressDetails> for AddressDetails {
    fn foreign_from(req: payments_api::AddressDetails) -> Self {
        Self {
            city: req.city,
            country: req.country,
            line1: req.line1,
            line2: req.line2,
            line3: req.line3,
            zip: req.zip,
            state: req.state,
            first_name: req.first_name,
            last_name: req.last_name,
            origin_zip: req.origin_zip,
        }
    }
}

impl ForeignFrom<payments_api::PhoneDetails> for PhoneDetails {
    fn foreign_from(req: payments_api::PhoneDetails) -> Self {
        Self {
            number: req.number,
            country_code: req.country_code,
        }
    }
}


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

pub struct MerchantConnectorAccountFeatureMetadata


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

impl api::PaymentSync for for Loonio


// Struct: UpiCollectData
// File: crates/hyperswitch_domain_models/src/payment_method_data.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct UpiCollectData


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

// Public submodules:
pub mod transformers;


// Implementation: impl PaymentIntent
// File: crates/diesel_models/src/query/payment_intent.rs
// Module: diesel_models
// Methods: 8 total (0 public)

impl PaymentIntent


// File: crates/drainer/src/logger.rs
// Module: drainer

#[doc(inline)]
pub use router_env::{debug, error, info, warn};


// Function: build
// File: crates/router/src/core/payment_methods/tokenize/card_executor.rs
// Module: router

pub fn build(self) -> api::CardNetworkTokenizeResponse


// Struct: JpmorganAuthType
// File: crates/hyperswitch_connectors/src/connectors/jpmorgan/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct JpmorganAuthType


// Struct: RedsysPaymentsResponse
// File: crates/hyperswitch_connectors/src/connectors/redsys/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct RedsysPaymentsResponse


// Struct: CustomerPaymentMethodsListResponse
// File: crates/api_models/src/payment_methods.rs
// Module: api_models
// Implementations: 0

pub struct CustomerPaymentMethodsListResponse


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

impl api::PaymentSync for for Authipay


// Function: get_payment_link_config_based_on_priority
// File: crates/router/src/core/payment_link.rs
// Module: router

pub fn get_payment_link_config_based_on_priority(
    payment_create_link_config: Option<api_models::payments::PaymentCreatePaymentLinkConfig>,
    business_link_config: Option<diesel_models::business_profile::BusinessPaymentLinkConfig>,
    merchant_name: String,
    default_domain_name: String,
    payment_link_config_id: Option<String>,
) -> Result<(PaymentLinkConfig, String), error_stack::Report<errors::ApiErrorResponse>>


// Implementation: impl api::PaymentSession for for Peachpayments
// File: crates/hyperswitch_connectors/src/connectors/peachpayments.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSession for for Peachpayments


// Struct: GlobepaySyncResponse
// File: crates/hyperswitch_connectors/src/connectors/globepay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct GlobepaySyncResponse


// Struct: LoonioPaymentRequest
// File: crates/hyperswitch_connectors/src/connectors/loonio/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct LoonioPaymentRequest


// Struct: SilverflowTokenizationResponse
// File: crates/hyperswitch_connectors/src/connectors/silverflow/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct SilverflowTokenizationResponse


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

impl api::PaymentToken for for Inespay


// Struct: SurchargeDetailsResponse
// File: crates/api_models/src/payment_methods.rs
// Module: api_models
// Implementations: 0

pub struct SurchargeDetailsResponse


// Function: program
// File: crates/euclid/src/frontend/ast/parser.rs
// Module: euclid

pub fn program<O: EuclidParsable + 'static>(input: &str) -> ParseResult<&str, ast::Program<O>>


// Struct: DeclinedPaymentDetails
// File: crates/hyperswitch_connectors/src/connectors/riskified/transformers/api.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct DeclinedPaymentDetails


// Struct: RecoveryTimestamp
// File: crates/router/src/types/storage/revenue_recovery.rs
// Module: router
// Implementations: 1
// Traits: Default

pub struct RecoveryTimestamp


// Implementation: impl ConnectorCommon for for Xendit
// File: crates/hyperswitch_connectors/src/connectors/xendit.rs
// Module: hyperswitch_connectors
// Methods: 6 total (0 public)

impl ConnectorCommon for for Xendit


// Implementation: impl Default for for CycleCheck
// File: crates/hyperswitch_constraint_graph/src/types.rs
// Module: hyperswitch_constraint_graph
// Methods: 1 total (0 public)

impl Default for for CycleCheck


// Function: validate_and_get_payment_method_records
// File: crates/payment_methods/src/core/migration.rs
// Module: payment_methods

pub fn validate_and_get_payment_method_records(self) -> MigrationValidationResult