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

pub struct Card


// Struct: ChallengeParams
// File: crates/hyperswitch_domain_models/src/router_request_types/authentication.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct ChallengeParams


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

pub fn get_aggregates_for_payments(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    profile_id_list: Option<Vec<id_type::ProfileId>>,
    time_range: common_utils::types::TimeRange,
) -> RouterResponse<api::PaymentsAggregateResponse>


// Struct: Relay
// File: crates/diesel_models/src/relay.rs
// Module: diesel_models
// Implementations: 0

pub struct Relay


// Function: validate
// File: crates/router/src/events.rs
// Module: router

pub fn validate(&self) -> Result<(), ApplicationError>


// File: crates/api_models/src/analytics/payments.rs
// Module: api_models
// Public functions: 1
// Public structs: 10

use std::{
    collections::hash_map::DefaultHasher,
    hash::{Hash, Hasher},
};

use common_utils::id_type;

use super::{ForexMetric, NameDescription, TimeRange};
use crate::enums::{
    AttemptStatus, AuthenticationType, CardNetwork, Connector, Currency, PaymentMethod,
    PaymentMethodType, RoutingApproach,
};

#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
pub struct PaymentFilters {
    #[serde(default)]
    pub currency: Vec<Currency>,
    #[serde(default)]
    pub status: Vec<AttemptStatus>,
    #[serde(default)]
    pub connector: Vec<Connector>,
    #[serde(default)]
    pub auth_type: Vec<AuthenticationType>,
    #[serde(default)]
    pub payment_method: Vec<PaymentMethod>,
    #[serde(default)]
    pub payment_method_type: Vec<PaymentMethodType>,
    #[serde(default)]
    pub client_source: Vec<String>,
    #[serde(default)]
    pub client_version: Vec<String>,
    #[serde(default)]
    pub card_network: Vec<CardNetwork>,
    #[serde(default)]
    pub profile_id: Vec<id_type::ProfileId>,
    #[serde(default)]
    pub merchant_id: Vec<id_type::MerchantId>,
    #[serde(default)]
    pub card_last_4: Vec<String>,
    #[serde(default)]
    pub card_issuer: Vec<String>,
    #[serde(default)]
    pub error_reason: Vec<String>,
    #[serde(default)]
    pub first_attempt: Vec<bool>,
    #[serde(default)]
    pub routing_approach: Vec<RoutingApproach>,
    #[serde(default)]
    pub signature_network: Vec<String>,
    #[serde(default)]
    pub is_issuer_regulated: Vec<bool>,
    #[serde(default)]
    pub is_debit_routed: Vec<bool>,
}

#[derive(
    Debug,
    serde::Serialize,
    serde::Deserialize,
    strum::AsRefStr,
    PartialEq,
    PartialOrd,
    Eq,
    Ord,
    strum::Display,
    strum::EnumIter,
    Clone,
    Copy,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum PaymentDimensions {
    // Do not change the order of these enums
    // Consult the Dashboard FE folks since these also affects the order of metrics on FE
    Connector,
    PaymentMethod,
    PaymentMethodType,
    Currency,
    #[strum(serialize = "authentication_type")]
    #[serde(rename = "authentication_type")]
    AuthType,
    #[strum(serialize = "status")]
    #[serde(rename = "status")]
    PaymentStatus,
    ClientSource,
    ClientVersion,
    ProfileId,
    CardNetwork,
    MerchantId,
    #[strum(serialize = "card_last_4")]
    #[serde(rename = "card_last_4")]
    CardLast4,
    CardIssuer,
    ErrorReason,
    RoutingApproach,
    SignatureNetwork,
    IsIssuerRegulated,
    IsDebitRouted,
}

#[derive(
    Clone,
    Debug,
    Hash,
    PartialEq,
    Eq,
    serde::Serialize,
    serde::Deserialize,
    strum::Display,
    strum::EnumIter,
    strum::AsRefStr,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum PaymentMetrics {
    PaymentSuccessRate,
    PaymentCount,
    PaymentSuccessCount,
    PaymentProcessedAmount,
    AvgTicketSize,
    RetriesCount,
    ConnectorSuccessRate,
    DebitRouting,
    SessionizedPaymentSuccessRate,
    SessionizedPaymentCount,
    SessionizedPaymentSuccessCount,
    SessionizedPaymentProcessedAmount,
    SessionizedAvgTicketSize,
    SessionizedRetriesCount,
    SessionizedConnectorSuccessRate,
    SessionizedDebitRouting,
    PaymentsDistribution,
    FailureReasons,
}

impl ForexMetric for PaymentMetrics {
    fn is_forex_metric(&self) -> bool {
        matches!(
            self,
            Self::PaymentProcessedAmount
                | Self::AvgTicketSize
                | Self::DebitRouting
                | Self::SessionizedPaymentProcessedAmount
                | Self::SessionizedAvgTicketSize
                | Self::SessionizedDebitRouting,
        )
    }
}
#[derive(Debug, Default, serde::Serialize)]
pub struct ErrorResult {
    pub reason: String,
    pub count: i64,
    pub percentage: f64,
}

#[derive(
    Clone,
    Copy,
    Debug,
    Hash,
    PartialEq,
    Eq,
    serde::Serialize,
    serde::Deserialize,
    strum::Display,
    strum::EnumIter,
    strum::AsRefStr,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum PaymentDistributions {
    #[strum(serialize = "error_message")]
    PaymentErrorMessage,
}

pub mod metric_behaviour {
    pub struct PaymentSuccessRate;
    pub struct PaymentCount;
    pub struct PaymentSuccessCount;
    pub struct PaymentProcessedAmount;
    pub struct AvgTicketSize;
}

impl From<PaymentMetrics> for NameDescription {
    fn from(value: PaymentMetrics) -> Self {
        Self {
            name: value.to_string(),
            desc: String::new(),
        }
    }
}

impl From<PaymentDimensions> for NameDescription {
    fn from(value: PaymentDimensions) -> Self {
        Self {
            name: value.to_string(),
            desc: String::new(),
        }
    }
}

#[derive(Debug, serde::Serialize, Eq)]
pub struct PaymentMetricsBucketIdentifier {
    pub currency: Option<Currency>,
    pub status: Option<AttemptStatus>,
    pub connector: Option<String>,
    #[serde(rename = "authentication_type")]
    pub auth_type: Option<AuthenticationType>,
    pub payment_method: Option<String>,
    pub payment_method_type: Option<String>,
    pub client_source: Option<String>,
    pub client_version: Option<String>,
    pub profile_id: Option<String>,
    pub card_network: Option<String>,
    pub merchant_id: Option<String>,
    pub card_last_4: Option<String>,
    pub card_issuer: Option<String>,
    pub error_reason: Option<String>,
    pub routing_approach: Option<RoutingApproach>,
    pub signature_network: Option<String>,
    pub is_issuer_regulated: Option<bool>,
    pub is_debit_routed: Option<bool>,
    #[serde(rename = "time_range")]
    pub time_bucket: TimeRange,
    // Coz FE sucks
    #[serde(rename = "time_bucket")]
    #[serde(with = "common_utils::custom_serde::iso8601custom")]
    pub start_time: time::PrimitiveDateTime,
}

impl PaymentMetricsBucketIdentifier {
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        currency: Option<Currency>,
        status: Option<AttemptStatus>,
        connector: Option<String>,
        auth_type: Option<AuthenticationType>,
        payment_method: Option<String>,
        payment_method_type: Option<String>,
        client_source: Option<String>,
        client_version: Option<String>,
        profile_id: Option<String>,
        card_network: Option<String>,
        merchant_id: Option<String>,
        card_last_4: Option<String>,
        card_issuer: Option<String>,
        error_reason: Option<String>,
        routing_approach: Option<RoutingApproach>,
        signature_network: Option<String>,
        is_issuer_regulated: Option<bool>,
        is_debit_routed: Option<bool>,
        normalized_time_range: TimeRange,
    ) -> Self {
        Self {
            currency,
            status,
            connector,
            auth_type,
            payment_method,
            payment_method_type,
            client_source,
            client_version,
            profile_id,
            card_network,
            merchant_id,
            card_last_4,
            card_issuer,
            error_reason,
            routing_approach,
            signature_network,
            is_issuer_regulated,
            is_debit_routed,
            time_bucket: normalized_time_range,
            start_time: normalized_time_range.start_time,
        }
    }
}

