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

pub mod aci;
pub mod adyen;
pub mod adyenplatform;
pub mod affirm;
pub mod airwallex;
pub mod amazonpay;
pub mod archipel;
pub mod authipay;
pub mod authorizedotnet;
pub mod bambora;
pub mod bamboraapac;
pub mod bankofamerica;
pub mod barclaycard;
pub mod billwerk;
pub mod bitpay;
pub mod blackhawknetwork;
pub mod bluecode;
pub mod bluesnap;
pub mod boku;
pub mod braintree;
pub mod breadpay;
pub mod cashtocode;
pub mod celero;
pub mod chargebee;
pub mod checkbook;
pub mod checkout;
pub mod coinbase;
pub mod coingate;
pub mod cryptopay;
pub mod ctp_mastercard;
pub mod custombilling;
pub mod cybersource;
pub mod datatrans;
pub mod deutschebank;
pub mod digitalvirgo;
pub mod dlocal;
#[cfg(feature = "dummy_connector")]
pub mod dummyconnector;
pub mod dwolla;
pub mod ebanx;
pub mod elavon;
pub mod facilitapay;
pub mod finix;
pub mod fiserv;
pub mod fiservemea;
pub mod fiuu;
pub mod flexiti;
pub mod forte;
pub mod getnet;
pub mod gigadat;
pub mod globalpay;
pub mod globepay;
pub mod gocardless;
pub mod gpayments;
pub mod helcim;
pub mod hipay;
pub mod hyperswitch_vault;
pub mod hyperwallet;
pub mod iatapay;
pub mod inespay;
pub mod itaubank;
pub mod jpmorgan;
pub mod juspaythreedsserver;
pub mod katapult;
pub mod klarna;
pub mod loonio;
pub mod mifinity;
pub mod mollie;
pub mod moneris;
pub mod mpgs;
pub mod multisafepay;
pub mod netcetera;
pub mod nexinets;
pub mod nexixpay;
pub mod nmi;
pub mod nomupay;
pub mod noon;
pub mod nordea;
pub mod novalnet;
pub mod nuvei;
pub mod opayo;
pub mod opennode;
pub mod paybox;
pub mod payeezy;
pub mod payload;
pub mod payme;
pub mod payone;
pub mod paypal;
pub mod paysafe;
pub mod paystack;
pub mod paytm;
pub mod payu;
pub mod peachpayments;
pub mod phonepe;
pub mod placetopay;
pub mod plaid;
pub mod powertranz;
pub mod prophetpay;
pub mod rapyd;
pub mod razorpay;
pub mod recurly;
pub mod redsys;
pub mod riskified;
pub mod santander;
pub mod shift4;
pub mod sift;
pub mod signifyd;
pub mod silverflow;
pub mod square;
pub mod stax;
pub mod stripe;
pub mod stripebilling;
pub mod taxjar;
pub mod tesouro;
pub mod threedsecureio;
pub mod thunes;
pub mod tokenex;
pub mod tokenio;
pub mod trustpay;
pub mod trustpayments;
pub mod tsys;
pub mod unified_authentication_service;
pub mod vgs;
pub mod volt;
pub mod wellsfargo;
pub mod wellsfargopayout;
pub mod wise;
pub mod worldline;
pub mod worldpay;
pub mod worldpayvantiv;
pub mod worldpayxml;
pub mod xendit;
pub mod zen;
pub mod zsl;
#[cfg(feature = "dummy_connector")]
pub use self::dummyconnector::DummyConnector;
pub use self::{
    aci::Aci, adyen::Adyen, adyenplatform::Adyenplatform, affirm::Affirm, airwallex::Airwallex,
    amazonpay::Amazonpay, archipel::Archipel, authipay::Authipay, authorizedotnet::Authorizedotnet,
    bambora::Bambora, bamboraapac::Bamboraapac, bankofamerica::Bankofamerica,
    barclaycard::Barclaycard, billwerk::Billwerk, bitpay::Bitpay,
    blackhawknetwork::Blackhawknetwork, bluecode::Bluecode, bluesnap::Bluesnap, boku::Boku,
    braintree::Braintree, breadpay::Breadpay, cashtocode::Cashtocode, celero::Celero,
    chargebee::Chargebee, checkbook::Checkbook, checkout::Checkout, coinbase::Coinbase,
    coingate::Coingate, cryptopay::Cryptopay, ctp_mastercard::CtpMastercard,
    custombilling::Custombilling, cybersource::Cybersource, datatrans::Datatrans,
    deutschebank::Deutschebank, digitalvirgo::Digitalvirgo, dlocal::Dlocal, dwolla::Dwolla,
    ebanx::Ebanx, elavon::Elavon, facilitapay::Facilitapay, finix::Finix, fiserv::Fiserv,
    fiservemea::Fiservemea, fiuu::Fiuu, flexiti::Flexiti, forte::Forte, getnet::Getnet,
    gigadat::Gigadat, globalpay::Globalpay, globepay::Globepay, gocardless::Gocardless,
    gpayments::Gpayments, helcim::Helcim, hipay::Hipay, hyperswitch_vault::HyperswitchVault,
    hyperwallet::Hyperwallet, iatapay::Iatapay, inespay::Inespay, itaubank::Itaubank,
    jpmorgan::Jpmorgan, juspaythreedsserver::Juspaythreedsserver, katapult::Katapult,
    klarna::Klarna, loonio::Loonio, mifinity::Mifinity, mollie::Mollie, moneris::Moneris,
    mpgs::Mpgs, multisafepay::Multisafepay, netcetera::Netcetera, nexinets::Nexinets,
    nexixpay::Nexixpay, nmi::Nmi, nomupay::Nomupay, noon::Noon, nordea::Nordea, novalnet::Novalnet,
    nuvei::Nuvei, opayo::Opayo, opennode::Opennode, paybox::Paybox, payeezy::Payeezy,
    payload::Payload, payme::Payme, payone::Payone, paypal::Paypal, paysafe::Paysafe,
    paystack::Paystack, paytm::Paytm, payu::Payu, peachpayments::Peachpayments, phonepe::Phonepe,
    placetopay::Placetopay, plaid::Plaid, powertranz::Powertranz, prophetpay::Prophetpay,
    rapyd::Rapyd, razorpay::Razorpay, recurly::Recurly, redsys::Redsys, riskified::Riskified,
    santander::Santander, shift4::Shift4, sift::Sift, signifyd::Signifyd, silverflow::Silverflow,
    square::Square, stax::Stax, stripe::Stripe, stripebilling::Stripebilling, taxjar::Taxjar,
    tesouro::Tesouro, threedsecureio::Threedsecureio, thunes::Thunes, tokenex::Tokenex,
    tokenio::Tokenio, trustpay::Trustpay, trustpayments::Trustpayments, tsys::Tsys,
    unified_authentication_service::UnifiedAuthenticationService, vgs::Vgs, volt::Volt,
    wellsfargo::Wellsfargo, wellsfargopayout::Wellsfargopayout, wise::Wise, worldline::Worldline,
    worldpay::Worldpay, worldpayvantiv::Worldpayvantiv, worldpayxml::Worldpayxml, xendit::Xendit,
    zen::Zen, zsl::Zsl,
};


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

impl api::PaymentAuthorize for for Airwallex


// Implementation: impl Verify
// File: crates/router/src/routes/app.rs
// Module: router
// Methods: 1 total (1 public)

impl Verify


// Function: get_trans_id
// File: crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs
// Module: hyperswitch_connectors

pub fn get_trans_id(
    details: &AuthorizedotnetWebhookObjectId,
) -> Result<String, errors::ConnectorError>


// File: crates/hyperswitch_domain_models/src/router_response_types/fraud_check.rs
// Module: hyperswitch_domain_models

use serde::Serialize;

use crate::router_response_types::ResponseId;

#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum FraudCheckResponseData {
    TransactionResponse {
        resource_id: ResponseId,
        status: diesel_models::enums::FraudCheckStatus,
        connector_metadata: Option<serde_json::Value>,
        reason: Option<serde_json::Value>,
        score: Option<i32>,
    },
    FulfillmentResponse {
        order_id: String,
        shipment_ids: Vec<String>,
    },
    RecordReturnResponse {
        resource_id: ResponseId,
        connector_metadata: Option<serde_json::Value>,
        return_id: Option<String>,
    },
}

impl common_utils::events::ApiEventMetric for FraudCheckResponseData {
    fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
        Some(common_utils::events::ApiEventsType::FraudCheck)
    }
}


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

impl api::PaymentSession for for Nordea


// Implementation: impl ApiEventMetric for for CsvParsingResult
// File: crates/api_models/src/revenue_recovery_data_backfill.rs
// Module: api_models
// Methods: 1 total (0 public)

impl ApiEventMetric for for CsvParsingResult


// Function: iter
// File: crates/hyperswitch_constraint_graph/src/dense_map.rs
// Module: hyperswitch_constraint_graph

pub fn iter(&self) -> Iter<'_, K, V>


// Struct: RedirectPayload
// File: crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct RedirectPayload


// Struct: RazorpayRefundWebhookPayload
// File: crates/hyperswitch_connectors/src/connectors/razorpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct RazorpayRefundWebhookPayload


// Struct: SessionFlowRoutingInput
// File: crates/router/src/core/payments/routing.rs
// Module: router
// Implementations: 0

pub struct SessionFlowRoutingInput<'a>


// File: crates/scheduler/src/metrics.rs
// Module: scheduler

use router_env::{counter_metric, global_meter, histogram_metric_f64};

global_meter!(PT_METER, "PROCESS_TRACKER");

histogram_metric_f64!(CONSUMER_OPS, PT_METER);

counter_metric!(PAYMENT_COUNT, PT_METER); // No. of payments created
counter_metric!(TASKS_PICKED_COUNT, PT_METER); // Tasks picked by
counter_metric!(BATCHES_CREATED, PT_METER); // Batches added to stream
counter_metric!(BATCHES_CONSUMED, PT_METER); // Batches consumed by consumer
counter_metric!(TASK_CONSUMED, PT_METER); // Tasks consumed by consumer
counter_metric!(TASK_PROCESSED, PT_METER); // Tasks completed processing
counter_metric!(TASK_FINISHED, PT_METER); // Tasks finished
counter_metric!(TASK_RETRIED, PT_METER); // Tasks added for retries


