pub async fn set_eligible_connector_for_nti_in_payment_data<F, D>(
    state: &SessionState,
    business_profile: &domain::Profile,
    key_store: &domain::MerchantKeyStore,
    payment_data: &mut D,
    connector_choice: api::ConnectorChoice,
) -> RouterResult<api::ConnectorData>
where
    F: Send + Clone,
    D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,
{
    let (mandate_reference_id, card_details_for_network_transaction_id, eligible_connector_data) =
        match connector_choice {
            api::ConnectorChoice::StraightThrough(straight_through) => {
                get_eligible_connector_for_nti(
                    state,
                    key_store,
                    payment_data,
                    core_routing::StraightThroughAlgorithmTypeSingle(straight_through),
                    business_profile,
                )
                .await?
            }
            api::ConnectorChoice::Decide => {
                get_eligible_connector_for_nti(
                    state,
                    key_store,
                    payment_data,
                    core_routing::DecideConnector,
                    business_profile,
                )
                .await?
            }
            api::ConnectorChoice::SessionMultiple(_) => {
                Err(errors::ApiErrorResponse::InternalServerError).attach_printable(
                    "Invalid routing rule configured for nti and card details based mit flow",
                )?
            }
        };

    // Set the eligible connector in the attempt
    payment_data
        .set_connector_in_payment_attempt(Some(eligible_connector_data.connector_name.to_string()));

    // Set `NetworkMandateId` as the MandateId
    payment_data.set_mandate_id(payments_api::MandateIds {
        mandate_id: None,
        mandate_reference_id: Some(mandate_reference_id),
    });

    // Set the card details received in the recurring details within the payment method data.
    payment_data.set_payment_method_data(Some(
        hyperswitch_domain_models::payment_method_data::PaymentMethodData::CardDetailsForNetworkTransactionId(card_details_for_network_transaction_id),
    ));

    Ok(eligible_connector_data)
}


impl Gpayments {
    pub fn new() -> &'static Self {
        &Self {
            _amount_converter: &MinorUnitForConnector,
        }
    }
}


/// Get when the customer acceptance was provided
    pub fn get_accepted_at(&self) -> PrimitiveDateTime {
        self.accepted_at.unwrap_or_else(date_time::now)
    }


impl Responder {
        let flow = AnalyticsFlow::GetSankey;
        let payload = json_payload.into_inner();
        Box::pin(api::server_wrap(
            flow,
            state,
            &req,
            payload,
            |state, auth: AuthenticationData, req, _| async move {
                let org_id = auth.merchant_account.get_org_id();
                let auth: AuthInfo = AuthInfo::OrgLevel {
                    org_id: org_id.clone(),
                };
                analytics::payment_intents::get_sankey(&state.pool, &auth, req)
                    .await
                    .map(ApplicationResponse::Json)
            },
            auth::auth_type(
                &auth::PlatformOrgAdminAuth {
                    is_admin_auth_allowed: false,
                    organization_id: None,
                },
                &auth::JWTAuth {
                    permission: Permission::OrganizationAnalyticsRead,
                },
                req.headers(),
            ),
            api_locking::LockAction::NotApplicable,
        ))
        .await
    }


pub async fn list_updatable_roles_at_entity_level(
    state: web::Data<AppState>,
    req: HttpRequest,
    query: web::Query<role_api::ListRolesAtEntityLevelRequest>,
) -> HttpResponse {
    let flow = Flow::ListUpdatableRolesAtEntityLevel;

    Box::pin(api::server_wrap(
        flow,
        state.clone(),
        &req,
        query.into_inner(),
        |state, user_from_token, req, _| {
            role_core::list_roles_at_entity_level(
                state,
                user_from_token,
                req,
                role_api::RoleCheckType::Update,
            )
        },
        &auth::JWTAuth {
            permission: Permission::ProfileUserRead,
        },
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub async fn find_by_merchant_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
    ) -> StorageResult<Vec<Self>> {
        generics::generic_filter::<
            <Self as HasTable>::Table,
            _,
            <<Self as HasTable>::Table as Table>::PrimaryKey,
            _,
        >(
            conn,
            dsl::merchant_id.eq(merchant_id.to_owned()),
            None,
            None,
            None,
        )
        .await
    }


pub struct SecretBytesMut(BytesMut);


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


impl api::RefundSync for Nuvei {}


pub async fn delete_totp_attempts_from_redis(
    state: &SessionState,
    user_id: &str,
) -> UserResult<()> {
    let redis_conn = super::get_redis_connection_for_global_tenant(state)?;
    redis_conn
        .delete_key(&get_totp_attempts_key(user_id).into())
        .await
        .change_context(UserErrors::InternalServerError)
        .map(|_| ())
}


File: crates/common_enums/src/transformers.rs
 Public functions: 10
 Public structs: 1

use std::fmt::{Display, Formatter};

use serde::{Deserialize, Serialize};

#[cfg(feature = "payouts")]
use crate::enums::PayoutStatus;
use crate::enums::{
    AttemptStatus, Country, CountryAlpha2, CountryAlpha3, DisputeStatus, EventType, IntentStatus,
    MandateStatus, PaymentMethod, PaymentMethodType, RefundStatus,
};

impl Display for NumericCountryCodeParseError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "Invalid Country Code")
    }
}