impl Hash for PaymentMetricsBucketIdentifier {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.currency.hash(state);
        self.status.map(|i| i.to_string()).hash(state);
        self.connector.hash(state);
        self.auth_type.map(|i| i.to_string()).hash(state);
        self.payment_method.hash(state);
        self.payment_method_type.hash(state);
        self.client_source.hash(state);
        self.client_version.hash(state);
        self.profile_id.hash(state);
        self.card_network.hash(state);
        self.merchant_id.hash(state);
        self.card_last_4.hash(state);
        self.card_issuer.hash(state);
        self.error_reason.hash(state);
        self.routing_approach
            .clone()
            .map(|i| i.to_string())
            .hash(state);
        self.signature_network.hash(state);
        self.is_issuer_regulated.hash(state);
        self.is_debit_routed.hash(state);
        self.time_bucket.hash(state);
    }
}

impl PartialEq for PaymentMetricsBucketIdentifier {
    fn eq(&self, other: &Self) -> bool {
        let mut left = DefaultHasher::new();
        self.hash(&mut left);
        let mut right = DefaultHasher::new();
        other.hash(&mut right);
        left.finish() == right.finish()
    }
}

#[derive(Debug, serde::Serialize)]
pub struct PaymentMetricsBucketValue {
    pub payment_success_rate: Option<f64>,
    pub payment_count: Option<u64>,
    pub payment_success_count: Option<u64>,
    pub payment_processed_amount: Option<u64>,
    pub payment_processed_amount_in_usd: Option<u64>,
    pub payment_processed_count: Option<u64>,
    pub payment_processed_amount_without_smart_retries: Option<u64>,
    pub payment_processed_amount_without_smart_retries_usd: Option<u64>,
    pub payment_processed_count_without_smart_retries: Option<u64>,
    pub avg_ticket_size: Option<f64>,
    pub payment_error_message: Option<Vec<ErrorResult>>,
    pub retries_count: Option<u64>,
    pub retries_amount_processed: Option<u64>,
    pub connector_success_rate: Option<f64>,
    pub payments_success_rate_distribution: Option<f64>,
    pub payments_success_rate_distribution_without_smart_retries: Option<f64>,
    pub payments_success_rate_distribution_with_only_retries: Option<f64>,
    pub payments_failure_rate_distribution: Option<f64>,
    pub payments_failure_rate_distribution_without_smart_retries: Option<f64>,
    pub payments_failure_rate_distribution_with_only_retries: Option<f64>,
    pub failure_reason_count: Option<u64>,
    pub failure_reason_count_without_smart_retries: Option<u64>,
    pub debit_routed_transaction_count: Option<u64>,
    pub debit_routing_savings: Option<u64>,
    pub debit_routing_savings_in_usd: Option<u64>,
}

#[derive(Debug, serde::Serialize)]
pub struct MetricsBucketResponse {
    #[serde(flatten)]
    pub values: PaymentMetricsBucketValue,
    #[serde(flatten)]
    pub dimensions: PaymentMetricsBucketIdentifier,
}


// Struct: RefundMetricsAccumulator
// File: crates/analytics/src/refunds/accumulator.rs
// Module: analytics
// Implementations: 1

pub struct RefundMetricsAccumulator


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

impl api::PaymentAuthorize for for Cashtocode


// Function: find_payment_intent_from_payment_id_type
// File: crates/router/src/utils.rs
// Module: router

pub fn find_payment_intent_from_payment_id_type(
    state: &SessionState,
    payment_id_type: payments::PaymentIdType,
    merchant_context: &domain::MerchantContext,
) -> CustomResult<PaymentIntent, errors::ApiErrorResponse>


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

impl api::PaymentCapture for for HyperswitchVault


// Function: get_id
// File: crates/hyperswitch_domain_models/src/merchant_connector_account.rs
// Module: hyperswitch_domain_models

pub fn get_id(&self) -> id_type::MerchantConnectorAccountId


// Struct: PaymentMethodAuthConfig
// File: crates/api_models/src/pm_auth.rs
// Module: api_models
// Implementations: 0

pub struct PaymentMethodAuthConfig


// Struct: PmFetched
// File: crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs
// Module: router
// Implementations: 1
// Traits: State

pub struct PmFetched


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

pub fn get_merchant_auth_event_sankey(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<TimeRange>,
    ) -> impl Responder


// Struct: CryptopayPaymentResponseData
// File: crates/hyperswitch_connectors/src/connectors/cryptopay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CryptopayPaymentResponseData


// Struct: ExchangeToken
// File: crates/pm_auth/src/types/api/auth_service.rs
// Module: pm_auth
// Implementations: 0

pub struct ExchangeToken


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

impl api::PaymentCapture for for Wise


// Function: revoke_mandate
// File: crates/router/src/routes/mandates.rs
// Module: router

pub fn revoke_mandate(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<String>,
) -> HttpResponse


// Struct: DisputeResponse
// File: crates/api_models/src/disputes.rs
// Module: api_models
// Implementations: 0

pub struct DisputeResponse


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

impl api::RefundSync for for Trustpayments


// File: crates/hyperswitch_connectors/src/connectors/globalpay/requests.rs
// Module: hyperswitch_connectors
// Public structs: 16

use common_utils::types::StringMinorUnit;
use masking::Secret;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize)]
pub struct GlobalPayRouterData<T> {
    pub amount: StringMinorUnit,
    pub router_data: T,
}

#[derive(Debug, Serialize)]
pub struct GlobalpayCancelRouterData<T> {
    pub amount: Option<StringMinorUnit>,
    pub router_data: T,
}

#[derive(Debug, Serialize)]
pub struct GlobalpayPaymentsRequest {
    pub account_name: Secret<String>,
    pub amount: Option<StringMinorUnit>,
    pub currency: String,
    pub reference: String,
    pub country: api_models::enums::CountryAlpha2,
    pub capture_mode: Option<CaptureMode>,
    pub notifications: Option<Notifications>,
    pub payment_method: GlobalPayPaymentMethodData,
    pub channel: Channel,
    pub initiator: Option<Initiator>,
    pub stored_credential: Option<StoredCredential>,
}

#[derive(Debug, Serialize)]
pub struct GlobalpayRefreshTokenRequest {
    pub app_id: Secret<String>,
    pub nonce: Secret<String>,
    pub secret: Secret<String>,
    pub grant_type: String,
}