// Struct: EphemeralKey
// File: crates/router/src/routes/app.rs
// Module: router
// Implementations: 2

pub struct EphemeralKey


// File: crates/hyperswitch_domain_models/src/merchant_connector_account.rs
// Module: hyperswitch_domain_models
// Public functions: 31
// Public structs: 8

#[cfg(feature = "v2")]
use std::collections::HashMap;

use common_utils::{
    crypto::Encryptable,
    date_time,
    encryption::Encryption,
    errors::{CustomResult, ValidationError},
    ext_traits::ValueExt,
    id_type, pii, type_name,
    types::keymanager::{Identifier, KeyManagerState, ToEncryptable},
};
#[cfg(feature = "v2")]
use diesel_models::merchant_connector_account::{
    BillingAccountReference as DieselBillingAccountReference,
    MerchantConnectorAccountFeatureMetadata as DieselMerchantConnectorAccountFeatureMetadata,
    RevenueRecoveryMetadata as DieselRevenueRecoveryMetadata,
};
use diesel_models::{enums, merchant_connector_account::MerchantConnectorAccountUpdateInternal};
use error_stack::ResultExt;
use masking::{PeekInterface, Secret};
use rustc_hash::FxHashMap;
use serde_json::Value;

use super::behaviour;
#[cfg(feature = "v2")]
use crate::errors::api_error_response;
use crate::{
    mandates::CommonMandateReference,
    router_data,
    type_encryption::{crypto_operation, CryptoOperation},
};

#[cfg(feature = "v1")]
#[derive(Clone, Debug, router_derive::ToEncryption)]
pub struct MerchantConnectorAccount {
    pub merchant_id: id_type::MerchantId,
    pub connector_name: String,
    #[encrypt]
    pub connector_account_details: Encryptable<Secret<Value>>,
    pub test_mode: Option<bool>,
    pub disabled: Option<bool>,
    pub merchant_connector_id: id_type::MerchantConnectorAccountId,
    pub payment_methods_enabled: Option<Vec<pii::SecretSerdeValue>>,
    pub connector_type: enums::ConnectorType,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub frm_configs: Option<Vec<pii::SecretSerdeValue>>,
    pub connector_label: Option<String>,
    pub business_country: Option<enums::CountryAlpha2>,
    pub business_label: Option<String>,
    pub business_sub_label: Option<String>,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub connector_webhook_details: Option<pii::SecretSerdeValue>,
    pub profile_id: id_type::ProfileId,
    pub applepay_verified_domains: Option<Vec<String>>,
    pub pm_auth_config: Option<pii::SecretSerdeValue>,
    pub status: enums::ConnectorStatus,
    #[encrypt]
    pub connector_wallets_details: Option<Encryptable<Secret<Value>>>,
    #[encrypt]
    pub additional_merchant_data: Option<Encryptable<Secret<Value>>>,
    pub version: common_enums::ApiVersion,
}

#[cfg(feature = "v1")]
impl MerchantConnectorAccount {
    pub fn get_id(&self) -> id_type::MerchantConnectorAccountId {
        self.merchant_connector_id.clone()
    }
    pub fn get_connector_account_details(
        &self,
    ) -> error_stack::Result<router_data::ConnectorAuthType, common_utils::errors::ParsingError>
    {
        self.connector_account_details
            .get_inner()
            .clone()
            .parse_value("ConnectorAuthType")
    }

    pub fn get_connector_wallets_details(&self) -> Option<Secret<Value>> {
        self.connector_wallets_details.as_deref().cloned()
    }

    pub fn get_connector_test_mode(&self) -> Option<bool> {
        self.test_mode
    }

    pub fn get_connector_name_as_string(&self) -> String {
        self.connector_name.clone()
    }

    pub fn get_metadata(&self) -> Option<Secret<Value>> {
        self.metadata.clone()
    }
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug)]
pub enum MerchantConnectorAccountTypeDetails {
    MerchantConnectorAccount(Box<MerchantConnectorAccount>),
    MerchantConnectorDetails(common_types::domain::MerchantConnectorAuthDetails),
}

#[cfg(feature = "v2")]
impl MerchantConnectorAccountTypeDetails {
    pub fn get_connector_account_details(
        &self,
    ) -> error_stack::Result<router_data::ConnectorAuthType, common_utils::errors::ParsingError>
    {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                merchant_connector_account
                    .connector_account_details
                    .peek()
                    .clone()
                    .parse_value("ConnectorAuthType")
            }
            Self::MerchantConnectorDetails(merchant_connector_details) => {
                merchant_connector_details
                    .merchant_connector_creds
                    .peek()
                    .clone()
                    .parse_value("ConnectorAuthType")
            }
        }
    }

    pub fn is_disabled(&self) -> bool {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                merchant_connector_account.disabled.unwrap_or(false)
            }
            Self::MerchantConnectorDetails(_) => false,
        }
    }

    pub fn get_metadata(&self) -> Option<Secret<Value>> {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                merchant_connector_account.metadata.to_owned()
            }
            Self::MerchantConnectorDetails(_) => None,
        }
    }

    pub fn get_id(&self) -> Option<id_type::MerchantConnectorAccountId> {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                Some(merchant_connector_account.id.clone())
            }
            Self::MerchantConnectorDetails(_) => None,
        }
    }

    pub fn get_mca_id(&self) -> Option<id_type::MerchantConnectorAccountId> {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                Some(merchant_connector_account.get_id())
            }
            Self::MerchantConnectorDetails(_) => None,
        }
    }

    pub fn get_connector_name(&self) -> Option<common_enums::connector_enums::Connector> {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                Some(merchant_connector_account.connector_name)
            }
            Self::MerchantConnectorDetails(merchant_connector_details) => {
                Some(merchant_connector_details.connector_name)
            }
        }
    }

    pub fn get_connector_name_as_string(&self) -> String {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                merchant_connector_account.connector_name.to_string()
            }
            Self::MerchantConnectorDetails(merchant_connector_details) => {
                merchant_connector_details.connector_name.to_string()
            }
        }
    }

    pub fn get_inner_db_merchant_connector_account(&self) -> Option<&MerchantConnectorAccount> {
        match self {
            Self::MerchantConnectorAccount(merchant_connector_account) => {
                Some(merchant_connector_account)
            }
            Self::MerchantConnectorDetails(_) => None,
        }
    }
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, router_derive::ToEncryption)]
pub struct MerchantConnectorAccount {
    pub id: id_type::MerchantConnectorAccountId,
    pub merchant_id: id_type::MerchantId,
    pub connector_name: common_enums::connector_enums::Connector,
    #[encrypt]
    pub connector_account_details: Encryptable<Secret<Value>>,
    pub disabled: Option<bool>,
    pub payment_methods_enabled: Option<Vec<common_types::payment_methods::PaymentMethodsEnabled>>,
    pub connector_type: enums::ConnectorType,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub frm_configs: Option<Vec<pii::SecretSerdeValue>>,
    pub connector_label: Option<String>,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub connector_webhook_details: Option<pii::SecretSerdeValue>,
    pub profile_id: id_type::ProfileId,
    pub applepay_verified_domains: Option<Vec<String>>,
    pub pm_auth_config: Option<pii::SecretSerdeValue>,
    pub status: enums::ConnectorStatus,
    #[encrypt]
    pub connector_wallets_details: Option<Encryptable<Secret<Value>>>,
    #[encrypt]
    pub additional_merchant_data: Option<Encryptable<Secret<Value>>>,
    pub version: common_enums::ApiVersion,
    pub feature_metadata: Option<MerchantConnectorAccountFeatureMetadata>,
}

#[cfg(feature = "v2")]
impl MerchantConnectorAccount {
    pub fn get_retry_threshold(&self) -> Option<u16> {
        self.feature_metadata
            .as_ref()
            .and_then(|metadata| metadata.revenue_recovery.as_ref())
            .map(|recovery| recovery.billing_connector_retry_threshold)
    }

    pub fn get_id(&self) -> id_type::MerchantConnectorAccountId {
        self.id.clone()
    }

    pub fn get_metadata(&self) -> Option<pii::SecretSerdeValue> {
        self.metadata.clone()
    }

    pub fn is_disabled(&self) -> bool {
        self.disabled.unwrap_or(false)
    }

    pub fn get_connector_account_details(
        &self,
    ) -> error_stack::Result<router_data::ConnectorAuthType, common_utils::errors::ParsingError>
    {
        use common_utils::ext_traits::ValueExt;

        self.connector_account_details
            .get_inner()
            .clone()
            .parse_value("ConnectorAuthType")
    }

    pub fn get_connector_wallets_details(&self) -> Option<Secret<Value>> {
        self.connector_wallets_details.as_deref().cloned()
    }

    pub fn get_connector_test_mode(&self) -> Option<bool> {
        todo!()
    }

    pub fn get_connector_name_as_string(&self) -> String {
        self.connector_name.clone().to_string()
    }

    #[cfg(feature = "v2")]
    pub fn get_connector_name(&self) -> common_enums::connector_enums::Connector {
        self.connector_name
    }

    pub fn get_payment_merchant_connector_account_id_using_account_reference_id(
        &self,
        account_reference_id: String,
    ) -> Option<id_type::MerchantConnectorAccountId> {
        self.feature_metadata.as_ref().and_then(|metadata| {
            metadata.revenue_recovery.as_ref().and_then(|recovery| {
                recovery
                    .mca_reference
                    .billing_to_recovery
                    .get(&account_reference_id)
                    .cloned()
            })
        })
    }
    pub fn get_account_reference_id_using_payment_merchant_connector_account_id(
        &self,
        payment_merchant_connector_account_id: id_type::MerchantConnectorAccountId,
    ) -> Option<String> {
        self.feature_metadata.as_ref().and_then(|metadata| {
            metadata.revenue_recovery.as_ref().and_then(|recovery| {
                recovery
                    .mca_reference
                    .recovery_to_billing
                    .get(&payment_merchant_connector_account_id)
                    .cloned()
            })
        })
    }
}

#[cfg(feature = "v2")]
/// Holds the payment methods enabled for a connector along with the connector name
/// This struct is a flattened representation of the payment methods enabled for a connector
#[derive(Debug)]
pub struct PaymentMethodsEnabledForConnector {
    pub payment_methods_enabled: common_types::payment_methods::RequestPaymentMethodTypes,
    pub payment_method: common_enums::PaymentMethod,
    pub connector: common_enums::connector_enums::Connector,
    pub merchant_connector_id: id_type::MerchantConnectorAccountId,
}

