// File: crates/euclid/src/frontend/dir/transformers.rs
// Module: euclid

use crate::{dirval, dssa::types::AnalysisErrorType, enums as global_enums, frontend::dir};

pub trait IntoDirValue {
    fn into_dir_value(self) -> Result<dir::DirValue, AnalysisErrorType>;
}
impl IntoDirValue for (global_enums::PaymentMethodType, global_enums::PaymentMethod) {
    fn into_dir_value(self) -> Result<dir::DirValue, AnalysisErrorType> {
        match self.0 {
            global_enums::PaymentMethodType::Credit => Ok(dirval!(CardType = Credit)),
            global_enums::PaymentMethodType::Debit => Ok(dirval!(CardType = Debit)),
            #[cfg(feature = "v2")]
            global_enums::PaymentMethodType::Card => Ok(dirval!(CardType = Card)),
            global_enums::PaymentMethodType::Giropay => Ok(dirval!(BankRedirectType = Giropay)),
            global_enums::PaymentMethodType::Ideal => Ok(dirval!(BankRedirectType = Ideal)),
            global_enums::PaymentMethodType::Sofort => Ok(dirval!(BankRedirectType = Sofort)),
            global_enums::PaymentMethodType::DuitNow => Ok(dirval!(RealTimePaymentType = DuitNow)),
            global_enums::PaymentMethodType::Eps => Ok(dirval!(BankRedirectType = Eps)),
            global_enums::PaymentMethodType::Fps => Ok(dirval!(RealTimePaymentType = Fps)),
            global_enums::PaymentMethodType::Klarna => Ok(dirval!(PayLaterType = Klarna)),
            global_enums::PaymentMethodType::Affirm => Ok(dirval!(PayLaterType = Affirm)),
            global_enums::PaymentMethodType::AfterpayClearpay => {
                Ok(dirval!(PayLaterType = AfterpayClearpay))
            }
            global_enums::PaymentMethodType::AmazonPay => Ok(dirval!(WalletType = AmazonPay)),
            global_enums::PaymentMethodType::Skrill => Ok(dirval!(WalletType = Skrill)),
            global_enums::PaymentMethodType::Paysera => Ok(dirval!(WalletType = Paysera)),
            global_enums::PaymentMethodType::GooglePay => Ok(dirval!(WalletType = GooglePay)),
            global_enums::PaymentMethodType::Bluecode => Ok(dirval!(WalletType = Bluecode)),
            global_enums::PaymentMethodType::ApplePay => Ok(dirval!(WalletType = ApplePay)),
            global_enums::PaymentMethodType::Paypal => Ok(dirval!(WalletType = Paypal)),
            global_enums::PaymentMethodType::RevolutPay => Ok(dirval!(WalletType = RevolutPay)),
            global_enums::PaymentMethodType::CryptoCurrency => {
                Ok(dirval!(CryptoType = CryptoCurrency))
            }
            global_enums::PaymentMethodType::Ach => match self.1 {
                global_enums::PaymentMethod::BankDebit => Ok(dirval!(BankDebitType = Ach)),
                global_enums::PaymentMethod::BankTransfer => Ok(dirval!(BankTransferType = Ach)),
                global_enums::PaymentMethod::PayLater
                | global_enums::PaymentMethod::Card
                | global_enums::PaymentMethod::CardRedirect
                | global_enums::PaymentMethod::Wallet
                | global_enums::PaymentMethod::BankRedirect
                | global_enums::PaymentMethod::Crypto
                | global_enums::PaymentMethod::Reward
                | global_enums::PaymentMethod::RealTimePayment
                | global_enums::PaymentMethod::Upi
                | global_enums::PaymentMethod::Voucher
                | global_enums::PaymentMethod::OpenBanking
                | global_enums::PaymentMethod::MobilePayment
                | global_enums::PaymentMethod::GiftCard => Err(AnalysisErrorType::NotSupported),
            },
            global_enums::PaymentMethodType::Bacs => match self.1 {
                global_enums::PaymentMethod::BankDebit => Ok(dirval!(BankDebitType = Bacs)),
                global_enums::PaymentMethod::BankTransfer => Ok(dirval!(BankTransferType = Bacs)),
                global_enums::PaymentMethod::PayLater
                | global_enums::PaymentMethod::Card
                | global_enums::PaymentMethod::CardRedirect
                | global_enums::PaymentMethod::Wallet
                | global_enums::PaymentMethod::BankRedirect
                | global_enums::PaymentMethod::Crypto
                | global_enums::PaymentMethod::Reward
                | global_enums::PaymentMethod::RealTimePayment
                | global_enums::PaymentMethod::Upi
                | global_enums::PaymentMethod::Voucher
                | global_enums::PaymentMethod::OpenBanking
                | global_enums::PaymentMethod::MobilePayment
                | global_enums::PaymentMethod::GiftCard => Err(AnalysisErrorType::NotSupported),
            },
            global_enums::PaymentMethodType::Becs => Ok(dirval!(BankDebitType = Becs)),
            global_enums::PaymentMethodType::Sepa => Ok(dirval!(BankDebitType = Sepa)),
            global_enums::PaymentMethodType::SepaBankTransfer => {
                Ok(dirval!(BankTransferType = SepaBankTransfer))
            }
            global_enums::PaymentMethodType::AliPay => Ok(dirval!(WalletType = AliPay)),
            global_enums::PaymentMethodType::AliPayHk => Ok(dirval!(WalletType = AliPayHk)),
            global_enums::PaymentMethodType::BancontactCard => {
                Ok(dirval!(BankRedirectType = BancontactCard))
            }
            global_enums::PaymentMethodType::Blik => Ok(dirval!(BankRedirectType = Blik)),
            global_enums::PaymentMethodType::MbWay => Ok(dirval!(WalletType = MbWay)),
            global_enums::PaymentMethodType::MobilePay => Ok(dirval!(WalletType = MobilePay)),
            global_enums::PaymentMethodType::Cashapp => Ok(dirval!(WalletType = Cashapp)),
            global_enums::PaymentMethodType::Multibanco => {
                Ok(dirval!(BankTransferType = Multibanco))
            }
            global_enums::PaymentMethodType::Pix => Ok(dirval!(BankTransferType = Pix)),
            global_enums::PaymentMethodType::Pse => Ok(dirval!(BankTransferType = Pse)),
            global_enums::PaymentMethodType::Interac => Ok(dirval!(BankRedirectType = Interac)),
            global_enums::PaymentMethodType::OnlineBankingCzechRepublic => {
                Ok(dirval!(BankRedirectType = OnlineBankingCzechRepublic))
            }
            global_enums::PaymentMethodType::OnlineBankingFinland => {
                Ok(dirval!(BankRedirectType = OnlineBankingFinland))
            }
            global_enums::PaymentMethodType::OnlineBankingPoland => {
                Ok(dirval!(BankRedirectType = OnlineBankingPoland))
            }
            global_enums::PaymentMethodType::OnlineBankingSlovakia => {
                Ok(dirval!(BankRedirectType = OnlineBankingSlovakia))
            }
            global_enums::PaymentMethodType::Swish => Ok(dirval!(WalletType = Swish)),
            global_enums::PaymentMethodType::Trustly => Ok(dirval!(BankRedirectType = Trustly)),
            global_enums::PaymentMethodType::Bizum => Ok(dirval!(BankRedirectType = Bizum)),

            global_enums::PaymentMethodType::PayBright => Ok(dirval!(PayLaterType = PayBright)),
            global_enums::PaymentMethodType::Flexiti => Ok(dirval!(PayLaterType = Flexiti)),
            global_enums::PaymentMethodType::Walley => Ok(dirval!(PayLaterType = Walley)),
            global_enums::PaymentMethodType::Breadpay => Ok(dirval!(PayLaterType = Breadpay)),
            global_enums::PaymentMethodType::Przelewy24 => {
                Ok(dirval!(BankRedirectType = Przelewy24))
            }
            global_enums::PaymentMethodType::PromptPay => {
                Ok(dirval!(RealTimePaymentType = PromptPay))
            }
            global_enums::PaymentMethodType::WeChatPay => Ok(dirval!(WalletType = WeChatPay)),

            global_enums::PaymentMethodType::ClassicReward => {
                Ok(dirval!(RewardType = ClassicReward))
            }
            global_enums::PaymentMethodType::Evoucher => Ok(dirval!(RewardType = Evoucher)),
            global_enums::PaymentMethodType::UpiCollect => Ok(dirval!(UpiType = UpiCollect)),
            global_enums::PaymentMethodType::UpiIntent => Ok(dirval!(UpiType = UpiIntent)),
            global_enums::PaymentMethodType::SamsungPay => Ok(dirval!(WalletType = SamsungPay)),
            global_enums::PaymentMethodType::GoPay => Ok(dirval!(WalletType = GoPay)),
            global_enums::PaymentMethodType::KakaoPay => Ok(dirval!(WalletType = KakaoPay)),
            global_enums::PaymentMethodType::Twint => Ok(dirval!(WalletType = Twint)),
            global_enums::PaymentMethodType::Gcash => Ok(dirval!(WalletType = Gcash)),
            global_enums::PaymentMethodType::Vipps => Ok(dirval!(WalletType = Vipps)),
            global_enums::PaymentMethodType::VietQr => Ok(dirval!(RealTimePaymentType = VietQr)),
            global_enums::PaymentMethodType::Momo => Ok(dirval!(WalletType = Momo)),
            global_enums::PaymentMethodType::Alma => Ok(dirval!(PayLaterType = Alma)),
            global_enums::PaymentMethodType::Dana => Ok(dirval!(WalletType = Dana)),
            global_enums::PaymentMethodType::OnlineBankingFpx => {
                Ok(dirval!(BankRedirectType = OnlineBankingFpx))
            }
            global_enums::PaymentMethodType::LocalBankRedirect => {
                Ok(dirval!(BankRedirectType = LocalBankRedirect))
            }
            global_enums::PaymentMethodType::OnlineBankingThailand => {
                Ok(dirval!(BankRedirectType = OnlineBankingThailand))
            }
            global_enums::PaymentMethodType::TouchNGo => Ok(dirval!(WalletType = TouchNGo)),
            global_enums::PaymentMethodType::Atome => Ok(dirval!(PayLaterType = Atome)),
            global_enums::PaymentMethodType::Boleto => Ok(dirval!(VoucherType = Boleto)),
            global_enums::PaymentMethodType::Efecty => Ok(dirval!(VoucherType = Efecty)),
            global_enums::PaymentMethodType::PagoEfectivo => {
                Ok(dirval!(VoucherType = PagoEfectivo))
            }
            global_enums::PaymentMethodType::RedCompra => Ok(dirval!(VoucherType = RedCompra)),
            global_enums::PaymentMethodType::RedPagos => Ok(dirval!(VoucherType = RedPagos)),
            global_enums::PaymentMethodType::Alfamart => Ok(dirval!(VoucherType = Alfamart)),
            global_enums::PaymentMethodType::BcaBankTransfer => {
                Ok(dirval!(BankTransferType = BcaBankTransfer))
            }
            global_enums::PaymentMethodType::BniVa => Ok(dirval!(BankTransferType = BniVa)),
            global_enums::PaymentMethodType::BriVa => Ok(dirval!(BankTransferType = BriVa)),
            global_enums::PaymentMethodType::CimbVa => Ok(dirval!(BankTransferType = CimbVa)),
            global_enums::PaymentMethodType::DanamonVa => Ok(dirval!(BankTransferType = DanamonVa)),
            global_enums::PaymentMethodType::Indomaret => Ok(dirval!(VoucherType = Indomaret)),
            global_enums::PaymentMethodType::MandiriVa => Ok(dirval!(BankTransferType = MandiriVa)),
            global_enums::PaymentMethodType::LocalBankTransfer => {
                Ok(dirval!(BankTransferType = LocalBankTransfer))
            }
            global_enums::PaymentMethodType::InstantBankTransfer => {
                Ok(dirval!(BankTransferType = InstantBankTransfer))
            }
            global_enums::PaymentMethodType::InstantBankTransferFinland => {
                Ok(dirval!(BankTransferType = InstantBankTransferFinland))
            }
            global_enums::PaymentMethodType::InstantBankTransferPoland => {
                Ok(dirval!(BankTransferType = InstantBankTransferPoland))
            }
            global_enums::PaymentMethodType::PermataBankTransfer => {
                Ok(dirval!(BankTransferType = PermataBankTransfer))
            }
            global_enums::PaymentMethodType::PaySafeCard => Ok(dirval!(GiftCardType = PaySafeCard)),
            global_enums::PaymentMethodType::SevenEleven => Ok(dirval!(VoucherType = SevenEleven)),
            global_enums::PaymentMethodType::Lawson => Ok(dirval!(VoucherType = Lawson)),
            global_enums::PaymentMethodType::MiniStop => Ok(dirval!(VoucherType = MiniStop)),
            global_enums::PaymentMethodType::FamilyMart => Ok(dirval!(VoucherType = FamilyMart)),
            global_enums::PaymentMethodType::Seicomart => Ok(dirval!(VoucherType = Seicomart)),
            global_enums::PaymentMethodType::PayEasy => Ok(dirval!(VoucherType = PayEasy)),
            global_enums::PaymentMethodType::Givex => Ok(dirval!(GiftCardType = Givex)),
            global_enums::PaymentMethodType::Benefit => Ok(dirval!(CardRedirectType = Benefit)),
            global_enums::PaymentMethodType::Knet => Ok(dirval!(CardRedirectType = Knet)),
            global_enums::PaymentMethodType::OpenBankingUk => {
                Ok(dirval!(BankRedirectType = OpenBankingUk))
            }
            global_enums::PaymentMethodType::MomoAtm => Ok(dirval!(CardRedirectType = MomoAtm)),
            global_enums::PaymentMethodType::Oxxo => Ok(dirval!(VoucherType = Oxxo)),
            global_enums::PaymentMethodType::CardRedirect => {
                Ok(dirval!(CardRedirectType = CardRedirect))
            }
            global_enums::PaymentMethodType::Venmo => Ok(dirval!(WalletType = Venmo)),
            global_enums::PaymentMethodType::Mifinity => Ok(dirval!(WalletType = Mifinity)),
            global_enums::PaymentMethodType::OpenBankingPIS => {
                Ok(dirval!(OpenBankingType = OpenBankingPIS))
            }
            global_enums::PaymentMethodType::Paze => Ok(dirval!(WalletType = Paze)),
            global_enums::PaymentMethodType::DirectCarrierBilling => {
                Ok(dirval!(MobilePaymentType = DirectCarrierBilling))
            }
            global_enums::PaymentMethodType::Eft => Ok(dirval!(BankRedirectType = Eft)),
            global_enums::PaymentMethodType::IndonesianBankTransfer => {
                Ok(dirval!(BankTransferType = IndonesianBankTransfer))
            }
            global_enums::PaymentMethodType::BhnCardNetwork => {
                Ok(dirval!(GiftCardType = BhnCardNetwork))
            }
        }
    }
}


