// File: crates/diesel_models/src/query/connector_response.rs
// Module: diesel_models
// Public functions: 3

use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
use router_env::{instrument, logger, tracing};

use super::generics;
use crate::{
    connector_response::{
        ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate,
        ConnectorResponseUpdateInternal,
    },
    errors,
    payment_attempt::{PaymentAttempt, PaymentAttemptUpdate, PaymentAttemptUpdateInternal},
    schema::{connector_response::dsl, payment_attempt::dsl as pa_dsl},
    PgPooledConn, StorageResult,
};

impl ConnectorResponseNew {
    #[instrument(skip(conn))]
    pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<ConnectorResponse> {
        let payment_attempt_update = PaymentAttemptUpdate::ConnectorResponse {
            authentication_data: self.authentication_data.clone(),
            encoded_data: self.encoded_data.clone(),
            connector_transaction_id: self.connector_transaction_id.clone(),
            connector: self.connector_name.clone(),
            updated_by: self.updated_by.clone(),
            charge_id: self.charge_id.clone(),
        };

        let _payment_attempt: Result<PaymentAttempt, _> =
            generics::generic_update_with_unique_predicate_get_result::<
                <PaymentAttempt as HasTable>::Table,
                _,
                _,
                _,
            >(
                conn,
                pa_dsl::attempt_id
                    .eq(self.attempt_id.to_owned())
                    .and(pa_dsl::merchant_id.eq(self.merchant_id.to_owned())),
                PaymentAttemptUpdateInternal::from(payment_attempt_update),
            )
            .await
            .inspect_err(|err| {
                logger::error!(
                    "Error while updating payment attempt in connector_response flow {:?}",
                    err
                );
            });

        generics::generic_insert(conn, self).await
    }
}

impl ConnectorResponse {
    #[instrument(skip(conn))]
    pub async fn update(
        self,
        conn: &PgPooledConn,
        connector_response: ConnectorResponseUpdate,
    ) -> StorageResult<Self> {
        let payment_attempt_update = match connector_response.clone() {
            ConnectorResponseUpdate::ResponseUpdate {
                connector_transaction_id,
                authentication_data,
                encoded_data,
                connector_name,
                charge_id,
                updated_by,
            } => PaymentAttemptUpdate::ConnectorResponse {
                authentication_data,
                encoded_data,
                connector_transaction_id,
                connector: connector_name,
                charge_id,
                updated_by,
            },
            ConnectorResponseUpdate::ErrorUpdate {
                connector_name,
                updated_by,
            } => PaymentAttemptUpdate::ConnectorResponse {
                authentication_data: None,
                encoded_data: None,
                connector_transaction_id: None,
                connector: connector_name,
                charge_id: None,
                updated_by,
            },
        };

        let _payment_attempt: Result<PaymentAttempt, _> =
            generics::generic_update_with_unique_predicate_get_result::<
                <PaymentAttempt as HasTable>::Table,
                _,
                _,
                _,
            >(
                conn,
                pa_dsl::attempt_id
                    .eq(self.attempt_id.to_owned())
                    .and(pa_dsl::merchant_id.eq(self.merchant_id.to_owned())),
                PaymentAttemptUpdateInternal::from(payment_attempt_update),
            )
            .await
            .inspect_err(|err| {
                logger::error!(
                    "Error while updating payment attempt in connector_response flow {:?}",
                    err
                );
            });

        let connector_response_result =
            match generics::generic_update_with_unique_predicate_get_result::<
                <Self as HasTable>::Table,
                _,
                _,
                _,
            >(
                conn,
                dsl::merchant_id
                    .eq(self.merchant_id.clone())
                    .and(dsl::payment_id.eq(self.payment_id.clone()))
                    .and(dsl::attempt_id.eq(self.attempt_id.clone())),
                ConnectorResponseUpdateInternal::from(connector_response),
            )
            .await
            {
                Err(error) => match error.current_context() {
                    errors::DatabaseError::NoFieldsToUpdate => Ok(self),
                    _ => Err(error),
                },
                result => result,
            };

        connector_response_result
    }

    #[instrument(skip(conn))]
    pub async fn find_by_payment_id_merchant_id_attempt_id(
        conn: &PgPooledConn,
        payment_id: &common_utils::id_type::PaymentId,
        merchant_id: &common_utils::id_type::MerchantId,
        attempt_id: &str,
    ) -> StorageResult<Self> {
        let connector_response: Self =
            generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
                conn,
                dsl::merchant_id.eq(merchant_id.to_owned()).and(
                    dsl::payment_id
                        .eq(payment_id.to_owned())
                        .and(dsl::attempt_id.eq(attempt_id.to_owned())),
                ),
            )
            .await?;

        match generics::generic_find_one::<<PaymentAttempt as HasTable>::Table, _, _>(
            conn,
            pa_dsl::payment_id.eq(payment_id.to_owned()).and(
                pa_dsl::merchant_id
                    .eq(merchant_id.to_owned())
                    .and(pa_dsl::attempt_id.eq(attempt_id.to_owned())),
            ),
        )
        .await
        {
            Ok::<PaymentAttempt, _>(payment_attempt) => {
                if payment_attempt.authentication_data != connector_response.authentication_data {
                    logger::error!(
                        "Not Equal pa_authentication_data : {:?}, cr_authentication_data: {:?} ",
                        payment_attempt.authentication_data,
                        connector_response.authentication_data
                    );
                }

                if payment_attempt.encoded_data != connector_response.encoded_data {
                    logger::error!(
                        "Not Equal pa_encoded_data : {:?}, cr_encoded_data: {:?} ",
                        payment_attempt.encoded_data,
                        connector_response.encoded_data
                    );
                }

                if payment_attempt.connector_transaction_id
                    != connector_response.connector_transaction_id
                {
                    logger::error!(
                            "Not Equal pa_connector_transaction_id : {:?}, cr_connector_transaction_id: {:?} ",
                            payment_attempt.connector_transaction_id,
                            connector_response.connector_transaction_id
                        );
                }
                if payment_attempt.connector != connector_response.connector_name {
                    logger::error!(
                        "Not Equal pa_connector : {:?}, cr_connector_name: {:?} ",
                        payment_attempt.connector,
                        connector_response.connector_name
                    );
                }
            }
            Err(err) => {
                logger::error!(
                    "Error while finding payment attempt in connector_response flow {:?}",
                    err
                );
            }
        }

        Ok(connector_response)
    }
}


// Struct: ThreedsecureioPreAuthenticationResponseData
// File: crates/hyperswitch_connectors/src/connectors/threedsecureio/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ThreedsecureioPreAuthenticationResponseData


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

// Public submodules:
pub mod transformers;


// Struct: Shipping
// File: crates/router/src/compatibility/stripe/customers/types.rs
// Module: router
// Implementations: 0

pub struct Shipping


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

impl api::PaymentAuthorize for for Ebanx


// Trait: IntoContext
// File: crates/kgraph_utils/src/transformers.rs
// Module: kgraph_utils

pub trait IntoContext


// Struct: NovalnetWebhookEvent
// File: crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NovalnetWebhookEvent


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

// Public submodules:
pub mod transformers;


// Function: api_key_list
// File: crates/router/src/routes/api_keys.rs
// Module: router