#[derive(Debug, Serialize, Deserialize, Default)]
pub struct Notifications {
    pub return_url: Option<String>,
    pub status_url: Option<String>,
    pub cancel_url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PaymentMethodData {
    Card(Card),
    Apm(Apm),
    DigitalWallet(DigitalWallet),
    Token(TokenizationData),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CommonPaymentMethodData {
    #[serde(flatten)]
    pub payment_method_data: PaymentMethodData,
    pub entry_mode: PaymentMethodEntryMode,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct MandatePaymentMethodData {
    pub entry_mode: PaymentMethodEntryMode,
    pub id: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GlobalPayPaymentMethodData {
    Common(CommonPaymentMethodData),
    Mandate(MandatePaymentMethodData),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Apm {
    /// A string used to identify the payment method provider being used to execute this
    /// transaction.
    pub provider: Option<ApmProvider>,
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Card {
    pub cvv: Secret<String>,
    pub expiry_month: Secret<String>,
    pub expiry_year: Secret<String>,
    pub number: cards::CardNumber,
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct TokenizationData {
    pub brand_reference: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DigitalWallet {
    /// Identifies who provides the digital wallet for the Payer.
    pub provider: Option<DigitalWalletProvider>,
    /// A token that represents, or is the payment method, stored with  the digital wallet.
    pub payment_token: Option<serde_json::Value>,
}

/// Stored data information used to create a transaction.
#[derive(Debug, Serialize, Deserialize)]
pub struct StoredCredential {
    /// Indicates the transaction processing model being executed when using stored
    /// credentials.
    pub model: Option<Model>,
    /// Indicates the order of this transaction in the sequence of a planned repeating
    /// transaction processing model.
    pub sequence: Option<Sequence>,
}

/// Indicates whether the transaction is to be captured automatically, later or later using
/// more than 1 partial capture.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum CaptureMode {
    /// If a transaction is authorized, funds will exchange between the payer and
    /// merchant automatically and as soon as possible.
    Auto,
    /// If a transaction is authorized, funds will not exchange between the payer and
    /// merchant automatically and will require a subsequent separate action to capture that
    /// transaction and start the funding process. Only one successful capture is permitted.
    Later,
    /// If a transaction is authorized, funds will not exchange between the payer
    /// and merchant automatically. One or more subsequent separate capture actions are required
    /// to capture that transaction in parts and start the funding process for the part captured.
    /// One or many successful capture are permitted once the total amount captured is within a
    /// range of the original authorized amount.'
    Multiple,
}

/// Describes whether the transaction was processed in a face to face(CP) scenario or a
/// Customer Not Present (CNP) scenario.
#[derive(Debug, Default, Serialize, Deserialize)]
pub enum Channel {
    #[default]
    #[serde(rename = "CNP")]
    /// A Customer NOT Present transaction is when the payer and the merchant are not
    /// together when exchanging payment method information to fulfill a transaction. e.g. a
    /// transaction executed from a merchant's website or over the phone
    CustomerNotPresent,
    #[serde(rename = "CP")]
    /// A Customer Present transaction is when the payer and the merchant are in direct
    /// face to face contact when exchanging payment method information to fulfill a transaction.
    /// e.g. in a store and paying at the counter that is attended by a clerk.
    CustomerPresent,
}

/// Indicates whether the Merchant or the Payer initiated the creation of a transaction.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Initiator {
    /// The transaction was initiated by the merchant, who is getting paid by the
    /// payer.'
    Merchant,
    /// The transaction was initiated by the customer who is paying the merchant.
    Payer,
}

/// A string used to identify the payment method provider being used to execute this
/// transaction.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ApmProvider {
    Giropay,
    Ideal,
    Paypal,
    Sofort,
    Eps,
    Testpay,
}

/// Identifies who provides the digital wallet for the Payer.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum DigitalWalletProvider {
    Applepay,
    PayByGoogle,
}

/// Indicates how the payment method information was obtained by the Merchant for this
/// transaction.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PaymentMethodEntryMode {
    /// A CP channel entry mode where the payment method information was obtained from a
    /// chip. E.g. card is inserted into a device to read the chip.
    Chip,
    ///  A CP channel entry mode where the payment method information was
    /// obtained by bringing the payment method to close proximity of a device. E.g. tap a cardon
    /// or near a device to exchange card information.
    ContactlessChip,
    ///  A CP channel entry mode where the payment method information was
    /// obtained by bringing the payment method to close proximity of a device and also swiping
    /// the card. E.g. tap a card on or near a device and swipe it through device to exchange
    /// card information
    ContactlessSwipe,
    #[default]
    /// A CNP channel entry mode where the payment method was obtained via a browser.
    Ecom,
    /// A CNP channel entry mode where the payment method was obtained via an
    /// application and applies to digital wallets only.
    InApp,
    /// A CNP channel entry mode where the payment method was obtained via postal mail.
    Mail,
    /// A CP channel entry mode where the payment method information was obtained by
    /// manually keying the payment method information into the device.
    Manual,
    /// A CNP channel entry mode where the payment method information was obtained over
    /// the phone or via postal mail.
    Moto,
    /// A CNP channel entry mode where the payment method was obtained over the
    /// phone.
    Phone,
    /// A CP channel entry mode where the payment method information was obtained from
    /// swiping a magnetic strip. E.g. card's magnetic strip is swiped through a device to read
    /// the card information.
    Swipe,
}

/// Indicates the transaction processing model being executed when using stored
/// credentials.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Model {
    /// The transaction is a repeat transaction initiated by the merchant and
    /// taken using the payment method stored with the merchant, as part of an agreed schedule of
    /// transactions and where the amount is known and agreed in advanced. For example the
    /// payment in full of a good in fixed installments over a defined period of time.'
    Installment,
    /// The transaction is a repeat transaction initiated by the merchant and taken
    /// using the payment method stored with the merchant, as part of an agreed schedule of
    /// transactions.
    Recurring,
    /// The transaction is a repeat transaction initiated by the merchant and
    /// taken using the payment method stored with the merchant, as part of an agreed schedule of
    /// transactions. The amount taken is based on the usage by the payer of the good or service.
    /// for example a monthly mobile phone bill.
    Subscription,
    /// the transaction is adhoc or unscheduled. For example a payer visiting a
    /// merchant to make purchase using the payment method stored with the merchant.
    Unscheduled,
}

/// Indicates the order of this transaction in the sequence of a planned repeating
/// transaction processing model.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Sequence {
    First,
    Last,
    Subsequent,
}

#[derive(Default, Debug, Serialize)]
pub struct GlobalpayRefundRequest {
    pub amount: StringMinorUnit,
}

#[derive(Default, Debug, Serialize)]
pub struct GlobalpayCaptureRequest {
    pub amount: Option<StringMinorUnit>,
    pub capture_sequence: Option<Sequence>,
    pub reference: Option<String>,
}

#[derive(Default, Debug, Serialize)]
pub struct GlobalpayCancelRequest {
    pub amount: Option<StringMinorUnit>,
}

#[derive(Default, Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum UsageMode {
    /// This value must be used if using the Hosted Fields or the Drop-in UI integration types.
    /// When creating the payment method token, this option ensures the payment method token is temporary and will be removed once a transaction is executed or after a short period of time.
    #[default]
    Single,
    /// When creating the payment method token, this indicates it is permanent and can be used to create many transactions.
    Multiple,
    /// When using the payment method token to transaction process, this indicates to use the card number also known as the PAN or FPAN when both the card number and the network token are available.
    UseCardNumber,
    /// When using the payment method token to transaction process, this indicates to use the network token instead of the card number if both are available.
    UseNetworkToken,
}

#[derive(Default, Debug, Serialize)]
pub struct GlobalPayPaymentMethodsRequest {
    pub reference: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub usage_mode: Option<UsageMode>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub card: Option<Card>,
}


// Implementation: impl RedisValue
// File: crates/redis_interface/src/types.rs
// Module: redis_interface
// Methods: 4 total (4 public)

impl RedisValue


// Implementation: impl utils::MultipleCaptureSyncResponse for for Box
// File: crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs
// Module: hyperswitch_connectors
// Methods: 5 total (0 public)

impl utils::MultipleCaptureSyncResponse for for Box


// Struct: DeutschebankBankAccount
// File: crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct DeutschebankBankAccount


// Struct: Shift4RefundRequest
// File: crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Shift4RefundRequest


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

impl api::MandateSetup for for Getnet


// Struct: FinalizeStatusDetails
// File: crates/hyperswitch_connectors/src/connectors/amazonpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct FinalizeStatusDetails


// Implementation: impl LockAction
// File: crates/router/src/core/api_locking.rs
// Module: router
// Methods: 2 total (0 public)

impl LockAction


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

pub struct MultisafepayErrorResponse


// Function: apply_changeset
// File: crates/diesel_models/src/payouts.rs
// Module: diesel_models

pub fn apply_changeset(self, source: Payouts) -> Payouts


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

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


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