// Function: new
// File: crates/external_services/src/grpc_client.rs
// Module: external_services

// Documentation: constructor for LineageIds

pub fn new(merchant_id: id_type::MerchantId, profile_id: id_type::ProfileId) -> Self


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

pub struct GetDataMessage


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

impl GetPaymentMethodType for for RealTimePaymentData


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

pub struct FiservResponseActions


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

pub struct ClientRiskInformationRules


// Struct: OutgoingWebhookLogsRequest
// File: crates/api_models/src/analytics/outgoing_webhook_event.rs
// Module: api_models
// Implementations: 0

pub struct OutgoingWebhookLogsRequest


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

pub fn new() -> &'static Self


// Module Structure
// File: crates/external_services/src/grpc_client/dynamic_routing.rs
// Module: external_services

// Public submodules:
pub mod contract_routing_client;
pub mod elimination_based_client;
pub mod success_rate_client;

// Public exports:
pub use contract_routing_client::ContractScoreCalculatorClient;
pub use elimination_based_client::EliminationAnalyserClient;
pub use success_rate_client::SuccessRateCalculatorClient;


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

pub struct ProcessorResponse


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

pub struct FiservSessionObject


// Struct: RefundsLedger
// File: crates/hyperswitch_connectors/src/connectors/payload/responses.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct RefundsLedger