pub fn api_key_list(
    state: web::Data<AppState>,
    req: HttpRequest,
    query: web::Query<api_types::ListApiKeyConstraints>,
) -> impl Responder


// Struct: RefundResponse
// File: crates/hyperswitch_connectors/src/connectors/hipay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct RefundResponse


// Struct: PoRecipientAccount
// File: crates/hyperswitch_domain_models/src/router_flow_types/payouts.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct PoRecipientAccount


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

pub fn payments_manual_update(
    state: SessionState,
    req: api_models::payments::PaymentsManualUpdateRequest,
) -> RouterResponse<api_models::payments::PaymentsManualUpdateResponse>


    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum UserAuthType {
    OpenIdConnect,
    MagicLink,
    #[default]
    Password,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum Owner {
    Organization,
    Tenant,
    Internal,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ApiVersion {
    V1,
    V2,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    Ord,
    PartialOrd,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    strum::EnumIter,
    ToSchema,
    Hash,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum EntityType {
    Tenant = 3,
    Organization = 2,
    Merchant = 1,
    Profile = 0,
}

#[derive(Clone, Debug, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum PayoutRetryType {
    SingleConnector,
    MultiConnector,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
    Hash,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum OrderFulfillmentTimeOrigin {
    Create,
    Confirm,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
    Hash,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum UIWidgetFormLayout {
    Tabs,
    Journey,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Default,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum DeleteStatus {
    #[default]
    Active,
    Redacted,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    Hash,
    strum::EnumString,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
#[router_derive::diesel_enum(storage_type = "db_enum")]
pub enum SuccessBasedRoutingConclusiveState {
    // pc: payment connector
    // sc: success based routing outcome/first connector
    // status: payment status
    //
    // status = success && pc == sc
    TruePositive,
    // status = failed && pc == sc
    FalsePositive,
    // status = failed && pc != sc
    TrueNegative,
    // status = success && pc != sc
    FalseNegative,
    // status = processing
    NonDeterministic,
}

/// Whether 3ds authentication is requested or not
#[derive(
    Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema,
)]
pub enum External3dsAuthenticationRequest {
    /// Request for 3ds authentication
    Enable,
    /// Skip 3ds authentication
    #[default]
    Skip,
}

/// Whether payment link is requested to be enabled or not for this transaction
#[derive(
    Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema,
)]
pub enum EnablePaymentLinkRequest {
    /// Request for enabling payment link
    Enable,
    /// Skip enabling payment link
    #[default]
    Skip,
}

#[derive(
    Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema,
)]
pub enum MitExemptionRequest {
    /// Request for applying MIT exemption
    Apply,
    /// Skip applying MIT exemption
    #[default]
    Skip,
}

/// Set to `present` to indicate that the customer is in your checkout flow during this payment, and therefore is able to authenticate. This parameter should be `absent` when merchant's doing merchant initiated payments and customer is not present while doing the payment.
#[derive(
    Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum PresenceOfCustomerDuringPayment {
    /// Customer is present during the payment. This is the default value
    #[default]
    Present,
    /// Customer is absent during the payment
    Absent,
}

impl From<ConnectorType> for TransactionType {
    fn from(connector_type: ConnectorType) -> Self {
        match connector_type {
            #[cfg(feature = "payouts")]
            ConnectorType::PayoutProcessor => Self::Payout,
            _ => Self::Payment,
        }
    }
}

impl From<RefundStatus> for RelayStatus {
    fn from(refund_status: RefundStatus) -> Self {
        match refund_status {
            RefundStatus::Failure | RefundStatus::TransactionFailure => Self::Failure,
            RefundStatus::ManualReview | RefundStatus::Pending => Self::Pending,
            RefundStatus::Success => Self::Success,
        }
    }
}

impl From<RelayStatus> for RefundStatus {
    fn from(relay_status: RelayStatus) -> Self {
        match relay_status {
            RelayStatus::Failure => Self::Failure,
            RelayStatus::Pending | RelayStatus::Created => Self::Pending,
            RelayStatus::Success => Self::Success,
        }
    }
}

#[derive(
    Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum TaxCalculationOverride {
    /// Skip calling the external tax provider
    #[default]
    Skip,
    /// Calculate tax by calling the external tax provider
    Calculate,
}

impl From<Option<bool>> for TaxCalculationOverride {
    fn from(value: Option<bool>) -> Self {
        match value {
            Some(true) => Self::Calculate,
            _ => Self::Skip,
        }
    }
}

impl TaxCalculationOverride {
    pub fn as_bool(self) -> bool {
        match self {
            Self::Skip => false,
            Self::Calculate => true,
        }
    }
}

#[derive(
    Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum SurchargeCalculationOverride {
    /// Skip calculating surcharge
    #[default]
    Skip,
    /// Calculate surcharge
    Calculate,
}

impl From<Option<bool>> for SurchargeCalculationOverride {
    fn from(value: Option<bool>) -> Self {
        match value {
            Some(true) => Self::Calculate,
            _ => Self::Skip,
        }
    }
}

impl SurchargeCalculationOverride {
    pub fn as_bool(self) -> bool {
        match self {
            Self::Skip => false,
            Self::Calculate => true,
        }
    }
}

/// Connector Mandate Status
#[derive(
    Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, strum::Display,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ConnectorMandateStatus {
    /// Indicates that the connector mandate is active and can be used for payments.
    Active,
    /// Indicates that the connector mandate  is not active and hence cannot be used for payments.
    Inactive,
}

/// Connector Mandate Status
#[derive(
    Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, strum::Display,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ConnectorTokenStatus {
    /// Indicates that the connector mandate is active and can be used for payments.
    Active,
    /// Indicates that the connector mandate  is not active and hence cannot be used for payments.
    Inactive,
}

#[derive(
    Clone,
    Copy,
    Debug,
    strum::Display,
    PartialEq,
    Eq,
    serde::Serialize,
    serde::Deserialize,
    strum::EnumString,
    ToSchema,
    PartialOrd,
    Ord,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum ErrorCategory {
    FrmDecline,
    ProcessorDowntime,
    ProcessorDeclineUnauthorized,
    IssueWithPaymentMethod,
    ProcessorDeclineIncorrectData,
    HardDecline,
    SoftDecline,
}

impl ErrorCategory {
    pub fn should_perform_elimination_routing(self) -> bool {
        match self {
            Self::ProcessorDowntime | Self::ProcessorDeclineUnauthorized => true,
            Self::IssueWithPaymentMethod
            | Self::ProcessorDeclineIncorrectData
            | Self::FrmDecline
            | Self::HardDecline
            | Self::SoftDecline => false,
        }
    }
}

#[derive(
    Clone,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
    Hash,
)]
pub enum PaymentChargeType {
    #[serde(untagged)]
    Stripe(StripeChargeType),
}

#[derive(
    Clone,
    Debug,
    Default,
    Hash,
    Eq,
    PartialEq,
    ToSchema,
    serde::Serialize,
    serde::Deserialize,
    strum::Display,
    strum::EnumString,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum StripeChargeType {
    #[default]
    Direct,
    Destination,
}

/// Authentication Products
#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    Hash,
    PartialEq,
    serde::Serialize,
    serde::Deserialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum AuthenticationProduct {
    ClickToPay,
}