use std::collections::HashSet;

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

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

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

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

        query_builder
            .add_select_column(Aggregate::Sum {
                field: "dispute_amount",
                alias: Some("total"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Min {
                field: "created_at",
                alias: Some("start_bucket"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Max {
                field: "created_at",
                alias: Some("end_bucket"),
            })
            .switch()?;

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

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

        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;

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

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

        query_builder
            .add_filter_clause("dispute_status", "dispute_lost")
            .switch()?;

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


// Struct: GenerateFingerprintResponsePayload
// File: crates/api_models/src/blocklist.rs
// Module: api_models
// Implementations: 1
// Traits: ApiEventMetric

pub struct GenerateFingerprintResponsePayload


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

impl api::PaymentsCompleteAuthorize for for Nuvei


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

impl ConnectorValidation for for Jpmorgan


// Struct: BluecodeAuthType
// File: crates/hyperswitch_connectors/src/connectors/bluecode/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct BluecodeAuthType


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

impl api::PaymentSync for for Trustpay


// Struct: MerchantKeyStore
// File: crates/hyperswitch_domain_models/src/merchant_key_store.rs
// Module: hyperswitch_domain_models
// Implementations: 1
// Traits: super::behaviour::Conversion

pub struct MerchantKeyStore


// Struct: VoltErrorResponse
// File: crates/hyperswitch_connectors/src/connectors/volt/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct VoltErrorResponse


// Implementation: impl ConnectorCommon for for Payeezy
// File: crates/hyperswitch_connectors/src/connectors/payeezy.rs
// Module: hyperswitch_connectors
// Methods: 5 total (0 public)

impl ConnectorCommon for for Payeezy


// Implementation: impl ConnectorSpecifications for for Payeezy
// File: crates/hyperswitch_connectors/src/connectors/payeezy.rs
// Module: hyperswitch_connectors
// Methods: 3 total (0 public)

impl ConnectorSpecifications for for Payeezy


// Struct: DecryptedData
// File: crates/common_utils/src/types/keymanager.rs
// Module: common_utils
// Implementations: 2
// Traits: Serialize

pub struct DecryptedData


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

pub fn decide_unified_connector_service_call<F, RouterDReq, ApiRequest, D>(
    state: &SessionState,
    req_state: ReqState,
    merchant_context: &domain::MerchantContext,
    connector: api::ConnectorData,
    operation: &BoxedOperation<'_, F, ApiRequest, D>,
    payment_data: &mut D,
    customer: &Option<domain::Customer>,
    call_connector_action: CallConnectorAction,
    schedule_time: Option<time::PrimitiveDateTime>,
    header_payload: HeaderPayload,
    frm_suggestion: Option<storage_enums::FrmSuggestion>,
    business_profile: &domain::Profile,
    is_retry_payment: bool,
    should_retry_with_pan: bool,
    return_raw_connector_response: Option<bool>,
    merchant_connector_account_type_details: domain::MerchantConnectorAccountTypeDetails,
    mut router_data: RouterData<F, RouterDReq, router_types::PaymentsResponseData>,
    updated_customer: Option<storage::CustomerUpdate>,
    tokenization_action: TokenizationAction,
) -> RouterResult<RouterData<F, RouterDReq, router_types::PaymentsResponseData>>
where
    F: Send + Clone + Sync,
    RouterDReq: Send + Sync,

    // To create connector flow specific interface data
    D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,
    D: ConstructFlowSpecificData<F, RouterDReq, router_types::PaymentsResponseData>,
    RouterData<F, RouterDReq, router_types::PaymentsResponseData>: Feature<F, RouterDReq> + Send,
    // To construct connector flow specific api
    dyn api::Connector:
        services::api::ConnectorIntegration<F, RouterDReq, router_types::PaymentsResponseData>,


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

impl api::MandateSetup for for Dlocal


// Implementation: impl PayoutsInterface for for KVRouterStore
// File: crates/storage_impl/src/kv_router_store.rs
// Module: storage_impl
// Methods: 0 total (0 public)

impl PayoutsInterface for for KVRouterStore


// Struct: NetworkTokenPaymentMethodDetails
// File: crates/router/src/core/payment_methods.rs
// Module: router
// Implementations: 0

pub struct NetworkTokenPaymentMethodDetails


            | WorldpayvantivResponseCode::InvalidRecurringRequestSeeRecurringResponseForDetails
            | WorldpayvantivResponseCode::ParentTransactionDeclinedRecurringSubscriptionNotCreated
            | WorldpayvantivResponseCode::InvalidPlanCode
            | WorldpayvantivResponseCode::InvalidSubscriptionId
            | WorldpayvantivResponseCode::AddOnCodeAlreadyExists
            | WorldpayvantivResponseCode::DuplicateAddOnCodesInRequests
            | WorldpayvantivResponseCode::NoMatchingAddOnCodeForTheSubscription
            | WorldpayvantivResponseCode::NoMatchingDiscountCodeForTheSubscription
            | WorldpayvantivResponseCode::DuplicateDiscountCodesInRequest
            | WorldpayvantivResponseCode::InvalidStartDate
            | WorldpayvantivResponseCode::MerchantNotRegisteredForRecurringEngine
            | WorldpayvantivResponseCode::InsufficientDataToUpdateSubscription
            | WorldpayvantivResponseCode::InvalidBillingDate
            | WorldpayvantivResponseCode::DiscountCodeAlreadyExists
            | WorldpayvantivResponseCode::PlanCodeAlreadyExists
            | WorldpayvantivResponseCode::TheAccountNumberWasChanged
            | WorldpayvantivResponseCode::TheAccountWasClosed
            | WorldpayvantivResponseCode::TheExpirationDateWasChanged
            | WorldpayvantivResponseCode::TheIssuingBankDoesNotParticipateInTheUpdateProgram
            | WorldpayvantivResponseCode::ContactTheCardholderForUpdatedInformation
            | WorldpayvantivResponseCode::TheCardholderHasOptedOutOfTheUpdateProgram
            | WorldpayvantivResponseCode::SoftDeclineCardReaderDecryptionServiceIsNotAvailable
            | WorldpayvantivResponseCode::SoftDeclineDecryptionFailed
            | WorldpayvantivResponseCode::HardDeclineInputDataIsInvalid
            | WorldpayvantivResponseCode::ApplePayKeyMismatch
            | WorldpayvantivResponseCode::ApplePayDecryptionFailed
            | WorldpayvantivResponseCode::HardDeclineDecryptionFailed
            | WorldpayvantivResponseCode::MerchantNotConfiguredForProcessingAtThisSite
            | WorldpayvantivResponseCode::AdvancedFraudFilterScoreBelowThreshold
            | WorldpayvantivResponseCode::SuspectedFraud
            | WorldpayvantivResponseCode::SystemErrorContactWorldpayRepresentative
            | WorldpayvantivResponseCode::AmazonPayAmazonUnavailable
            | WorldpayvantivResponseCode::AmazonPayAmazonDeclined
            | WorldpayvantivResponseCode::AmazonPayInvalidToken
            | WorldpayvantivResponseCode::MerchantNotEnabledForAmazonPay
            | WorldpayvantivResponseCode::TransactionNotSupportedBlockedByIssuer
            | WorldpayvantivResponseCode::BlockedByCardholderContactCardholder
            | WorldpayvantivResponseCode::SoftDeclinePrimaryFundingSourceFailed
            | WorldpayvantivResponseCode::SoftDeclineBuyerHasAlternateFundingSource
            | WorldpayvantivResponseCode::HardDeclineInvalidBillingAgreementId
            | WorldpayvantivResponseCode::HardDeclinePrimaryFundingSourceFailed
            | WorldpayvantivResponseCode::HardDeclineIssueWithPaypalAccount
            | WorldpayvantivResponseCode::HardDeclinePayPalAuthorizationIdMissing
            | WorldpayvantivResponseCode::HardDeclineConfirmedEmailAddressIsNotAvailable
            | WorldpayvantivResponseCode::HardDeclinePayPalBuyerAccountDenied
            | WorldpayvantivResponseCode::HardDeclinePayPalBuyerAccountRestricted
            | WorldpayvantivResponseCode::HardDeclinePayPalOrderHasBeenVoidedExpiredOrCompleted
            | WorldpayvantivResponseCode::HardDeclineIssueWithPayPalRefund
            | WorldpayvantivResponseCode::HardDeclinePayPalCredentialsIssue
            | WorldpayvantivResponseCode::HardDeclinePayPalAuthorizationVoidedOrExpired
            | WorldpayvantivResponseCode::HardDeclineRequiredPayPalParameterMissing
            | WorldpayvantivResponseCode::HardDeclinePayPalTransactionIdOrAuthIdIsInvalid
            | WorldpayvantivResponseCode::HardDeclineExceededMaximumNumberOfPayPalAuthorizationAttempts
            | WorldpayvantivResponseCode::HardDeclineTransactionAmountExceedsMerchantsPayPalAccountLimit
            | WorldpayvantivResponseCode::HardDeclinePayPalFundingSourcesUnavailable
            | WorldpayvantivResponseCode::HardDeclineIssueWithPayPalPrimaryFundingSource
            | WorldpayvantivResponseCode::HardDeclinePayPalProfileDoesNotAllowThisTransactionType
            | WorldpayvantivResponseCode::InternalSystemErrorWithPayPalContactVantiv
            | WorldpayvantivResponseCode::HardDeclineContactPayPalConsumerForAnotherPaymentMethod
            | WorldpayvantivResponseCode::InvalidTerminalId
            | WorldpayvantivResponseCode::PinlessDebitProcessingNotSupportedForNonRecurringTransactions
            | WorldpayvantivResponseCode::PinlessDebitProcessingNotSupportedForPartialAuths
            | WorldpayvantivResponseCode::MerchantNotConfiguredForPinlessDebitProcessing
            | WorldpayvantivResponseCode::DeclineCustomerCancellation
            | WorldpayvantivResponseCode::DeclineReTryTransaction
            | WorldpayvantivResponseCode::DeclineUnableToLocateRecordOnFile
            | WorldpayvantivResponseCode::DeclineFileUpdateFieldEditError
            | WorldpayvantivResponseCode::RemoteFunctionUnknown
            | WorldpayvantivResponseCode::DeclinedExceedsWithdrawalFrequencyLimit
            | WorldpayvantivResponseCode::DeclineCardRecordNotAvailable
            | WorldpayvantivResponseCode::InvalidAuthorizationCode
            | WorldpayvantivResponseCode::ReconciliationError
            | WorldpayvantivResponseCode::PreferredDebitRoutingDenialCreditTransactionCanBeDebit
            | WorldpayvantivResponseCode::DeclinedCurrencyConversionCompleteNoAuthPerformed
            | WorldpayvantivResponseCode::DeclinedMultiCurrencyDccFail
            | WorldpayvantivResponseCode::DeclinedMultiCurrencyInvertFail
            | WorldpayvantivResponseCode::Invalid3DSecurePassword
            | WorldpayvantivResponseCode::InvalidSocialSecurityNumber
            | WorldpayvantivResponseCode::InvalidMothersMaidenName
            | WorldpayvantivResponseCode::EnrollmentInquiryDeclined
            | WorldpayvantivResponseCode::SocialSecurityNumberNotAvailable
            | WorldpayvantivResponseCode::MothersMaidenNameNotAvailable
            | WorldpayvantivResponseCode::PinAlreadyExistsOnDatabase
            | WorldpayvantivResponseCode::Under18YearsOld
            | WorldpayvantivResponseCode::BillToOutsideUsa
            | WorldpayvantivResponseCode::BillToAddressIsNotEqualToShipToAddress
            | WorldpayvantivResponseCode::DeclinedForeignCurrencyMustBeUsd
            | WorldpayvantivResponseCode::OnNegativeFile
            | WorldpayvantivResponseCode::BlockedAgreement
            | WorldpayvantivResponseCode::InsufficientBuyingPower
            | WorldpayvantivResponseCode::InvalidData
            | WorldpayvantivResponseCode::InvalidDataDataElementsMissing
            | WorldpayvantivResponseCode::InvalidDataDataFormatError
            | WorldpayvantivResponseCode::InvalidDataInvalidTCVersion
            | WorldpayvantivResponseCode::DuplicateTransactionPaypalCredit
            | WorldpayvantivResponseCode::VerifyBillingAddress
            | WorldpayvantivResponseCode::InactiveAccount
            | WorldpayvantivResponseCode::InvalidAuth
            | WorldpayvantivResponseCode::AuthorizationAlreadyExistsForTheOrder
            | WorldpayvantivResponseCode::LodgingTransactionsAreNotAllowedForThisMcc
            | WorldpayvantivResponseCode::DurationCannotBeNegative
            | WorldpayvantivResponseCode::HotelFolioNumberCannotBeBlank
            | WorldpayvantivResponseCode::InvalidCheckInDate
            | WorldpayvantivResponseCode::InvalidCheckOutDate
            | WorldpayvantivResponseCode::InvalidCheckInOrCheckOutDate
            | WorldpayvantivResponseCode::CheckOutDateCannotBeBeforeCheckInDate
            | WorldpayvantivResponseCode::NumberOfAdultsCannotBeNegative
            | WorldpayvantivResponseCode::RoomRateCannotBeNegative
            | WorldpayvantivResponseCode::RoomTaxCannotBeNegative
            | WorldpayvantivResponseCode::DurationCanOnlyBeFrom0To99ForVisa
            | WorldpayvantivResponseCode::MerchantIsNotAuthorizedForTokens
            | WorldpayvantivResponseCode::CreditCardNumberWasInvalid
        | WorldpayvantivResponseCode::TokenWasNotFound
        | WorldpayvantivResponseCode::TokenInvalid
        | WorldpayvantivResponseCode::MerchantNotAuthorizedForECheckTokens
        | WorldpayvantivResponseCode::CheckoutIdWasInvalid
        | WorldpayvantivResponseCode::CheckoutIdWasNotFound
        | WorldpayvantivResponseCode::GenericCheckoutIdError
        | WorldpayvantivResponseCode::CaptureAmountCanNotBeMoreThanAuthorizedAmount
        | WorldpayvantivResponseCode::TaxBillingOnlyAllowedForMcc9311
        | WorldpayvantivResponseCode::Mcc9311RequiresTaxTypeElement
        | WorldpayvantivResponseCode::DebtRepaymentOnlyAllowedForViTransactionsOnMccs6012And6051
        | WorldpayvantivResponseCode::RoutingNumberDidNotMatchOneOnFileForToken
        | WorldpayvantivResponseCode::InvalidPayPageRegistrationId
        | WorldpayvantivResponseCode::ExpiredPayPageRegistrationId
        | WorldpayvantivResponseCode::MerchantIsNotAuthorizedForPayPage
        | WorldpayvantivResponseCode::MaximumNumberOfUpdatesForThisTokenExceeded
        | WorldpayvantivResponseCode::TooManyTokensCreatedForExistingNamespace
        | WorldpayvantivResponseCode::PinValidationNotPossible
        | WorldpayvantivResponseCode::GenericTokenRegistrationError
        | WorldpayvantivResponseCode::GenericTokenUseError
        | WorldpayvantivResponseCode::InvalidBankRoutingNumber
        | WorldpayvantivResponseCode::MissingName
        | WorldpayvantivResponseCode::InvalidName
        | WorldpayvantivResponseCode::MissingBillingCountryCode
        | WorldpayvantivResponseCode::InvalidIban
        | WorldpayvantivResponseCode::MissingEmailAddress
        | WorldpayvantivResponseCode::MissingMandateReference
        | WorldpayvantivResponseCode::InvalidMandateReference
        | WorldpayvantivResponseCode::MissingMandateUrl
        | WorldpayvantivResponseCode::InvalidMandateUrl
        | WorldpayvantivResponseCode::MissingMandateSignatureDate
        | WorldpayvantivResponseCode::InvalidMandateSignatureDate
        | WorldpayvantivResponseCode::RecurringMandateAlreadyExists
        | WorldpayvantivResponseCode::RecurringMandateWasNotFound
        | WorldpayvantivResponseCode::FinalRecurringWasAlreadyReceivedUsingThisMandate
        | WorldpayvantivResponseCode::IbanDidNotMatchOneOnFileForMandate
        | WorldpayvantivResponseCode::InvalidBillingCountry
        | WorldpayvantivResponseCode::ExpirationDateRequiredForInteracTransaction
        | WorldpayvantivResponseCode::TransactionTypeIsNotSupportedWithThisMethodOfPayment
        | WorldpayvantivResponseCode::UnreferencedOrphanRefundsAreNotAllowed
        | WorldpayvantivResponseCode::UnableToVoidATransactionWithAHeldState
        | WorldpayvantivResponseCode::ThisFundingInstructionResultsInANegativeAccountBalance
        | WorldpayvantivResponseCode::AccountBalanceInformationUnavailableAtThisTime
        | WorldpayvantivResponseCode::TheSubmittedCardIsNotEligibleForFastAccessFunding
        | WorldpayvantivResponseCode::TransactionCannotUseBothCcdPaymentInformationAndCtxPaymentInformation
        | WorldpayvantivResponseCode::ProcessingError
        | WorldpayvantivResponseCode::ThisFundingInstructionTypeIsInvalidForCanadianMerchants
        | WorldpayvantivResponseCode::CtxAndCcdRecordsAreNotAllowedForCanadianMerchants
        | WorldpayvantivResponseCode::CanadianAccountNumberCannotExceed12Digits
        | WorldpayvantivResponseCode::ThisFundingInstructionTypeIsInvalid
        | WorldpayvantivResponseCode::DeclineNegativeInformationOnFile
        | WorldpayvantivResponseCode::AbsoluteDecline
        | WorldpayvantivResponseCode::TheMerchantProfileDoesNotAllowTheRequestedOperation
        | WorldpayvantivResponseCode::TheAccountCannotAcceptAchTransactions
        | WorldpayvantivResponseCode::TheAccountCannotAcceptAchTransactionsOrSiteDrafts
        | WorldpayvantivResponseCode::AmountGreaterThanLimitSpecifiedInTheMerchantProfile
        | WorldpayvantivResponseCode::MerchantIsNotAuthorizedToPerformECheckVerificationTransactions
        | WorldpayvantivResponseCode::FirstNameAndLastNameRequiredForECheckVerifications
        | WorldpayvantivResponseCode::CompanyNameRequiredForCorporateAccountForECheckVerifications
        | WorldpayvantivResponseCode::PhoneNumberRequiredForECheckVerifications
        | WorldpayvantivResponseCode::CardBrandTokenNotSupported
        | WorldpayvantivResponseCode::PrivateLabelCardNotSupported
        | WorldpayvantivResponseCode::AllowedDailyDirectDebitCaptureECheckSaleLimitExceeded
        | WorldpayvantivResponseCode::AllowedDailyDirectDebitCreditECheckCreditLimitExceeded
        | WorldpayvantivResponseCode::AccountNotEligibleForRtp
        | WorldpayvantivResponseCode::SoftDeclineCustomerAuthenticationRequired
        | WorldpayvantivResponseCode::TransactionNotReversedVoidWorkflowNeedToBeInvoked
        | WorldpayvantivResponseCode::TransactionReversalNotSupportedForTheCoreMerchants
        | WorldpayvantivResponseCode::NoValidParentDepositOrParentRefundFound
        | WorldpayvantivResponseCode::TransactionReversalNotEnabledForVisa
        | WorldpayvantivResponseCode::TransactionReversalNotEnabledForMastercard
        | WorldpayvantivResponseCode::TransactionReversalNotEnabledForAmEx
        | WorldpayvantivResponseCode::TransactionReversalNotEnabledForDiscover
        | WorldpayvantivResponseCode::TransactionReversalNotSupported
        | WorldpayvantivResponseCode::FundingInstructionHeldPleaseContactYourRelationshipManager
        | WorldpayvantivResponseCode::MissingAddressInformation
        | WorldpayvantivResponseCode::CryptographicFailure
        | WorldpayvantivResponseCode::InvalidRegionCode
        | WorldpayvantivResponseCode::InvalidCountryCode
        | WorldpayvantivResponseCode::InvalidCreditAccount
        | WorldpayvantivResponseCode::InvalidCheckingAccount
        | WorldpayvantivResponseCode::InvalidSavingsAccount
        | WorldpayvantivResponseCode::InvalidUseOfMccCorrectAndReattempt
        | WorldpayvantivResponseCode::ExceedsRtpTransactionLimit
             => match flow {
                WorldpayvantivPaymentFlow::Sale => Ok(common_enums::AttemptStatus::Failure),
                WorldpayvantivPaymentFlow::Auth => Ok(common_enums::AttemptStatus::AuthorizationFailed),
                WorldpayvantivPaymentFlow::Capture => Ok(common_enums::AttemptStatus::CaptureFailed),
                WorldpayvantivPaymentFlow::Void => Ok(common_enums::AttemptStatus::VoidFailed),
                WorldpayvantivPaymentFlow::VoidPC => Ok(common_enums::AttemptStatus::VoidFailed)
            }
    }
}

fn get_refund_status(
    response: WorldpayvantivResponseCode,
) -> Result<common_enums::RefundStatus, errors::ConnectorError> {
    match response {
        WorldpayvantivResponseCode::Approved
            | WorldpayvantivResponseCode::PartiallyApproved
            | WorldpayvantivResponseCode::OfflineApproval
            | WorldpayvantivResponseCode::OfflineApprovalUnableToGoOnline => {
                Ok(common_enums::RefundStatus::Pending)
            },
        WorldpayvantivResponseCode::TransactionReceived => Ok(common_enums::RefundStatus::Pending),
        WorldpayvantivResponseCode::ProcessingNetworkUnavailable
        | WorldpayvantivResponseCode::IssuerUnavailable
        | WorldpayvantivResponseCode::ReSubmitTransaction
        | WorldpayvantivResponseCode::MerchantNotConfiguredForProcessingAtThisSite
        | WorldpayvantivResponseCode::TryAgainLater
        | WorldpayvantivResponseCode::InsufficientFunds
        | WorldpayvantivResponseCode::AuthorizationAmountHasAlreadyBeenDepleted
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter1Hour
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter24Hour
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter2Days
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter4Days
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter6Days
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter8Days
        | WorldpayvantivResponseCode::InsufficientFundsRetryAfter10Days
        | WorldpayvantivResponseCode::CallIssuer
        | WorldpayvantivResponseCode::CallAmex
        | WorldpayvantivResponseCode::CallDinersClub
        | WorldpayvantivResponseCode::CallDiscover
        | WorldpayvantivResponseCode::CallJbs
        | WorldpayvantivResponseCode::CallVisaMastercard
        | WorldpayvantivResponseCode::ExceedsApprovalAmountLimit
        | WorldpayvantivResponseCode::CallIndicatedNumber
        | WorldpayvantivResponseCode::ConsumerMultiUseVirtualCardNumberSoftDecline
        | WorldpayvantivResponseCode::ConsumerNonReloadablePrepaidCardSoftDecline
        | WorldpayvantivResponseCode::ConsumerSingleUseVirtualCardNumberSoftDecline
        | WorldpayvantivResponseCode::MerchantDoesntQualifyForProductCode
        | WorldpayvantivResponseCode::Lifecycle
        | WorldpayvantivResponseCode::Policy
        | WorldpayvantivResponseCode::InvalidOrExpiredCardContactCardholderToUpdate
        | WorldpayvantivResponseCode::InvalidTransactionOrCardRestrictionVerifyInformationAndResubmit
        | WorldpayvantivResponseCode::AtLeastOneOfOrigIdOrOrigCnpTxnIdIsRequired
        | WorldpayvantivResponseCode::OrigCnpTxnIdIsRequiredWhenShowStatusOnlyIsUsed
        | WorldpayvantivResponseCode::TransactionMustReferenceTheEstimatedAuth
        | WorldpayvantivResponseCode::IncrementedAuthExceedsMaxTransactionAmount
        | WorldpayvantivResponseCode::SubmittedMccNotAllowed
        | WorldpayvantivResponseCode::MerchantNotCertifiedEnabledForIias
        | WorldpayvantivResponseCode::IssuerGeneratedError
        | WorldpayvantivResponseCode::InvalidAmountHardDecline
        | WorldpayvantivResponseCode::ReversalUnsuccessful
        | WorldpayvantivResponseCode::MissingData
        | WorldpayvantivResponseCode::InvalidDeactivate
        | WorldpayvantivResponseCode::OverMaxBalance
        | WorldpayvantivResponseCode::InvalidActivate
        | WorldpayvantivResponseCode::NoTransactionFoundForReversal
        | WorldpayvantivResponseCode::IllegalTransaction
        | WorldpayvantivResponseCode::DuplicateTransaction
        | WorldpayvantivResponseCode::SystemError
        | WorldpayvantivResponseCode::MerchantDepleted
        | WorldpayvantivResponseCode::InvalidReversalTypeForCreditCardTransaction
        | WorldpayvantivResponseCode::SystemErrorMessageFormatError
        | WorldpayvantivResponseCode::SystemErrorCannotProcess
        | WorldpayvantivResponseCode::RefundRejectedDueToPendingDepositStatus
        | WorldpayvantivResponseCode::RefundRejectedDueToDeclinedDepositStatus
        | WorldpayvantivResponseCode::RefundRejectedByTheProcessingNetwork
        | WorldpayvantivResponseCode::CaptureCreditAndAuthReversalTagsCannotBeUsedForGiftCardTransactions
        | WorldpayvantivResponseCode::InvalidAccountNumber
        | WorldpayvantivResponseCode::AuthorizationHasExpiredNoNeedToReverse
        | WorldpayvantivResponseCode::InvalidTrackData
        | WorldpayvantivResponseCode::DepositIsAlreadyReferencedByAChargeback
        | WorldpayvantivResponseCode::AutomaticRefundAlreadyIssued
        | WorldpayvantivResponseCode::InvalidMerchant
        | WorldpayvantivResponseCode::InvalidTransaction
        | WorldpayvantivResponseCode::TransactionNotAllowedAtTerminal
        | WorldpayvantivResponseCode::ThisMethodOfPaymentDoesNotSupportAuthorizationReversals
        | WorldpayvantivResponseCode::ReversalAmountDoesNotMatchAuthorizationAmount
        | WorldpayvantivResponseCode::InvalidAmountSoftDecline
        | WorldpayvantivResponseCode::InvalidReportGroup
        | WorldpayvantivResponseCode::DoNotHonor
        | WorldpayvantivResponseCode::GenericDecline
        | WorldpayvantivResponseCode::DeclineRequestPositiveId
        | WorldpayvantivResponseCode::ThreeDSecureTransactionNotSupportedByMerchant
        | WorldpayvantivResponseCode::RestrictedByVantivDueToSecurityCodeMismatch
        | WorldpayvantivResponseCode::NoTransactionFoundWithSpecifiedTransactionId
        | WorldpayvantivResponseCode::AuthorizationNoLongerAvailable
        | WorldpayvantivResponseCode::TransactionNotVoidedAlreadySettled
        | WorldpayvantivResponseCode::AutoVoidOnRefund
        | WorldpayvantivResponseCode::InvalidAccountNumberOriginalOrNocUpdatedECheckAccountRequired
        | WorldpayvantivResponseCode::TotalCreditAmountExceedsCaptureAmount
        | WorldpayvantivResponseCode::ExceedTheThresholdForSendingRedeposits
        | WorldpayvantivResponseCode::DepositHasNotBeenReturnedForInsufficientNonSufficientFunds
        | WorldpayvantivResponseCode::RedepositAgainstInvalidTransactionType
        | WorldpayvantivResponseCode::InternalSystemErrorCallVantiv
        | WorldpayvantivResponseCode::OriginalTransactionHasBeenProcessedFutureRedepositsCanceled
        | WorldpayvantivResponseCode::SoftDeclineAutoRecyclingInProgress
        | WorldpayvantivResponseCode::HardDeclineAutoRecyclingComplete
        | WorldpayvantivResponseCode::TransactionDeclinedByTheProcessingNetwork
        | WorldpayvantivResponseCode::SecondaryAmountCannotExceedTheSaleAmount
        | WorldpayvantivResponseCode::ThisMethodOfPaymentDoesNotSupportSecondaryAmount
        | WorldpayvantivResponseCode::SecondaryAmountCannotBeLessThanZero
        | WorldpayvantivResponseCode::PartialTransactionIsNotSupportedWhenIncludingASecondaryAmount
        | WorldpayvantivResponseCode::SecondaryAmountRequiredOnPartialRefundWhenUsedOnDeposit
        | WorldpayvantivResponseCode::SecondaryAmountNotAllowedOnRefundIfNotIncludedOnDeposit
        | WorldpayvantivResponseCode::ProcessingNetworkError
        | WorldpayvantivResponseCode::InvalidEMail
        | WorldpayvantivResponseCode::InvalidCombinationOfAccountFundingTransactionTypeAndMcc
        | WorldpayvantivResponseCode::InvalidAccountFundingTransactionTypeForThisMethodOfPayment
        | WorldpayvantivResponseCode::MissingOneOrMoreReceiverFieldsForAccountFundingTransaction
        | WorldpayvantivResponseCode::SoftDeclineDecryptionFailed
        | WorldpayvantivResponseCode::HardDeclineInputDataIsInvalid
        | WorldpayvantivResponseCode::HardDeclineDecryptionFailed
        | WorldpayvantivResponseCode::SuspectedFraud
        | WorldpayvantivResponseCode::SystemErrorContactWorldpayRepresentative
        | WorldpayvantivResponseCode::InvalidTerminalId
        | WorldpayvantivResponseCode::DeclineReTryTransaction
        | WorldpayvantivResponseCode::RemoteFunctionUnknown
        | WorldpayvantivResponseCode::InvalidData
        | WorldpayvantivResponseCode::InvalidDataDataElementsMissing
        | WorldpayvantivResponseCode::InvalidDataDataFormatError
        | WorldpayvantivResponseCode::VerifyBillingAddress
        | WorldpayvantivResponseCode::InactiveAccount
        | WorldpayvantivResponseCode::InvalidAuth
        | WorldpayvantivResponseCode::CheckoutIdWasInvalid
        | WorldpayvantivResponseCode::CheckoutIdWasNotFound
        | WorldpayvantivResponseCode::TransactionTypeIsNotSupportedWithThisMethodOfPayment
        | WorldpayvantivResponseCode::UnreferencedOrphanRefundsAreNotAllowed
        | WorldpayvantivResponseCode::ThisFundingInstructionResultsInANegativeAccountBalance
        | WorldpayvantivResponseCode::ProcessingError
        | WorldpayvantivResponseCode::ThisFundingInstructionTypeIsInvalidForCanadianMerchants
        | WorldpayvantivResponseCode::ThisFundingInstructionTypeIsInvalid
        | WorldpayvantivResponseCode::AbsoluteDecline
        | WorldpayvantivResponseCode::TheMerchantProfileDoesNotAllowTheRequestedOperation
        | WorldpayvantivResponseCode::AmountGreaterThanLimitSpecifiedInTheMerchantProfile
        | WorldpayvantivResponseCode::AccountNotEligibleForRtp
        | WorldpayvantivResponseCode::NoValidParentDepositOrParentRefundFound
        | WorldpayvantivResponseCode::FundingInstructionHeldPleaseContactYourRelationshipManager
        | WorldpayvantivResponseCode::InvalidCreditAccount => Ok(common_enums::RefundStatus::Failure),
         _ => {
            Err(errors::ConnectorError::UnexpectedResponseError(
                bytes::Bytes::from("Invalid response code for refund".to_string()),
            ))
        }
            }
}

fn get_vantiv_card_data(
    payment_method_data: &PaymentMethodData,
    payment_method_token: Option<hyperswitch_domain_models::router_data::PaymentMethodToken>,
) -> Result<
    (
        Option<WorldpayvantivCardData>,
        Option<CardholderAuthentication>,
    ),
    error_stack::Report<errors::ConnectorError>,
> {
    match payment_method_data {
        PaymentMethodData::Card(card) => {
            let card_type = match card.card_network.clone() {
                Some(card_type) => WorldpayvativCardType::try_from(card_type)?,
                None => WorldpayvativCardType::try_from(&card.get_card_issuer()?)?,
            };

            let exp_date = card.get_expiry_date_as_mmyy()?;

            Ok((
                Some(WorldpayvantivCardData {
                    card_type,
                    number: card.card_number.clone(),
                    exp_date,
                    card_validation_num: Some(card.card_cvc.clone()),
                }),
                None,
            ))
        }
        PaymentMethodData::CardDetailsForNetworkTransactionId(card_data) => {
            let card_type = match card_data.card_network.clone() {
                Some(card_type) => WorldpayvativCardType::try_from(card_type)?,
                None => WorldpayvativCardType::try_from(&card_data.get_card_issuer()?)?,
            };

            let exp_date = card_data.get_expiry_date_as_mmyy()?;

            Ok((
                Some(WorldpayvantivCardData {
                    card_type,
                    number: card_data.card_number.clone(),
                    exp_date,
                    card_validation_num: None,
                }),
                None,
            ))
        }
        PaymentMethodData::MandatePayment => Ok((None, None)),
        PaymentMethodData::Wallet(wallet_data) => match wallet_data {
            hyperswitch_domain_models::payment_method_data::WalletData::ApplePay(
                apple_pay_data,
            ) => match payment_method_token.clone() {
                Some(
                    hyperswitch_domain_models::router_data::PaymentMethodToken::ApplePayDecrypt(
                        apple_pay_decrypted_data,
                    ),
                ) => {
                    let number = apple_pay_decrypted_data
                        .application_primary_account_number
                        .clone();
                    let exp_date = apple_pay_decrypted_data
                        .get_expiry_date_as_mmyy()
                        .change_context(errors::ConnectorError::InvalidDataFormat {
                            field_name: "payment_method_data.card.card_exp_month",
                        })?;

                    let cardholder_authentication = CardholderAuthentication {
                        authentication_value: apple_pay_decrypted_data
                            .payment_data
                            .online_payment_cryptogram
                            .clone(),
                    };

                    let apple_pay_network = apple_pay_data
    .payment_method
    .network
    .parse::<WorldPayVativApplePayNetwork>()
    .map_err(|_| {
        error_stack::Report::new(errors::ConnectorError::NotSupported {
            message: format!(
                "Invalid Apple Pay network '{}'. Supported networks: Visa,MasterCard,AmEx,Discover,DinersClub,JCB,UnionPay",
                apple_pay_data.payment_method.network
            ),
            connector: "worldpay_vativ"
        })
    })?;

                    Ok((
                        (Some(WorldpayvantivCardData {
                            card_type: apple_pay_network.into(),
                            number,
                            exp_date,
                            card_validation_num: None,
                        })),
                        Some(cardholder_authentication),
                    ))
                }
                _ => Err(
                    errors::ConnectorError::NotImplemented("Payment method type".to_string())
                        .into(),
                ),
            },
            hyperswitch_domain_models::payment_method_data::WalletData::GooglePay(
                google_pay_data,
            ) => match payment_method_token.clone() {
                Some(
                    hyperswitch_domain_models::router_data::PaymentMethodToken::GooglePayDecrypt(
                        google_pay_decrypted_data,
                    ),
                ) => {
                    let number = google_pay_decrypted_data
                        .application_primary_account_number
                        .clone();
                    let exp_date = google_pay_decrypted_data
                        .get_expiry_date_as_mmyy()
                        .change_context(errors::ConnectorError::InvalidDataFormat {
                            field_name: "payment_method_data.card.card_exp_month",
                        })?;

                    let cardholder_authentication = CardholderAuthentication {
                        authentication_value: google_pay_decrypted_data
                            .cryptogram
                            .clone()
                            .ok_or_else(|| errors::ConnectorError::MissingRequiredField {
                                field_name: "cryptogram",
                            })?,
                    };
                    let google_pay_network = google_pay_data
    .info
    .card_network
    .parse::<WorldPayVativGooglePayNetwork>()
    .map_err(|_| {
        error_stack::Report::new(errors::ConnectorError::NotSupported {
            message: format!(
                "Invalid Google Pay card network '{}'. Supported networks: VISA, MASTERCARD, AMEX, DISCOVER, JCB, UNIONPAY",
                google_pay_data.info.card_network
            ),
            connector: "worldpay_vativ"
        })
    })?;

                    Ok((
                        (Some(WorldpayvantivCardData {
                            card_type: google_pay_network.into(),
                            number,
                            exp_date,
                            card_validation_num: None,
                        })),
                        Some(cardholder_authentication),
                    ))
                }
                _ => {
                    Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into())
                }
            },
            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
        },
        _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
    }
}

fn get_connector_response(payment_response: &FraudResult) -> ConnectorResponseData {
    let payment_checks = Some(serde_json::json!({
        "avs_result": payment_response.avs_result,
        "card_validation_result": payment_response.card_validation_result,
        "authentication_result": payment_response.authentication_result,
        "advanced_a_v_s_result": payment_response.advanced_a_v_s_result,
    }));

    ConnectorResponseData::with_additional_payment_method_data(
        AdditionalPaymentMethodConnectorResponse::Card {
            authentication_data: None,
            payment_checks,
            card_network: None,
            domestic_network: None,
        },
    )
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename = "chargebackRetrievalResponse", rename_all = "camelCase")]
pub struct ChargebackRetrievalResponse {
    #[serde(rename = "@xmlns")]
    pub xmlns: String,
    pub transaction_id: String,
    pub chargeback_case: Option<Vec<ChargebackCase>>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ChargebackCase {
    pub case_id: String,
    pub merchant_id: String,
    pub day_issued_by_bank: Option<String>,
    pub date_received_by_vantiv_cnp: Option<String>,
    pub vantiv_cnp_txn_id: String,
    pub cycle: String,
    pub order_id: String,
    pub card_number_last4: Option<String>,
    pub card_type: Option<String>,
    pub chargeback_amount: MinorUnit,
    pub chargeback_currency_type: common_enums::enums::Currency,
    pub original_txn_day: Option<String>,
    pub chargeback_type: Option<String>,
    pub reason_code: Option<String>,
    pub reason_code_description: Option<String>,
    pub current_queue: Option<String>,
    pub acquirer_reference_number: Option<String>,
    pub chargeback_reference_number: Option<String>,
    pub bin: Option<String>,
    pub payment_amount: Option<MinorUnit>,
    pub reply_by_day: Option<String>,
    pub pre_arbitration_amount: Option<MinorUnit>,
    pub pre_arbitration_currency_type: Option<common_enums::enums::Currency>,
    pub activity: Vec<Activity>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Activity {
    pub activity_date: Option<String>,
    pub activity_type: Option<String>,
    pub from_queue: Option<String>,
    pub to_queue: Option<String>,
    pub notes: Option<String>,
}

impl
    TryFrom<
        ResponseRouterData<
            Fetch,
            ChargebackRetrievalResponse,
            FetchDisputesRequestData,
            FetchDisputesResponse,
        >,
    > for RouterData<Fetch, FetchDisputesRequestData, FetchDisputesResponse>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            Fetch,
            ChargebackRetrievalResponse,
            FetchDisputesRequestData,
            FetchDisputesResponse,
        >,
    ) -> Result<Self, Self::Error> {
        let dispute_list = item
            .response
            .chargeback_case
            .unwrap_or_default()
            .into_iter()
            .map(DisputeSyncResponse::try_from)
            .collect::<Result<Vec<_>, _>>()?;

        Ok(FetchDisputeRouterData {
            response: Ok(dispute_list),
            ..item.data
        })
    }
}