// Function: fetch_forex_rates_from_fallback_api
// File: crates/router/src/utils/currency.rs
// Module: router

pub fn fetch_forex_rates_from_fallback_api(
    state: &SessionState,
) -> CustomResult<FxExchangeRatesCacheEntry, ForexError>


// Struct: NoonActionTransaction
// File: crates/hyperswitch_connectors/src/connectors/noon/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NoonActionTransaction


// Function: health
// File: crates/router/src/routes/health.rs
// Module: router

pub fn health() -> impl actix_web::Responder


// File: crates/kgraph_utils/src/lib.rs
// Module: kgraph_utils

pub mod error;
pub mod mca;
pub mod transformers;
pub mod types;


// File: crates/router/tests/connectors/nordea.rs
// Module: router

use masking::Secret;
use router::types::{self, api, domain, storage::enums};
use test_utils::connector_auth;

use crate::utils::{self, ConnectorActions};

#[derive(Clone, Copy)]
struct NordeaTest;
impl ConnectorActions for NordeaTest {}
impl utils::Connector for NordeaTest {
    fn get_data(&self) -> api::ConnectorData {
        use router::connector::Nordea;
        utils::construct_connector_data_old(
            Box::new(Nordea::new()),
            types::Connector::DummyConnector1,
            api::GetToken::Connector,
            None,
        )
    }

    fn get_auth_token(&self) -> types::ConnectorAuthType {
        utils::to_connector_auth_type(
            connector_auth::ConnectorAuthentication::new()
                .nordea
                .expect("Missing connector authentication configuration")
                .into(),
        )
    }

    fn get_name(&self) -> String {
        "nordea".to_string()
    }
}

static CONNECTOR: NordeaTest = NordeaTest {};

fn get_default_payment_info() -> Option<utils::PaymentInfo> {
    None
}

fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    None
}

// Cards Positive Tests
// Creates a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_only_authorize_payment() {
    let response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized);
}

// Captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info())
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Partially captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(
            payment_method_details(),
            Some(types::PaymentsCaptureData {
                amount_to_capture: 50,
                ..utils::PaymentCaptureType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_authorized_payment() {
    let authorize_response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Authorized,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("PSync response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
}

// Voids a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_void_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_void_payment(
            payment_method_details(),
            Some(types::PaymentsCancelData {
                connector_transaction_id: String::from(""),
                cancellation_reason: Some("requested_by_customer".to_string()),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Void payment response");
    assert_eq!(response.status, enums::AttemptStatus::Voided);
}

// Refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Synchronizes a refund using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_manually_captured_refund() {
    let refund_response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_make_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_auto_captured_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Charged,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                capture_method: Some(enums::CaptureMethod::Automatic),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(response.status, enums::AttemptStatus::Charged,);
}

// Refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_auto_captured_payment() {
    let response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_succeeded_payment() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        refund_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_succeeded_payment_multiple_times() {
    CONNECTOR
        .make_payment_and_multiple_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await;
}

// Synchronizes a refund using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_refund() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Cards Negative scenarios
// Creates a payment with incorrect CVC.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_cvc: Secret::new("12345".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's security code is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry month.
#[actix_web::test]
async fn should_fail_payment_for_invalid_exp_month() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_exp_month: Secret::new("20".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration month is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry year.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_expiry_year() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_exp_year: Secret::new("2000".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration year is invalid.".to_string(),
    );
}

// Voids a payment using automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_fail_void_payment_for_auto_capture() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let void_response = CONNECTOR
        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        void_response.response.unwrap_err().message,
        "You cannot cancel this PaymentIntent because it has a status of succeeded."
    );
}

// Captures a payment using invalid connector payment id.
#[actix_web::test]
async fn should_fail_capture_for_invalid_payment() {
    let capture_response = CONNECTOR
        .capture_payment("123456789".to_string(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        capture_response.response.unwrap_err().message,
        String::from("No such payment_intent: '123456789'")
    );
}

// Refunds a payment with refund amount higher than payment amount.
#[actix_web::test]
async fn should_fail_for_refund_amount_higher_than_payment_amount() {
    let response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 150,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Refund amount (₹1.50) is greater than charge amount (₹1.00)",
    );
}

// Connector dependent test cases goes here

// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests


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

impl UserNew


// File: crates/router/tests/connectors/plaid.rs
// Module: router

use masking::Secret;
use router::types::{self, api, domain, storage::enums};
use test_utils::connector_auth;

use crate::utils::{self, Connector, ConnectorActions};

#[derive(Clone, Copy)]
struct PlaidTest;
impl ConnectorActions for PlaidTest {}

static CONNECTOR: PlaidTest = PlaidTest {};

impl Connector for PlaidTest {
    fn get_data(&self) -> api::ConnectorData {
        use router::connector::Plaid;
        utils::construct_connector_data_old(
            Box::new(Plaid::new()),
            types::Connector::Plaid,
            api::GetToken::Connector,
            None,
        )
    }

    fn get_auth_token(&self) -> types::ConnectorAuthType {
        utils::to_connector_auth_type(
            connector_auth::ConnectorAuthentication::new()
                .plaid
                .expect("Missing connector authentication configuration")
                .into(),
        )
    }

    fn get_name(&self) -> String {
        "plaid".to_string()
    }
}

fn get_default_payment_info() -> Option<utils::PaymentInfo> {
    None
}

fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    None
}

// Cards Positive Tests
// Creates a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_only_authorize_payment() {
    let response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized);
}

// Captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info())
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Partially captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(
            payment_method_details(),
            Some(types::PaymentsCaptureData {
                amount_to_capture: 50,
                ..utils::PaymentCaptureType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_authorized_payment() {
    let authorize_response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Authorized,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("PSync response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
}

// Voids a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_void_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_void_payment(
            payment_method_details(),
            Some(types::PaymentsCancelData {
                connector_transaction_id: String::from(""),
                cancellation_reason: Some("requested_by_customer".to_string()),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Void payment response");
    assert_eq!(response.status, enums::AttemptStatus::Voided);
}

// Refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Synchronizes a refund using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_manually_captured_refund() {
    let refund_response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_make_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_auto_captured_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Charged,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                capture_method: Some(enums::CaptureMethod::Automatic),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(response.status, enums::AttemptStatus::Charged,);
}

// Refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_auto_captured_payment() {
    let response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_succeeded_payment() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        refund_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_succeeded_payment_multiple_times() {
    CONNECTOR
        .make_payment_and_multiple_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await;
}

// Synchronizes a refund using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_refund() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Cards Negative scenarios
// Creates a payment with incorrect CVC.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_cvc: Secret::new("12345".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Invalid card cvc.".to_string(),
    );
}

// Creates a payment with incorrect expiry month.
#[actix_web::test]
async fn should_fail_payment_for_invalid_exp_month() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_exp_month: Secret::new("20".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration month is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry year.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_expiry_year() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_exp_year: Secret::new("2000".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration year is invalid.".to_string(),
    );
}

// Voids a payment using automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_fail_void_payment_for_auto_capture() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let void_response = CONNECTOR
        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        void_response.response.unwrap_err().message,
        "You cannot cancel this PaymentIntent because it has a status of succeeded."
    );
}

// Captures a payment using invalid connector payment id.
#[actix_web::test]
async fn should_fail_capture_for_invalid_payment() {
    let capture_response = CONNECTOR
        .capture_payment("123456789".to_string(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        capture_response.response.unwrap_err().message,
        String::from("No such payment_intent: '123456789'")
    );
}

// Refunds a payment with refund amount higher than payment amount.
#[actix_web::test]
async fn should_fail_for_refund_amount_higher_than_payment_amount() {
    let response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 150,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Refund amount (₹1.50) is greater than charge amount (₹1.00)",
    );
}

// Connector dependent test cases goes here

// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests


// Struct: PaymentMetricsBucketIdentifier
// File: crates/api_models/src/analytics/payments.rs
// Module: api_models
// Implementations: 3
// Traits: Hash, PartialEq

pub struct PaymentMetricsBucketIdentifier


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

pub fn new(gateway_name: String, gateway_id: Option<String>) -> Self


// Function: get_totp_attempts_from_redis
// File: crates/router/src/utils/user/two_factor_auth.rs
// Module: router

pub fn get_totp_attempts_from_redis(state: &SessionState, user_id: &str) -> UserResult<u8>


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

impl ConnectorSpecifications for for Paybox


// Implementation: impl auth_service::PaymentInitiation for for Plaid
// File: crates/pm_auth/src/connector/plaid.rs
// Module: pm_auth
// Methods: 0 total (0 public)

impl auth_service::PaymentInitiation for for Plaid


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

// Public submodules:
pub mod transformers;


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

impl ConnectorSpecifications for for Zsl


// Implementation: impl Default for for PayoutsUpdateInternal
// File: crates/diesel_models/src/payouts.rs
// Module: diesel_models
// Methods: 1 total (0 public)

impl Default for for PayoutsUpdateInternal


// Struct: Program
// File: crates/euclid/src/frontend/ast.rs
// Module: euclid
// Implementations: 0

pub struct Program<O>


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

// Public submodules:
pub mod transformers;


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

impl api::ExternalVaultInsert for for Vgs


// Struct: PaymentAttemptNew
// File: crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct PaymentAttemptNew


// Function: get_merchant_scoped_metadata_from_db
// File: crates/router/src/utils/user/dashboard_metadata.rs
// Module: router

pub fn get_merchant_scoped_metadata_from_db(
    state: &SessionState,
    merchant_id: id_type::MerchantId,
    org_id: id_type::OrganizationId,
    metadata_keys: Vec<DBEnum>,
) -> UserResult<Vec<DashboardMetadata>>


// File: crates/router/src/types/api/fraud_check.rs
// Module: router
// Public functions: 1
// Public structs: 2

use std::str::FromStr;

use api_models::enums;
use common_utils::errors::CustomResult;
use error_stack::ResultExt;
pub use hyperswitch_domain_models::router_flow_types::fraud_check::{
    Checkout, Fulfillment, RecordReturn, Sale, Transaction,
};
pub use hyperswitch_interfaces::api::fraud_check::{
    FraudCheckCheckout, FraudCheckFulfillment, FraudCheckRecordReturn, FraudCheckSale,
    FraudCheckTransaction,
};

pub use super::fraud_check_v2::{
    FraudCheckCheckoutV2, FraudCheckFulfillmentV2, FraudCheckRecordReturnV2, FraudCheckSaleV2,
    FraudCheckTransactionV2, FraudCheckV2,
};
use super::{ConnectorData, SessionConnectorDatas};
use crate::{
    connector,
    core::{errors, payments::ActionType},
    services::connector_integration_interface::ConnectorEnum,
};