#[cfg(feature = "v2")]
#[derive(Debug, Clone)]
pub struct MerchantConnectorAccountFeatureMetadata {
    pub revenue_recovery: Option<RevenueRecoveryMetadata>,
}

#[cfg(feature = "v2")]
#[derive(Debug, Clone)]
pub struct RevenueRecoveryMetadata {
    pub max_retry_count: u16,
    pub billing_connector_retry_threshold: u16,
    pub mca_reference: AccountReferenceMap,
}

#[cfg(feature = "v2")]
#[derive(Debug, Clone, serde::Deserialize)]
pub struct ExternalVaultConnectorMetadata {
    pub proxy_url: common_utils::types::Url,
    pub certificate: Secret<String>,
}
#[cfg(feature = "v2")]
#[derive(Debug, Clone)]
pub struct AccountReferenceMap {
    pub recovery_to_billing: HashMap<id_type::MerchantConnectorAccountId, String>,
    pub billing_to_recovery: HashMap<String, id_type::MerchantConnectorAccountId>,
}

#[cfg(feature = "v2")]
impl AccountReferenceMap {
    pub fn new(
        hash_map: HashMap<id_type::MerchantConnectorAccountId, String>,
    ) -> Result<Self, api_error_response::ApiErrorResponse> {
        Self::validate(&hash_map)?;

        let recovery_to_billing = hash_map.clone();
        let mut billing_to_recovery = HashMap::new();

        for (key, value) in &hash_map {
            billing_to_recovery.insert(value.clone(), key.clone());
        }

        Ok(Self {
            recovery_to_billing,
            billing_to_recovery,
        })
    }

    fn validate(
        hash_map: &HashMap<id_type::MerchantConnectorAccountId, String>,
    ) -> Result<(), api_error_response::ApiErrorResponse> {
        let mut seen_values = std::collections::HashSet::new(); // To check uniqueness of values

        for value in hash_map.values() {
            if !seen_values.insert(value.clone()) {
                return Err(api_error_response::ApiErrorResponse::InvalidRequestData {
                    message: "Duplicate account reference IDs found in Recovery feature metadata. Each account reference ID must be unique.".to_string(),
                });
            }
        }
        Ok(())
    }
}

#[cfg(feature = "v2")]
/// Holds the payment methods enabled for a connector
pub struct FlattenedPaymentMethodsEnabled {
    pub payment_methods_enabled: Vec<PaymentMethodsEnabledForConnector>,
}

#[cfg(feature = "v2")]
impl FlattenedPaymentMethodsEnabled {
    /// This functions flattens the payment methods enabled from the connector accounts
    /// Retains the connector name and payment method in every flattened element
    pub fn from_payment_connectors_list(payment_connectors: Vec<MerchantConnectorAccount>) -> Self {
        let payment_methods_enabled_flattened_with_connector = payment_connectors
            .into_iter()
            .map(|connector| {
                (
                    connector
                        .payment_methods_enabled
                        .clone()
                        .unwrap_or_default(),
                    connector.connector_name,
                    connector.get_id(),
                )
            })
            .flat_map(
                |(payment_method_enabled, connector, merchant_connector_id)| {
                    payment_method_enabled
                        .into_iter()
                        .flat_map(move |payment_method| {
                            let request_payment_methods_enabled =
                                payment_method.payment_method_subtypes.unwrap_or_default();
                            let length = request_payment_methods_enabled.len();
                            request_payment_methods_enabled
                                .into_iter()
                                .zip(std::iter::repeat_n(
                                    (
                                        connector,
                                        merchant_connector_id.clone(),
                                        payment_method.payment_method_type,
                                    ),
                                    length,
                                ))
                        })
                },
            )
            .map(
                |(request_payment_methods, (connector, merchant_connector_id, payment_method))| {
                    PaymentMethodsEnabledForConnector {
                        payment_methods_enabled: request_payment_methods,
                        connector,
                        payment_method,
                        merchant_connector_id,
                    }
                },
            )
            .collect();

        Self {
            payment_methods_enabled: payment_methods_enabled_flattened_with_connector,
        }
    }
}

#[cfg(feature = "v1")]
#[derive(Debug)]
pub enum MerchantConnectorAccountUpdate {
    Update {
        connector_type: Option<enums::ConnectorType>,
        connector_name: Option<String>,
        connector_account_details: Box<Option<Encryptable<pii::SecretSerdeValue>>>,
        test_mode: Option<bool>,
        disabled: Option<bool>,
        merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
        payment_methods_enabled: Option<Vec<pii::SecretSerdeValue>>,
        metadata: Option<pii::SecretSerdeValue>,
        frm_configs: Option<Vec<pii::SecretSerdeValue>>,
        connector_webhook_details: Box<Option<pii::SecretSerdeValue>>,
        applepay_verified_domains: Option<Vec<String>>,
        pm_auth_config: Box<Option<pii::SecretSerdeValue>>,
        connector_label: Option<String>,
        status: Option<enums::ConnectorStatus>,
        connector_wallets_details: Box<Option<Encryptable<pii::SecretSerdeValue>>>,
        additional_merchant_data: Box<Option<Encryptable<pii::SecretSerdeValue>>>,
    },
    ConnectorWalletDetailsUpdate {
        connector_wallets_details: Encryptable<pii::SecretSerdeValue>,
    },
}

#[cfg(feature = "v2")]
#[derive(Debug)]
pub enum MerchantConnectorAccountUpdate {
    Update {
        connector_type: Option<enums::ConnectorType>,
        connector_account_details: Box<Option<Encryptable<pii::SecretSerdeValue>>>,
        disabled: Option<bool>,
        payment_methods_enabled: Option<Vec<common_types::payment_methods::PaymentMethodsEnabled>>,
        metadata: Option<pii::SecretSerdeValue>,
        frm_configs: Option<Vec<pii::SecretSerdeValue>>,
        connector_webhook_details: Box<Option<pii::SecretSerdeValue>>,
        applepay_verified_domains: Option<Vec<String>>,
        pm_auth_config: Box<Option<pii::SecretSerdeValue>>,
        connector_label: Option<String>,
        status: Option<enums::ConnectorStatus>,
        connector_wallets_details: Box<Option<Encryptable<pii::SecretSerdeValue>>>,
        additional_merchant_data: Box<Option<Encryptable<pii::SecretSerdeValue>>>,
        feature_metadata: Box<Option<MerchantConnectorAccountFeatureMetadata>>,
    },
    ConnectorWalletDetailsUpdate {
        connector_wallets_details: Encryptable<pii::SecretSerdeValue>,
    },
}

#[cfg(feature = "v1")]
#[async_trait::async_trait]
impl behaviour::Conversion for MerchantConnectorAccount {
    type DstType = diesel_models::merchant_connector_account::MerchantConnectorAccount;
    type NewDstType = diesel_models::merchant_connector_account::MerchantConnectorAccountNew;

    async fn convert(self) -> CustomResult<Self::DstType, ValidationError> {
        Ok(
            diesel_models::merchant_connector_account::MerchantConnectorAccount {
                merchant_id: self.merchant_id,
                connector_name: self.connector_name,
                connector_account_details: self.connector_account_details.into(),
                test_mode: self.test_mode,
                disabled: self.disabled,
                merchant_connector_id: self.merchant_connector_id.clone(),
                id: Some(self.merchant_connector_id),
                payment_methods_enabled: self.payment_methods_enabled,
                connector_type: self.connector_type,
                metadata: self.metadata,
                frm_configs: None,
                frm_config: self.frm_configs,
                business_country: self.business_country,
                business_label: self.business_label,
                connector_label: self.connector_label,
                business_sub_label: self.business_sub_label,
                created_at: self.created_at,
                modified_at: self.modified_at,
                connector_webhook_details: self.connector_webhook_details,
                profile_id: Some(self.profile_id),
                applepay_verified_domains: self.applepay_verified_domains,
                pm_auth_config: self.pm_auth_config,
                status: self.status,
                connector_wallets_details: self.connector_wallets_details.map(Encryption::from),
                additional_merchant_data: self.additional_merchant_data.map(|data| data.into()),
                version: self.version,
            },
        )
    }

    async fn convert_back(
        state: &KeyManagerState,
        other: Self::DstType,
        key: &Secret<Vec<u8>>,
        _key_manager_identifier: Identifier,
    ) -> CustomResult<Self, ValidationError> {
        let identifier = Identifier::Merchant(other.merchant_id.clone());
        let decrypted_data = crypto_operation(
            state,
            type_name!(Self::DstType),
            CryptoOperation::BatchDecrypt(EncryptedMerchantConnectorAccount::to_encryptable(
                EncryptedMerchantConnectorAccount {
                    connector_account_details: other.connector_account_details,
                    additional_merchant_data: other.additional_merchant_data,
                    connector_wallets_details: other.connector_wallets_details,
                },
            )),
            identifier.clone(),
            key.peek(),
        )
        .await
        .and_then(|val| val.try_into_batchoperation())
        .change_context(ValidationError::InvalidValue {
            message: "Failed while decrypting connector account details".to_string(),
        })?;

        let decrypted_data = EncryptedMerchantConnectorAccount::from_encryptable(decrypted_data)
            .change_context(ValidationError::InvalidValue {
                message: "Failed while decrypting connector account details".to_string(),
            })?;

        Ok(Self {
            merchant_id: other.merchant_id,
            connector_name: other.connector_name,
            connector_account_details: decrypted_data.connector_account_details,
            test_mode: other.test_mode,
            disabled: other.disabled,
            merchant_connector_id: other.merchant_connector_id,
            payment_methods_enabled: other.payment_methods_enabled,
            connector_type: other.connector_type,
            metadata: other.metadata,

            frm_configs: other.frm_config,
            business_country: other.business_country,
            business_label: other.business_label,
            connector_label: other.connector_label,
            business_sub_label: other.business_sub_label,
            created_at: other.created_at,
            modified_at: other.modified_at,
            connector_webhook_details: other.connector_webhook_details,
            profile_id: other
                .profile_id
                .ok_or(ValidationError::MissingRequiredField {
                    field_name: "profile_id".to_string(),
                })?,
            applepay_verified_domains: other.applepay_verified_domains,
            pm_auth_config: other.pm_auth_config,
            status: other.status,
            connector_wallets_details: decrypted_data.connector_wallets_details,
            additional_merchant_data: decrypted_data.additional_merchant_data,
            version: other.version,
        })
    }