impl
    TryFrom<
        ResponseRouterData<
            Dsync,
            ChargebackRetrievalResponse,
            DisputeSyncData,
            DisputeSyncResponse,
        >,
    > for RouterData<Dsync, DisputeSyncData, DisputeSyncResponse>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            Dsync,
            ChargebackRetrievalResponse,
            DisputeSyncData,
            DisputeSyncResponse,
        >,
    ) -> Result<Self, Self::Error> {
        let dispute_response = item
            .response
            .chargeback_case
            .and_then(|chargeback_case| chargeback_case.first().cloned())
            .ok_or(errors::ConnectorError::RequestEncodingFailedWithReason(
                "Could not find chargeback case".to_string(),
            ))?;

        let dispute_sync_response = DisputeSyncResponse::try_from(dispute_response.clone())?;
        Ok(DisputeSyncRouterData {
            response: Ok(dispute_sync_response),
            ..item.data
        })
    }
}

fn get_dispute_stage(
    dispute_cycle: String,
) -> Result<common_enums::enums::DisputeStage, error_stack::Report<errors::ConnectorError>> {
    match connector_utils::normalize_string(dispute_cycle.clone())
        .change_context(errors::ConnectorError::RequestEncodingFailed)?
        .as_str()
    {
        "arbitration"
        | "arbitrationmastercard"
        | "arbitrationchargeback"
        | "arbitrationlost"
        | "arbitrationsplit"
        | "arbitrationwon" => Ok(common_enums::enums::DisputeStage::Arbitration),
        "chargebackreversal" | "firstchargeback" | "rapiddisputeresolution" | "representment" => {
            Ok(common_enums::enums::DisputeStage::Dispute)
        }

        "issueracceptedprearbitration"
        | "issuerarbitration"
        | "issuerdeclinedprearbitration"
        | "prearbitration"
        | "responsetoissuerarbitration" => Ok(common_enums::enums::DisputeStage::PreArbitration),

        "retrievalrequest" => Ok(common_enums::enums::DisputeStage::PreDispute),
        _ => Err(errors::ConnectorError::NotSupported {
            message: format!("Dispute stage {dispute_cycle}",),
            connector: "worldpayvantiv",
        }
        .into()),
    }
}