impl CountryAlpha2 {
    pub const fn from_alpha2_to_alpha3(code: Self) -> CountryAlpha3 {
        match code {
            Self::AF => CountryAlpha3::AFG,
            Self::AX => CountryAlpha3::ALA,
            Self::AL => CountryAlpha3::ALB,
            Self::DZ => CountryAlpha3::DZA,
            Self::AS => CountryAlpha3::ASM,
            Self::AD => CountryAlpha3::AND,
            Self::AO => CountryAlpha3::AGO,
            Self::AI => CountryAlpha3::AIA,
            Self::AQ => CountryAlpha3::ATA,
            Self::AG => CountryAlpha3::ATG,
            Self::AR => CountryAlpha3::ARG,
            Self::AM => CountryAlpha3::ARM,
            Self::AW => CountryAlpha3::ABW,
            Self::AU => CountryAlpha3::AUS,
            Self::AT => CountryAlpha3::AUT,
            Self::AZ => CountryAlpha3::AZE,
            Self::BS => CountryAlpha3::BHS,
            Self::BH => CountryAlpha3::BHR,
            Self::BD => CountryAlpha3::BGD,
            Self::BB => CountryAlpha3::BRB,
            Self::BY => CountryAlpha3::BLR,
            Self::BE => CountryAlpha3::BEL,
            Self::BZ => CountryAlpha3::BLZ,
            Self::BJ => CountryAlpha3::BEN,
            Self::BM => CountryAlpha3::BMU,
            Self::BT => CountryAlpha3::BTN,
            Self::BO => CountryAlpha3::BOL,
            Self::BQ => CountryAlpha3::BES,
            Self::BA => CountryAlpha3::BIH,
            Self::BW => CountryAlpha3::BWA,
            Self::BV => CountryAlpha3::BVT,
            Self::BR => CountryAlpha3::BRA,
            Self::IO => CountryAlpha3::IOT,
            Self::BN => CountryAlpha3::BRN,
            Self::BG => CountryAlpha3::BGR,
            Self::BF => CountryAlpha3::BFA,
            Self::BI => CountryAlpha3::BDI,
            Self::CV => CountryAlpha3::CPV,
            Self::KH => CountryAlpha3::KHM,
            Self::CM => CountryAlpha3::CMR,
            Self::CA => CountryAlpha3::CAN,
            Self::KY => CountryAlpha3::CYM,
            Self::CF => CountryAlpha3::CAF,
            Self::TD => CountryAlpha3::TCD,
            Self::CL => CountryAlpha3::CHL,
            Self::CN => CountryAlpha3::CHN,
            Self::CX => CountryAlpha3::CXR,
            Self::CC => CountryAlpha3::CCK,
            Self::CO => CountryAlpha3::COL,
            Self::KM => CountryAlpha3::COM,
            Self::CG => CountryAlpha3::COG,
            Self::CD => CountryAlpha3::COD,
            Self::CK => CountryAlpha3::COK,
            Self::CR => CountryAlpha3::CRI,
            Self::CI => CountryAlpha3::CIV,
            Self::HR => CountryAlpha3::HRV,
            Self::CU => CountryAlpha3::CUB,
            Self::CW => CountryAlpha3::CUW,
            Self::CY => CountryAlpha3::CYP,
            Self::CZ => CountryAlpha3::CZE,
            Self::DK => CountryAlpha3::DNK,
            Self::DJ => CountryAlpha3::DJI,
            Self::DM => CountryAlpha3::DMA,
            Self::DO => CountryAlpha3::DOM,
            Self::EC => CountryAlpha3::ECU,
            Self::EG => CountryAlpha3::EGY,
            Self::SV => CountryAlpha3::SLV,
            Self::GQ => CountryAlpha3::GNQ,
            Self::ER => CountryAlpha3::ERI,
            Self::EE => CountryAlpha3::EST,
            Self::ET => CountryAlpha3::ETH,
            Self::FK => CountryAlpha3::FLK,
            Self::FO => CountryAlpha3::FRO,
            Self::FJ => CountryAlpha3::FJI,
            Self::FI => CountryAlpha3::FIN,
            Self::FR => CountryAlpha3::FRA,
            Self::GF => CountryAlpha3::GUF,
            Self::PF => CountryAlpha3::PYF,
            Self::TF => CountryAlpha3::ATF,
            Self::GA => CountryAlpha3::GAB,
            Self::GM => CountryAlpha3::GMB,
            Self::GE => CountryAlpha3::GEO,
            Self::DE => CountryAlpha3::DEU,
            Self::GH => CountryAlpha3::GHA,
            Self::GI => CountryAlpha3::GIB,
            Self::GR => CountryAlpha3::GRC,
            Self::GL => CountryAlpha3::GRL,
            Self::GD => CountryAlpha3::GRD,
            Self::GP => CountryAlpha3::GLP,
            Self::GU => CountryAlpha3::GUM,
            Self::GT => CountryAlpha3::GTM,
            Self::GG => CountryAlpha3::GGY,
            Self::GN => CountryAlpha3::GIN,
            Self::GW => CountryAlpha3::GNB,
            Self::GY => CountryAlpha3::GUY,
            Self::HT => CountryAlpha3::HTI,
            Self::HM => CountryAlpha3::HMD,
            Self::VA => CountryAlpha3::VAT,
            Self::HN => CountryAlpha3::HND,
            Self::HK => CountryAlpha3::HKG,
            Self::HU => CountryAlpha3::HUN,
            Self::IS => CountryAlpha3::ISL,
            Self::IN => CountryAlpha3::IND,
            Self::ID => CountryAlpha3::IDN,
            Self::IR => CountryAlpha3::IRN,
            Self::IQ => CountryAlpha3::IRQ,
            Self::IE => CountryAlpha3::IRL,
            Self::IM => CountryAlpha3::IMN,
            Self::IL => CountryAlpha3::ISR,
            Self::IT => CountryAlpha3::ITA,
            Self::JM => CountryAlpha3::JAM,
            Self::JP => CountryAlpha3::JPN,
            Self::JE => CountryAlpha3::JEY,
            Self::JO => CountryAlpha3::JOR,
            Self::KZ => CountryAlpha3::KAZ,
            Self::KE => CountryAlpha3::KEN,
            Self::KI => CountryAlpha3::KIR,
            Self::KP => CountryAlpha3::PRK,
            Self::KR => CountryAlpha3::KOR,
            Self::KW => CountryAlpha3::KWT,
            Self::KG => CountryAlpha3::KGZ,
            Self::LA => CountryAlpha3::LAO,
            Self::LV => CountryAlpha3::LVA,
            Self::LB => CountryAlpha3::LBN,
            Self::LS => CountryAlpha3::LSO,
            Self::LR => CountryAlpha3::LBR,
            Self::LY => CountryAlpha3::LBY,
            Self::LI => CountryAlpha3::LIE,
            Self::LT => CountryAlpha3::LTU,
            Self::LU => CountryAlpha3::LUX,
            Self::MO => CountryAlpha3::MAC,
            Self::MK => CountryAlpha3::MKD,
            Self::MG => CountryAlpha3::MDG,
            Self::MW => CountryAlpha3::MWI,
            Self::MY => CountryAlpha3::MYS,
            Self::MV => CountryAlpha3::MDV,
            Self::ML => CountryAlpha3::MLI,
            Self::MT => CountryAlpha3::MLT,
            Self::MH => CountryAlpha3::MHL,
            Self::MQ => CountryAlpha3::MTQ,
            Self::MR => CountryAlpha3::MRT,
            Self::MU => CountryAlpha3::MUS,
            Self::YT => CountryAlpha3::MYT,
            Self::MX => CountryAlpha3::MEX,
            Self::FM => CountryAlpha3::FSM,
            Self::MD => CountryAlpha3::MDA,
            Self::MC => CountryAlpha3::MCO,
            Self::MN => CountryAlpha3::MNG,
            Self::ME => CountryAlpha3::MNE,
            Self::MS => CountryAlpha3::MSR,
            Self::MA => CountryAlpha3::MAR,
            Self::MZ => CountryAlpha3::MOZ,
            Self::MM => CountryAlpha3::MMR,
            Self::NA => CountryAlpha3::NAM,
            Self::NR => CountryAlpha3::NRU,
            Self::NP => CountryAlpha3::NPL,
            Self::NL => CountryAlpha3::NLD,
            Self::NC => CountryAlpha3::NCL,
            Self::NZ => CountryAlpha3::NZL,
            Self::NI => CountryAlpha3::NIC,
            Self::NE => CountryAlpha3::NER,
            Self::NG => CountryAlpha3::NGA,
            Self::NU => CountryAlpha3::NIU,
            Self::NF => CountryAlpha3::NFK,
            Self::MP => CountryAlpha3::MNP,
            Self::NO => CountryAlpha3::NOR,
            Self::OM => CountryAlpha3::OMN,
            Self::PK => CountryAlpha3::PAK,
            Self::PW => CountryAlpha3::PLW,
            Self::PS => CountryAlpha3::PSE,
            Self::PA => CountryAlpha3::PAN,
            Self::PG => CountryAlpha3::PNG,
            Self::PY => CountryAlpha3::PRY,
            Self::PE => CountryAlpha3::PER,
            Self::PH => CountryAlpha3::PHL,
            Self::PN => CountryAlpha3::PCN,
            Self::PL => CountryAlpha3::POL,
            Self::PT => CountryAlpha3::PRT,
            Self::PR => CountryAlpha3::PRI,
            Self::QA => CountryAlpha3::QAT,
            Self::RE => CountryAlpha3::REU,
            Self::RO => CountryAlpha3::ROU,
            Self::RU => CountryAlpha3::RUS,
            Self::RW => CountryAlpha3::RWA,
            Self::BL => CountryAlpha3::BLM,
            Self::SH => CountryAlpha3::SHN,
            Self::KN => CountryAlpha3::KNA,
            Self::LC => CountryAlpha3::LCA,
            Self::MF => CountryAlpha3::MAF,
            Self::PM => CountryAlpha3::SPM,
            Self::VC => CountryAlpha3::VCT,
            Self::WS => CountryAlpha3::WSM,
            Self::SM => CountryAlpha3::SMR,
            Self::ST => CountryAlpha3::STP,
            Self::SA => CountryAlpha3::SAU,
            Self::SN => CountryAlpha3::SEN,
            Self::RS => CountryAlpha3::SRB,
            Self::SC => CountryAlpha3::SYC,
            Self::SL => CountryAlpha3::SLE,
            Self::SG => CountryAlpha3::SGP,
            Self::SX => CountryAlpha3::SXM,
            Self::SK => CountryAlpha3::SVK,
            Self::SI => CountryAlpha3::SVN,
            Self::SB => CountryAlpha3::SLB,
            Self::SO => CountryAlpha3::SOM,
            Self::ZA => CountryAlpha3::ZAF,
            Self::GS => CountryAlpha3::SGS,
            Self::SS => CountryAlpha3::SSD,
            Self::ES => CountryAlpha3::ESP,
            Self::LK => CountryAlpha3::LKA,
            Self::SD => CountryAlpha3::SDN,
            Self::SR => CountryAlpha3::SUR,
            Self::SJ => CountryAlpha3::SJM,
            Self::SZ => CountryAlpha3::SWZ,
            Self::SE => CountryAlpha3::SWE,
            Self::CH => CountryAlpha3::CHE,
            Self::SY => CountryAlpha3::SYR,
            Self::TW => CountryAlpha3::TWN,
            Self::TJ => CountryAlpha3::TJK,
            Self::TZ => CountryAlpha3::TZA,
            Self::TH => CountryAlpha3::THA,
            Self::TL => CountryAlpha3::TLS,
            Self::TG => CountryAlpha3::TGO,
            Self::TK => CountryAlpha3::TKL,
            Self::TO => CountryAlpha3::TON,
            Self::TT => CountryAlpha3::TTO,
            Self::TN => CountryAlpha3::TUN,
            Self::TR => CountryAlpha3::TUR,
            Self::TM => CountryAlpha3::TKM,
            Self::TC => CountryAlpha3::TCA,
            Self::TV => CountryAlpha3::TUV,
            Self::UG => CountryAlpha3::UGA,
            Self::UA => CountryAlpha3::UKR,
            Self::AE => CountryAlpha3::ARE,
            Self::GB => CountryAlpha3::GBR,
            Self::US => CountryAlpha3::USA,
            Self::UM => CountryAlpha3::UMI,
            Self::UY => CountryAlpha3::URY,
            Self::UZ => CountryAlpha3::UZB,
            Self::VU => CountryAlpha3::VUT,
            Self::VE => CountryAlpha3::VEN,
            Self::VN => CountryAlpha3::VNM,
            Self::VG => CountryAlpha3::VGB,
            Self::VI => CountryAlpha3::VIR,
            Self::WF => CountryAlpha3::WLF,
            Self::EH => CountryAlpha3::ESH,
            Self::YE => CountryAlpha3::YEM,
            Self::ZM => CountryAlpha3::ZMB,
            Self::ZW => CountryAlpha3::ZWE,
        }
    }
}
impl Country {
    pub const fn from_alpha2(code: CountryAlpha2) -> Self {
        match code {
            CountryAlpha2::AF => Self::Afghanistan,
            CountryAlpha2::AX => Self::AlandIslands,
            CountryAlpha2::AL => Self::Albania,
            CountryAlpha2::DZ => Self::Algeria,
            CountryAlpha2::AS => Self::AmericanSamoa,
            CountryAlpha2::AD => Self::Andorra,
            CountryAlpha2::AO => Self::Angola,
            CountryAlpha2::AI => Self::Anguilla,
            CountryAlpha2::AQ => Self::Antarctica,
            CountryAlpha2::AG => Self::AntiguaAndBarbuda,
            CountryAlpha2::AR => Self::Argentina,
            CountryAlpha2::AM => Self::Armenia,
            CountryAlpha2::AW => Self::Aruba,
            CountryAlpha2::AU => Self::Australia,
            CountryAlpha2::AT => Self::Austria,
            CountryAlpha2::AZ => Self::Azerbaijan,
            CountryAlpha2::BS => Self::Bahamas,
            CountryAlpha2::BH => Self::Bahrain,
            CountryAlpha2::BD => Self::Bangladesh,
            CountryAlpha2::BB => Self::Barbados,
            CountryAlpha2::BY => Self::Belarus,
            CountryAlpha2::BE => Self::Belgium,
            CountryAlpha2::BZ => Self::Belize,
            CountryAlpha2::BJ => Self::Benin,
            CountryAlpha2::BM => Self::Bermuda,
            CountryAlpha2::BT => Self::Bhutan,
            CountryAlpha2::BO => Self::BoliviaPlurinationalState,
            CountryAlpha2::BQ => Self::BonaireSintEustatiusAndSaba,
            CountryAlpha2::BA => Self::BosniaAndHerzegovina,
            CountryAlpha2::BW => Self::Botswana,
            CountryAlpha2::BV => Self::BouvetIsland,
            CountryAlpha2::BR => Self::Brazil,
            CountryAlpha2::IO => Self::BritishIndianOceanTerritory,
            CountryAlpha2::BN => Self::BruneiDarussalam,
            CountryAlpha2::BG => Self::Bulgaria,
            CountryAlpha2::BF => Self::BurkinaFaso,
            CountryAlpha2::BI => Self::Burundi,
            CountryAlpha2::CV => Self::CaboVerde,
            CountryAlpha2::KH => Self::Cambodia,
            CountryAlpha2::CM => Self::Cameroon,
            CountryAlpha2::CA => Self::Canada,
            CountryAlpha2::KY => Self::CaymanIslands,
            CountryAlpha2::CF => Self::CentralAfricanRepublic,
            CountryAlpha2::TD => Self::Chad,
            CountryAlpha2::CL => Self::Chile,
            CountryAlpha2::CN => Self::China,
            CountryAlpha2::CX => Self::ChristmasIsland,
            CountryAlpha2::CC => Self::CocosKeelingIslands,
            CountryAlpha2::CO => Self::Colombia,
            CountryAlpha2::KM => Self::Comoros,
            CountryAlpha2::CG => Self::Congo,
            CountryAlpha2::CD => Self::CongoDemocraticRepublic,
            CountryAlpha2::CK => Self::CookIslands,
            CountryAlpha2::CR => Self::CostaRica,
            CountryAlpha2::CI => Self::CotedIvoire,
            CountryAlpha2::HR => Self::Croatia,
            CountryAlpha2::CU => Self::Cuba,
            CountryAlpha2::CW => Self::Curacao,
            CountryAlpha2::CY => Self::Cyprus,
            CountryAlpha2::CZ => Self::Czechia,
            CountryAlpha2::DK => Self::Denmark,
            CountryAlpha2::DJ => Self::Djibouti,
            CountryAlpha2::DM => Self::Dominica,
            CountryAlpha2::DO => Self::DominicanRepublic,
            CountryAlpha2::EC => Self::Ecuador,
            CountryAlpha2::EG => Self::Egypt,
            CountryAlpha2::SV => Self::ElSalvador,
            CountryAlpha2::GQ => Self::EquatorialGuinea,
            CountryAlpha2::ER => Self::Eritrea,
            CountryAlpha2::EE => Self::Estonia,
            CountryAlpha2::ET => Self::Ethiopia,
            CountryAlpha2::FK => Self::FalklandIslandsMalvinas,
            CountryAlpha2::FO => Self::FaroeIslands,
            CountryAlpha2::FJ => Self::Fiji,
            CountryAlpha2::FI => Self::Finland,
            CountryAlpha2::FR => Self::France,
            CountryAlpha2::GF => Self::FrenchGuiana,
            CountryAlpha2::PF => Self::FrenchPolynesia,
            CountryAlpha2::TF => Self::FrenchSouthernTerritories,
            CountryAlpha2::GA => Self::Gabon,
            CountryAlpha2::GM => Self::Gambia,
            CountryAlpha2::GE => Self::Georgia,
            CountryAlpha2::DE => Self::Germany,
            CountryAlpha2::GH => Self::Ghana,
            CountryAlpha2::GI => Self::Gibraltar,
            CountryAlpha2::GR => Self::Greece,
            CountryAlpha2::GL => Self::Greenland,
            CountryAlpha2::GD => Self::Grenada,
            CountryAlpha2::GP => Self::Guadeloupe,
            CountryAlpha2::GU => Self::Guam,
            CountryAlpha2::GT => Self::Guatemala,
            CountryAlpha2::GG => Self::Guernsey,
            CountryAlpha2::GN => Self::Guinea,
            CountryAlpha2::GW => Self::GuineaBissau,
            CountryAlpha2::GY => Self::Guyana,
            CountryAlpha2::HT => Self::Haiti,
            CountryAlpha2::HM => Self::HeardIslandAndMcDonaldIslands,
            CountryAlpha2::VA => Self::HolySee,
            CountryAlpha2::HN => Self::Honduras,
            CountryAlpha2::HK => Self::HongKong,
            CountryAlpha2::HU => Self::Hungary,
            CountryAlpha2::IS => Self::Iceland,
            CountryAlpha2::IN => Self::India,
            CountryAlpha2::ID => Self::Indonesia,
            CountryAlpha2::IR => Self::IranIslamicRepublic,
            CountryAlpha2::IQ => Self::Iraq,
            CountryAlpha2::IE => Self::Ireland,
            CountryAlpha2::IM => Self::IsleOfMan,
            CountryAlpha2::IL => Self::Israel,
            CountryAlpha2::IT => Self::Italy,
            CountryAlpha2::JM => Self::Jamaica,
            CountryAlpha2::JP => Self::Japan,
            CountryAlpha2::JE => Self::Jersey,
            CountryAlpha2::JO => Self::Jordan,
            CountryAlpha2::KZ => Self::Kazakhstan,
            CountryAlpha2::KE => Self::Kenya,
            CountryAlpha2::KI => Self::Kiribati,
            CountryAlpha2::KP => Self::KoreaDemocraticPeoplesRepublic,
            CountryAlpha2::KR => Self::KoreaRepublic,
            CountryAlpha2::KW => Self::Kuwait,
            CountryAlpha2::KG => Self::Kyrgyzstan,
            CountryAlpha2::LA => Self::LaoPeoplesDemocraticRepublic,
            CountryAlpha2::LV => Self::Latvia,
            CountryAlpha2::LB => Self::Lebanon,
            CountryAlpha2::LS => Self::Lesotho,
            CountryAlpha2::LR => Self::Liberia,
            CountryAlpha2::LY => Self::Libya,
            CountryAlpha2::LI => Self::Liechtenstein,
            CountryAlpha2::LT => Self::Lithuania,
            CountryAlpha2::LU => Self::Luxembourg,
            CountryAlpha2::MO => Self::Macao,
            CountryAlpha2::MK => Self::MacedoniaTheFormerYugoslavRepublic,
            CountryAlpha2::MG => Self::Madagascar,
            CountryAlpha2::MW => Self::Malawi,
            CountryAlpha2::MY => Self::Malaysia,
            CountryAlpha2::MV => Self::Maldives,
            CountryAlpha2::ML => Self::Mali,
            CountryAlpha2::MT => Self::Malta,
            CountryAlpha2::MH => Self::MarshallIslands,
            CountryAlpha2::MQ => Self::Martinique,
            CountryAlpha2::MR => Self::Mauritania,
            CountryAlpha2::MU => Self::Mauritius,
            CountryAlpha2::YT => Self::Mayotte,
            CountryAlpha2::MX => Self::Mexico,
            CountryAlpha2::FM => Self::MicronesiaFederatedStates,
            CountryAlpha2::MD => Self::MoldovaRepublic,
            CountryAlpha2::MC => Self::Monaco,
            CountryAlpha2::MN => Self::Mongolia,
            CountryAlpha2::ME => Self::Montenegro,
            CountryAlpha2::MS => Self::Montserrat,
            CountryAlpha2::MA => Self::Morocco,
            CountryAlpha2::MZ => Self::Mozambique,
            CountryAlpha2::MM => Self::Myanmar,
            CountryAlpha2::NA => Self::Namibia,
            CountryAlpha2::NR => Self::Nauru,
            CountryAlpha2::NP => Self::Nepal,
            CountryAlpha2::NL => Self::Netherlands,
            CountryAlpha2::NC => Self::NewCaledonia,
            CountryAlpha2::NZ => Self::NewZealand,
            CountryAlpha2::NI => Self::Nicaragua,
            CountryAlpha2::NE => Self::Niger,
            CountryAlpha2::NG => Self::Nigeria,
            CountryAlpha2::NU => Self::Niue,
            CountryAlpha2::NF => Self::NorfolkIsland,
            CountryAlpha2::MP => Self::NorthernMarianaIslands,
            CountryAlpha2::NO => Self::Norway,
            CountryAlpha2::OM => Self::Oman,
            CountryAlpha2::PK => Self::Pakistan,
            CountryAlpha2::PW => Self::Palau,
            CountryAlpha2::PS => Self::PalestineState,
            CountryAlpha2::PA => Self::Panama,
            CountryAlpha2::PG => Self::PapuaNewGuinea,
            CountryAlpha2::PY => Self::Paraguay,
            CountryAlpha2::PE => Self::Peru,
            CountryAlpha2::PH => Self::Philippines,
            CountryAlpha2::PN => Self::Pitcairn,
            CountryAlpha2::PL => Self::Poland,
            CountryAlpha2::PT => Self::Portugal,
            CountryAlpha2::PR => Self::PuertoRico,
            CountryAlpha2::QA => Self::Qatar,
            CountryAlpha2::RE => Self::Reunion,
            CountryAlpha2::RO => Self::Romania,
            CountryAlpha2::RU => Self::RussianFederation,
            CountryAlpha2::RW => Self::Rwanda,
            CountryAlpha2::BL => Self::SaintBarthelemy,
            CountryAlpha2::SH => Self::SaintHelenaAscensionAndTristandaCunha,
            CountryAlpha2::KN => Self::SaintKittsAndNevis,
            CountryAlpha2::LC => Self::SaintLucia,
            CountryAlpha2::MF => Self::SaintMartinFrenchpart,
            CountryAlpha2::PM => Self::SaintPierreAndMiquelon,
            CountryAlpha2::VC => Self::SaintVincentAndTheGrenadines,
            CountryAlpha2::WS => Self::Samoa,
            CountryAlpha2::SM => Self::SanMarino,
            CountryAlpha2::ST => Self::SaoTomeAndPrincipe,
            CountryAlpha2::SA => Self::SaudiArabia,
            CountryAlpha2::SN => Self::Senegal,
            CountryAlpha2::RS => Self::Serbia,
            CountryAlpha2::SC => Self::Seychelles,
            CountryAlpha2::SL => Self::SierraLeone,
            CountryAlpha2::SG => Self::Singapore,
            CountryAlpha2::SX => Self::SintMaartenDutchpart,
            CountryAlpha2::SK => Self::Slovakia,
            CountryAlpha2::SI => Self::Slovenia,
            CountryAlpha2::SB => Self::SolomonIslands,
            CountryAlpha2::SO => Self::Somalia,
            CountryAlpha2::ZA => Self::SouthAfrica,
            CountryAlpha2::GS => Self::SouthGeorgiaAndTheSouthSandwichIslands,
            CountryAlpha2::SS => Self::SouthSudan,
            CountryAlpha2::ES => Self::Spain,
            CountryAlpha2::LK => Self::SriLanka,
            CountryAlpha2::SD => Self::Sudan,
            CountryAlpha2::SR => Self::Suriname,
            CountryAlpha2::SJ => Self::SvalbardAndJanMayen,
            CountryAlpha2::SZ => Self::Swaziland,
            CountryAlpha2::SE => Self::Sweden,
            CountryAlpha2::CH => Self::Switzerland,
            CountryAlpha2::SY => Self::SyrianArabRepublic,
            CountryAlpha2::TW => Self::TaiwanProvinceOfChina,
            CountryAlpha2::TJ => Self::Tajikistan,
            CountryAlpha2::TZ => Self::TanzaniaUnitedRepublic,
            CountryAlpha2::TH => Self::Thailand,
            CountryAlpha2::TL => Self::TimorLeste,
            CountryAlpha2::TG => Self::Togo,
            CountryAlpha2::TK => Self::Tokelau,
            CountryAlpha2::TO => Self::Tonga,
            CountryAlpha2::TT => Self::TrinidadAndTobago,
            CountryAlpha2::TN => Self::Tunisia,
            CountryAlpha2::TR => Self::Turkey,
            CountryAlpha2::TM => Self::Turkmenistan,
            CountryAlpha2::TC => Self::TurksAndCaicosIslands,
            CountryAlpha2::TV => Self::Tuvalu,
            CountryAlpha2::UG => Self::Uganda,
            CountryAlpha2::UA => Self::Ukraine,
            CountryAlpha2::AE => Self::UnitedArabEmirates,
            CountryAlpha2::GB => Self::UnitedKingdomOfGreatBritainAndNorthernIreland,
            CountryAlpha2::US => Self::UnitedStatesOfAmerica,
            CountryAlpha2::UM => Self::UnitedStatesMinorOutlyingIslands,
            CountryAlpha2::UY => Self::Uruguay,
            CountryAlpha2::UZ => Self::Uzbekistan,
            CountryAlpha2::VU => Self::Vanuatu,
            CountryAlpha2::VE => Self::VenezuelaBolivarianRepublic,
            CountryAlpha2::VN => Self::Vietnam,
            CountryAlpha2::VG => Self::VirginIslandsBritish,
            CountryAlpha2::VI => Self::VirginIslandsUS,
            CountryAlpha2::WF => Self::WallisAndFutuna,
            CountryAlpha2::EH => Self::WesternSahara,
            CountryAlpha2::YE => Self::Yemen,
            CountryAlpha2::ZM => Self::Zambia,
            CountryAlpha2::ZW => Self::Zimbabwe,
        }
    }
    pub const fn to_alpha2(self) -> CountryAlpha2 {
        match self {
            Self::Afghanistan => CountryAlpha2::AF,
            Self::AlandIslands => CountryAlpha2::AX,
            Self::Albania => CountryAlpha2::AL,
            Self::Algeria => CountryAlpha2::DZ,
            Self::AmericanSamoa => CountryAlpha2::AS,
            Self::Andorra => CountryAlpha2::AD,
            Self::Angola => CountryAlpha2::AO,
            Self::Anguilla => CountryAlpha2::AI,
            Self::Antarctica => CountryAlpha2::AQ,
            Self::AntiguaAndBarbuda => CountryAlpha2::AG,
            Self::Argentina => CountryAlpha2::AR,
            Self::Armenia => CountryAlpha2::AM,
            Self::Aruba => CountryAlpha2::AW,
            Self::Australia => CountryAlpha2::AU,
            Self::Austria => CountryAlpha2::AT,
            Self::Azerbaijan => CountryAlpha2::AZ,
            Self::Bahamas => CountryAlpha2::BS,
            Self::Bahrain => CountryAlpha2::BH,
            Self::Bangladesh => CountryAlpha2::BD,
            Self::Barbados => CountryAlpha2::BB,
            Self::Belarus => CountryAlpha2::BY,
            Self::Belgium => CountryAlpha2::BE,
            Self::Belize => CountryAlpha2::BZ,
            Self::Benin => CountryAlpha2::BJ,
            Self::Bermuda => CountryAlpha2::BM,
            Self::Bhutan => CountryAlpha2::BT,
            Self::BoliviaPlurinationalState => CountryAlpha2::BO,
            Self::BonaireSintEustatiusAndSaba => CountryAlpha2::BQ,
            Self::BosniaAndHerzegovina => CountryAlpha2::BA,
            Self::Botswana => CountryAlpha2::BW,
            Self::BouvetIsland => CountryAlpha2::BV,
            Self::Brazil => CountryAlpha2::BR,
            Self::BritishIndianOceanTerritory => CountryAlpha2::IO,
            Self::BruneiDarussalam => CountryAlpha2::BN,
            Self::Bulgaria => CountryAlpha2::BG,
            Self::BurkinaFaso => CountryAlpha2::BF,
            Self::Burundi => CountryAlpha2::BI,
            Self::CaboVerde => CountryAlpha2::CV,
            Self::Cambodia => CountryAlpha2::KH,
            Self::Cameroon => CountryAlpha2::CM,
            Self::Canada => CountryAlpha2::CA,
            Self::CaymanIslands => CountryAlpha2::KY,
            Self::CentralAfricanRepublic => CountryAlpha2::CF,
            Self::Chad => CountryAlpha2::TD,
            Self::Chile => CountryAlpha2::CL,
            Self::China => CountryAlpha2::CN,
            Self::ChristmasIsland => CountryAlpha2::CX,
            Self::CocosKeelingIslands => CountryAlpha2::CC,
            Self::Colombia => CountryAlpha2::CO,
            Self::Comoros => CountryAlpha2::KM,
            Self::Congo => CountryAlpha2::CG,
            Self::CongoDemocraticRepublic => CountryAlpha2::CD,
            Self::CookIslands => CountryAlpha2::CK,
            Self::CostaRica => CountryAlpha2::CR,
            Self::CotedIvoire => CountryAlpha2::CI,
            Self::Croatia => CountryAlpha2::HR,
            Self::Cuba => CountryAlpha2::CU,
            Self::Curacao => CountryAlpha2::CW,
            Self::Cyprus => CountryAlpha2::CY,
            Self::Czechia => CountryAlpha2::CZ,
            Self::Denmark => CountryAlpha2::DK,
            Self::Djibouti => CountryAlpha2::DJ,
            Self::Dominica => CountryAlpha2::DM,
            Self::DominicanRepublic => CountryAlpha2::DO,
            Self::Ecuador => CountryAlpha2::EC,
            Self::Egypt => CountryAlpha2::EG,
            Self::ElSalvador => CountryAlpha2::SV,
            Self::EquatorialGuinea => CountryAlpha2::GQ,
            Self::Eritrea => CountryAlpha2::ER,
            Self::Estonia => CountryAlpha2::EE,
            Self::Ethiopia => CountryAlpha2::ET,
            Self::FalklandIslandsMalvinas => CountryAlpha2::FK,
            Self::FaroeIslands => CountryAlpha2::FO,
            Self::Fiji => CountryAlpha2::FJ,
            Self::Finland => CountryAlpha2::FI,
            Self::France => CountryAlpha2::FR,
            Self::FrenchGuiana => CountryAlpha2::GF,
            Self::FrenchPolynesia => CountryAlpha2::PF,
            Self::FrenchSouthernTerritories => CountryAlpha2::TF,
            Self::Gabon => CountryAlpha2::GA,
            Self::Gambia => CountryAlpha2::GM,
            Self::Georgia => CountryAlpha2::GE,
            Self::Germany => CountryAlpha2::DE,
            Self::Ghana => CountryAlpha2::GH,
            Self::Gibraltar => CountryAlpha2::GI,
            Self::Greece => CountryAlpha2::GR,
            Self::Greenland => CountryAlpha2::GL,
            Self::Grenada => CountryAlpha2::GD,
            Self::Guadeloupe => CountryAlpha2::GP,
            Self::Guam => CountryAlpha2::GU,
            Self::Guatemala => CountryAlpha2::GT,
            Self::Guernsey => CountryAlpha2::GG,
            Self::Guinea => CountryAlpha2::GN,
            Self::GuineaBissau => CountryAlpha2::GW,
            Self::Guyana => CountryAlpha2::GY,
            Self::Haiti => CountryAlpha2::HT,
            Self::HeardIslandAndMcDonaldIslands => CountryAlpha2::HM,
            Self::HolySee => CountryAlpha2::VA,
            Self::Honduras => CountryAlpha2::HN,
            Self::HongKong => CountryAlpha2::HK,
            Self::Hungary => CountryAlpha2::HU,
            Self::Iceland => CountryAlpha2::IS,
            Self::India => CountryAlpha2::IN,
            Self::Indonesia => CountryAlpha2::ID,
            Self::IranIslamicRepublic => CountryAlpha2::IR,
            Self::Iraq => CountryAlpha2::IQ,
            Self::Ireland => CountryAlpha2::IE,
            Self::IsleOfMan => CountryAlpha2::IM,
            Self::Israel => CountryAlpha2::IL,
            Self::Italy => CountryAlpha2::IT,
            Self::Jamaica => CountryAlpha2::JM,
            Self::Japan => CountryAlpha2::JP,
            Self::Jersey => CountryAlpha2::JE,
            Self::Jordan => CountryAlpha2::JO,
            Self::Kazakhstan => CountryAlpha2::KZ,
            Self::Kenya => CountryAlpha2::KE,
            Self::Kiribati => CountryAlpha2::KI,
            Self::KoreaDemocraticPeoplesRepublic => CountryAlpha2::KP,
            Self::KoreaRepublic => CountryAlpha2::KR,
            Self::Kuwait => CountryAlpha2::KW,
            Self::Kyrgyzstan => CountryAlpha2::KG,
            Self::LaoPeoplesDemocraticRepublic => CountryAlpha2::LA,
            Self::Latvia => CountryAlpha2::LV,
            Self::Lebanon => CountryAlpha2::LB,
            Self::Lesotho => CountryAlpha2::LS,
            Self::Liberia => CountryAlpha2::LR,
            Self::Libya => CountryAlpha2::LY,
            Self::Liechtenstein => CountryAlpha2::LI,
            Self::Lithuania => CountryAlpha2::LT,
            Self::Luxembourg => CountryAlpha2::LU,
            Self::Macao => CountryAlpha2::MO,


pub struct XenditMultipleSplitResponse {
    /// Identifier for split rule created for the payment
    pub split_rule_id: String,
    /// The sub-account user-id that you want to make this transaction for.
    pub for_user_id: Option<String>,
    /// Name to identify split rule. Not required to be unique. Typically based on transaction and/or sub-merchant types.
    pub name: String,
    /// Description to identify fee rule
    pub description: String,
    /// Array of objects that define how the platform wants to route the fees and to which accounts.
    pub routes: Vec<XenditSplitRoute>,
}


impl TryFrom<&types::RefundSyncRouterData> for BraintreeRSyncRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::RefundSyncRouterData) -> Result<Self, Self::Error> {
        let metadata: BraintreeMeta = if let (
            Some(merchant_account_id),
            Some(merchant_config_currency),
        ) = (
            item.request.merchant_account_id.clone(),
            item.request.merchant_config_currency,
        ) {
            router_env::logger::info!(
                "BRAINTREE: Picking merchant_account_id and merchant_config_currency from payments request"
            );

            BraintreeMeta {
                merchant_account_id,
                merchant_config_currency,
            }
        } else {
            utils::to_connector_meta_from_secret(item.connector_meta_data.clone()).change_context(
                errors::ConnectorError::InvalidConnectorConfig { config: "metadata" },
            )?
        };
        utils::validate_currency(
            item.request.currency,
            Some(metadata.merchant_config_currency),
        )?;
        let refund_id = item.request.get_connector_refund_id()?;
        Ok(Self {
            query: REFUND_QUERY.to_string(),
            variables: RSyncInput {
                input: RefundSearchInput {
                    id: IdFilter { is: refund_id },
                },
            },
        })
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RSyncNodeData {
    id: String,
    status: BraintreeRefundStatus,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RSyncEdgeData {
    node: RSyncNodeData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RefundData {
    edges: Vec<RSyncEdgeData>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RSyncSearchData {
    refunds: RefundData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RSyncResponseData {
    search: RSyncSearchData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RSyncResponse {
    data: RSyncResponseData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BraintreeRSyncResponse {
    RSyncResponse(Box<RSyncResponse>),
    ErrorResponse(Box<ErrorResponse>),
}

impl TryFrom<RefundsResponseRouterData<RSync, BraintreeRSyncResponse>>
    for RefundsRouterData<RSync>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<RSync, BraintreeRSyncResponse>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            BraintreeRSyncResponse::ErrorResponse(error_response) => Ok(Self {
                response: build_error_response(&error_response.errors, item.http_code)
                    .map_err(|err| *err),
                ..item.data
            }),
            BraintreeRSyncResponse::RSyncResponse(rsync_response) => {
                let edge_data = rsync_response
                    .data
                    .search
                    .refunds
                    .edges
                    .first()
                    .ok_or(errors::ConnectorError::MissingConnectorRefundID)?;
                let connector_refund_id = &edge_data.node.id;
                let response = Ok(RefundsResponseData {
                    connector_refund_id: connector_refund_id.to_string(),
                    refund_status: enums::RefundStatus::from(edge_data.node.status.clone()),
                });
                Ok(Self {
                    response,
                    ..item.data
                })
            }
        }
    }
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreditCardData {
    number: cards::CardNumber,
    expiration_year: Secret<String>,
    expiration_month: Secret<String>,
    cvv: Secret<String>,
    cardholder_name: Secret<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientTokenInput {
    merchant_account_id: Secret<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InputData {
    credit_card: CreditCardData,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InputClientTokenData {
    client_token: ClientTokenInput,
}

impl TryFrom<&types::TokenizationRouterData> for BraintreeTokenRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::TokenizationRouterData) -> Result<Self, Self::Error> {
        match item.request.payment_method_data.clone() {
            PaymentMethodData::Card(card_data) => Ok(Self {
                query: TOKENIZE_CREDIT_CARD.to_string(),
                variables: VariableInput {
                    input: InputData {
                        credit_card: CreditCardData {
                            number: card_data.card_number,
                            expiration_year: card_data.card_exp_year,
                            expiration_month: card_data.card_exp_month,
                            cvv: card_data.card_cvc,
                            cardholder_name: item
                                .get_optional_billing_full_name()
                                .unwrap_or(Secret::new("".to_string())),
                        },
                    },
                },
            }),
            PaymentMethodData::CardRedirect(_)
            | PaymentMethodData::Wallet(_)
            | PaymentMethodData::PayLater(_)
            | PaymentMethodData::BankRedirect(_)
            | PaymentMethodData::BankDebit(_)
            | PaymentMethodData::BankTransfer(_)
            | PaymentMethodData::Crypto(_)
            | PaymentMethodData::MandatePayment
            | PaymentMethodData::OpenBanking(_)
            | PaymentMethodData::Reward
            | PaymentMethodData::RealTimePayment(_)
            | PaymentMethodData::MobilePayment(_)
            | PaymentMethodData::Upi(_)
            | PaymentMethodData::Voucher(_)
            | PaymentMethodData::GiftCard(_)
            | PaymentMethodData::CardToken(_)
            | PaymentMethodData::NetworkToken(_)
            | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                Err(errors::ConnectorError::NotImplemented(
                    utils::get_unimplemented_payment_method_error_message("braintree"),
                )
                .into())
            }
        }
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TokenizePaymentMethodData {
    id: Secret<String>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TokenizeCreditCardData {
    payment_method: TokenizePaymentMethodData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientToken {
    client_token: Secret<String>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TokenizeCreditCard {
    tokenize_credit_card: TokenizeCreditCardData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientTokenData {
    create_client_token: ClientToken,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ClientTokenResponse {
    data: ClientTokenData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TokenResponse {
    data: TokenizeCreditCard,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ErrorResponse {
    errors: Vec<ErrorDetails>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BraintreeTokenResponse {
    TokenResponse(Box<TokenResponse>),
    ErrorResponse(Box<ErrorResponse>),
}

impl<F, T> TryFrom<ResponseRouterData<F, BraintreeTokenResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, BraintreeTokenResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: match item.response {
                BraintreeTokenResponse::ErrorResponse(error_response) => {
                    build_error_response(error_response.errors.as_ref(), item.http_code)
                        .map_err(|err| *err)
                }

                BraintreeTokenResponse::TokenResponse(token_response) => {
                    Ok(PaymentsResponseData::TokenizationResponse {
                        token: token_response
                            .data
                            .tokenize_credit_card
                            .payment_method
                            .id
                            .expose()
                            .clone(),
                    })
                }
            },
            ..item.data
        })
    }
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CaptureTransactionBody {
    amount: StringMajorUnit,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CaptureInputData {
    transaction_id: String,
    transaction: CaptureTransactionBody,
}

impl TryFrom<&BraintreeRouterData<&types::PaymentsCaptureRouterData>> for BraintreeCaptureRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BraintreeRouterData<&types::PaymentsCaptureRouterData>,
    ) -> Result<Self, Self::Error> {
        let query = CAPTURE_TRANSACTION_MUTATION.to_string();
        let variables = VariableCaptureInput {
            input: CaptureInputData {
                transaction_id: item.router_data.request.connector_transaction_id.clone(),
                transaction: CaptureTransactionBody {
                    amount: item.amount.to_owned(),
                },
            },
        };
        Ok(Self { query, variables })
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CaptureResponseTransactionBody {
    id: String,
    status: BraintreePaymentStatus,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CaptureTransactionData {
    transaction: CaptureResponseTransactionBody,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CaptureResponseData {
    capture_transaction: CaptureTransactionData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CaptureResponse {
    data: CaptureResponseData,
}

impl TryFrom<PaymentsCaptureResponseRouterData<BraintreeCaptureResponse>>
    for types::PaymentsCaptureRouterData
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: PaymentsCaptureResponseRouterData<BraintreeCaptureResponse>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            BraintreeCaptureResponse::SuccessResponse(capture_data) => {
                let transaction_data = capture_data.data.capture_transaction.transaction;
                let status = enums::AttemptStatus::from(transaction_data.status.clone());
                let response = if utils::is_payment_failure(status) {
                    Err(hyperswitch_domain_models::router_data::ErrorResponse {
                        code: transaction_data.status.to_string().clone(),
                        message: transaction_data.status.to_string().clone(),
                        reason: Some(transaction_data.status.to_string().clone()),
                        attempt_status: None,
                        connector_transaction_id: Some(transaction_data.id),
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    })
                } else {
                    Ok(PaymentsResponseData::TransactionResponse {
                        resource_id: ResponseId::ConnectorTransactionId(transaction_data.id),
                        redirection_data: Box::new(None),
                        mandate_reference: Box::new(None),
                        connector_metadata: None,
                        network_txn_id: None,
                        connector_response_reference_id: None,
                        incremental_authorization_allowed: None,
                        charges: None,
                    })
                };
                Ok(Self {
                    status,
                    response,
                    ..item.data
                })
            }
            BraintreeCaptureResponse::ErrorResponse(error_data) => Ok(Self {
                response: build_error_response(&error_data.errors, item.http_code)
                    .map_err(|err| *err),
                ..item.data
            }),
        }
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeletePaymentMethodFromVaultInputData {
    payment_method_id: Secret<String>,
}

#[derive(Debug, Serialize)]
pub struct VariableDeletePaymentMethodFromVaultInput {
    input: DeletePaymentMethodFromVaultInputData,
}

#[derive(Debug, Serialize)]
pub struct BraintreeRevokeMandateRequest {
    query: String,
    variables: VariableDeletePaymentMethodFromVaultInput,
}

impl TryFrom<&types::MandateRevokeRouterData> for BraintreeRevokeMandateRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::MandateRevokeRouterData) -> Result<Self, Self::Error> {
        let query = DELETE_PAYMENT_METHOD_FROM_VAULT_MUTATION.to_string();
        let variables = VariableDeletePaymentMethodFromVaultInput {
            input: DeletePaymentMethodFromVaultInputData {
                payment_method_id: Secret::new(
                    item.request
                        .connector_mandate_id
                        .clone()
                        .ok_or(errors::ConnectorError::MissingConnectorMandateID)?,
                ),
            },
        };
        Ok(Self { query, variables })
    }
}

impl<F>
    TryFrom<
        ResponseRouterData<
            F,
            BraintreeRevokeMandateResponse,
            MandateRevokeRequestData,
            MandateRevokeResponseData,
        >,
    > for RouterData<F, MandateRevokeRequestData, MandateRevokeResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            BraintreeRevokeMandateResponse,
            MandateRevokeRequestData,
            MandateRevokeResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: match item.response {
                BraintreeRevokeMandateResponse::ErrorResponse(error_response) => {
                    build_error_response(error_response.errors.as_ref(), item.http_code)
                        .map_err(|err| *err)
                }
                BraintreeRevokeMandateResponse::RevokeMandateResponse(..) => {
                    Ok(MandateRevokeResponseData {
                        mandate_status: common_enums::MandateStatus::Revoked,
                    })
                }
            },
            ..item.data
        })
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BraintreeRevokeMandateResponse {
    RevokeMandateResponse(Box<RevokeMandateResponse>),
    ErrorResponse(Box<ErrorResponse>),
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RevokeMandateResponse {
    data: DeletePaymentMethodFromVault,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeletePaymentMethodFromVault {
    client_mutation_id: Option<String>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CancelInputData {
    transaction_id: String,
}

#[derive(Debug, Serialize)]
pub struct VariableCancelInput {
    input: CancelInputData,
}

#[derive(Debug, Serialize)]
pub struct BraintreeCancelRequest {
    query: String,
    variables: VariableCancelInput,
}

impl TryFrom<&types::PaymentsCancelRouterData> for BraintreeCancelRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
        let query = VOID_TRANSACTION_MUTATION.to_string();
        let variables = VariableCancelInput {
            input: CancelInputData {
                transaction_id: item.request.connector_transaction_id.clone(),
            },
        };
        Ok(Self { query, variables })
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CancelResponseTransactionBody {
    id: String,
    status: BraintreePaymentStatus,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CancelTransactionData {
    reversal: CancelResponseTransactionBody,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CancelResponseData {
    reverse_transaction: CancelTransactionData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CancelResponse {
    data: CancelResponseData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BraintreeCancelResponse {
    CancelResponse(Box<CancelResponse>),
    ErrorResponse(Box<ErrorResponse>),
}

impl<F, T> TryFrom<ResponseRouterData<F, BraintreeCancelResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, BraintreeCancelResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            BraintreeCancelResponse::ErrorResponse(error_response) => Ok(Self {
                response: build_error_response(&error_response.errors, item.http_code)
                    .map_err(|err| *err),
                ..item.data
            }),
            BraintreeCancelResponse::CancelResponse(void_response) => {
                let void_data = void_response.data.reverse_transaction.reversal;
                let status = enums::AttemptStatus::from(void_data.status.clone());
                let response = if utils::is_payment_failure(status) {
                    Err(hyperswitch_domain_models::router_data::ErrorResponse {
                        code: void_data.status.to_string().clone(),
                        message: void_data.status.to_string().clone(),
                        reason: Some(void_data.status.to_string().clone()),
                        attempt_status: None,
                        connector_transaction_id: None,
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    })
                } else {
                    Ok(PaymentsResponseData::TransactionResponse {
                        resource_id: ResponseId::NoResponseId,
                        redirection_data: Box::new(None),
                        mandate_reference: Box::new(None),
                        connector_metadata: None,
                        network_txn_id: None,
                        connector_response_reference_id: None,
                        incremental_authorization_allowed: None,
                        charges: None,
                    })
                };
                Ok(Self {
                    status,
                    response,
                    ..item.data
                })
            }
        }
    }
}

impl TryFrom<&types::PaymentsSyncRouterData> for BraintreePSyncRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::PaymentsSyncRouterData) -> Result<Self, Self::Error> {
        let transaction_id = item
            .request
            .connector_transaction_id
            .get_connector_transaction_id()
            .change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
        Ok(Self {
            query: TRANSACTION_QUERY.to_string(),
            variables: PSyncInput {
                input: TransactionSearchInput {
                    id: IdFilter { is: transaction_id },
                },
            },
        })
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct NodeData {
    id: String,
    status: BraintreePaymentStatus,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct EdgeData {
    node: NodeData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TransactionData {
    edges: Vec<EdgeData>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SearchData {
    transactions: TransactionData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PSyncResponseData {
    search: SearchData,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PSyncResponse {
    data: PSyncResponseData,
}

impl<F, T> TryFrom<ResponseRouterData<F, BraintreePSyncResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, BraintreePSyncResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            BraintreePSyncResponse::ErrorResponse(error_response) => Ok(Self {
                response: build_error_response(&error_response.errors, item.http_code)
                    .map_err(|err| *err),
                ..item.data
            }),
            BraintreePSyncResponse::SuccessResponse(psync_response) => {
                let edge_data = psync_response
                    .data
                    .search
                    .transactions
                    .edges
                    .first()
                    .ok_or(errors::ConnectorError::MissingConnectorTransactionID)?;
                let status = enums::AttemptStatus::from(edge_data.node.status.clone());
                let response = if utils::is_payment_failure(status) {
                    Err(hyperswitch_domain_models::router_data::ErrorResponse {
                        code: edge_data.node.status.to_string().clone(),
                        message: edge_data.node.status.to_string().clone(),
                        reason: Some(edge_data.node.status.to_string().clone()),
                        attempt_status: None,
                        connector_transaction_id: None,
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    })
                } else {
                    Ok(PaymentsResponseData::TransactionResponse {
                        resource_id: ResponseId::ConnectorTransactionId(edge_data.node.id.clone()),
                        redirection_data: Box::new(None),
                        mandate_reference: Box::new(None),
                        connector_metadata: None,
                        network_txn_id: None,
                        connector_response_reference_id: None,
                        incremental_authorization_allowed: None,
                        charges: None,
                    })
                };
                Ok(Self {
                    status,
                    response,
                    ..item.data
                })
            }
        }
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BraintreeThreeDsResponse {
    pub nonce: Secret<String>,
    pub liability_shifted: bool,
    pub liability_shift_possible: bool,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BraintreeThreeDsErrorResponse {
    pub code: String,
    pub message: String,
}

#[derive(Debug, Deserialize)]
pub struct BraintreeRedirectionResponse {
    pub authentication_response: String,
}

impl TryFrom<BraintreeMeta> for BraintreeClientTokenRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(metadata: BraintreeMeta) -> Result<Self, Self::Error> {
        Ok(Self {
            query: CLIENT_TOKEN_MUTATION.to_owned(),
            variables: VariableClientTokenInput {
                input: InputClientTokenData {
                    client_token: ClientTokenInput {
                        merchant_account_id: metadata.merchant_account_id,
                    },
                },
            },
        })
    }
}

impl
    TryFrom<(
        &BraintreeRouterData<&types::PaymentsAuthorizeRouterData>,
        BraintreeMeta,
    )> for CardPaymentRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, metadata): (
            &BraintreeRouterData<&types::PaymentsAuthorizeRouterData>,
            BraintreeMeta,
        ),
    ) -> Result<Self, Self::Error> {
        let (query, transaction_body) = if item.router_data.request.is_mandate_payment() {
            (
                match item.router_data.request.is_auto_capture()? {
                    true => CHARGE_AND_VAULT_TRANSACTION_MUTATION.to_string(),
                    false => AUTHORIZE_AND_VAULT_CREDIT_CARD_MUTATION.to_string(),
                },
                TransactionBody::Vault(VaultTransactionBody {
                    amount: item.amount.to_owned(),
                    merchant_account_id: metadata.merchant_account_id,
                    vault_payment_method_after_transacting: TransactionTiming {
                        when: "ALWAYS".to_string(),
                    },
                    customer_details: item
                        .router_data
                        .get_billing_email()
                        .ok()
                        .map(|email| CustomerBody { email }),
                    order_id: item.router_data.connector_request_reference_id.clone(),
                }),
            )
        } else {
            (
                match item.router_data.request.is_auto_capture()? {
                    true => CHARGE_CREDIT_CARD_MUTATION.to_string(),
                    false => AUTHORIZE_CREDIT_CARD_MUTATION.to_string(),
                },
                TransactionBody::Regular(RegularTransactionBody {
                    amount: item.amount.to_owned(),
                    merchant_account_id: metadata.merchant_account_id,
                    channel: CHANNEL_CODE.to_string(),
                    customer_details: item
                        .router_data
                        .get_billing_email()
                        .ok()
                        .map(|email| CustomerBody { email }),
                    order_id: item.router_data.connector_request_reference_id.clone(),
                }),
            )
        };
        Ok(Self {
            query,
            variables: VariablePaymentInput {
                input: PaymentInput {
                    payment_method_id: match item.router_data.get_payment_method_token()? {
                        PaymentMethodToken::Token(token) => token,
                        PaymentMethodToken::ApplePayDecrypt(_) => Err(
                            unimplemented_payment_method!("Apple Pay", "Simplified", "Braintree"),
                        )?,
                        PaymentMethodToken::PazeDecrypt(_) => {
                            Err(unimplemented_payment_method!("Paze", "Braintree"))?
                        }
                        PaymentMethodToken::GooglePayDecrypt(_) => {
                            Err(unimplemented_payment_method!("Google Pay", "Braintree"))?
                        }
                    },
                    transaction: transaction_body,
                },
            },
        })
    }
}

impl TryFrom<&BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>>
    for CardPaymentRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        let metadata: BraintreeMeta = if let (
            Some(merchant_account_id),
            Some(merchant_config_currency),
        ) = (
            item.router_data.request.merchant_account_id.clone(),
            item.router_data.request.merchant_config_currency,
        ) {
            router_env::logger::info!(
                "BRAINTREE: Picking merchant_account_id and merchant_config_currency from payments request"
            );

            BraintreeMeta {
                merchant_account_id,
                merchant_config_currency,
            }
        } else {
            utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())
                .change_context(errors::ConnectorError::InvalidConnectorConfig {
                    config: "metadata",
                })?
        };
        utils::validate_currency(
            item.router_data.request.currency,
            Some(metadata.merchant_config_currency),
        )?;
        let payload_data = PaymentsCompleteAuthorizeRequestData::get_redirect_response_payload(
            &item.router_data.request,
        )?
        .expose();
        let redirection_response: BraintreeRedirectionResponse = serde_json::from_value(
            payload_data,
        )
        .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload {
            field_name: "redirection_response",
        })?;
        let three_ds_data = serde_json::from_str::<BraintreeThreeDsResponse>(
            &redirection_response.authentication_response,
        )
        .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload {
            field_name: "three_ds_data",
        })?;

        let (query, transaction_body) = if item.router_data.request.is_mandate_payment() {
            (
                match item.router_data.request.is_auto_capture()? {
                    true => CHARGE_AND_VAULT_TRANSACTION_MUTATION.to_string(),
                    false => AUTHORIZE_AND_VAULT_CREDIT_CARD_MUTATION.to_string(),
                },
                TransactionBody::Vault(VaultTransactionBody {
                    amount: item.amount.to_owned(),
                    merchant_account_id: metadata.merchant_account_id,
                    vault_payment_method_after_transacting: TransactionTiming {
                        when: "ALWAYS".to_string(),
                    },
                    customer_details: item
                        .router_data
                        .get_billing_email()
                        .ok()
                        .map(|email| CustomerBody { email }),
                    order_id: item.router_data.connector_request_reference_id.clone(),
                }),
            )
        } else {
            (
                match item.router_data.request.is_auto_capture()? {
                    true => CHARGE_CREDIT_CARD_MUTATION.to_string(),
                    false => AUTHORIZE_CREDIT_CARD_MUTATION.to_string(),
                },
                TransactionBody::Regular(RegularTransactionBody {
                    amount: item.amount.to_owned(),
                    merchant_account_id: metadata.merchant_account_id,
                    channel: CHANNEL_CODE.to_string(),
                    customer_details: item
                        .router_data
                        .get_billing_email()
                        .ok()
                        .map(|email| CustomerBody { email }),
                    order_id: item.router_data.connector_request_reference_id.clone(),
                }),
            )
        };
        Ok(Self {
            query,
            variables: VariablePaymentInput {
                input: PaymentInput {
                    payment_method_id: three_ds_data.nonce,
                    transaction: transaction_body,
                },
            },
        })
    }
}

fn get_braintree_redirect_form(
    client_token_data: ClientTokenResponse,
    payment_method_token: PaymentMethodToken,
    card_details: PaymentMethodData,
    complete_authorize_url: String,
) -> Result<RedirectForm, error_stack::Report<errors::ConnectorError>> {
    Ok(RedirectForm::Braintree {
        client_token: client_token_data
            .data
            .create_client_token
            .client_token
            .expose(),
        card_token: match payment_method_token {
            PaymentMethodToken::Token(token) => token.expose(),
            PaymentMethodToken::ApplePayDecrypt(_) => Err(unimplemented_payment_method!(
                "Apple Pay",
                "Simplified",
                "Braintree"
            ))?,
            PaymentMethodToken::PazeDecrypt(_) => {
                Err(unimplemented_payment_method!("Paze", "Braintree"))?
            }
            PaymentMethodToken::GooglePayDecrypt(_) => {
                Err(unimplemented_payment_method!("Google Pay", "Braintree"))?
            }
        },
        bin: match card_details {
            PaymentMethodData::Card(card_details) => card_details.card_number.get_card_isin(),
            PaymentMethodData::CardRedirect(_)
            | PaymentMethodData::Wallet(_)
            | PaymentMethodData::PayLater(_)
            | PaymentMethodData::BankRedirect(_)
            | PaymentMethodData::BankDebit(_)
            | PaymentMethodData::BankTransfer(_)
            | PaymentMethodData::Crypto(_)
            | PaymentMethodData::MandatePayment
            | PaymentMethodData::OpenBanking(_)
            | PaymentMethodData::Reward
            | PaymentMethodData::RealTimePayment(_)
            | PaymentMethodData::MobilePayment(_)
            | PaymentMethodData::Upi(_)
            | PaymentMethodData::Voucher(_)
            | PaymentMethodData::GiftCard(_)
            | PaymentMethodData::CardToken(_)
            | PaymentMethodData::NetworkToken(_)
            | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => Err(
                errors::ConnectorError::NotImplemented("given payment method".to_owned()),
            )?,
        },
        acs_url: complete_authorize_url,
    })
}

#[derive(Debug, Deserialize)]
pub struct BraintreeWebhookResponse {
    pub bt_signature: String,
    pub bt_payload: String,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct Notification {
    pub kind: String, // xml parse only string to fields
    pub timestamp: String,
    pub dispute: Option<BraintreeDisputeData>,
}

pub(crate) fn get_status(status: &str) -> IncomingWebhookEvent {
    match status {
        "dispute_opened" => IncomingWebhookEvent::DisputeOpened,
        "dispute_lost" => IncomingWebhookEvent::DisputeLost,
        "dispute_won" => IncomingWebhookEvent::DisputeWon,
        "dispute_accepted" | "dispute_auto_accepted" => IncomingWebhookEvent::DisputeAccepted,
        "dispute_expired" => IncomingWebhookEvent::DisputeExpired,
        "dispute_disputed" => IncomingWebhookEvent::DisputeChallenged,
        _ => IncomingWebhookEvent::EventNotSupported,
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct BraintreeDisputeData {
    pub amount_disputed: MinorUnit,
    pub amount_won: Option<String>,
    pub case_number: Option<String>,
    pub chargeback_protection_level: Option<String>,
    pub currency_iso_code: enums::Currency,
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub created_at: Option<PrimitiveDateTime>,
    pub evidence: Option<DisputeEvidence>,
    pub id: String,
    pub kind: String, // xml parse only string to fields
    pub status: String,
    pub reason: Option<String>,
    pub reason_code: Option<String>,
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub updated_at: Option<PrimitiveDateTime>,
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub reply_by_date: Option<PrimitiveDateTime>,
    pub transaction: DisputeTransaction,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct DisputeTransaction {
    pub amount: StringMajorUnit,
    pub id: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct DisputeEvidence {
    pub comment: String,
    pub id: Secret<String>,
    pub created_at: Option<PrimitiveDateTime>,
    pub url: url::Url,
}

pub(crate) fn get_dispute_stage(code: &str) -> Result<enums::DisputeStage, errors::ConnectorError> {
    match code {
        "CHARGEBACK" => Ok(enums::DisputeStage::Dispute),
        "PRE_ARBITRATION" => Ok(enums::DisputeStage::PreArbitration),
        "RETRIEVAL" => Ok(enums::DisputeStage::PreDispute),
        _ => Err(errors::ConnectorError::WebhookBodyDecodingFailed),
    }
}


File: crates/euclid/src/frontend/vir.rs
 Public structs: 4

//! Valued Intermediate Representation
use serde::{Deserialize, Serialize};

use crate::types::{EuclidValue, Metadata};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValuedComparisonLogic {
    NegativeConjunction,
    PositiveDisjunction,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ValuedComparison {
    pub values: Vec<EuclidValue>,
    pub logic: ValuedComparisonLogic,
    pub metadata: Metadata,
}

pub type ValuedIfCondition = Vec<ValuedComparison>;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ValuedIfStatement {
    pub condition: ValuedIfCondition,
    pub nested: Option<Vec<ValuedIfStatement>>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ValuedRule<O> {
    pub name: String,
    pub connector_selection: O,
    pub statements: Vec<ValuedIfStatement>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ValuedProgram<O> {
    pub default_selection: O,
    pub rules: Vec<ValuedRule<O>>,
    pub metadata: Metadata,
}


impl api::RefundSync for Boku {}


pub struct MandateResponseBody {
    return_value: u8,
    token: Option<String>,
}


pub struct NmiAuthType {
    pub(super) api_key: Secret<String>,
    pub(super) public_key: Option<Secret<String>>,
}


File: crates/router/src/services/kafka/revenue_recovery.rs
 Public structs: 1

use common_utils::{id_type, types::MinorUnit};
use masking::Secret;
use time::OffsetDateTime;
#[derive(serde::Serialize, Debug)]
pub struct RevenueRecovery<'a> {
    pub merchant_id: &'a id_type::MerchantId,
    pub invoice_amount: MinorUnit,
    pub invoice_currency: &'a common_enums::Currency,
    #[serde(default, with = "time::serde::timestamp::nanoseconds::option")]
    pub invoice_due_date: Option<OffsetDateTime>,
    #[serde(with = "time::serde::timestamp::nanoseconds::option")]
    pub invoice_date: Option<OffsetDateTime>,
    pub billing_country: Option<&'a common_enums::CountryAlpha2>,
    pub billing_state: Option<Secret<String>>,
    pub billing_city: Option<Secret<String>>,
    pub attempt_amount: MinorUnit,
    pub attempt_currency: &'a common_enums::Currency,
    pub attempt_status: &'a common_enums::AttemptStatus,
    pub pg_error_code: Option<String>,
    pub network_advice_code: Option<String>,
    pub network_error_code: Option<String>,
    pub first_pg_error_code: Option<String>,
    pub first_network_advice_code: Option<String>,
    pub first_network_error_code: Option<String>,
    #[serde(default, with = "time::serde::timestamp::nanoseconds")]
    pub attempt_created_at: OffsetDateTime,
    pub payment_method_type: Option<&'a common_enums::PaymentMethod>,
    pub payment_method_subtype: Option<&'a common_enums::PaymentMethodType>,
    pub card_network: Option<&'a common_enums::CardNetwork>,
    pub card_issuer: Option<String>,
    pub retry_count: Option<i32>,
    pub payment_gateway: Option<common_enums::connector_enums::Connector>,
}

impl super::KafkaMessage for RevenueRecovery<'_> {
    fn key(&self) -> String {
        self.merchant_id.get_string_repr().to_string()
    }

    fn event_type(&self) -> crate::events::EventType {
        crate::events::EventType::RevenueRecovery
    }
}


impl PaymentCapture for Worldline {}


pub async fn insert_totp_attempts_in_redis(
    state: &SessionState,
    user_id: &str,
    user_totp_attempts: u8,
) -> UserResult<()> {
    let redis_conn = super::get_redis_connection_for_global_tenant(state)?;
    redis_conn
        .set_key_with_expiry(
            &get_totp_attempts_key(user_id).into(),
            user_totp_attempts,
            consts::user::REDIS_TOTP_ATTEMPTS_TTL_IN_SECS,
        )
        .await
        .change_context(UserErrors::InternalServerError)
}


pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<ReverseLookup> {
        generics::generic_insert(conn, self).await
    }


impl Responder {
    let flow = Flow::SessionUpdateTaxCalculation;
    let payment_id = path.into_inner();
    let payload = payment_types::PaymentsDynamicTaxCalculationRequest {
        payment_id,
        ..json_payload.into_inner()
    };
    let header_payload = match HeaderPayload::foreign_try_from(req.headers()) {
        Ok(headers) => headers,
        Err(error) => {
            logger::error!(
                ?error,
                "Failed to get headers in payments_connector_session"
            );
            HeaderPayload::default()
        }
    };
    tracing::Span::current().record("payment_id", payload.payment_id.get_string_repr());
    let locking_action = payload.get_locking_input(flow.clone());
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload,
        |state, auth: auth::AuthenticationData, payload, req_state| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            payments::payments_core::<
                api_types::SdkSessionUpdate,
                payment_types::PaymentsDynamicTaxCalculationResponse,
                _,
                _,
                _,
                _,
            >(
                state,
                req_state,
                merchant_context,
                auth.profile_id,
                payments::PaymentSessionUpdate,
                payload,
                api::AuthFlow::Client,
                payments::CallConnectorAction::Trigger,
                None,
                header_payload.clone(),
            )
        },
        &auth::PublishableKeyAuth,
        locking_action,
    ))
    .await
}


impl api::Payment for Bitpay {}


pub struct Item {
    pub display_name: String,
    pub sku: String,
    pub unit_price: MinorUnit,
    pub qty: i64,
}


pub struct RefundResponse {
    action_id: String,
    reference: String,
}


impl PaymentIncrementalAuthorization for Stripe {}

impl PaymentIncrementalAuthorization for for Stripe


impl api::MandateSetup for Nexinets {}