    async fn construct_new(self) -> CustomResult<Self::NewDstType, ValidationError> {
        let now = date_time::now();
        Ok(Self::NewDstType {
            merchant_id: Some(self.merchant_id),
            connector_name: Some(self.connector_name),
            connector_account_details: Some(self.connector_account_details.into()),
            test_mode: self.test_mode,
            disabled: self.disabled,
            merchant_connector_id: self.merchant_connector_id.clone(),
            id: Some(self.merchant_connector_id),
            payment_methods_enabled: self.payment_methods_enabled,
            connector_type: Some(self.connector_type),
            metadata: self.metadata,
            frm_configs: None,
            frm_config: self.frm_configs,
            business_country: self.business_country,
            business_label: self.business_label,
            connector_label: self.connector_label,
            business_sub_label: self.business_sub_label,
            created_at: now,
            modified_at: now,
            connector_webhook_details: self.connector_webhook_details,
            profile_id: Some(self.profile_id),
            applepay_verified_domains: self.applepay_verified_domains,
            pm_auth_config: self.pm_auth_config,
            status: self.status,
            connector_wallets_details: self.connector_wallets_details.map(Encryption::from),
            additional_merchant_data: self.additional_merchant_data.map(|data| data.into()),
            version: self.version,
        })
    }
}

#[cfg(feature = "v2")]
#[async_trait::async_trait]
impl behaviour::Conversion for MerchantConnectorAccount {
    type DstType = diesel_models::merchant_connector_account::MerchantConnectorAccount;
    type NewDstType = diesel_models::merchant_connector_account::MerchantConnectorAccountNew;

    async fn convert(self) -> CustomResult<Self::DstType, ValidationError> {
        Ok(
            diesel_models::merchant_connector_account::MerchantConnectorAccount {
                id: self.id,
                merchant_id: self.merchant_id,
                connector_name: self.connector_name,
                connector_account_details: self.connector_account_details.into(),
                disabled: self.disabled,
                payment_methods_enabled: self.payment_methods_enabled,
                connector_type: self.connector_type,
                metadata: self.metadata,
                frm_config: self.frm_configs,
                connector_label: self.connector_label,
                created_at: self.created_at,
                modified_at: self.modified_at,
                connector_webhook_details: self.connector_webhook_details,
                profile_id: self.profile_id,
                applepay_verified_domains: self.applepay_verified_domains,
                pm_auth_config: self.pm_auth_config,
                status: self.status,
                connector_wallets_details: self.connector_wallets_details.map(Encryption::from),
                additional_merchant_data: self.additional_merchant_data.map(|data| data.into()),
                version: self.version,
                feature_metadata: self.feature_metadata.map(From::from),
            },
        )
    }

    async fn convert_back(
        state: &KeyManagerState,
        other: Self::DstType,
        key: &Secret<Vec<u8>>,
        _key_manager_identifier: Identifier,
    ) -> CustomResult<Self, ValidationError> {
        let identifier = Identifier::Merchant(other.merchant_id.clone());

        let decrypted_data = crypto_operation(
            state,
            type_name!(Self::DstType),
            CryptoOperation::BatchDecrypt(EncryptedMerchantConnectorAccount::to_encryptable(
                EncryptedMerchantConnectorAccount {
                    connector_account_details: other.connector_account_details,
                    additional_merchant_data: other.additional_merchant_data,
                    connector_wallets_details: other.connector_wallets_details,
                },
            )),
            identifier.clone(),
            key.peek(),
        )
        .await
        .and_then(|val| val.try_into_batchoperation())
        .change_context(ValidationError::InvalidValue {
            message: "Failed while decrypting connector account details".to_string(),
        })?;

        let decrypted_data = EncryptedMerchantConnectorAccount::from_encryptable(decrypted_data)
            .change_context(ValidationError::InvalidValue {
                message: "Failed while decrypting connector account details".to_string(),
            })?;

        Ok(Self {
            id: other.id,
            merchant_id: other.merchant_id,
            connector_name: other.connector_name,
            connector_account_details: decrypted_data.connector_account_details,
            disabled: other.disabled,
            payment_methods_enabled: other.payment_methods_enabled,
            connector_type: other.connector_type,
            metadata: other.metadata,

            frm_configs: other.frm_config,
            connector_label: other.connector_label,
            created_at: other.created_at,
            modified_at: other.modified_at,
            connector_webhook_details: other.connector_webhook_details,
            profile_id: other.profile_id,
            applepay_verified_domains: other.applepay_verified_domains,
            pm_auth_config: other.pm_auth_config,
            status: other.status,
            connector_wallets_details: decrypted_data.connector_wallets_details,
            additional_merchant_data: decrypted_data.additional_merchant_data,
            version: other.version,
            feature_metadata: other.feature_metadata.map(From::from),
        })
    }

    async fn construct_new(self) -> CustomResult<Self::NewDstType, ValidationError> {
        let now = date_time::now();
        Ok(Self::NewDstType {
            id: self.id,
            merchant_id: Some(self.merchant_id),
            connector_name: Some(self.connector_name),
            connector_account_details: Some(self.connector_account_details.into()),
            disabled: self.disabled,
            payment_methods_enabled: self.payment_methods_enabled,
            connector_type: Some(self.connector_type),
            metadata: self.metadata,
            frm_config: self.frm_configs,
            connector_label: self.connector_label,
            created_at: now,
            modified_at: now,
            connector_webhook_details: self.connector_webhook_details,
            profile_id: self.profile_id,
            applepay_verified_domains: self.applepay_verified_domains,
            pm_auth_config: self.pm_auth_config,
            status: self.status,
            connector_wallets_details: self.connector_wallets_details.map(Encryption::from),
            additional_merchant_data: self.additional_merchant_data.map(|data| data.into()),
            version: self.version,
            feature_metadata: self.feature_metadata.map(From::from),
        })
    }
}

#[cfg(feature = "v1")]
impl From<MerchantConnectorAccountUpdate> for MerchantConnectorAccountUpdateInternal {
    fn from(merchant_connector_account_update: MerchantConnectorAccountUpdate) -> Self {
        match merchant_connector_account_update {
            MerchantConnectorAccountUpdate::Update {
                connector_type,
                connector_name,
                connector_account_details,
                test_mode,
                disabled,
                merchant_connector_id,
                payment_methods_enabled,
                metadata,
                frm_configs,
                connector_webhook_details,
                applepay_verified_domains,
                pm_auth_config,
                connector_label,
                status,
                connector_wallets_details,
                additional_merchant_data,
            } => Self {
                connector_type,
                connector_name,
                connector_account_details: connector_account_details.map(Encryption::from),
                test_mode,
                disabled,
                merchant_connector_id,
                payment_methods_enabled,
                metadata,
                frm_configs: None,
                frm_config: frm_configs,
                modified_at: Some(date_time::now()),
                connector_webhook_details: *connector_webhook_details,
                applepay_verified_domains,
                pm_auth_config: *pm_auth_config,
                connector_label,
                status,
                connector_wallets_details: connector_wallets_details.map(Encryption::from),
                additional_merchant_data: additional_merchant_data.map(Encryption::from),
            },
            MerchantConnectorAccountUpdate::ConnectorWalletDetailsUpdate {
                connector_wallets_details,
            } => Self {
                connector_wallets_details: Some(Encryption::from(connector_wallets_details)),
                connector_type: None,
                connector_name: None,
                connector_account_details: None,
                connector_label: None,
                test_mode: None,
                disabled: None,
                merchant_connector_id: None,
                payment_methods_enabled: None,
                frm_configs: None,
                metadata: None,
                modified_at: None,
                connector_webhook_details: None,
                frm_config: None,
                applepay_verified_domains: None,
                pm_auth_config: None,
                status: None,
                additional_merchant_data: None,
            },
        }
    }
}

#[cfg(feature = "v2")]
impl From<MerchantConnectorAccountUpdate> for MerchantConnectorAccountUpdateInternal {
    fn from(merchant_connector_account_update: MerchantConnectorAccountUpdate) -> Self {
        match merchant_connector_account_update {
            MerchantConnectorAccountUpdate::Update {
                connector_type,
                connector_account_details,
                disabled,
                payment_methods_enabled,
                metadata,
                frm_configs,
                connector_webhook_details,
                applepay_verified_domains,
                pm_auth_config,
                connector_label,
                status,
                connector_wallets_details,
                additional_merchant_data,
                feature_metadata,
            } => Self {
                connector_type,
                connector_account_details: connector_account_details.map(Encryption::from),
                disabled,
                payment_methods_enabled,
                metadata,
                frm_config: frm_configs,
                modified_at: Some(date_time::now()),
                connector_webhook_details: *connector_webhook_details,
                applepay_verified_domains,
                pm_auth_config: *pm_auth_config,
                connector_label,
                status,
                connector_wallets_details: connector_wallets_details.map(Encryption::from),
                additional_merchant_data: additional_merchant_data.map(Encryption::from),
                feature_metadata: feature_metadata.map(From::from),
            },
            MerchantConnectorAccountUpdate::ConnectorWalletDetailsUpdate {
                connector_wallets_details,
            } => Self {
                connector_wallets_details: Some(Encryption::from(connector_wallets_details)),
                connector_type: None,
                connector_account_details: None,
                connector_label: None,
                disabled: None,
                payment_methods_enabled: None,
                metadata: None,
                modified_at: None,
                connector_webhook_details: None,
                frm_config: None,
                applepay_verified_domains: None,
                pm_auth_config: None,
                status: None,
                additional_merchant_data: None,
                feature_metadata: None,
            },
        }
    }
}