#[derive(Clone)]
pub struct FraudCheckConnectorData {
    pub connector: ConnectorEnum,
    pub connector_name: enums::FrmConnectors,
}
pub enum ConnectorCallType {
    PreDetermined(ConnectorRoutingData),
    Retryable(Vec<ConnectorRoutingData>),
    SessionMultiple(SessionConnectorDatas),
}

#[derive(Clone)]
pub struct ConnectorRoutingData {
    pub connector_data: ConnectorData,
    pub network: Option<common_enums::CardNetwork>,
    // action_type is used for mandates currently
    pub action_type: Option<ActionType>,
}

impl FraudCheckConnectorData {
    pub fn get_connector_by_name(name: &str) -> CustomResult<Self, errors::ApiErrorResponse> {
        let connector_name = enums::FrmConnectors::from_str(name)
            .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven)
            .attach_printable_lazy(|| {
                format!("unable to parse connector: {:?}", name.to_string())
            })?;
        let connector = Self::convert_connector(connector_name)?;
        Ok(Self {
            connector,
            connector_name,
        })
    }

    fn convert_connector(
        connector_name: enums::FrmConnectors,
    ) -> CustomResult<ConnectorEnum, errors::ApiErrorResponse> {
        match connector_name {
            enums::FrmConnectors::Signifyd => {
                Ok(ConnectorEnum::Old(Box::new(&connector::Signifyd)))
            }
            enums::FrmConnectors::Riskified => {
                Ok(ConnectorEnum::Old(Box::new(connector::Riskified::new())))
            }
        }
    }
}


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

impl api::Payment for for Dwolla


// Implementation: impl api::PayoutSync for for Paypal
// File: crates/hyperswitch_connectors/src/connectors/paypal.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PayoutSync for for Paypal


// File: crates/api_models/src/external_service_auth.rs
// Module: api_models
// Public functions: 1
// Public structs: 3

use common_utils::{id_type, pii};
use masking::Secret;

#[derive(Debug, serde::Serialize)]
pub struct ExternalTokenResponse {
    pub token: Secret<String>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ExternalVerifyTokenRequest {
    pub token: Secret<String>,
}

#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ExternalSignoutTokenRequest {
    pub token: Secret<String>,
}

#[derive(serde::Serialize, Debug)]
#[serde(untagged)]
pub enum ExternalVerifyTokenResponse {
    Hypersense {
        user_id: String,
        merchant_id: id_type::MerchantId,
        name: Secret<String>,
        email: pii::Email,
    },
}

impl ExternalVerifyTokenResponse {
    pub fn get_user_id(&self) -> &str {
        match self {
            Self::Hypersense { user_id, .. } => user_id,
        }
    }
}


// Struct: Paybox
// File: crates/hyperswitch_connectors/src/connectors/paybox.rs
// Module: hyperswitch_connectors
// Implementations: 19
// 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, api::PaymentsCompleteAuthorize, ConnectorCommon, ConnectorValidation, IncomingWebhook, ConnectorRedirectResponse, ConnectorSpecifications

pub struct Paybox

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


// Implementation: impl prost::Message for for StrongSecret
// File: crates/masking/src/strong_secret.rs
// Module: masking
// Methods: 4 total (0 public)

impl prost::Message for for StrongSecret


// Function: get_gsm_rule
// File: crates/router/src/routes/gsm.rs
// Module: router

pub fn get_gsm_rule(
    state: web::Data<AppState>,
    req: HttpRequest,
    json_payload: web::Json<gsm_api_types::GsmRetrieveRequest>,
) -> impl Responder


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

impl Responder


// Struct: PaymentAdditionalData
// File: crates/router/src/core/payments/transformers.rs
// Module: router
// Implementations: 0

pub struct PaymentAdditionalData<'a, F>


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

pub struct PaymentMethodDataWalletInfo


// Function: create_customer_on_connector
// File: crates/router/src/core/subscription.rs
// Module: router

pub fn create_customer_on_connector(
        &self,
        state: &SessionState,
    ) -> errors::RouterResult<ConnectorCustomerResponseData>


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

impl api::Payment for for Paybox


// Implementation: impl api::PayoutFulfill for for Nomupay
// File: crates/hyperswitch_connectors/src/connectors/nomupay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PayoutFulfill for for Nomupay


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

pub struct RefundResponse


// Struct: StripeBillingCardDetails
// File: crates/hyperswitch_connectors/src/connectors/stripebilling/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct StripeBillingCardDetails


// Function: set_payment_method
// File: crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs
// Module: router

pub fn set_payment_method(
        self,
        payment_method: &'a domain::PaymentMethod,
    ) -> NetworkTokenizationBuilder<'a, PmTokenUpdated>


// Implementation: impl crate::events::ApiEventMetric for for GlobalPaymentMethodId
// File: crates/common_utils/src/id_type/global_id/payment_methods.rs
// Module: common_utils
// Methods: 1 total (0 public)

impl crate::events::ApiEventMetric for for GlobalPaymentMethodId


// Function: extract_data_and_perform_action
// File: crates/router/src/workflows/revenue_recovery.rs
// Module: router

pub fn extract_data_and_perform_action(
    state: &SessionState,
    tracking_data: &pcr_storage_types::RevenueRecoveryWorkflowTrackingData,
) -> Result<pcr_storage_types::RevenueRecoveryPaymentData, errors::ProcessTrackerError>


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

pub struct PaypalWebhooksPurchaseUnits


// Implementation: impl SdkEventMetricAccumulator for for AverageAccumulator
// File: crates/analytics/src/sdk_events/accumulator.rs
// Module: analytics
// Methods: 2 total (0 public)

impl SdkEventMetricAccumulator for for AverageAccumulator


// Implementation: impl AuthEventMetricAccumulator for for AuthenticationErrorMessageAccumulator
// File: crates/analytics/src/auth_events/accumulator.rs
// Module: analytics
// Methods: 2 total (0 public)

impl AuthEventMetricAccumulator for for AuthenticationErrorMessageAccumulator


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

impl api::PayoutRecipient for for Wise


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

impl ApiEventMetric for for AuthenticationCreateRequest


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

impl ConnectorPostAuthentication for for Threedsecureio


// Struct: ApplepayHeader
// File: crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ApplepayHeader


// File: crates/router/tests/connectors/loonio.rs
// Module: router

use hyperswitch_domain_models::payment_method_data::{Card, PaymentMethodData};
use masking::Secret;
use router::types::{self, api, storage::enums};
use test_utils::connector_auth;

use crate::utils::{self, ConnectorActions};

#[derive(Clone, Copy)]
struct LoonioTest;
impl ConnectorActions for LoonioTest {}
impl utils::Connector for LoonioTest {
    fn get_data(&self) -> api::ConnectorData {
        use router::connector::Loonio;
        utils::construct_connector_data_old(
            Box::new(Loonio::new()),
            types::Connector::Plaid,
            api::GetToken::Connector,
            None,
        )
    }