/// Connector Access Method
#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    Hash,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    ToSchema,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum HyperswitchConnectorCategory {
    PaymentGateway,
    AlternativePaymentMethod,
    BankAcquirer,
    PayoutProcessor,
    AuthenticationProvider,
    FraudAndRiskManagementProvider,
    TaxCalculationProvider,
    RevenueGrowthManagementPlatform,
}

/// Connector Integration Status
#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    Hash,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    ToSchema,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ConnectorIntegrationStatus {
    /// Connector is integrated and live on production
    Live,
    /// Connector is integrated and fully tested on sandbox
    Sandbox,
    /// Connector is integrated and partially tested on sandbox
    Beta,
    /// Connector is integrated using the online documentation but not tested yet
    Alpha,
}

/// The status of the feature
#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    ToSchema,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum FeatureStatus {
    NotSupported,
    Supported,
}

/// The type of tokenization to use for the payment method
#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    ToSchema,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum TokenizationType {
    /// Create a single use token for the given payment method
    /// The user might have to go through additional factor authentication when using the single use token if required by the payment method
    SingleUse,
    /// Create a multi use token for the given payment method
    /// User will have to complete the additional factor authentication only once when creating the multi use token
    /// This will create a mandate at the connector which can be used for recurring payments
    MultiUse,
}

/// The network tokenization toggle, whether to enable or skip the network tokenization
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
pub enum NetworkTokenizationToggle {
    /// Enable network tokenization for the payment method
    Enable,
    /// Skip network tokenization for the payment method
    Skip,
}

#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize, ToSchema)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum GooglePayAuthMethod {
    /// Contain pan data only
    PanOnly,
    /// Contain cryptogram data along with pan data
    #[serde(rename = "CRYPTOGRAM_3DS")]
    Cryptogram,
}

#[derive(
    Clone,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[strum(serialize_all = "PascalCase")]
#[serde(rename_all = "PascalCase")]
pub enum AdyenSplitType {
    /// Books split amount to the specified account.
    BalanceAccount,
    /// The aggregated amount of the interchange and scheme fees.
    AcquiringFees,
    /// The aggregated amount of all transaction fees.
    PaymentFee,
    /// The aggregated amount of Adyen's commission and markup fees.
    AdyenFees,
    ///  The transaction fees due to Adyen under blended rates.
    AdyenCommission,
    /// The transaction fees due to Adyen under Interchange ++ pricing.
    AdyenMarkup,
    ///  The fees paid to the issuer for each payment made with the card network.
    Interchange,
    ///  The fees paid to the card scheme for using their network.
    SchemeFee,
    /// Your platform's commission on the payment (specified in amount), booked to your liable balance account.
    Commission,
    /// Allows you and your users to top up balance accounts using direct debit, card payments, or other payment methods.
    TopUp,
    /// The value-added tax charged on the payment, booked to your platforms liable balance account.
    Vat,
}

#[derive(
    Clone, Copy, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema, Default,
)]
#[serde(rename = "snake_case")]
pub enum PaymentConnectorTransmission {
    /// Failed to call the payment connector
    #[default]
    ConnectorCallUnsuccessful,
    /// Payment Connector call succeeded
    ConnectorCallSucceeded,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Default,
    Eq,
    Hash,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum TriggeredBy {
    /// Denotes payment attempt is been created by internal system.
    #[default]
    Internal,
    /// Denotes payment attempt is been created by external system.
    External,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum ProcessTrackerStatus {
    // Picked by the producer
    Processing,
    // State when the task is added
    New,
    // Send to retry
    Pending,
    // Picked by consumer
    ProcessStarted,
    // Finished by consumer
    Finish,
    // Review the task
    Review,
}

#[derive(
    serde::Serialize,
    serde::Deserialize,
    Clone,
    Copy,
    Debug,
    PartialEq,
    Eq,
    strum::EnumString,
    strum::Display,
)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
pub enum ProcessTrackerRunner {
    PaymentsSyncWorkflow,
    RefundWorkflowRouter,
    DeleteTokenizeDataWorkflow,
    ApiKeyExpiryWorkflow,
    OutgoingWebhookRetryWorkflow,
    AttachPayoutAccountWorkflow,
    PaymentMethodStatusUpdateWorkflow,
    PassiveRecoveryWorkflow,
    ProcessDisputeWorkflow,
    DisputeListWorkflow,
}

#[derive(Debug)]
pub enum CryptoPadding {
    PKCS7,
    ZeroPadding,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum TokenizationFlag {
    /// Token is active and can be used for payments
    Enabled,
    /// Token is inactive and cannot be used for payments
    Disabled,
}

/// The type of token data to fetch for get-token endpoint

#[derive(Clone, Copy, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum TokenDataType {
    /// Fetch single use token for the given payment method
    SingleUseToken,
    /// Fetch multi use token for the given payment method
    MultiUseToken,
    /// Fetch network token for the given payment method
    NetworkToken,
}

#[derive(
    Clone,
    Debug,
    Default,
    Eq,
    Hash,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::VariantNames,
    strum::EnumIter,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum RoutingApproach {
    SuccessRateExploitation,
    SuccessRateExploration,
    ContractBasedRouting,
    DebitRouting,
    RuleBasedRouting,
    VolumeBasedRouting,
    StraightThroughRouting,
    #[default]
    DefaultFallback,
    #[serde(untagged)]
    #[strum(default)]
    Other(String),
}

impl RoutingApproach {
    pub fn from_decision_engine_approach(approach: &str) -> Self {
        match approach {
            "SR_SELECTION_V3_ROUTING" => Self::SuccessRateExploitation,
            "SR_V3_HEDGING" | "DEFAULT" => Self::SuccessRateExploration,
            "NTW_BASED_ROUTING" => Self::DebitRouting,
            _ => Self::DefaultFallback,
        }
    }
}

#[derive(
    Clone,
    Copy,
    Debug,
    Eq,
    PartialEq,
    serde::Serialize,
    serde::Deserialize,
    ToSchema,
    strum::Display,
    strum::EnumString,
    Hash,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
#[router_derive::diesel_enum(storage_type = "text")]
pub enum CallbackMapperIdType {
    NetworkTokenRequestorReferenceID,
}

/// Payment Method Status
#[derive(
    Clone,
    Copy,
    Debug,
    PartialEq,
    Eq,
    Hash,
    serde::Serialize,
    serde::Deserialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum VaultType {
    /// Indicates that the payment method is stored in internal vault.
    Internal,
    /// Indicates that the payment method is stored in external vault.
    External,
}

#[derive(
    Clone,
    Debug,
    Copy,
    Default,
    Eq,
    Hash,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    strum::Display,
    strum::EnumString,
    ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum ExternalVaultEnabled {
    Enable,
    #[default]
    Skip,
}


// File: crates/diesel_models/src/kv.rs
// Module: diesel_models
// Public functions: 4
// Public structs: 12

use error_stack::ResultExt;
use serde::{Deserialize, Serialize};

#[cfg(feature = "v2")]
use crate::payment_attempt::PaymentAttemptUpdateInternal;
#[cfg(feature = "v1")]
use crate::payment_intent::PaymentIntentUpdate;
#[cfg(feature = "v2")]
use crate::payment_intent::PaymentIntentUpdateInternal;
use crate::{
    address::{Address, AddressNew, AddressUpdateInternal},
    customers::{Customer, CustomerNew, CustomerUpdateInternal},
    errors,
    payment_attempt::{PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
    payment_intent::PaymentIntentNew,
    payout_attempt::{PayoutAttempt, PayoutAttemptNew, PayoutAttemptUpdate},
    payouts::{Payouts, PayoutsNew, PayoutsUpdate},
    refund::{Refund, RefundNew, RefundUpdate},
    reverse_lookup::{ReverseLookup, ReverseLookupNew},
    Mandate, MandateNew, MandateUpdateInternal, PaymentIntent, PaymentMethod, PaymentMethodNew,
    PaymentMethodUpdateInternal, PgPooledConn,
};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "db_op", content = "data")]
pub enum DBOperation {
    Insert { insertable: Box<Insertable> },
    Update { updatable: Box<Updateable> },
}