common_utils::create_list_wrapper!(
    MerchantConnectorAccounts,
    MerchantConnectorAccount,
    impl_functions: {
        fn filter_and_map<'a, T>(
            &'a self,
            filter: impl Fn(&'a MerchantConnectorAccount) -> bool,
            func: impl Fn(&'a MerchantConnectorAccount) -> T,
        ) -> rustc_hash::FxHashSet<T>
        where
            T: std::hash::Hash + Eq,
        {
            self.0
                .iter()
                .filter(|mca| filter(mca))
                .map(func)
                .collect::<rustc_hash::FxHashSet<_>>()
        }

        pub fn filter_by_profile<'a, T>(
            &'a self,
            profile_id: &'a id_type::ProfileId,
            func: impl Fn(&'a MerchantConnectorAccount) -> T,
        ) -> rustc_hash::FxHashSet<T>
        where
            T: std::hash::Hash + Eq,
        {
            self.filter_and_map(|mca| mca.profile_id == *profile_id, func)
        }
        #[cfg(feature = "v2")]
        pub fn get_connector_and_supporting_payment_method_type_for_session_call(
            &self,
        ) -> Vec<(&MerchantConnectorAccount, common_enums::PaymentMethodType, common_enums::PaymentMethod)> {
            // This vector is created to work around lifetimes
            let ref_vector = Vec::default();

            let connector_and_supporting_payment_method_type = self.iter().flat_map(|connector_account| {
                connector_account
                    .payment_methods_enabled.as_ref()
                    .unwrap_or(&Vec::default())
                    .iter()
                    .flat_map(|payment_method_types| payment_method_types.payment_method_subtypes.as_ref().unwrap_or(&ref_vector).iter().map(|payment_method_subtype| (payment_method_subtype, payment_method_types.payment_method_type)).collect::<Vec<_>>())
                    .filter(|(payment_method_types_enabled, _)| {
                        payment_method_types_enabled.payment_experience == Some(api_models::enums::PaymentExperience::InvokeSdkClient)
                    })
                    .map(|(payment_method_subtypes, payment_method_type)| {
                        (connector_account, payment_method_subtypes.payment_method_subtype, payment_method_type)
                    })
                    .collect::<Vec<_>>()
            }).collect();
            connector_and_supporting_payment_method_type
        }
        pub fn filter_based_on_profile_and_connector_type(
            self,
            profile_id: &id_type::ProfileId,
            connector_type: common_enums::ConnectorType,
        ) -> Self {
            self.into_iter()
                .filter(|mca| &mca.profile_id == profile_id && mca.connector_type == connector_type)
                .collect()
        }
        pub fn is_merchant_connector_account_id_in_connector_mandate_details(
            &self,
            profile_id: Option<&id_type::ProfileId>,
            connector_mandate_details: &CommonMandateReference,
        ) -> bool {
            let mca_ids = self
                .iter()
                .filter(|mca| {
                    mca.disabled.is_some_and(|disabled| !disabled)
                        && profile_id.is_some_and(|profile_id| *profile_id == mca.profile_id)
                })
                .map(|mca| mca.get_id())
                .collect::<std::collections::HashSet<_>>();

            connector_mandate_details
            .payments
            .as_ref()
            .as_ref().is_some_and(|payments| {
                payments.0.keys().any(|mca_id| mca_ids.contains(mca_id))
            })
        }
    }
);

#[cfg(feature = "v2")]
impl From<MerchantConnectorAccountFeatureMetadata>
    for DieselMerchantConnectorAccountFeatureMetadata
{
    fn from(feature_metadata: MerchantConnectorAccountFeatureMetadata) -> Self {
        let revenue_recovery = feature_metadata.revenue_recovery.map(|recovery_metadata| {
            DieselRevenueRecoveryMetadata {
                max_retry_count: recovery_metadata.max_retry_count,
                billing_connector_retry_threshold: recovery_metadata
                    .billing_connector_retry_threshold,
                billing_account_reference: DieselBillingAccountReference(
                    recovery_metadata.mca_reference.recovery_to_billing,
                ),
            }
        });
        Self { revenue_recovery }
    }
}

#[cfg(feature = "v2")]
impl From<DieselMerchantConnectorAccountFeatureMetadata>
    for MerchantConnectorAccountFeatureMetadata
{
    fn from(feature_metadata: DieselMerchantConnectorAccountFeatureMetadata) -> Self {
        let revenue_recovery = feature_metadata.revenue_recovery.map(|recovery_metadata| {
            let mut billing_to_recovery = HashMap::new();
            for (key, value) in &recovery_metadata.billing_account_reference.0 {
                billing_to_recovery.insert(value.to_string(), key.clone());
            }
            RevenueRecoveryMetadata {
                max_retry_count: recovery_metadata.max_retry_count,
                billing_connector_retry_threshold: recovery_metadata
                    .billing_connector_retry_threshold,
                mca_reference: AccountReferenceMap {
                    recovery_to_billing: recovery_metadata.billing_account_reference.0,
                    billing_to_recovery,
                },
            }
        });
        Self { revenue_recovery }
    }
}


// Function: get_card_networks
// File: crates/api_models/src/open_router.rs
// Module: api_models

pub fn get_card_networks(&self) -> Vec<common_enums::CardNetwork>


// File: crates/router/src/core/payments/operations/proxy_payments_intent.rs
// Module: router
// Public structs: 1

use api_models::payments::ProxyPaymentsRequest;
use async_trait::async_trait;
use common_enums::enums;
use common_utils::types::keymanager::ToEncryptable;
use error_stack::ResultExt;
use hyperswitch_domain_models::{
    payment_method_data::PaymentMethodData, payments::PaymentConfirmData,
};
use hyperswitch_interfaces::api::ConnectorSpecifications;
use masking::PeekInterface;
use router_env::{instrument, tracing};

use super::{Domain, GetTracker, Operation, PostUpdateTracker, UpdateTracker, ValidateRequest};
use crate::{
    core::{
        errors::{self, CustomResult, RouterResult, StorageErrorExt},
        payments::{
            operations::{self, ValidateStatusForOperation},
            OperationSessionGetters, OperationSessionSetters,
        },
    },
    routes::{app::ReqState, SessionState},
    types::{
        self,
        api::{self, ConnectorCallType},
        domain::{self, types as domain_types},
        storage::{self, enums as storage_enums},
    },
    utils::OptionExt,
};

#[derive(Debug, Clone, Copy)]
pub struct PaymentProxyIntent;

impl ValidateStatusForOperation for PaymentProxyIntent {
    /// Validate if the current operation can be performed on the current status of the payment intent
    fn validate_status_for_operation(
        &self,
        intent_status: common_enums::IntentStatus,
    ) -> Result<(), errors::ApiErrorResponse> {
        match intent_status {
            //Failed state is included here so that in PCR, retries can be done for failed payments, otherwise for a failed attempt it was asking for new payment_intent
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Processing => Ok(()),
            //Failed state is included here so that in PCR, retries can be done for failed payments, otherwise for a failed attempt it was asking for new payment_intent
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::Failed => Ok(()),
            common_enums::IntentStatus::Conflicted
            | common_enums::IntentStatus::Succeeded
            | common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture
            | common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::RequiresConfirmation
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable
            | common_enums::IntentStatus::Expired => {
                Err(errors::ApiErrorResponse::PaymentUnexpectedState {
                    current_flow: format!("{self:?}"),
                    field_name: "status".to_string(),
                    current_value: intent_status.to_string(),
                    states: ["requires_payment_method".to_string()].join(", "),
                })
            }
        }
    }
}
type BoxedConfirmOperation<'b, F> =
    super::BoxedOperation<'b, F, ProxyPaymentsRequest, PaymentConfirmData<F>>;

impl<F: Send + Clone + Sync> Operation<F, ProxyPaymentsRequest> for &PaymentProxyIntent {
    type Data = PaymentConfirmData<F>;
    fn to_validate_request(
        &self,
    ) -> RouterResult<&(dyn ValidateRequest<F, ProxyPaymentsRequest, Self::Data> + Send + Sync)>
    {
        Ok(*self)
    }
    fn to_get_tracker(
        &self,
    ) -> RouterResult<&(dyn GetTracker<F, Self::Data, ProxyPaymentsRequest> + Send + Sync)> {
        Ok(*self)
    }
    fn to_domain(&self) -> RouterResult<&(dyn Domain<F, ProxyPaymentsRequest, Self::Data>)> {
        Ok(*self)
    }
    fn to_update_tracker(
        &self,
    ) -> RouterResult<&(dyn UpdateTracker<F, Self::Data, ProxyPaymentsRequest> + Send + Sync)> {
        Ok(*self)
    }
}

#[automatically_derived]
impl<F: Send + Clone + Sync> Operation<F, ProxyPaymentsRequest> for PaymentProxyIntent {
    type Data = PaymentConfirmData<F>;
    fn to_validate_request(
        &self,
    ) -> RouterResult<&(dyn ValidateRequest<F, ProxyPaymentsRequest, Self::Data> + Send + Sync)>
    {
        Ok(self)
    }
    fn to_get_tracker(
        &self,
    ) -> RouterResult<&(dyn GetTracker<F, Self::Data, ProxyPaymentsRequest> + Send + Sync)> {
        Ok(self)
    }
    fn to_domain(&self) -> RouterResult<&dyn Domain<F, ProxyPaymentsRequest, Self::Data>> {
        Ok(self)
    }
    fn to_update_tracker(
        &self,
    ) -> RouterResult<&(dyn UpdateTracker<F, Self::Data, ProxyPaymentsRequest> + Send + Sync)> {
        Ok(self)
    }
}

impl<F: Send + Clone + Sync> ValidateRequest<F, ProxyPaymentsRequest, PaymentConfirmData<F>>
    for PaymentProxyIntent
{
    #[instrument(skip_all)]
    fn validate_request<'a, 'b>(
        &'b self,
        _request: &ProxyPaymentsRequest,
        merchant_context: &'a domain::MerchantContext,
    ) -> RouterResult<operations::ValidateResult> {
        let validate_result = operations::ValidateResult {
            merchant_id: merchant_context.get_merchant_account().get_id().to_owned(),
            storage_scheme: merchant_context.get_merchant_account().storage_scheme,
            requeue: false,
        };

        Ok(validate_result)
    }
}

#[async_trait]
impl<F: Send + Clone + Sync> GetTracker<F, PaymentConfirmData<F>, ProxyPaymentsRequest>
    for PaymentProxyIntent
{
    #[instrument(skip_all)]
    async fn get_trackers<'a>(
        &'a self,
        state: &'a SessionState,
        payment_id: &common_utils::id_type::GlobalPaymentId,
        request: &ProxyPaymentsRequest,
        merchant_context: &domain::MerchantContext,
        _profile: &domain::Profile,
        header_payload: &hyperswitch_domain_models::payments::HeaderPayload,
    ) -> RouterResult<operations::GetTrackerResponse<PaymentConfirmData<F>>> {
        let db = &*state.store;
        let key_manager_state = &state.into();

        let storage_scheme = merchant_context.get_merchant_account().storage_scheme;

        let payment_intent = db
            .find_payment_intent_by_id(
                key_manager_state,
                payment_id,
                merchant_context.get_merchant_key_store(),
                storage_scheme,
            )
            .await
            .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;

        self.validate_status_for_operation(payment_intent.status)?;

        let cell_id = state.conf.cell_information.id.clone();

        let batch_encrypted_data = domain_types::crypto_operation(
            key_manager_state,
            common_utils::type_name!(hyperswitch_domain_models::payments::payment_attempt::PaymentAttempt),
            domain_types::CryptoOperation::BatchEncrypt(
                hyperswitch_domain_models::payments::payment_attempt::FromRequestEncryptablePaymentAttempt::to_encryptable(
                    hyperswitch_domain_models::payments::payment_attempt::FromRequestEncryptablePaymentAttempt {
                        payment_method_billing_address: None,
                    },
                ),
            ),
            common_utils::types::keymanager::Identifier::Merchant(merchant_context.get_merchant_account().get_id().to_owned()),
            merchant_context.get_merchant_key_store().key.peek(),
        )
        .await
        .and_then(|val| val.try_into_batchoperation())
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Failed while encrypting payment intent details".to_string())?;

        let encrypted_data =
             hyperswitch_domain_models::payments::payment_attempt::FromRequestEncryptablePaymentAttempt::from_encryptable(batch_encrypted_data)
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed while encrypting payment intent details")?;

        let payment_attempt = match payment_intent.active_attempt_id.clone() {
            Some(ref active_attempt_id) => db
                .find_payment_attempt_by_id(
                    key_manager_state,
                    merchant_context.get_merchant_key_store(),
                    active_attempt_id,
                    storage_scheme,
                )
                .await
                .change_context(errors::ApiErrorResponse::PaymentNotFound)
                .attach_printable("Could not find payment attempt")?,

            None => {
                let payment_attempt_domain_model: hyperswitch_domain_models::payments::payment_attempt::PaymentAttempt =
                hyperswitch_domain_models::payments::payment_attempt::PaymentAttempt::proxy_create_domain_model(
                    &payment_intent,
                    cell_id,
                    storage_scheme,
                    request,
                    encrypted_data
                )
                .await?;
                db.insert_payment_attempt(
                    key_manager_state,
                    merchant_context.get_merchant_key_store(),
                    payment_attempt_domain_model,
                    storage_scheme,
                )
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Could not insert payment attempt")?
            }
        };

        let processor_payment_token = request.recurring_details.processor_payment_token.clone();

        let payment_address = hyperswitch_domain_models::payment_address::PaymentAddress::new(
            payment_intent
                .shipping_address
                .clone()
                .map(|address| address.into_inner()),
            payment_intent
                .billing_address
                .clone()
                .map(|address| address.into_inner()),
            payment_attempt
                .payment_method_billing_address
                .clone()
                .map(|address| address.into_inner()),
            Some(true),
        );
        let mandate_data_input = api_models::payments::MandateIds {
            mandate_id: None,
            mandate_reference_id: Some(
                api_models::payments::MandateReferenceId::ConnectorMandateId(
                    api_models::payments::ConnectorMandateReferenceId::new(
                        Some(processor_payment_token),
                        None,
                        None,
                        None,
                        None,
                    ),
                ),
            ),
        };

        let payment_data = PaymentConfirmData {
            flow: std::marker::PhantomData,
            payment_intent,
            payment_attempt,
            payment_method_data: Some(PaymentMethodData::MandatePayment),
            payment_address,
            mandate_data: Some(mandate_data_input),
            payment_method: None,
            merchant_connector_details: None,
            external_vault_pmd: None,
        };

        let get_trackers_response = operations::GetTrackerResponse { payment_data };

        Ok(get_trackers_response)
    }
}