    fn get_auth_token(&self) -> types::ConnectorAuthType {
        utils::to_connector_auth_type(
            connector_auth::ConnectorAuthentication::new()
                .loonio
                .expect("Missing connector authentication configuration")
                .into(),
        )
    }

    fn get_name(&self) -> String {
        "loonio".to_string()
    }
}

static CONNECTOR: LoonioTest = LoonioTest {};

fn get_default_payment_info() -> Option<utils::PaymentInfo> {
    None
}

fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    None
}

// Cards Positive Tests
// Creates a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_only_authorize_payment() {
    let response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized);
}

// Captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info())
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Partially captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(
            payment_method_details(),
            Some(types::PaymentsCaptureData {
                amount_to_capture: 50,
                ..utils::PaymentCaptureType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_authorized_payment() {
    let authorize_response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Authorized,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("PSync response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
}

// Voids a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_void_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_void_payment(
            payment_method_details(),
            Some(types::PaymentsCancelData {
                connector_transaction_id: String::from(""),
                cancellation_reason: Some("requested_by_customer".to_string()),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Void payment response");
    assert_eq!(response.status, enums::AttemptStatus::Voided);
}

// Refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Synchronizes a refund using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_manually_captured_refund() {
    let refund_response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_make_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_auto_captured_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Charged,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                capture_method: Some(enums::CaptureMethod::Automatic),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(response.status, enums::AttemptStatus::Charged,);
}

// Refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_auto_captured_payment() {
    let response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_succeeded_payment() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        refund_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_succeeded_payment_multiple_times() {
    CONNECTOR
        .make_payment_and_multiple_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await;
}

// Synchronizes a refund using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_refund() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Cards Negative scenarios
// Creates a payment with incorrect CVC.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_cvc: Secret::new("12345".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's security code is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry month.
#[actix_web::test]
async fn should_fail_payment_for_invalid_exp_month() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_exp_month: Secret::new("20".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration month is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry year.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_expiry_year() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_exp_year: Secret::new("2000".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration year is invalid.".to_string(),
    );
}

// Voids a payment using automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_fail_void_payment_for_auto_capture() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let void_response = CONNECTOR
        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        void_response.response.unwrap_err().message,
        "You cannot cancel this PaymentIntent because it has a status of succeeded."
    );
}

// Captures a payment using invalid connector payment id.
#[actix_web::test]
async fn should_fail_capture_for_invalid_payment() {
    let capture_response = CONNECTOR
        .capture_payment("123456789".to_string(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        capture_response.response.unwrap_err().message,
        String::from("No such payment_intent: '123456789'")
    );
}

// Refunds a payment with refund amount higher than payment amount.
#[actix_web::test]
async fn should_fail_for_refund_amount_higher_than_payment_amount() {
    let response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 150,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Refund amount (₹1.50) is greater than charge amount (₹1.00)",
    );
}

// Connector dependent test cases goes here

// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests


// Function: is_step_up_possible
// File: crates/common_types/src/domain.rs
// Module: common_types

// Documentation: Checks if step-up retry is possible.

pub fn is_step_up_possible(&self) -> bool


// File: crates/payment_methods/src/controller.rs
// Module: payment_methods
// Public functions: 1
// Public structs: 1

use std::fmt::Debug;

#[cfg(feature = "payouts")]
use api_models::payouts;
use api_models::{enums as api_enums, payment_methods as api};
#[cfg(feature = "v1")]
use common_enums::enums as common_enums;
#[cfg(feature = "v2")]
use common_utils::encryption;
use common_utils::{crypto, ext_traits, id_type, type_name, types::keymanager};
use error_stack::ResultExt;
#[cfg(feature = "v1")]
use hyperswitch_domain_models::payment_methods::PaymentMethodVaultSourceDetails;
use hyperswitch_domain_models::{merchant_key_store, payment_methods, type_encryption};
use masking::{PeekInterface, Secret};
#[cfg(feature = "v1")]
use scheduler::errors as sch_errors;
use serde::{Deserialize, Serialize};
use storage_impl::{errors as storage_errors, payment_method};

use crate::core::errors;

#[derive(Debug, Deserialize, Serialize)]
pub struct DeleteCardResp {
    pub status: String,
    pub error_message: Option<String>,
    pub error_code: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum DataDuplicationCheck {
    Duplicated,
    MetaDataChanged,
}

#[async_trait::async_trait]
pub trait PaymentMethodsController {
    #[cfg(feature = "v1")]
    #[allow(clippy::too_many_arguments)]
    async fn create_payment_method(
        &self,
        req: &api::PaymentMethodCreate,
        customer_id: &id_type::CustomerId,
        payment_method_id: &str,
        locker_id: Option<String>,
        merchant_id: &id_type::MerchantId,
        pm_metadata: Option<serde_json::Value>,
        customer_acceptance: Option<serde_json::Value>,
        payment_method_data: crypto::OptionalEncryptableValue,
        connector_mandate_details: Option<serde_json::Value>,
        status: Option<common_enums::PaymentMethodStatus>,
        network_transaction_id: Option<String>,
        payment_method_billing_address: crypto::OptionalEncryptableValue,
        card_scheme: Option<String>,
        network_token_requestor_reference_id: Option<String>,
        network_token_locker_id: Option<String>,
        network_token_payment_method_data: crypto::OptionalEncryptableValue,
        vault_source_details: Option<PaymentMethodVaultSourceDetails>,
    ) -> errors::PmResult<payment_methods::PaymentMethod>;

    #[cfg(feature = "v1")]
    #[allow(clippy::too_many_arguments)]
    async fn insert_payment_method(
        &self,
        resp: &api::PaymentMethodResponse,
        req: &api::PaymentMethodCreate,
        key_store: &merchant_key_store::MerchantKeyStore,
        merchant_id: &id_type::MerchantId,
        customer_id: &id_type::CustomerId,
        pm_metadata: Option<serde_json::Value>,
        customer_acceptance: Option<serde_json::Value>,
        locker_id: Option<String>,
        connector_mandate_details: Option<serde_json::Value>,
        network_transaction_id: Option<String>,
        payment_method_billing_address: crypto::OptionalEncryptableValue,
        network_token_requestor_reference_id: Option<String>,
        network_token_locker_id: Option<String>,
        network_token_payment_method_data: crypto::OptionalEncryptableValue,
        vault_source_details: Option<PaymentMethodVaultSourceDetails>,
    ) -> errors::PmResult<payment_methods::PaymentMethod>;

    #[cfg(feature = "v2")]
    #[allow(clippy::too_many_arguments)]
    async fn insert_payment_method(
        &self,
        resp: &api::PaymentMethodResponse,
        req: &api::PaymentMethodCreate,
        key_store: &merchant_key_store::MerchantKeyStore,
        merchant_id: &id_type::MerchantId,
        customer_id: &id_type::CustomerId,
        pm_metadata: Option<serde_json::Value>,
        customer_acceptance: Option<serde_json::Value>,
        locker_id: Option<String>,
        connector_mandate_details: Option<serde_json::Value>,
        network_transaction_id: Option<String>,
        payment_method_billing_address: Option<encryption::Encryption>,
    ) -> errors::PmResult<payment_methods::PaymentMethod>;

    #[cfg(feature = "v1")]
    async fn add_payment_method(
        &self,
        req: &api::PaymentMethodCreate,
    ) -> errors::PmResponse<api::PaymentMethodResponse>;

    #[cfg(feature = "v1")]
    async fn retrieve_payment_method(
        &self,
        pm: api::PaymentMethodId,
    ) -> errors::PmResponse<api::PaymentMethodResponse>;

    #[cfg(feature = "v1")]
    async fn delete_payment_method(
        &self,
        pm_id: api::PaymentMethodId,
    ) -> errors::PmResponse<api::PaymentMethodDeleteResponse>;

    async fn add_card_hs(
        &self,
        req: api::PaymentMethodCreate,
        card: &api::CardDetail,
        customer_id: &id_type::CustomerId,
        locker_choice: api_enums::LockerChoice,
        card_reference: Option<&str>,
    ) -> errors::VaultResult<(api::PaymentMethodResponse, Option<DataDuplicationCheck>)>;

    /// The response will be the tuple of PaymentMethodResponse and the duplication check of payment_method
    async fn add_card_to_locker(
        &self,
        req: api::PaymentMethodCreate,
        card: &api::CardDetail,
        customer_id: &id_type::CustomerId,
        card_reference: Option<&str>,
    ) -> errors::VaultResult<(api::PaymentMethodResponse, Option<DataDuplicationCheck>)>;

    #[cfg(feature = "payouts")]
    async fn add_bank_to_locker(
        &self,
        req: api::PaymentMethodCreate,
        key_store: &merchant_key_store::MerchantKeyStore,
        bank: &payouts::Bank,
        customer_id: &id_type::CustomerId,
    ) -> errors::VaultResult<(api::PaymentMethodResponse, Option<DataDuplicationCheck>)>;

    #[cfg(feature = "v1")]
    async fn get_or_insert_payment_method(
        &self,
        req: api::PaymentMethodCreate,
        resp: &mut api::PaymentMethodResponse,
        customer_id: &id_type::CustomerId,
        key_store: &merchant_key_store::MerchantKeyStore,
    ) -> errors::PmResult<payment_methods::PaymentMethod>;

    #[cfg(feature = "v2")]
    async fn get_or_insert_payment_method(
        &self,
        _req: api::PaymentMethodCreate,
        _resp: &mut api::PaymentMethodResponse,
        _customer_id: &id_type::CustomerId,
        _key_store: &merchant_key_store::MerchantKeyStore,
    ) -> errors::PmResult<payment_methods::PaymentMethod> {
        todo!()
    }

    #[cfg(feature = "v1")]
    async fn get_card_details_with_locker_fallback(
        &self,
        pm: &payment_methods::PaymentMethod,
    ) -> errors::PmResult<Option<api::CardDetailFromLocker>>;

    #[cfg(feature = "v1")]
    async fn get_card_details_without_locker_fallback(
        &self,
        pm: &payment_methods::PaymentMethod,
    ) -> errors::PmResult<api::CardDetailFromLocker>;

    async fn delete_card_from_locker(
        &self,
        customer_id: &id_type::CustomerId,
        merchant_id: &id_type::MerchantId,
        card_reference: &str,
    ) -> errors::PmResult<DeleteCardResp>;

    #[cfg(feature = "v1")]
    fn store_default_payment_method(
        &self,
        req: &api::PaymentMethodCreate,
        customer_id: &id_type::CustomerId,
        merchant_id: &id_type::MerchantId,
    ) -> (api::PaymentMethodResponse, Option<DataDuplicationCheck>);

    #[cfg(feature = "v2")]
    fn store_default_payment_method(
        &self,
        req: &api::PaymentMethodCreate,
        customer_id: &id_type::CustomerId,
        merchant_id: &id_type::MerchantId,
    ) -> (api::PaymentMethodResponse, Option<DataDuplicationCheck>);

    #[cfg(feature = "v1")]
    #[allow(clippy::too_many_arguments)]
    async fn save_network_token_and_update_payment_method(
        &self,
        req: &api::PaymentMethodMigrate,
        key_store: &merchant_key_store::MerchantKeyStore,
        network_token_data: &api_models::payment_methods::MigrateNetworkTokenData,
        network_token_requestor_ref_id: String,
        pm_id: String,
    ) -> errors::PmResult<bool>;

    #[cfg(feature = "v1")]
    async fn set_default_payment_method(
        &self,
        merchant_id: &id_type::MerchantId,
        customer_id: &id_type::CustomerId,
        payment_method_id: String,
    ) -> errors::PmResponse<api_models::payment_methods::CustomerDefaultPaymentMethodResponse>;

    #[cfg(feature = "v1")]
    async fn add_payment_method_status_update_task(
        &self,
        payment_method: &payment_methods::PaymentMethod,
        prev_status: common_enums::PaymentMethodStatus,
        curr_status: common_enums::PaymentMethodStatus,
        merchant_id: &id_type::MerchantId,
    ) -> Result<(), sch_errors::ProcessTrackerError>;

    #[cfg(feature = "v1")]
    async fn validate_merchant_connector_ids_in_connector_mandate_details(
        &self,
        key_store: &merchant_key_store::MerchantKeyStore,
        connector_mandate_details: &api_models::payment_methods::CommonMandateReference,
        merchant_id: &id_type::MerchantId,
        card_network: Option<common_enums::CardNetwork>,
    ) -> errors::PmResult<()>;

    #[cfg(feature = "v1")]
    async fn get_card_details_from_locker(
        &self,
        pm: &payment_methods::PaymentMethod,
    ) -> errors::PmResult<api::CardDetailFromLocker>;
}

pub async fn create_encrypted_data<T>(
    key_manager_state: &keymanager::KeyManagerState,
    key_store: &merchant_key_store::MerchantKeyStore,
    data: T,
) -> Result<
    crypto::Encryptable<Secret<serde_json::Value>>,
    error_stack::Report<storage_errors::StorageError>,
>
where
    T: Debug + Serialize,
{
    let key = key_store.key.get_inner().peek();
    let identifier = keymanager::Identifier::Merchant(key_store.merchant_id.clone());

    let encoded_data = ext_traits::Encode::encode_to_value(&data)
        .change_context(storage_errors::StorageError::SerializationFailed)
        .attach_printable("Unable to encode data")?;

    let secret_data = Secret::<_, masking::WithType>::new(encoded_data);

    let encrypted_data = type_encryption::crypto_operation(
        key_manager_state,
        type_name!(payment_method::PaymentMethod),
        type_encryption::CryptoOperation::Encrypt(secret_data),
        identifier.clone(),
        key,
    )
    .await
    .and_then(|val| val.try_into_operation())
    .change_context(storage_errors::StorageError::EncryptionError)
    .attach_printable("Unable to encrypt data")?;

    Ok(encrypted_data)
}


// Function: find_user_scoped_dashboard_metadata
// File: crates/diesel_models/src/query/dashboard_metadata.rs
// Module: diesel_models

pub fn find_user_scoped_dashboard_metadata(
        conn: &PgPooledConn,
        user_id: String,
        merchant_id: id_type::MerchantId,
        org_id: id_type::OrganizationId,
        data_types: Vec<enums::DashboardMetadata>,
    ) -> StorageResult<Vec<Self>>


// Function: wrap
// File: crates/common_utils/src/id_type/merchant_connector_account.rs
// Module: common_utils

// Documentation: Get a merchant connector account id from String

pub fn wrap(merchant_connector_account_id: String) -> CustomResult<Self, ValidationError>


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

impl api::RefundExecute for for Aci


// Module Structure
// File: crates/hyperswitch_domain_models/src/router_data_v2.rs
// Module: hyperswitch_domain_models

// Public submodules:
pub mod flow_common_types;

// Public exports:
pub use flow_common_types::FrmFlowData;
pub use flow_common_types::PayoutFlowData;
pub use flow_common_types::{
    AccessTokenFlowData, AuthenticationTokenFlowData, DisputesFlowData,
    ExternalAuthenticationFlowData, ExternalVaultProxyFlowData, FilesFlowData,
    MandateRevokeFlowData, PaymentFlowData, RefundFlowData, UasFlowData, VaultConnectorFlowData,
    WebhookSourceVerifyData,
};


// Function: unlink_routing_config
// File: crates/router/src/core/routing.rs
// Module: router

pub fn unlink_routing_config(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    request: routing_types::RoutingConfigRequest,
    authentication_profile_id: Option<common_utils::id_type::ProfileId>,
    transaction_type: enums::TransactionType,
) -> RouterResponse<routing_types::RoutingDictionaryRecord>


// File: crates/router/src/core/connector_onboarding.rs
// Module: router
// Public functions: 3

use api_models::{connector_onboarding as api, enums};
use masking::Secret;

use crate::{
    core::errors::{ApiErrorResponse, RouterResponse, RouterResult},
    routes::app::ReqState,
    services::{authentication as auth, ApplicationResponse},
    types as oss_types,
    utils::connector_onboarding as utils,
    SessionState,
};

pub mod paypal;

#[async_trait::async_trait]
pub trait AccessToken {
    async fn access_token(state: &SessionState) -> RouterResult<oss_types::AccessToken>;
}

pub async fn get_action_url(
    state: SessionState,
    user_from_token: auth::UserFromToken,
    request: api::ActionUrlRequest,
    _req_state: ReqState,
) -> RouterResponse<api::ActionUrlResponse> {
    utils::check_if_connector_exists(&state, &request.connector_id, &user_from_token.merchant_id)
        .await?;

    let connector_onboarding_conf = state.conf.connector_onboarding.get_inner();
    let is_enabled = utils::is_enabled(request.connector, connector_onboarding_conf);
    let tracking_id =
        utils::get_tracking_id_from_configs(&state, &request.connector_id, request.connector)
            .await?;

    match (is_enabled, request.connector) {
        (Some(true), enums::Connector::Paypal) => {
            let action_url = Box::pin(paypal::get_action_url_from_paypal(
                state,
                tracking_id,
                request.return_url,
            ))
            .await?;
            Ok(ApplicationResponse::Json(api::ActionUrlResponse::PayPal(
                api::PayPalActionUrlResponse { action_url },
            )))
        }
        _ => Err(ApiErrorResponse::FlowNotSupported {
            flow: "Connector onboarding".to_string(),
            connector: request.connector.to_string(),
        }
        .into()),
    }
}

pub async fn sync_onboarding_status(
    state: SessionState,
    user_from_token: auth::UserFromToken,
    request: api::OnboardingSyncRequest,
    _req_state: ReqState,
) -> RouterResponse<api::OnboardingStatus> {
    utils::check_if_connector_exists(&state, &request.connector_id, &user_from_token.merchant_id)
        .await?;

    let connector_onboarding_conf = state.conf.connector_onboarding.get_inner();
    let is_enabled = utils::is_enabled(request.connector, connector_onboarding_conf);
    let tracking_id =
        utils::get_tracking_id_from_configs(&state, &request.connector_id, request.connector)
            .await?;

    match (is_enabled, request.connector) {
        (Some(true), enums::Connector::Paypal) => {
            let status = Box::pin(paypal::sync_merchant_onboarding_status(
                state.clone(),
                tracking_id,
            ))
            .await?;
            if let api::OnboardingStatus::PayPal(api::PayPalOnboardingStatus::Success(
                ref paypal_onboarding_data,
            )) = status
            {
                let connector_onboarding_conf = state.conf.connector_onboarding.get_inner();
                let auth_details = oss_types::ConnectorAuthType::SignatureKey {
                    api_key: connector_onboarding_conf.paypal.client_secret.clone(),
                    key1: connector_onboarding_conf.paypal.client_id.clone(),
                    api_secret: Secret::new(
                        paypal_onboarding_data.payer_id.get_string_repr().to_owned(),
                    ),
                };
                let update_mca_data = paypal::update_mca(
                    &state,
                    user_from_token.merchant_id,
                    request.connector_id.to_owned(),
                    auth_details,
                )
                .await?;

                return Ok(ApplicationResponse::Json(api::OnboardingStatus::PayPal(
                    api::PayPalOnboardingStatus::ConnectorIntegrated(Box::new(update_mca_data)),
                )));
            }
            Ok(ApplicationResponse::Json(status))
        }
        _ => Err(ApiErrorResponse::FlowNotSupported {
            flow: "Connector onboarding".to_string(),
            connector: request.connector.to_string(),
        }
        .into()),
    }
}

pub async fn reset_tracking_id(
    state: SessionState,
    user_from_token: auth::UserFromToken,
    request: api::ResetTrackingIdRequest,
    _req_state: ReqState,
) -> RouterResponse<()> {
    utils::check_if_connector_exists(&state, &request.connector_id, &user_from_token.merchant_id)
        .await?;
    utils::set_tracking_id_in_configs(&state, &request.connector_id, request.connector).await?;

    Ok(ApplicationResponse::StatusOk)
}


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

pub struct RefundFiltersResponse


// Function: get_id
// File: crates/diesel_models/src/payment_method.rs
// Module: diesel_models

pub fn get_id(&self) -> &String


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

impl ConnectorSpecifications for for Rapyd