impl DBOperation {
    pub fn operation<'a>(&self) -> &'a str {
        match self {
            Self::Insert { .. } => "insert",
            Self::Update { .. } => "update",
        }
    }
    pub fn table<'a>(&self) -> &'a str {
        match self {
            Self::Insert { insertable } => match **insertable {
                Insertable::PaymentIntent(_) => "payment_intent",
                Insertable::PaymentAttempt(_) => "payment_attempt",
                Insertable::Refund(_) => "refund",
                Insertable::Address(_) => "address",
                Insertable::Payouts(_) => "payouts",
                Insertable::PayoutAttempt(_) => "payout_attempt",
                Insertable::Customer(_) => "customer",
                Insertable::ReverseLookUp(_) => "reverse_lookup",
                Insertable::PaymentMethod(_) => "payment_method",
                Insertable::Mandate(_) => "mandate",
            },
            Self::Update { updatable } => match **updatable {
                Updateable::PaymentIntentUpdate(_) => "payment_intent",
                Updateable::PaymentAttemptUpdate(_) => "payment_attempt",
                Updateable::RefundUpdate(_) => "refund",
                Updateable::CustomerUpdate(_) => "customer",
                Updateable::AddressUpdate(_) => "address",
                Updateable::PayoutsUpdate(_) => "payouts",
                Updateable::PayoutAttemptUpdate(_) => "payout_attempt",
                Updateable::PaymentMethodUpdate(_) => "payment_method",
                Updateable::MandateUpdate(_) => " mandate",
            },
        }
    }
}

#[derive(Debug)]
pub enum DBResult {
    PaymentIntent(Box<PaymentIntent>),
    PaymentAttempt(Box<PaymentAttempt>),
    Refund(Box<Refund>),
    Address(Box<Address>),
    Customer(Box<Customer>),
    ReverseLookUp(Box<ReverseLookup>),
    Payouts(Box<Payouts>),
    PayoutAttempt(Box<PayoutAttempt>),
    PaymentMethod(Box<PaymentMethod>),
    Mandate(Box<Mandate>),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TypedSql {
    #[serde(flatten)]
    pub op: DBOperation,
}

impl DBOperation {
    pub async fn execute(self, conn: &PgPooledConn) -> crate::StorageResult<DBResult> {
        Ok(match self {
            Self::Insert { insertable } => match *insertable {
                Insertable::PaymentIntent(a) => {
                    DBResult::PaymentIntent(Box::new(a.insert(conn).await?))
                }
                Insertable::PaymentAttempt(a) => {
                    DBResult::PaymentAttempt(Box::new(a.insert(conn).await?))
                }
                Insertable::Refund(a) => DBResult::Refund(Box::new(a.insert(conn).await?)),
                Insertable::Address(addr) => DBResult::Address(Box::new(addr.insert(conn).await?)),
                Insertable::Customer(cust) => {
                    DBResult::Customer(Box::new(cust.insert(conn).await?))
                }
                Insertable::ReverseLookUp(rev) => {
                    DBResult::ReverseLookUp(Box::new(rev.insert(conn).await?))
                }
                Insertable::Payouts(rev) => DBResult::Payouts(Box::new(rev.insert(conn).await?)),
                Insertable::PayoutAttempt(rev) => {
                    DBResult::PayoutAttempt(Box::new(rev.insert(conn).await?))
                }
                Insertable::PaymentMethod(rev) => {
                    DBResult::PaymentMethod(Box::new(rev.insert(conn).await?))
                }
                Insertable::Mandate(m) => DBResult::Mandate(Box::new(m.insert(conn).await?)),
            },
            Self::Update { updatable } => match *updatable {
                #[cfg(feature = "v1")]
                Updateable::PaymentIntentUpdate(a) => {
                    DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                #[cfg(feature = "v2")]
                Updateable::PaymentIntentUpdate(a) => {
                    DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                #[cfg(feature = "v1")]
                Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new(
                    a.orig.update_with_attempt_id(conn, a.update_data).await?,
                )),
                #[cfg(feature = "v2")]
                Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new(
                    a.orig.update_with_attempt_id(conn, a.update_data).await?,
                )),
                #[cfg(feature = "v1")]
                Updateable::RefundUpdate(a) => {
                    DBResult::Refund(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                #[cfg(feature = "v2")]
                Updateable::RefundUpdate(a) => {
                    DBResult::Refund(Box::new(a.orig.update_with_id(conn, a.update_data).await?))
                }
                Updateable::AddressUpdate(a) => {
                    DBResult::Address(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                Updateable::PayoutsUpdate(a) => {
                    DBResult::Payouts(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                Updateable::PayoutAttemptUpdate(a) => DBResult::PayoutAttempt(Box::new(
                    a.orig.update_with_attempt_id(conn, a.update_data).await?,
                )),
                #[cfg(feature = "v1")]
                Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
                    v.orig
                        .update_with_payment_method_id(conn, v.update_data)
                        .await?,
                )),
                #[cfg(feature = "v2")]
                Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
                    v.orig.update_with_id(conn, v.update_data).await?,
                )),
                Updateable::MandateUpdate(m) => DBResult::Mandate(Box::new(
                    Mandate::update_by_merchant_id_mandate_id(
                        conn,
                        &m.orig.merchant_id,
                        &m.orig.mandate_id,
                        m.update_data,
                    )
                    .await?,
                )),
                #[cfg(feature = "v1")]
                Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
                    Customer::update_by_customer_id_merchant_id(
                        conn,
                        cust.orig.customer_id.clone(),
                        cust.orig.merchant_id.clone(),
                        cust.update_data,
                    )
                    .await?,
                )),
                #[cfg(feature = "v2")]
                Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
                    Customer::update_by_id(conn, cust.orig.id, cust.update_data).await?,
                )),
            },
        })
    }
}

impl TypedSql {
    pub fn to_field_value_pairs(
        &self,
        request_id: String,
        global_id: String,
    ) -> crate::StorageResult<Vec<(&str, String)>> {
        let pushed_at = common_utils::date_time::now_unix_timestamp();

        Ok(vec![
            (
                "typed_sql",
                serde_json::to_string(self)
                    .change_context(errors::DatabaseError::QueryGenerationFailed)?,
            ),
            ("global_id", global_id),
            ("request_id", request_id),
            ("pushed_at", pushed_at.to_string()),
        ])
    }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "table", content = "data")]