#[async_trait]
impl<F: Clone + Send + Sync> Domain<F, ProxyPaymentsRequest, PaymentConfirmData<F>>
    for PaymentProxyIntent
{
    async fn get_customer_details<'a>(
        &'a self,
        _state: &SessionState,
        _payment_data: &mut PaymentConfirmData<F>,
        _merchant_key_store: &domain::MerchantKeyStore,
        _storage_scheme: storage_enums::MerchantStorageScheme,
    ) -> CustomResult<(BoxedConfirmOperation<'a, F>, Option<domain::Customer>), errors::StorageError>
    {
        Ok((Box::new(self), None))
    }

    #[instrument(skip_all)]
    async fn make_pm_data<'a>(
        &'a self,
        _state: &'a SessionState,
        _payment_data: &mut PaymentConfirmData<F>,
        _storage_scheme: storage_enums::MerchantStorageScheme,
        _key_store: &domain::MerchantKeyStore,
        _customer: &Option<domain::Customer>,
        _business_profile: &domain::Profile,
        _should_retry_with_pan: bool,
    ) -> RouterResult<(
        BoxedConfirmOperation<'a, F>,
        Option<PaymentMethodData>,
        Option<String>,
    )> {
        Ok((Box::new(self), None, None))
    }
    #[instrument(skip_all)]
    async fn populate_payment_data<'a>(
        &'a self,
        _state: &SessionState,
        payment_data: &mut PaymentConfirmData<F>,
        _merchant_context: &domain::MerchantContext,
        _business_profile: &domain::Profile,
        connector_data: &api::ConnectorData,
    ) -> CustomResult<(), errors::ApiErrorResponse> {
        let connector_request_reference_id = connector_data
            .connector
            .generate_connector_request_reference_id(
                &payment_data.payment_intent,
                &payment_data.payment_attempt,
            );
        payment_data.set_connector_request_reference_id(Some(connector_request_reference_id));
        Ok(())
    }

    async fn perform_routing<'a>(
        &'a self,
        _merchant_context: &domain::MerchantContext,
        _business_profile: &domain::Profile,
        state: &SessionState,
        payment_data: &mut PaymentConfirmData<F>,
    ) -> CustomResult<ConnectorCallType, errors::ApiErrorResponse> {
        let connector_name = payment_data.get_payment_attempt_connector();
        if let Some(connector_name) = connector_name {
            let merchant_connector_id = payment_data.get_merchant_connector_id_in_attempt();
            let connector_data = api::ConnectorData::get_connector_by_name(
                &state.conf.connectors,
                connector_name,
                api::GetToken::Connector,
                merchant_connector_id,
            )?;

            Ok(ConnectorCallType::PreDetermined(connector_data.into()))
        } else {
            Err(error_stack::Report::new(
                errors::ApiErrorResponse::InternalServerError,
            ))
        }
    }
}
#[async_trait]
impl<F: Clone + Sync> UpdateTracker<F, PaymentConfirmData<F>, ProxyPaymentsRequest>
    for PaymentProxyIntent
{
    #[instrument(skip_all)]
    async fn update_trackers<'b>(
        &'b self,
        state: &'b SessionState,
        _req_state: ReqState,
        mut payment_data: PaymentConfirmData<F>,
        _customer: Option<domain::Customer>,
        storage_scheme: storage_enums::MerchantStorageScheme,
        _updated_customer: Option<storage::CustomerUpdate>,
        key_store: &domain::MerchantKeyStore,
        _frm_suggestion: Option<api_models::enums::FrmSuggestion>,
        _header_payload: hyperswitch_domain_models::payments::HeaderPayload,
    ) -> RouterResult<(BoxedConfirmOperation<'b, F>, PaymentConfirmData<F>)>
    where
        F: 'b + Send,
    {
        let db = &*state.store;
        let key_manager_state = &state.into();

        let intent_status = common_enums::IntentStatus::Processing;
        let attempt_status = common_enums::AttemptStatus::Pending;

        let connector = payment_data
            .payment_attempt
            .connector
            .clone()
            .get_required_value("connector")
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Connector is none when constructing response")?;

        let merchant_connector_id = Some(
            payment_data
                .payment_attempt
                .merchant_connector_id
                .clone()
                .get_required_value("merchant_connector_id")
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Merchant connector id is none when constructing response")?,
        );

        let payment_intent_update =
            hyperswitch_domain_models::payments::payment_intent::PaymentIntentUpdate::ConfirmIntent {
                status: intent_status,
                updated_by: storage_scheme.to_string(),
                active_attempt_id: Some(payment_data.payment_attempt.id.clone()),
            };

        let authentication_type = payment_data
            .payment_intent
            .authentication_type
            .unwrap_or_default();

        let connector_request_reference_id = payment_data
            .payment_attempt
            .connector_request_reference_id
            .clone();

        let connector_response_reference_id = payment_data
            .payment_attempt
            .connector_response_reference_id
            .clone();

        let payment_attempt_update = hyperswitch_domain_models::payments::payment_attempt::PaymentAttemptUpdate::ConfirmIntent {
            status: attempt_status,
            updated_by: storage_scheme.to_string(),
            connector,
            merchant_connector_id,
            authentication_type,
            connector_request_reference_id,
            connector_response_reference_id,
        };

        let updated_payment_intent = db
            .update_payment_intent(
                key_manager_state,
                payment_data.payment_intent.clone(),
                payment_intent_update,
                key_store,
                storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Unable to update payment intent")?;

        payment_data.payment_intent = updated_payment_intent;

        let updated_payment_attempt = db
            .update_payment_attempt(
                key_manager_state,
                key_store,
                payment_data.payment_attempt.clone(),
                payment_attempt_update,
                storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Unable to update payment attempt")?;

        payment_data.payment_attempt = updated_payment_attempt;

        Ok((Box::new(self), payment_data))
    }
}

#[cfg(feature = "v2")]
#[async_trait]
impl<F: Clone> PostUpdateTracker<F, PaymentConfirmData<F>, types::PaymentsAuthorizeData>
    for PaymentProxyIntent
{
    async fn update_tracker<'b>(
        &'b self,
        state: &'b SessionState,
        mut payment_data: PaymentConfirmData<F>,
        response: types::RouterData<F, types::PaymentsAuthorizeData, types::PaymentsResponseData>,
        key_store: &domain::MerchantKeyStore,
        storage_scheme: enums::MerchantStorageScheme,
    ) -> RouterResult<PaymentConfirmData<F>>
    where
        F: 'b + Send + Sync,
        types::RouterData<F, types::PaymentsAuthorizeData, types::PaymentsResponseData>:
            hyperswitch_domain_models::router_data::TrackerPostUpdateObjects<
                F,
                types::PaymentsAuthorizeData,
                PaymentConfirmData<F>,
            >,
    {
        use hyperswitch_domain_models::router_data::TrackerPostUpdateObjects;

        let db = &*state.store;
        let key_manager_state = &state.into();

        let response_router_data = response;

        let payment_intent_update =
            response_router_data.get_payment_intent_update(&payment_data, storage_scheme);
        let payment_attempt_update =
            response_router_data.get_payment_attempt_update(&payment_data, storage_scheme);

        let updated_payment_intent = db
            .update_payment_intent(
                key_manager_state,
                payment_data.payment_intent,
                payment_intent_update,
                key_store,
                storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Unable to update payment intent")?;

        let updated_payment_attempt = db
            .update_payment_attempt(
                key_manager_state,
                key_store,
                payment_data.payment_attempt,
                payment_attempt_update,
                storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Unable to update payment attempt")?;

        payment_data.payment_intent = updated_payment_intent;
        payment_data.payment_attempt = updated_payment_attempt;

        Ok(payment_data)
    }
}


// Implementation: impl ConnectorSpecifications for for Redsys
// File: crates/hyperswitch_connectors/src/connectors/redsys.rs
// Module: hyperswitch_connectors
// Methods: 4 total (0 public)

impl ConnectorSpecifications for for Redsys


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

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


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

impl api::RefundSync for for Nmi


// Implementation: impl State for for PmValidated
// File: crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs
// Module: router
// Methods: 0 total (0 public)

impl State for for PmValidated


// Function: list_all_themes_in_lineage
// File: crates/router/src/core/user/theme.rs
// Module: router

pub fn list_all_themes_in_lineage(
    state: SessionState,
    user: UserFromToken,
    entity_type: EntityType,
) -> UserResponse<Vec<theme_api::GetThemeResponse>>


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

impl Default for for PollConfig


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

impl Opayo


// Struct: ShipToList
// File: crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ShipToList


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

impl PaymentAuthorize for for Threedsecureio


// File: crates/router/src/types/api/connector_onboarding/paypal.rs
// Module: router
// Public functions: 6
// Public structs: 12

use api_models::connector_onboarding as api;
use error_stack::ResultExt;

use crate::core::errors::{ApiErrorResponse, RouterResult};

#[derive(serde::Deserialize, Debug)]
pub struct HateoasLink {
    pub href: String,
    pub rel: String,
    pub method: String,
}

#[derive(serde::Deserialize, Debug)]
pub struct PartnerReferralResponse {
    pub links: Vec<HateoasLink>,
}

#[derive(serde::Serialize, Debug)]
pub struct PartnerReferralRequest {
    pub tracking_id: String,
    pub operations: Vec<PartnerReferralOperations>,
    pub products: Vec<PayPalProducts>,
    pub capabilities: Vec<PayPalCapabilities>,
    pub partner_config_override: PartnerConfigOverride,
    pub legal_consents: Vec<LegalConsent>,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PayPalProducts {
    Ppcp,
    AdvancedVaulting,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PayPalCapabilities {
    PaypalWalletVaultingAdvanced,
}

#[derive(serde::Serialize, Debug)]
pub struct PartnerReferralOperations {
    pub operation: PayPalReferralOperationType,
    pub api_integration_preference: PartnerReferralIntegrationPreference,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PayPalReferralOperationType {
    ApiIntegration,
}

#[derive(serde::Serialize, Debug)]
pub struct PartnerReferralIntegrationPreference {
    pub rest_api_integration: PartnerReferralRestApiIntegration,
}

#[derive(serde::Serialize, Debug)]
pub struct PartnerReferralRestApiIntegration {
    pub integration_method: IntegrationMethod,
    pub integration_type: PayPalIntegrationType,
    pub third_party_details: PartnerReferralThirdPartyDetails,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum IntegrationMethod {
    Paypal,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PayPalIntegrationType {
    ThirdParty,
}

#[derive(serde::Serialize, Debug)]
pub struct PartnerReferralThirdPartyDetails {
    pub features: Vec<PayPalFeatures>,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PayPalFeatures {
    Payment,
    Refund,
    Vault,
    AccessMerchantInformation,
    BillingAgreement,
    ReadSellerDispute,
}

#[derive(serde::Serialize, Debug)]
pub struct PartnerConfigOverride {
    pub partner_logo_url: String,
    pub return_url: String,
}

#[derive(serde::Serialize, Debug)]
pub struct LegalConsent {
    #[serde(rename = "type")]
    pub consent_type: LegalConsentType,
    pub granted: bool,
}

#[derive(serde::Serialize, Debug)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum LegalConsentType {
    ShareDataConsent,
}

impl PartnerReferralRequest {
    pub fn new(tracking_id: String, return_url: String) -> Self {
        Self {
            tracking_id,
            operations: vec![PartnerReferralOperations {
                operation: PayPalReferralOperationType::ApiIntegration,
                api_integration_preference: PartnerReferralIntegrationPreference {
                    rest_api_integration: PartnerReferralRestApiIntegration {
                        integration_method: IntegrationMethod::Paypal,
                        integration_type: PayPalIntegrationType::ThirdParty,
                        third_party_details: PartnerReferralThirdPartyDetails {
                            features: vec![
                                PayPalFeatures::Payment,
                                PayPalFeatures::Refund,
                                PayPalFeatures::Vault,
                                PayPalFeatures::AccessMerchantInformation,
                                PayPalFeatures::BillingAgreement,
                                PayPalFeatures::ReadSellerDispute,
                            ],
                        },
                    },
                },
            }],
            products: vec![PayPalProducts::Ppcp, PayPalProducts::AdvancedVaulting],
            capabilities: vec![PayPalCapabilities::PaypalWalletVaultingAdvanced],
            partner_config_override: PartnerConfigOverride {
                partner_logo_url: "https://hyperswitch.io/img/websiteIcon.svg".to_string(),
                return_url,
            },
            legal_consents: vec![LegalConsent {
                consent_type: LegalConsentType::ShareDataConsent,
                granted: true,
            }],
        }
    }
}

#[derive(serde::Deserialize, Debug)]
pub struct SellerStatusResponse {
    pub merchant_id: common_utils::id_type::MerchantId,
    pub links: Vec<HateoasLink>,
}

#[derive(serde::Deserialize, Debug)]
pub struct SellerStatusDetailsResponse {
    pub merchant_id: common_utils::id_type::MerchantId,
    pub primary_email_confirmed: bool,
    pub payments_receivable: bool,
    pub products: Vec<SellerStatusProducts>,
}

#[derive(serde::Deserialize, Debug)]
pub struct SellerStatusProducts {
    pub name: String,
    pub vetting_status: Option<VettingStatus>,
}

#[derive(serde::Deserialize, Debug, Clone)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum VettingStatus {
    NeedMoreData,
    Subscribed,
    Denied,
}

impl SellerStatusResponse {
    pub fn extract_merchant_details_url(self, paypal_base_url: &str) -> RouterResult<String> {
        self.links
            .first()
            .and_then(|link| link.href.strip_prefix('/'))
            .map(|link| format!("{paypal_base_url}{link}"))
            .ok_or(ApiErrorResponse::InternalServerError)
            .attach_printable("Merchant details not received in onboarding status")
    }
}

impl SellerStatusDetailsResponse {
    pub fn check_payments_receivable(&self) -> Option<api::PayPalOnboardingStatus> {
        if !self.payments_receivable {
            return Some(api::PayPalOnboardingStatus::PaymentsNotReceivable);
        }
        None
    }

    pub fn check_ppcp_custom_status(&self) -> Option<api::PayPalOnboardingStatus> {
        match self.get_ppcp_custom_status() {
            Some(VettingStatus::Denied) => Some(api::PayPalOnboardingStatus::PpcpCustomDenied),
            Some(VettingStatus::Subscribed) => None,
            _ => Some(api::PayPalOnboardingStatus::MorePermissionsNeeded),
        }
    }

    fn check_email_confirmation(&self) -> Option<api::PayPalOnboardingStatus> {
        if !self.primary_email_confirmed {
            return Some(api::PayPalOnboardingStatus::EmailNotVerified);
        }
        None
    }

    pub async fn get_eligibility_status(&self) -> RouterResult<api::PayPalOnboardingStatus> {
        Ok(self
            .check_payments_receivable()
            .or(self.check_email_confirmation())
            .or(self.check_ppcp_custom_status())
            .unwrap_or(api::PayPalOnboardingStatus::Success(
                api::PayPalOnboardingDone {
                    payer_id: self.get_payer_id(),
                },
            )))
    }

    fn get_ppcp_custom_status(&self) -> Option<VettingStatus> {
        self.products
            .iter()
            .find(|product| product.name == "PPCP_CUSTOM")
            .and_then(|ppcp_custom| ppcp_custom.vetting_status.clone())
    }

    fn get_payer_id(&self) -> common_utils::id_type::MerchantId {
        self.merchant_id.to_owned()
    }
}

impl PartnerReferralResponse {
    pub fn extract_action_url(self) -> RouterResult<String> {
        Ok(self
            .links
            .into_iter()
            .find(|hateoas_link| hateoas_link.rel == "action_url")
            .ok_or(ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to get action_url from paypal response")?
            .href)
    }
}


// Function: get_frm_config_as_secret
// File: crates/api_models/src/admin.rs
// Module: api_models

pub fn get_frm_config_as_secret(&self) -> Option<Vec<Secret<serde_json::Value>>>


// Struct: GetSubscriptionEstimateResponse
// File: crates/hyperswitch_domain_models/src/router_response_types/subscriptions.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct GetSubscriptionEstimateResponse


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

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


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

impl api::PaymentCapture for for Coinbase


// Function: list_de_euclid_active_routing_algorithm
// File: crates/router/src/core/payments/routing/utils.rs
// Module: router

pub fn list_de_euclid_active_routing_algorithm(
    state: &SessionState,
    created_by: String,
) -> RoutingResult<Vec<api_routing::RoutingDictionaryRecord>>


// Function: unify_with_payment_data_billing
// File: crates/hyperswitch_domain_models/src/payment_address.rs
// Module: hyperswitch_domain_models

// Documentation: Here the `self` takes precedence

pub fn unify_with_payment_data_billing(
        self,
        other_payment_method_billing: Option<Address>,
    ) -> Self


// Struct: ResponseMessages
// File: crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ResponseMessages


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

impl Responder


// Struct: Giropay
// File: crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Giropay


// Struct: ProducerSettings
// File: crates/scheduler/src/configs/settings.rs
// Module: scheduler
// Implementations: 0

pub struct ProducerSettings


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

impl MerchantAccountNew


// Struct: ExternalToken
// File: crates/router/src/services/authentication.rs
// Module: router
// Implementations: 1

pub struct ExternalToken


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

impl api::PayoutCancel for for Adyen


// Implementation: impl ConnectorValidation for for Hyperwallet
// File: crates/hyperswitch_connectors/src/connectors/hyperwallet.rs
// Module: hyperswitch_connectors
// Methods: 2 total (0 public)

impl ConnectorValidation for for Hyperwallet


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

pub struct ThreedsInvokeRequest


// Function: get_api_event_metrics_info
// File: crates/analytics/src/utils.rs
// Module: analytics

pub fn get_api_event_metrics_info() -> Vec<NameDescription>


// Struct: WellsfargoAuthorizationOptions
// File: crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct WellsfargoAuthorizationOptions


// File: crates/diesel_models/src/mod.rs
// Module: diesel_models

#[cfg(all(feature = "v2", feature = "tokenization_v2"))]
pub mod tokenization;


// Struct: WorldpayvantivMetadataObject
// File: crates/hyperswitch_connectors/src/connectors/worldpayvantiv/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct WorldpayvantivMetadataObject


// Struct: NexinetsPaymentsRequest
// File: crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NexinetsPaymentsRequest


// Struct: GpaymentsMetaData
// File: crates/hyperswitch_connectors/src/connectors/gpayments/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct GpaymentsMetaData


// Implementation: impl FileMetadataInterface for for KafkaStore
// File: crates/router/src/db/kafka_store.rs
// Module: router
// Methods: 4 total (0 public)

impl FileMetadataInterface for for KafkaStore


// Function: profile_payments_list
// File: crates/router/src/routes/payments.rs
// Module: router

pub fn profile_payments_list(
    state: web::Data<app::AppState>,
    req: actix_web::HttpRequest,
    payload: web::Query<payment_types::PaymentListConstraints>,
) -> impl Responder


// Struct: PaymentsResponse
// File: crates/hyperswitch_connectors/src/connectors/dummyconnector/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaymentsResponse


// Implementation: impl KafkaFraudCheck
// File: crates/router/src/services/kafka/fraud_check.rs
// Module: router
// Methods: 1 total (1 public)

impl KafkaFraudCheck


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

pub fn retrieve_payment_link(
    state: SessionState,
    payment_link_id: String,
) -> RouterResponse<api_models::payments::RetrievePaymentLinkResponse>


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

impl Responder


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

pub struct ErrorDetailItem


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

impl ConnectorValidation for for Payeezy


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

// Public submodules:
pub mod transformers;


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

pub struct FiuuPaymentCancelRequest


// Struct: KlarnaSessionRequest
// File: crates/hyperswitch_connectors/src/connectors/klarna/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct KlarnaSessionRequest


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

pub fn get_additional_payout_data(
    pm_data: &api::PayoutMethodData,
    db: &dyn StorageInterface,
    profile_id: &id_type::ProfileId,
) -> Option<payout_additional::AdditionalPayoutMethodData>


// File: crates/api_models/src/process_tracker/revenue_recovery.rs
// Module: api_models
// Public structs: 3

use common_utils::id_type;
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;
use utoipa::ToSchema;

use crate::enums;
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RevenueRecoveryResponse {
    pub id: String,
    pub name: Option<String>,
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub schedule_time_for_payment: Option<PrimitiveDateTime>,
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub schedule_time_for_psync: Option<PrimitiveDateTime>,
    #[schema(value_type = ProcessTrackerStatus, example = "finish")]
    pub status: enums::ProcessTrackerStatus,
    pub business_status: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RevenueRecoveryId {
    pub revenue_recovery_id: id_type::GlobalPaymentId,
}

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct RevenueRecoveryRetriggerRequest {
    /// The task we want to resume
    pub revenue_recovery_task: String,
    /// Time at which the job was scheduled at
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub schedule_time: Option<PrimitiveDateTime>,
    /// Status of The Process Tracker Task
    pub status: enums::ProcessTrackerStatus,
    /// Business Status of The Process Tracker Task
    pub business_status: String,
}


// Implementation: impl Airwallex
// File: crates/hyperswitch_connectors/src/connectors/airwallex.rs
// Module: hyperswitch_connectors
// Methods: 1 total (0 public)

impl Airwallex


// Struct: SdkEventMetricRow
// File: crates/analytics/src/sdk_events/metrics.rs
// Module: analytics
// Implementations: 0

pub struct SdkEventMetricRow


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

impl ConnectorCommon for for Taxjar


// Function: add_model
// File: crates/smithy-core/src/generator.rs
// Module: smithy-core

pub fn add_model(&mut self, model: SmithyModel)


// Function: get_valid_webhook_status
// File: crates/euclid_wasm/src/lib.rs
// Module: euclid_wasm

pub fn get_valid_webhook_status(key: &str) -> JsResult


// Function: parse_paybox_response
// File: crates/hyperswitch_connectors/src/connectors/paybox/transformers.rs
// Module: hyperswitch_connectors

pub fn parse_paybox_response(
    query_bytes: Bytes,
    is_three_ds: bool,
) -> CustomResult<PayboxResponse, errors::ConnectorError>


// Function: pg_connection
// File: crates/drainer/src/connection.rs
// Module: drainer

pub fn pg_connection(
    pool: &PgPool,
) -> PooledConnection<'_, async_bb8_diesel::ConnectionManager<PgConnection>>


// Function: find_by_merchant_id_fingerprint
// File: crates/diesel_models/src/query/blocklist_lookup.rs
// Module: diesel_models

pub fn find_by_merchant_id_fingerprint(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        fingerprint: &str,
    ) -> StorageResult<Self>


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

impl api::Payment for for Bamboraapac


// Implementation: impl api::RefundExecute for for Powertranz
// File: crates/hyperswitch_connectors/src/connectors/powertranz.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::RefundExecute for for Powertranz


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

pub struct FiuuFPXData


// Implementation: impl super::frm::filters::FrmFilterAnalytics for for SqlxClient
// File: crates/analytics/src/sqlx.rs
// Module: analytics
// Methods: 0 total (0 public)

impl super::frm::filters::FrmFilterAnalytics for for SqlxClient


// Implementation: impl api::PaymentUpdateMetadata for for Stripe
// File: crates/hyperswitch_connectors/src/connectors/stripe.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentUpdateMetadata for for Stripe


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

impl api::PaymentToken for for Affirm


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

impl Payone


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

impl LockerMockUpNew


// Implementation: impl AppState
// File: crates/router/src/routes/app.rs
// Module: router
// Methods: 5 total (2 public)

impl AppState


// Struct: SquarePaymentsAmountData
// File: crates/hyperswitch_connectors/src/connectors/square/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct SquarePaymentsAmountData


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

impl api::PaymentVoid for for Nexixpay


// Struct: WellsfargoTransactionResponse
// File: crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct WellsfargoTransactionResponse


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

pub fn delete_card_from_hs_locker<'a>(
    state: &routes::SessionState,
    customer_id: &id_type::CustomerId,
    merchant_id: &id_type::MerchantId,
    card_reference: &'a str,
) -> errors::CustomResult<payment_methods::DeleteCardResp, errors::VaultError>


// Function: get_billing_address
// File: crates/api_models/src/authentication.rs
// Module: api_models

pub fn get_billing_address(&self) -> Option<Address>


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

pub struct DeutschebankThreeDSInitializeResponse


// Implementation: impl fred::types::FromRedis for for DelReply
// File: crates/redis_interface/src/types.rs
// Module: redis_interface
// Methods: 1 total (0 public)

impl fred::types::FromRedis for for DelReply


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

pub fn should_call_payout_connector_create_customer<'a>(
    state: &'a SessionState,
    connector: &'a api::ConnectorData,
    customer: &'a Option<domain::Customer>,
    connector_label: &'a str,
) -> (bool, Option<&'a str>)


// Struct: Itaubank
// File: crates/hyperswitch_connectors/src/connectors/itaubank.rs
// Module: hyperswitch_connectors
// Implementations: 17
// Traits: api::Payment, api::PaymentSession, api::ConnectorAccessToken, api::MandateSetup, api::PaymentAuthorize, api::PaymentSync, api::PaymentCapture, api::PaymentVoid, api::Refund, api::RefundExecute, api::RefundSync, api::PaymentToken, ConnectorCommon, ConnectorValidation, IncomingWebhook, ConnectorSpecifications

pub struct Itaubank

api::Payment api::PaymentSession api::ConnectorAccessToken api::MandateSetup api::PaymentAuthorize api::PaymentSync api::PaymentCapture api::PaymentVoid api::Refund api::RefundExecute api::RefundSync api::PaymentToken ConnectorCommon ConnectorValidation IncomingWebhook ConnectorSpecifications


// Implementation: impl VerifyIdForUpdateCustomer
// File: crates/router/src/core/customers.rs
// Module: router
// Methods: 1 total (0 public)

impl VerifyIdForUpdateCustomer


// Struct: OrderLines
// File: crates/hyperswitch_connectors/src/connectors/klarna/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct OrderLines


// Function: update_merchant_account
// File: crates/router/src/routes/admin.rs
// Module: router

pub fn update_merchant_account(
    state: web::Data<AppState>,
    req: HttpRequest,
    mid: web::Path<common_utils::id_type::MerchantId>,
    json_payload: web::Json<admin::MerchantAccountUpdate>,
) -> HttpResponse


// Function: toggle_blocklist_guard
// File: crates/openapi/src/routes/blocklist.rs
// Module: openapi

pub fn toggle_blocklist_guard()


// Struct: PayoutsMandateReferenceRecord
// File: crates/diesel_models/src/payment_method.rs
// Module: diesel_models
// Implementations: 0

pub struct PayoutsMandateReferenceRecord


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

impl Responder