pub fn get_dispute_status(
    dispute_cycle: String,
    dispute_activities: Vec<Activity>,
) -> Result<common_enums::DisputeStatus, error_stack::Report<errors::ConnectorError>> {
    if let Some(activity) = get_last_non_auxiliary_activity_type(dispute_activities) {
        match activity.as_ref() {
            "Merchant Accept"
            | "Issuer Accepted Pre-Arbitration"
            | "Vantiv Accept"


// File: crates/analytics/src/sdk_events/metrics/payment_methods_call_count.rs
// Module: analytics

use std::collections::HashSet;

use api_models::analytics::{
    sdk_events::{
        SdkEventDimensions, SdkEventFilters, SdkEventMetricsBucketIdentifier, SdkEventNames,
    },
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::SdkEventMetricRow;
use crate::{
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
};

#[derive(Default)]
pub(super) struct PaymentMethodsCallCount;

#[async_trait::async_trait]
impl<T> super::SdkEventMetric<T> for PaymentMethodsCallCount
where
    T: AnalyticsDataSource + super::SdkEventMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        dimensions: &[SdkEventDimensions],
        publishable_key: &str,
        filters: &SdkEventFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(SdkEventMetricsBucketIdentifier, SdkEventMetricRow)>> {
        let mut query_builder: QueryBuilder<T> =
            QueryBuilder::new(AnalyticsCollection::SdkEventsAnalytics);
        let dimensions = dimensions.to_vec();

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

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

        if let Some(granularity) = granularity {
            query_builder
                .add_granularity_in_mins(granularity)
                .switch()?;
        }

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

        query_builder
            .add_filter_clause("merchant_id", publishable_key)
            .switch()?;

        query_builder
            .add_bool_filter_clause("first_event", 1)
            .switch()?;

        query_builder
            .add_filter_clause("event_name", SdkEventNames::PaymentMethodsCall)
            .switch()?;

        query_builder
            .add_filter_clause("log_type", "INFO")
            .switch()?;

        query_builder
            .add_filter_clause("category", "API")
            .switch()?;

        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;

        for dim in dimensions.iter() {
            query_builder
                .add_group_by_clause(dim)
                .attach_printable("Error grouping by dimensions")
                .switch()?;
        }

        if let Some(_granularity) = granularity.as_ref() {
            query_builder
                .add_group_by_clause("time_bucket")
                .attach_printable("Error adding granularity")
                .switch()?;
        }

        query_builder
            .execute_query::<SdkEventMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    SdkEventMetricsBucketIdentifier::new(
                        i.payment_method.clone(),
                        i.platform.clone(),
                        i.browser_name.clone(),
                        i.source.clone(),
                        i.component.clone(),
                        i.payment_experience.clone(),
                        i.time_bucket.clone(),
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(SdkEventMetricsBucketIdentifier, SdkEventMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}