pub enum Insertable {
    PaymentIntent(Box<PaymentIntentNew>),
    PaymentAttempt(Box<PaymentAttemptNew>),
    Refund(RefundNew),
    Address(Box<AddressNew>),
    Customer(CustomerNew),
    ReverseLookUp(ReverseLookupNew),
    Payouts(PayoutsNew),
    PayoutAttempt(PayoutAttemptNew),
    PaymentMethod(PaymentMethodNew),
    Mandate(MandateNew),
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "table", content = "data")]
pub enum Updateable {
    PaymentIntentUpdate(Box<PaymentIntentUpdateMems>),
    PaymentAttemptUpdate(Box<PaymentAttemptUpdateMems>),
    RefundUpdate(Box<RefundUpdateMems>),
    CustomerUpdate(CustomerUpdateMems),
    AddressUpdate(Box<AddressUpdateMems>),
    PayoutsUpdate(PayoutsUpdateMems),
    PayoutAttemptUpdate(PayoutAttemptUpdateMems),
    PaymentMethodUpdate(Box<PaymentMethodUpdateMems>),
    MandateUpdate(MandateUpdateMems),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CustomerUpdateMems {
    pub orig: Customer,
    pub update_data: CustomerUpdateInternal,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AddressUpdateMems {
    pub orig: Address,
    pub update_data: AddressUpdateInternal,
}
#[cfg(feature = "v1")]
#[derive(Debug, Serialize, Deserialize)]
pub struct PaymentIntentUpdateMems {
    pub orig: PaymentIntent,
    pub update_data: PaymentIntentUpdate,
}

#[cfg(feature = "v2")]
#[derive(Debug, Serialize, Deserialize)]
pub struct PaymentIntentUpdateMems {
    pub orig: PaymentIntent,
    pub update_data: PaymentIntentUpdateInternal,
}

#[cfg(feature = "v1")]
#[derive(Debug, Serialize, Deserialize)]
pub struct PaymentAttemptUpdateMems {
    pub orig: PaymentAttempt,
    pub update_data: PaymentAttemptUpdate,
}

#[cfg(feature = "v2")]
#[derive(Debug, Serialize, Deserialize)]
pub struct PaymentAttemptUpdateMems {
    pub orig: PaymentAttempt,
    pub update_data: PaymentAttemptUpdateInternal,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RefundUpdateMems {
    pub orig: Refund,
    pub update_data: RefundUpdate,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PayoutsUpdateMems {
    pub orig: Payouts,
    pub update_data: PayoutsUpdate,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PayoutAttemptUpdateMems {
    pub orig: PayoutAttempt,
    pub update_data: PayoutAttemptUpdate,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PaymentMethodUpdateMems {
    pub orig: PaymentMethod,
    pub update_data: PaymentMethodUpdateInternal,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct MandateUpdateMems {
    pub orig: Mandate,
    pub update_data: MandateUpdateInternal,
}


// Implementation: impl api::PaymentCapture for for Bankofamerica
// File: crates/hyperswitch_connectors/src/connectors/bankofamerica.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentCapture for for Bankofamerica


// Implementation: impl api::Refund for for Blackhawknetwork
// File: crates/hyperswitch_connectors/src/connectors/blackhawknetwork.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Refund for for Blackhawknetwork


// File: crates/router/src/env.rs
// Module: router

#[doc(inline)]
pub use router_env::*;


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

impl api::Payment for for Prophetpay


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

impl ConnectorCommon for for Vgs


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

pub struct DsResponse


// Struct: IntegrationMethod
// File: crates/api_models/src/user/dashboard_metadata.rs
// Module: api_models
// Implementations: 0

pub struct IntegrationMethod


// Struct: TrustpaymentsSyncRequest
// File: crates/hyperswitch_connectors/src/connectors/trustpayments/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct TrustpaymentsSyncRequest


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

pub struct PaypalSupplementaryData


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

pub fn initiate_secure_payment_link_flow(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    merchant_id: common_utils::id_type::MerchantId,
    payment_id: common_utils::id_type::PaymentId,
    request_headers: &header::HeaderMap,
) -> RouterResponse<services::PaymentLinkFormData>


// File: crates/hyperswitch_connectors/src/connectors/breadpay.rs
// Module: hyperswitch_connectors
// Public functions: 1
// Public structs: 1

pub mod transformers;

use std::sync::LazyLock;

use base64::Engine;
use common_enums::{enums, CallConnectorAction, PaymentAction};
use common_utils::{
    consts::BASE64_ENGINE,
    errors::CustomResult,
    ext_traits::BytesExt,
    request::{Method, Request, RequestBuilder, RequestContent},
    types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector},
};
use error_stack::{report, ResultExt};
use hyperswitch_domain_models::{
    router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
    router_flow_types::{
        access_token_auth::AccessTokenAuth,
        payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
        refunds::{Execute, RSync},
        CompleteAuthorize,
    },
    router_request_types::{
        AccessTokenRequestData, CompleteAuthorizeData, PaymentMethodTokenizationData,
        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData,
        PaymentsSyncData, RefundsData, SetupMandateRequestData,
    },
    router_response_types::{
        ConnectorInfo, PaymentMethodDetails, PaymentsResponseData, RefundsResponseData,
        SupportedPaymentMethods, SupportedPaymentMethodsExt,
    },
    types::{
        PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
        PaymentsCompleteAuthorizeRouterData, PaymentsSyncRouterData, RefundSyncRouterData,
        RefundsRouterData,
    },
};
use hyperswitch_interfaces::{
    api::{
        self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorRedirectResponse,
        ConnectorSpecifications, ConnectorValidation,
    },
    configs::Connectors,
    errors,
    events::connector_api_logs::ConnectorEvent,
    types::{self, Response},
    webhooks,
};
use masking::{ExposeInterface, Mask, Maskable, PeekInterface};
use transformers::{
    self as breadpay, BreadpayTransactionRequest, BreadpayTransactionResponse,
    BreadpayTransactionType,
};

use crate::{
    connectors::breadpay::transformers::CallBackResponse,
    constants::headers,
    types::ResponseRouterData,
    utils::{self, PaymentsCompleteAuthorizeRequestData},
};

#[derive(Clone)]
pub struct Breadpay {
    amount_converter: &'static (dyn AmountConvertor<Output = StringMinorUnit> + Sync),
}

impl Breadpay {
    pub fn new() -> &'static Self {
        &Self {
            amount_converter: &StringMinorUnitForConnector,
        }
    }
}

impl api::Payment for Breadpay {}
impl api::PaymentSession for Breadpay {}
impl api::PaymentsCompleteAuthorize for Breadpay {}
impl api::ConnectorAccessToken for Breadpay {}
impl api::MandateSetup for Breadpay {}
impl api::PaymentAuthorize for Breadpay {}
impl api::PaymentSync for Breadpay {}
impl api::PaymentCapture for Breadpay {}
impl api::PaymentVoid for Breadpay {}
impl api::Refund for Breadpay {}
impl api::RefundExecute for Breadpay {}
impl api::RefundSync for Breadpay {}
impl api::PaymentToken for Breadpay {}

impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
    for Breadpay
{
    // Not Implemented (R)
}

impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Breadpay
where
    Self: ConnectorIntegration<Flow, Request, Response>,
{
    fn build_headers(
        &self,
        req: &RouterData<Flow, Request, Response>,
        _connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        let mut header = vec![(
            headers::CONTENT_TYPE.to_string(),
            self.get_content_type().to_string().into(),
        )];
        let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
        header.append(&mut api_key);
        Ok(header)
    }
}

impl ConnectorCommon for Breadpay {
    fn id(&self) -> &'static str {
        "breadpay"
    }

    fn get_currency_unit(&self) -> api::CurrencyUnit {
        api::CurrencyUnit::Minor
        //    TODO! Check connector documentation, on which unit they are processing the currency.
        //    If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor,
        //    if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base
    }

    fn common_get_content_type(&self) -> &'static str {
        "application/json"
    }

    fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str {
        connectors.breadpay.base_url.as_ref()
    }

    fn get_auth_header(
        &self,
        auth_type: &ConnectorAuthType,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        let auth = breadpay::BreadpayAuthType::try_from(auth_type)
            .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
        let encoded_api_key = BASE64_ENGINE.encode(format!(
            "{}:{}",
            auth.api_key.peek(),
            auth.api_secret.peek()
        ));
        Ok(vec![(
            headers::AUTHORIZATION.to_string(),
            format!("Basic {encoded_api_key}").into_masked(),
        )])
    }

    fn build_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        let response: breadpay::BreadpayErrorResponse = res
            .response
            .parse_struct("BreadpayErrorResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);

        Ok(ErrorResponse {
            status_code: res.status_code,
            code: response.error_type.clone(),
            message: response.description.clone(),
            reason: Some(response.description),
            attempt_status: None,
            connector_transaction_id: None,
            network_advice_code: None,
            network_decline_code: None,
            network_error_message: None,
            connector_metadata: None,
        })
    }
}

impl ConnectorValidation for Breadpay {}

impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Breadpay {
    //TODO: implement sessions flow
}

impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken> for Breadpay {}

impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
    for Breadpay
{
}

impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Breadpay {
    fn get_headers(
        &self,
        req: &PaymentsAuthorizeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_url(
        &self,
        _req: &PaymentsAuthorizeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        Ok(format!("{}{}", self.base_url(connectors), "/carts"))
    }

    fn get_request_body(
        &self,
        req: &PaymentsAuthorizeRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let amount = utils::convert_amount(
            self.amount_converter,
            req.request.minor_amount,
            req.request.currency,
        )?;

        let connector_router_data = breadpay::BreadpayRouterData::from((amount, req));
        let connector_req = breadpay::BreadpayCartRequest::try_from(&connector_router_data)?;
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn build_request(
        &self,
        req: &PaymentsAuthorizeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Post)
                .url(&types::PaymentsAuthorizeType::get_url(
                    self, req, connectors,
                )?)
                .attach_default_headers()
                .headers(types::PaymentsAuthorizeType::get_headers(
                    self, req, connectors,
                )?)
                .set_body(types::PaymentsAuthorizeType::get_request_body(
                    self, req, connectors,
                )?)
                .build(),
        ))
    }

    fn handle_response(
        &self,
        data: &PaymentsAuthorizeRouterData,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> {
        let response: breadpay::BreadpayPaymentsResponse = res
            .response
            .parse_struct("Breadpay BreadpayPaymentsResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

impl ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResponseData>
    for Breadpay
{
    fn get_headers(
        &self,
        req: &PaymentsCompleteAuthorizeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_request_body(
        &self,
        req: &PaymentsCompleteAuthorizeRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let transaction_type = if req.request.is_auto_capture()? {
            BreadpayTransactionType::Settle
        } else {
            BreadpayTransactionType::Authorize
        };
        let connector_req = BreadpayTransactionRequest { transaction_type };
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn get_url(
        &self,
        req: &PaymentsCompleteAuthorizeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        let redirect_response = req.request.redirect_response.clone().ok_or(
            errors::ConnectorError::MissingRequiredField {
                field_name: "redirect_response",
            },
        )?;
        let redirect_payload = redirect_response
            .payload
            .ok_or(errors::ConnectorError::MissingConnectorRedirectionPayload {
                field_name: "request.redirect_response.payload",
            })?
            .expose();
        let call_back_response: CallBackResponse = serde_json::from_value::<CallBackResponse>(
            redirect_payload.clone(),
        )
        .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload {
            field_name: "redirection_payload",
        })?;

        Ok(format!(
            "{}{}{}",
            self.base_url(connectors),
            "/transactions/actions",
            call_back_response.transaction_id
        ))
    }

    fn build_request(
        &self,
        req: &PaymentsCompleteAuthorizeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Post)
                .url(&types::PaymentsCompleteAuthorizeType::get_url(
                    self, req, connectors,
                )?)
                .headers(types::PaymentsCompleteAuthorizeType::get_headers(
                    self, req, connectors,
                )?)
                .set_body(types::PaymentsCompleteAuthorizeType::get_request_body(
                    self, req, connectors,
                )?)
                .build(),
        ))
    }

    fn handle_response(
        &self,
        data: &PaymentsCompleteAuthorizeRouterData,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<PaymentsCompleteAuthorizeRouterData, errors::ConnectorError> {
        let response: BreadpayTransactionResponse = res
            .response
            .parse_struct("BreadpayTransactionResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Breadpay {
    fn get_headers(
        &self,
        req: &PaymentsSyncRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_url(
        &self,
        req: &PaymentsSyncRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        Ok(format!(
            "{}{}{}",
            self.base_url(connectors),
            "/transactions",
            req.request
                .connector_transaction_id
                .get_connector_transaction_id()
                .change_context(errors::ConnectorError::MissingConnectorTransactionID)?
        ))
    }

    fn build_request(
        &self,
        req: &PaymentsSyncRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Get)
                .url(&types::PaymentsSyncType::get_url(self, req, connectors)?)
                .attach_default_headers()
                .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?)
                .build(),
        ))
    }

    fn handle_response(
        &self,
        data: &PaymentsSyncRouterData,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<PaymentsSyncRouterData, errors::ConnectorError> {
        let response: BreadpayTransactionResponse = res
            .response
            .parse_struct("BreadpayTransactionResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> for Breadpay {
    fn get_headers(
        &self,
        req: &PaymentsCaptureRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_url(
        &self,
        req: &PaymentsCaptureRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        Ok(format!(
            "{}{}{}",
            self.base_url(connectors),
            "/transactions/actions",
            req.request.connector_transaction_id
        ))
    }

    fn get_request_body(
        &self,
        _req: &PaymentsCaptureRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let connector_req = BreadpayTransactionRequest {
            transaction_type: BreadpayTransactionType::Settle,
        };
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn build_request(
        &self,
        req: &PaymentsCaptureRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Post)
                .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?)
                .attach_default_headers()
                .headers(types::PaymentsCaptureType::get_headers(
                    self, req, connectors,
                )?)
                .set_body(types::PaymentsCaptureType::get_request_body(
                    self, req, connectors,
                )?)
                .build(),
        ))
    }

    fn handle_response(
        &self,
        data: &PaymentsCaptureRouterData,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<PaymentsCaptureRouterData, errors::ConnectorError> {
        let response: BreadpayTransactionResponse = res
            .response
            .parse_struct("BreadpayTransactionResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Breadpay {
    fn get_headers(
        &self,
        req: &PaymentsCancelRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_url(
        &self,
        req: &PaymentsCancelRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        Ok(format!(
            "{}{}{}",
            self.base_url(connectors),
            "/transactions/actions",
            req.request.connector_transaction_id
        ))
    }

    fn get_request_body(
        &self,
        _req: &PaymentsCancelRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let connector_req = BreadpayTransactionRequest {
            transaction_type: BreadpayTransactionType::Cancel,
        };
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn build_request(
        &self,
        req: &PaymentsCancelRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Post)
                .url(&types::PaymentsVoidType::get_url(self, req, connectors)?)
                .attach_default_headers()
                .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?)
                .set_body(types::PaymentsVoidType::get_request_body(
                    self, req, connectors,
                )?)
                .build(),
        ))
    }

    fn handle_response(
        &self,
        data: &PaymentsCancelRouterData,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<PaymentsCancelRouterData, errors::ConnectorError> {
        let response: BreadpayTransactionResponse = res
            .response
            .parse_struct("BreadpayTransactionResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Breadpay {
    fn get_headers(
        &self,
        req: &RefundsRouterData<Execute>,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_url(
        &self,
        _req: &RefundsRouterData<Execute>,
        _connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
    }

    fn get_request_body(
        &self,
        req: &RefundsRouterData<Execute>,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let refund_amount = utils::convert_amount(
            self.amount_converter,
            req.request.minor_refund_amount,
            req.request.currency,
        )?;

        let connector_router_data = breadpay::BreadpayRouterData::from((refund_amount, req));
        let connector_req = breadpay::BreadpayRefundRequest::try_from(&connector_router_data)?;
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn build_request(
        &self,
        req: &RefundsRouterData<Execute>,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        let request = RequestBuilder::new()
            .method(Method::Post)
            .url(&types::RefundExecuteType::get_url(self, req, connectors)?)
            .attach_default_headers()
            .headers(types::RefundExecuteType::get_headers(
                self, req, connectors,
            )?)
            .set_body(types::RefundExecuteType::get_request_body(
                self, req, connectors,
            )?)
            .build();
        Ok(Some(request))
    }

    fn handle_response(
        &self,
        data: &RefundsRouterData<Execute>,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<RefundsRouterData<Execute>, errors::ConnectorError> {
        let response: breadpay::RefundResponse = res
            .response
            .parse_struct("breadpay RefundResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Breadpay {
    fn get_headers(
        &self,
        req: &RefundSyncRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        self.build_headers(req, connectors)
    }

    fn get_content_type(&self) -> &'static str {
        self.common_get_content_type()
    }

    fn get_url(
        &self,
        _req: &RefundSyncRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
    }

    fn build_request(
        &self,
        req: &RefundSyncRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Get)
                .url(&types::RefundSyncType::get_url(self, req, connectors)?)
                .attach_default_headers()
                .headers(types::RefundSyncType::get_headers(self, req, connectors)?)
                .set_body(types::RefundSyncType::get_request_body(
                    self, req, connectors,
                )?)
                .build(),
        ))
    }

    fn handle_response(
        &self,
        data: &RefundSyncRouterData,
        event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<RefundSyncRouterData, errors::ConnectorError> {
        let response: breadpay::RefundResponse = res
            .response
            .parse_struct("breadpay RefundSyncResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        event_builder.map(|i| i.set_response_body(&response));
        router_env::logger::info!(connector_response=?response);
        RouterData::try_from(ResponseRouterData {
            response,
            data: data.clone(),
            http_code: res.status_code,
        })
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}

#[async_trait::async_trait]
impl webhooks::IncomingWebhook for Breadpay {
    fn get_webhook_object_reference_id(
        &self,
        _request: &webhooks::IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }

    fn get_webhook_event_type(
        &self,
        _request: &webhooks::IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::IncomingWebhookEvent, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }

    fn get_webhook_resource_object(
        &self,
        _request: &webhooks::IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }
}

static BREADPAY_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> =
    LazyLock::new(|| {
        let supported_capture_methods = vec![
            enums::CaptureMethod::Automatic,
            enums::CaptureMethod::Manual,
            enums::CaptureMethod::SequentialAutomatic,
        ];

        let mut breadpay_supported_payment_methods = SupportedPaymentMethods::new();

        breadpay_supported_payment_methods.add(
            enums::PaymentMethod::PayLater,
            enums::PaymentMethodType::Breadpay,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods,
                specific_features: None,
            },
        );

        breadpay_supported_payment_methods
    });

static BREADPAY_CONNECTOR_INFO: ConnectorInfo = ConnectorInfo {
    display_name: "Breadpay",
    description: "Breadpay connector",
    connector_type: enums::HyperswitchConnectorCategory::PaymentGateway,
    integration_status: enums::ConnectorIntegrationStatus::Alpha,
};

static BREADPAY_SUPPORTED_WEBHOOK_FLOWS: [enums::EventClass; 0] = [];

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

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

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

impl ConnectorRedirectResponse for Breadpay {
    fn get_flow_type(
        &self,
        _query_params: &str,
        _json_payload: Option<serde_json::Value>,
        action: PaymentAction,
    ) -> CustomResult<CallConnectorAction, errors::ConnectorError> {
        match action {
            PaymentAction::PSync
            | PaymentAction::CompleteAuthorize
            | PaymentAction::PaymentAuthenticateCompleteAuthorize => {
                Ok(CallConnectorAction::Trigger)
            }
        }
    }
}


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

impl api::PaymentSession for for Taxjar


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

pub struct BamboraPaymentsCaptureRequest


// Struct: DebitRoutingOutput
// File: crates/api_models/src/open_router.rs
// Module: api_models
// Implementations: 0

pub struct DebitRoutingOutput


// Struct: PaytmAuthType
// File: crates/hyperswitch_connectors/src/connectors/paytm/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaytmAuthType


// Function: fetch_payout_method_data
// File: crates/router/src/core/payouts/helpers.rs
// Module: router

pub fn fetch_payout_method_data(
    state: &SessionState,
    payout_data: &mut PayoutData,
    connector_data: &api::ConnectorData,
    merchant_context: &domain::MerchantContext,
) -> RouterResult<()>


// Implementation: impl api::PaymentVoid for for Mifinity
// File: crates/hyperswitch_connectors/src/connectors/mifinity.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentVoid for for Mifinity


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

impl Responder


// File: crates/hyperswitch_constraint_graph/src/types.rs
// Module: hyperswitch_constraint_graph
// Public functions: 6
// Public structs: 9

use std::{
    any::Any,
    fmt, hash,
    ops::{Deref, DerefMut},
    sync::Arc,
};

use rustc_hash::{FxHashMap, FxHashSet};

use crate::{dense_map::impl_entity, error::AnalysisTrace};

pub trait KeyNode: fmt::Debug + Clone + hash::Hash + serde::Serialize + PartialEq + Eq {}

pub trait ValueNode: fmt::Debug + Clone + hash::Hash + serde::Serialize + PartialEq + Eq {
    type Key: KeyNode;

    fn get_key(&self) -> Self::Key;
}

#[cfg(feature = "viz")]
pub trait NodeViz {
    fn viz(&self) -> String;
}

#[derive(Debug, Clone, Copy, serde::Serialize, PartialEq, Eq, Hash)]
#[serde(transparent)]
pub struct NodeId(usize);

impl_entity!(NodeId);

#[derive(Debug)]
pub struct Node<V: ValueNode> {
    pub node_type: NodeType<V>,
    pub preds: Vec<EdgeId>,
    pub succs: Vec<EdgeId>,
}

impl<V: ValueNode> Node<V> {
    pub(crate) fn new(node_type: NodeType<V>) -> Self {
        Self {
            node_type,
            preds: Vec::new(),
            succs: Vec::new(),
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum NodeType<V: ValueNode> {
    AllAggregator,
    AnyAggregator,
    InAggregator(FxHashSet<V>),
    Value(NodeValue<V>),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize)]
#[serde(tag = "type", content = "value", rename_all = "snake_case")]
pub enum NodeValue<V: ValueNode> {
    Key(<V as ValueNode>::Key),
    Value(V),
}

impl<V: ValueNode> From<V> for NodeValue<V> {
    fn from(value: V) -> Self {
        Self::Value(value)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EdgeId(usize);

impl_entity!(EdgeId);

#[derive(
    Debug, Clone, Copy, serde::Serialize, PartialEq, Eq, Hash, strum::Display, PartialOrd, Ord,
)]
pub enum Strength {
    Weak,
    Normal,
    Strong,
}

impl Strength {
    pub fn get_resolved_strength(prev_strength: Self, curr_strength: Self) -> Self {
        std::cmp::max(prev_strength, curr_strength)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Relation {
    Positive,
    Negative,
}

impl From<Relation> for bool {
    fn from(value: Relation) -> Self {
        matches!(value, Relation::Positive)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, serde::Serialize)]
pub enum RelationResolution {
    Positive,
    Negative,
    Contradiction,
}

impl From<Relation> for RelationResolution {
    fn from(value: Relation) -> Self {
        match value {
            Relation::Positive => Self::Positive,
            Relation::Negative => Self::Negative,
        }
    }
}

impl RelationResolution {
    pub fn get_resolved_relation(prev_relation: Self, curr_relation: Self) -> Self {
        if prev_relation != curr_relation {
            Self::Contradiction
        } else {
            curr_relation
        }
    }
}

#[derive(Debug, Clone)]
pub struct Edge {
    pub strength: Strength,
    pub relation: Relation,
    pub pred: NodeId,
    pub succ: NodeId,
    pub domain: Option<DomainId>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DomainId(usize);

impl_entity!(DomainId);

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DomainIdentifier(String);

impl DomainIdentifier {
    pub fn new(identifier: String) -> Self {
        Self(identifier)
    }

    pub fn into_inner(&self) -> String {
        self.0.clone()
    }
}

impl From<String> for DomainIdentifier {
    fn from(value: String) -> Self {
        Self(value)
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DomainInfo {
    pub domain_identifier: DomainIdentifier,
    pub domain_description: String,
}

pub trait CheckingContext {
    type Value: ValueNode;

    fn from_node_values<L>(vals: impl IntoIterator<Item = L>) -> Self
    where
        L: Into<Self::Value>;

    fn check_presence(&self, value: &NodeValue<Self::Value>, strength: Strength) -> bool;

    fn get_values_by_key(
        &self,
        expected: &<Self::Value as ValueNode>::Key,
    ) -> Option<Vec<Self::Value>>;
}

#[derive(Debug, Clone, serde::Serialize)]
pub struct Memoization<V: ValueNode>(
    #[allow(clippy::type_complexity)]
    FxHashMap<(NodeId, Relation, Strength), Result<(), Arc<AnalysisTrace<V>>>>,
);

impl<V: ValueNode> Memoization<V> {
    pub fn new() -> Self {
        Self(FxHashMap::default())
    }
}

impl<V: ValueNode> Default for Memoization<V> {
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}

impl<V: ValueNode> Deref for Memoization<V> {
    type Target = FxHashMap<(NodeId, Relation, Strength), Result<(), Arc<AnalysisTrace<V>>>>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<V: ValueNode> DerefMut for Memoization<V> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

#[derive(Debug, Clone)]
pub struct CycleCheck(FxHashMap<NodeId, (Strength, RelationResolution)>);
impl CycleCheck {
    pub fn new() -> Self {
        Self(FxHashMap::default())
    }
}

impl Default for CycleCheck {
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}

impl Deref for CycleCheck {
    type Target = FxHashMap<NodeId, (Strength, RelationResolution)>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for CycleCheck {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

pub trait Metadata: erased_serde::Serialize + Any + Send + Sync + fmt::Debug {}
erased_serde::serialize_trait_object!(Metadata);

impl<M> Metadata for M where M: erased_serde::Serialize + Any + Send + Sync + fmt::Debug {}


// Function: get_lineage_for_user_id_and_entity_for_accepting_invite
// File: crates/router/src/utils/user_role.rs
// Module: router

pub fn get_lineage_for_user_id_and_entity_for_accepting_invite(
    state: &SessionState,
    user_id: &str,
    tenant_id: &id_type::TenantId,
    entity_id: String,
    entity_type: EntityType,
) -> UserResult<
    Option<(
        id_type::OrganizationId,
        Option<id_type::MerchantId>,
        Option<id_type::ProfileId>,
    )>,
>


// Struct: BokuRouterData
// File: crates/hyperswitch_connectors/src/connectors/boku/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct BokuRouterData<T>


// Struct: PSyncResponseData
// File: crates/hyperswitch_connectors/src/connectors/braintree/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PSyncResponseData


// Struct: CardDetailsPaymentMethod
// File: crates/hyperswitch_domain_models/src/payment_method_data.rs
// Module: hyperswitch_domain_models
// Implementations: 1

pub struct CardDetailsPaymentMethod


// Function: get_setup_mandate_body
// File: crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs
// Module: hyperswitch_connectors

pub fn get_setup_mandate_body(req: &types::SetupMandateRouterData) -> Result<Vec<u8>, Error>


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

pub struct MultisafepayPaymentDetails


// Function: update_by_merchant_id_payout_id
// File: crates/diesel_models/src/query/payouts.rs
// Module: diesel_models

pub fn update_by_merchant_id_payout_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        payout_id: &common_utils::id_type::PayoutId,
        payout: PayoutsUpdate,
    ) -> StorageResult<Self>


// Implementation: impl PartialEq for for PaymentMetricsBucketIdentifier
// File: crates/api_models/src/analytics/payments.rs
// Module: api_models
// Methods: 1 total (0 public)

impl PartialEq for for PaymentMetricsBucketIdentifier


// Implementation: impl api::PaymentsPreProcessing for for Nuvei
// File: crates/hyperswitch_connectors/src/connectors/nuvei.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentsPreProcessing for for Nuvei


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

pub fn decode_and_decrypt_locker_data(
    state: &routes::SessionState,
    key_store: &domain::MerchantKeyStore,
    enc_card_data: String,
) -> errors::CustomResult<Secret<String>, errors::VaultError>


// Struct: AuthipayCaptureRequest
// File: crates/hyperswitch_connectors/src/connectors/authipay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct AuthipayCaptureRequest


// Implementation: impl api::RefundSync for for Adyen
// File: crates/hyperswitch_connectors/src/connectors/adyen.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::RefundSync for for Adyen


// Implementation: impl api::PaymentVoid for for Nordea
// File: crates/hyperswitch_connectors/src/connectors/nordea.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentVoid for for Nordea


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

pub struct DashboardNoPermissionAuth


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

impl api::PaymentSync for for Worldpayxml