File: crates/analytics/src/auth_events/metrics/authentication_exemption_approved_count.rs

use std::collections::HashSet;

use api_models::analytics::{
    auth_events::{AuthEventDimensions, AuthEventFilters, AuthEventMetricsBucketIdentifier},
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

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

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

#[async_trait::async_trait]
impl<T> super::AuthEventMetric<T> for AuthenticationExemptionApprovedCount
where
    T: AnalyticsDataSource + super::AuthEventMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        auth: &AuthInfo,
        dimensions: &[AuthEventDimensions],
        filters: &AuthEventFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
        let mut query_builder: QueryBuilder<T> =
            QueryBuilder::new(AnalyticsCollection::Authentications);
        for dim in dimensions.iter() {
            query_builder.add_select_column(dim).switch()?;
        }
        query_builder
            .add_select_column(Aggregate::Count {
                field: None,
                alias: Some("count"),
            })
            .switch()?;

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

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

        query_builder
            .add_filter_clause(AuthEventDimensions::ExemptionAccepted, true)
            .switch()?;
        filters.set_filter_clause(&mut query_builder).switch()?;
        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;
        auth.set_filter_clause(&mut query_builder).switch()?;

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

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

        query_builder
            .execute_query::<AuthEventMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    AuthEventMetricsBucketIdentifier::new(
                        i.authentication_status.as_ref().map(|i| i.0),
                        i.trans_status.as_ref().map(|i| i.0.clone()),
                        i.authentication_type.as_ref().map(|i| i.0),
                        i.error_message.clone(),
                        i.authentication_connector.as_ref().map(|i| i.0),
                        i.message_version.clone(),
                        i.acs_reference_number.clone(),
                        i.mcc.clone(),
                        i.currency.as_ref().map(|i| i.0),
                        i.merchant_country.clone(),
                        i.billing_country.clone(),
                        i.shipping_country.clone(),
                        i.issuer_country.clone(),
                        i.earliest_supported_version.clone(),
                        i.latest_supported_version.clone(),
                        i.whitelist_decision,
                        i.device_manufacturer.clone(),
                        i.device_type.clone(),
                        i.device_brand.clone(),
                        i.device_os.clone(),
                        i.device_display.clone(),
                        i.browser_name.clone(),
                        i.browser_version.clone(),
                        i.issuer_id.clone(),
                        i.scheme_name.clone(),
                        i.exemption_requested,
                        i.exemption_accepted,
                        TimeRange {
                            start_time: match (granularity, i.start_bucket) {
                                (Some(g), Some(st)) => g.clip_to_start(st)?,
                                _ => time_range.start_time,
                            },
                            end_time: granularity.as_ref().map_or_else(
                                || Ok(time_range.end_time),
                                |g| i.end_bucket.map(|et| g.clip_to_end(et)).transpose(),
                            )?,
                        },
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


pub fn compare_password(&self, candidate: &Secret<String>) -> UserResult<()> {
        if let Some(password) = self.0.password.as_ref() {
            match password::is_correct_password(candidate, password) {
                Ok(true) => Ok(()),
                Ok(false) => Err(UserErrors::InvalidCredentials.into()),
                Err(e) => Err(e),
            }
        } else {
            Err(UserErrors::InvalidCredentials.into())
        }
    }


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


File: crates/router/src/types/storage/merchant_key_store.rs

pub use diesel_models::merchant_key_store::MerchantKeyStore;


impl Default for ContractBasedRoutingConfig {
    fn default() -> Self {
        Self {
            config: Some(ContractBasedRoutingConfigBody {
                constants: Some(vec![0.7, 0.35]),
                time_scale: Some(ContractBasedTimeScale::Day),
            }),
            label_info: None,
        }
    }
}

impl Default for for ContractBasedRoutingConfig


pub fn from_bytes(bytes: &[u8]) -> Self {
        // First try to parse as JSON
        if let Ok(json_response) = serde_json::from_slice::<Self>(bytes) {
            json_response
        } else {
            // If JSON parsing fails, treat as plain text
            let text = String::from_utf8_lossy(bytes).to_string();
            Self::Text(text)
        }
    }


impl super::sdk_events::events::SdkEventsFilterAnalytics for ClickhouseClient {}

impl super::sdk_events::events::SdkEventsFilterAnalytics for for ClickhouseClient


pub struct CycleCheck(FxHashMap<NodeId, (Strength, RelationResolution)>);


pub fn deserialize_to_response<T>(data: Option<&DashboardMetadata>) -> UserResult<Option<T>>
where
    T: serde::de::DeserializeOwned,
{
    data.map(|metadata| serde_json::from_value(metadata.data_value.clone().expose()))
        .transpose()
        .change_context(UserErrors::InternalServerError)
        .attach_printable("Error Serializing Metadata from DB")
}


OpenAPI Block Path: components.schemas.PayoutRetrieveRequest
{
  "type": "object",
  "required": [
    "payout_id"
  ],
  "properties": {
    "payout_id": {
      "type": "string",
      "description": "Unique identifier for the payout. This ensures idempotency for multiple payouts\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.",
      "example": "187282ab-40ef-47a9-9206-5099ba31e432",
      "maxLength": 30,
      "minLength": 30
    },
    "force_sync": {
      "type": "boolean",
      "description": "`force_sync` with the connector to get payout details\n(defaults to false)",
      "default": false,
      "example": true,
      "nullable": true
    },
    "merchant_id": {
      "type": "string",
      "description": "The identifier for the Merchant Account.",
      "nullable": true
    }
  }
}


File: crates/hyperswitch_constraint_graph/src/error.rs
 Public functions: 1

use std::sync::{Arc, Weak};

use crate::types::{Metadata, NodeValue, Relation, RelationResolution, ValueNode};

#[derive(Debug, Clone, serde::Serialize)]
#[serde(tag = "type", content = "predecessor", rename_all = "snake_case")]
pub enum ValueTracePredecessor<V: ValueNode> {
    Mandatory(Box<Weak<AnalysisTrace<V>>>),
    OneOf(Vec<Weak<AnalysisTrace<V>>>),
}

#[derive(Debug, Clone, serde::Serialize)]
#[serde(tag = "type", content = "trace", rename_all = "snake_case")]
pub enum AnalysisTrace<V: ValueNode> {
    Value {
        value: NodeValue<V>,
        relation: Relation,
        predecessors: Option<ValueTracePredecessor<V>>,
        info: Option<&'static str>,
        metadata: Option<Arc<dyn Metadata>>,
    },

    AllAggregation {
        unsatisfied: Vec<Weak<AnalysisTrace<V>>>,
        info: Option<&'static str>,
        metadata: Option<Arc<dyn Metadata>>,
    },

    AnyAggregation {
        unsatisfied: Vec<Weak<AnalysisTrace<V>>>,
        info: Option<&'static str>,
        metadata: Option<Arc<dyn Metadata>>,
    },

    InAggregation {
        expected: Vec<V>,
        found: Option<V>,
        relation: Relation,
        info: Option<&'static str>,
        metadata: Option<Arc<dyn Metadata>>,
    },
    Contradiction {
        relation: RelationResolution,
    },
}

#[derive(Debug, Clone, serde::Serialize, thiserror::Error)]
#[serde(tag = "type", content = "info", rename_all = "snake_case")]
pub enum GraphError<V: ValueNode> {
    #[error("An edge was not found in the graph")]
    EdgeNotFound,
    #[error("Attempted to create a conflicting edge between two nodes")]
    ConflictingEdgeCreated,
    #[error("Cycle detected in graph")]
    CycleDetected,
    #[error("Domain wasn't found in the Graph")]
    DomainNotFound,
    #[error("Malformed Graph: {reason}")]
    MalformedGraph { reason: String },
    #[error("A node was not found in the graph")]
    NodeNotFound,
    #[error("A value node was not found: {0:#?}")]
    ValueNodeNotFound(V),
    #[error("No values provided for an 'in' aggregator node")]
    NoInAggregatorValues,
    #[error("Error during analysis: {0:#?}")]
    AnalysisError(Weak<AnalysisTrace<V>>),
}

impl<V: ValueNode> GraphError<V> {
    pub fn get_analysis_trace(self) -> Result<Weak<AnalysisTrace<V>>, Self> {
        match self {
            Self::AnalysisError(trace) => Ok(trace),
            _ => Err(self),
        }
    }
}


File: crates/api_models/src/user/theme.rs
 Public structs: 8

use actix_multipart::form::{bytes::Bytes, text::Text, MultipartForm};
use common_enums::EntityType;
use common_utils::{
    id_type,
    types::user::{EmailThemeConfig, ThemeLineage},
};
use masking::Secret;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize)]
pub struct GetThemeResponse {
    pub theme_id: String,
    pub theme_name: String,
    pub entity_type: EntityType,
    pub tenant_id: id_type::TenantId,
    pub org_id: Option<id_type::OrganizationId>,
    pub merchant_id: Option<id_type::MerchantId>,
    pub profile_id: Option<id_type::ProfileId>,
    pub email_config: EmailThemeConfig,
    pub theme_data: ThemeData,
}

#[derive(Debug, MultipartForm)]
pub struct UploadFileAssetData {
    pub asset_name: Text<String>,
    #[multipart(limit = "10MB")]
    pub asset_data: Bytes,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct UploadFileRequest {
    pub asset_name: String,
    pub asset_data: Secret<Vec<u8>>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct CreateThemeRequest {
    pub lineage: ThemeLineage,
    pub theme_name: String,
    pub theme_data: ThemeData,
    pub email_config: Option<EmailThemeConfig>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct CreateUserThemeRequest {
    pub entity_type: EntityType,
    pub theme_name: String,
    pub theme_data: ThemeData,
    pub email_config: Option<EmailThemeConfig>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct UpdateThemeRequest {
    pub theme_data: Option<ThemeData>,
    pub email_config: Option<EmailThemeConfig>,
}

// All the below structs are for the theme.json file,
// which will be used by frontend to style the dashboard.
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ThemeData {
    settings: Settings,
    urls: Option<Urls>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Settings {
    colors: Colors,
    sidebar: Option<Sidebar>,
    typography: Option<Typography>,
    buttons: Buttons,
    borders: Option<Borders>,
    spacing: Option<Spacing>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Colors {
    primary: String,
    secondary: Option<String>,
    background: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Sidebar {
    primary: String,
    text_color: Option<String>,
    text_color_primary: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Typography {
    font_family: Option<String>,
    font_size: Option<String>,
    heading_font_size: Option<String>,
    text_color: Option<String>,
    link_color: Option<String>,
    link_hover_color: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Buttons {
    primary: PrimaryButton,
    secondary: Option<SecondaryButton>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct PrimaryButton {
    background_color: Option<String>,
    text_color: Option<String>,
    hover_background_color: String,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct SecondaryButton {
    background_color: Option<String>,
    text_color: Option<String>,
    hover_background_color: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Borders {
    default_radius: Option<String>,
    border_color: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Spacing {
    padding: Option<String>,
    margin: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Urls {
    favicon_url: Option<String>,
    logo_url: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
pub struct EntityTypeQueryParam {
    pub entity_type: EntityType,
}


impl api::Payment for Bambora {}


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


impl CreateProfile {
    /// Create a new profile action from the given information
    /// If primary business details exist, then create profiles from them
    /// If primary business details are empty, then create default profile
    fn new(primary_business_details: Option<Vec<admin_types::PrimaryBusinessDetails>>) -> Self {
        match primary_business_details {
            Some(primary_business_details) if !primary_business_details.is_empty() => {
                Self::CreateFromPrimaryBusinessDetails {
                    primary_business_details,
                }
            }
            _ => Self::CreateDefaultProfile,
        }
    }

    async fn create_profiles(
        &self,
        state: &SessionState,
        merchant_account: &mut domain::MerchantAccount,
        key_store: &domain::MerchantKeyStore,
    ) -> RouterResult<()> {
        match self {
            Self::CreateFromPrimaryBusinessDetails {
                primary_business_details,
            } => {
                let business_profiles = Self::create_profiles_for_each_business_details(
                    state,
                    merchant_account.clone(),
                    primary_business_details,
                    key_store,
                )
                .await?;

                // Update the default business profile in merchant account
                if business_profiles.len() == 1 {
                    merchant_account.default_profile = business_profiles
                        .first()
                        .map(|business_profile| business_profile.get_id().to_owned())
                }
            }
            Self::CreateDefaultProfile => {
                let business_profile = self
                    .create_default_business_profile(state, merchant_account.clone(), key_store)
                    .await?;

                merchant_account.default_profile = Some(business_profile.get_id().to_owned());
            }
        }

        Ok(())
    }

    /// Create default profile
    async fn create_default_business_profile(
        &self,
        state: &SessionState,
        merchant_account: domain::MerchantAccount,
        key_store: &domain::MerchantKeyStore,
    ) -> RouterResult<domain::Profile> {
        let business_profile = create_and_insert_business_profile(
            state,
            api_models::admin::ProfileCreate::default(),
            merchant_account.clone(),
            key_store,
        )
        .await?;

        Ok(business_profile)
    }

    /// Create profile for each primary_business_details,
    /// If there is no default profile in merchant account and only one primary_business_detail
    /// is available, then create a default profile.
    async fn create_profiles_for_each_business_details(
        state: &SessionState,
        merchant_account: domain::MerchantAccount,
        primary_business_details: &Vec<admin_types::PrimaryBusinessDetails>,
        key_store: &domain::MerchantKeyStore,
    ) -> RouterResult<Vec<domain::Profile>> {
        let mut business_profiles_vector = Vec::with_capacity(primary_business_details.len());

        // This must ideally be run in a transaction,
        // if there is an error in inserting some profile, because of unique constraints
        // the whole query must be rolled back
        for business_profile in primary_business_details {
            let profile_name =
                format!("{}_{}", business_profile.country, business_profile.business);

            let profile_create_request = api_models::admin::ProfileCreate {
                profile_name: Some(profile_name),
                ..Default::default()
            };

            create_and_insert_business_profile(
                state,
                profile_create_request,
                merchant_account.clone(),
                key_store,
            )
            .await
            .map_err(|profile_insert_error| {
                logger::warn!("Profile already exists {profile_insert_error:?}");
            })
            .map(|business_profile| business_profiles_vector.push(business_profile))
            .ok();
        }

        Ok(business_profiles_vector)
    }
}


impl Connector {
    #[cfg(feature = "payouts")]
    pub fn supports_instant_payout(self, payout_method: Option<PayoutType>) -> bool {
        matches!(
            (self, payout_method),
            (Self::Paypal, Some(PayoutType::Wallet))
                | (_, Some(PayoutType::Card))
                | (Self::Adyenplatform, _)
                | (Self::Nomupay, _)
        )
    }
    #[cfg(feature = "payouts")]
    pub fn supports_create_recipient(self, payout_method: Option<PayoutType>) -> bool {
        matches!((self, payout_method), (_, Some(PayoutType::Bank)))
    }
    #[cfg(feature = "payouts")]
    pub fn supports_payout_eligibility(self, payout_method: Option<PayoutType>) -> bool {
        matches!((self, payout_method), (_, Some(PayoutType::Card)))
    }
    #[cfg(feature = "payouts")]
    pub fn is_payout_quote_call_required(self) -> bool {
        matches!(self, Self::Wise)
    }
    #[cfg(feature = "payouts")]
    pub fn supports_access_token_for_payout(self, payout_method: Option<PayoutType>) -> bool {
        matches!((self, payout_method), (Self::Paypal, _))
    }
    #[cfg(feature = "payouts")]
    pub fn supports_vendor_disburse_account_create_for_payout(self) -> bool {
        matches!(self, Self::Stripe | Self::Nomupay)
    }
    pub fn supports_access_token(self, payment_method: PaymentMethod) -> bool {
        matches!(
            (self, payment_method),
            (Self::Airwallex, _)
                | (Self::Deutschebank, _)
                | (Self::Globalpay, _)
                | (Self::Jpmorgan, _)
                | (Self::Moneris, _)
                | (Self::Nordea, _)
                | (Self::Paypal, _)
                | (Self::Payu, _)
                | (
                    Self::Trustpay,
                    PaymentMethod::BankRedirect | PaymentMethod::BankTransfer
                )
                | (Self::Iatapay, _)
                | (Self::Volt, _)
                | (Self::Itaubank, _)
                | (Self::Facilitapay, _)
                | (Self::Dwolla, _)
        )
    }
    pub fn requires_order_creation_before_payment(self, payment_method: PaymentMethod) -> bool {
        matches!((self, payment_method), (Self::Razorpay, PaymentMethod::Upi))
    }
    pub fn supports_file_storage_module(self) -> bool {
        matches!(self, Self::Stripe | Self::Checkout | Self::Worldpayvantiv)
    }
    pub fn requires_defend_dispute(self) -> bool {
        matches!(self, Self::Checkout)
    }
    pub fn is_separate_authentication_supported(self) -> bool {
        match self {
            #[cfg(feature = "dummy_connector")]
            Self::DummyBillingConnector => false,
            #[cfg(feature = "dummy_connector")]
            Self::DummyConnector1
            | Self::DummyConnector2
            | Self::DummyConnector3
            | Self::DummyConnector4
            | Self::DummyConnector5
            | Self::DummyConnector6
            | Self::DummyConnector7 => false,
            Self::Aci
            // Add Separate authentication support for connectors
			| Self::Authipay
            | Self::Adyen
            | Self::Affirm
            | Self::Adyenplatform
            | Self::Airwallex
            | Self::Amazonpay
            | Self::Authorizedotnet
            | Self::Bambora
            | Self::Bamboraapac
            | Self::Bankofamerica
            | Self::Barclaycard
            | Self::Billwerk
            | Self::Bitpay
            | Self::Bluesnap
            | Self::Blackhawknetwork
            | Self::Bluecode
            | Self::Boku
            | Self::Braintree
            | Self::Breadpay
            | Self::Cashtocode
            | Self::Celero
            | Self::Chargebee
            | Self::Checkbook
            | Self::Coinbase
            | Self::Coingate
            | Self::Cryptopay
            | Self::Custombilling
            | Self::Deutschebank
            | Self::Digitalvirgo
            | Self::Dlocal
            | Self::Dwolla
            | Self::Ebanx
            | Self::Elavon
            | Self::Facilitapay
            | Self::Fiserv
            | Self::Fiservemea
            | Self::Fiuu
            | Self::Flexiti
            | Self::Forte
            | Self::Getnet
            | Self::Globalpay
            | Self::Globepay
            | Self::Gocardless
            | Self::Gpayments
            | Self::Hipay
            | Self::Helcim
            | Self::HyperswitchVault
            | Self::Iatapay
			| Self::Inespay
            | Self::Itaubank
            | Self::Jpmorgan
            | Self::Juspaythreedsserver
            | Self::Klarna
            | Self::Mifinity
            | Self::Mollie
            | Self::Moneris
            | Self::Multisafepay
            | Self::Nexinets
            | Self::Nexixpay
            | Self::Nomupay
            | Self::Nordea
            | Self::Novalnet
            | Self::Nuvei
            | Self::Opennode
            | Self::Paybox
            | Self::Payload
            | Self::Payme
            | Self::Payone
            | Self::Paypal
            | Self::Paysafe
            | Self::Paystack
            | Self::Payu
            | Self::Placetopay
            | Self::Powertranz
            | Self::Prophetpay
            | Self::Rapyd
            | Self::Recurly
            | Self::Redsys
            | Self::Santander
            | Self::Shift4
            | Self::Silverflow
            | Self::Square
            | Self::Stax
            | Self::Stripebilling
            | Self::Taxjar
            // | Self::Thunes
            | Self::Trustpay
            // | Self::Tokenio
            | Self::Tsys
            // | Self::UnifiedAuthenticationService
            | Self::Vgs
            | Self::Volt
            | Self::Wellsfargo
            // | Self::Wellsfargopayout
            | Self::Wise
            | Self::Worldline
            | Self::Worldpay
            | Self::Worldpayvantiv
            | Self::Worldpayxml
            | Self::Xendit
            | Self::Zen
            | Self::Zsl
            | Self::Signifyd
            | Self::Plaid
            | Self::Razorpay
            | Self::Riskified
            | Self::Threedsecureio
            | Self::Netcetera
            | Self::CtpMastercard
            | Self::CtpVisa
            | Self::Noon
            | Self::Tokenio
            | Self::Stripe
            | Self::Datatrans
            | Self::Paytm
            | Self::Phonepe => false,
            Self::Checkout | Self::Nmi |Self::Cybersource | Self::Archipel => true,
        }
    }

    pub fn is_pre_processing_required_before_authorize(self) -> bool {
        matches!(self, Self::Airwallex)
    }

    pub fn get_payment_methods_supporting_extended_authorization(self) -> HashSet<PaymentMethod> {
        HashSet::from([PaymentMethod::Card])
    }
    pub fn get_payment_method_types_supporting_extended_authorization(
        self,
    ) -> HashSet<PaymentMethodType> {
        HashSet::from([PaymentMethodType::Credit, PaymentMethodType::Debit])
    }

    pub fn should_acknowledge_webhook_for_resource_not_found_errors(self) -> bool {
        matches!(self, Self::Adyenplatform)
    }

    /// Validates if dummy connector can be created
    /// Dummy connectors can be created only if dummy_connector feature is enabled in the configs
    #[cfg(feature = "dummy_connector")]
    pub fn validate_dummy_connector_create(self, is_dummy_connector_enabled: bool) -> bool {
        matches!(
            self,
            Self::DummyConnector1
                | Self::DummyConnector2
                | Self::DummyConnector3
                | Self::DummyConnector4
                | Self::DummyConnector5
                | Self::DummyConnector6
                | Self::DummyConnector7
        ) && !is_dummy_connector_enabled
    }
}


pub struct ErrorDetailItem {
    pub field: String,
    pub message: String,
}


OpenAPI Block Path: components.schemas.BankTransferTypes
{
  "type": "object",
  "required": [
    "eligible_connectors"
  ],
  "properties": {
    "eligible_connectors": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "The list of eligible connectors for a given payment experience",
      "example": [
        "stripe",
        "adyen"
      ]
    }
  }
}


/// Generate Api Key Id from prefix
    pub fn generate_key_id(prefix: &'static str) -> Self {
        Self(crate::generate_ref_id_with_default_length(prefix))
    }


impl api::PaymentSession for Paytm {}


impl api::PaymentSession for Zsl {}


pub struct Bambora {
    amount_convertor: &'static (dyn AmountConvertor<Output = FloatMajorUnit> + Sync),
}


pub async fn validate_and_create_refund(
    state: &SessionState,
    merchant_context: &domain::MerchantContext,
    payment_attempt: &storage::PaymentAttempt,
    payment_intent: &storage::PaymentIntent,
    refund_amount: MinorUnit,
    req: refunds::RefundRequest,
    creds_identifier: Option<String>,
) -> RouterResult<refunds::RefundResponse> {
    let db = &*state.store;
    let split_refunds = core_utils::get_split_refunds(SplitRefundInput {
        split_payment_request: payment_intent.split_payments.clone(),
        payment_charges: payment_attempt.charges.clone(),
        charge_id: payment_attempt.charge_id.clone(),
        refund_request: req.split_refunds.clone(),
    })?;

    // Only for initial dev and testing
    let refund_type = req.refund_type.unwrap_or_default();

    // If Refund Id not passed in request Generate one.

    let refund_id = core_utils::get_or_generate_id("refund_id", &req.refund_id, "ref")?;

    let predicate = req
        .merchant_id
        .as_ref()
        .map(|merchant_id| merchant_id != merchant_context.get_merchant_account().get_id());

    utils::when(predicate.unwrap_or(false), || {
        Err(report!(errors::ApiErrorResponse::InvalidDataFormat {
            field_name: "merchant_id".to_string(),
            expected_format: "merchant_id from merchant account".to_string()
        })
        .attach_printable("invalid merchant_id in request"))
    })?;

    let connector_transaction_id = payment_attempt.clone().connector_transaction_id.ok_or_else(|| {
        report!(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Transaction in invalid. Missing field \"connector_transaction_id\" in payment_attempt.")
    })?;

    let all_refunds = db
        .find_refund_by_merchant_id_connector_transaction_id(
            merchant_context.get_merchant_account().get_id(),
            &connector_transaction_id,
            merchant_context.get_merchant_account().storage_scheme,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::RefundNotFound)?;

    let currency = payment_attempt.currency.get_required_value("currency")?;

    //[#249]: Add Connector Based Validation here.
    validator::validate_payment_order_age(&payment_intent.created_at, state.conf.refund.max_age)
        .change_context(errors::ApiErrorResponse::InvalidDataFormat {
            field_name: "created_at".to_string(),
            expected_format: format!(
                "created_at not older than {} days",
                state.conf.refund.max_age,
            ),
        })?;

    let total_amount_captured = payment_intent
        .amount_captured
        .unwrap_or(payment_attempt.get_total_amount());

    validator::validate_refund_amount(
        total_amount_captured.get_amount_as_i64(),
        &all_refunds,
        refund_amount.get_amount_as_i64(),
    )
    .change_context(errors::ApiErrorResponse::RefundAmountExceedsPaymentAmount)?;

    validator::validate_maximum_refund_against_payment_attempt(
        &all_refunds,
        state.conf.refund.max_attempts,
    )
    .change_context(errors::ApiErrorResponse::MaximumRefundCount)?;

    let connector = payment_attempt
        .connector
        .clone()
        .ok_or(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("No connector populated in payment attempt")?;
    let (connector_transaction_id, processor_transaction_data) =
        ConnectorTransactionId::form_id_and_data(connector_transaction_id);
    let refund_create_req = diesel_refund::RefundNew {
        refund_id: refund_id.to_string(),
        internal_reference_id: utils::generate_id(consts::ID_LENGTH, "refid"),
        external_reference_id: Some(refund_id.clone()),
        payment_id: req.payment_id,
        merchant_id: merchant_context.get_merchant_account().get_id().clone(),
        connector_transaction_id,
        connector,
        refund_type: req.refund_type.unwrap_or_default().foreign_into(),
        total_amount: payment_attempt.get_total_amount(),
        refund_amount,
        currency,
        created_at: common_utils::date_time::now(),
        modified_at: common_utils::date_time::now(),
        refund_status: enums::RefundStatus::Pending,
        metadata: req.metadata,
        description: req.reason.clone(),
        attempt_id: payment_attempt.attempt_id.clone(),
        refund_reason: req.reason,
        profile_id: payment_intent.profile_id.clone(),
        merchant_connector_id: payment_attempt.merchant_connector_id.clone(),
        charges: None,
        split_refunds: req.split_refunds,
        connector_refund_id: None,
        sent_to_gateway: Default::default(),
        refund_arn: None,
        updated_by: Default::default(),
        organization_id: merchant_context
            .get_merchant_account()
            .organization_id
            .clone(),
        processor_transaction_data,
        processor_refund_data: None,
    };

    let refund = match db
        .insert_refund(
            refund_create_req,
            merchant_context.get_merchant_account().storage_scheme,
        )
        .await
    {
        Ok(refund) => {
            Box::pin(schedule_refund_execution(
                state,
                refund.clone(),
                refund_type,
                merchant_context,
                payment_attempt,
                payment_intent,
                creds_identifier,
                split_refunds,
            ))
            .await?
        }
        Err(err) => {
            if err.current_context().is_db_unique_violation() {
                Err(errors::ApiErrorResponse::DuplicateRefundRequest)?
            } else {
                return Err(err)
                    .change_context(errors::ApiErrorResponse::RefundNotFound)
                    .attach_printable("Inserting Refund failed");
            }
        }
    };
    let unified_translated_message = if let (Some(unified_code), Some(unified_message)) =
        (refund.unified_code.clone(), refund.unified_message.clone())
    {
        helpers::get_unified_translation(
            state,
            unified_code,
            unified_message.clone(),
            state.locale.to_string(),
        )
        .await
        .or(Some(unified_message))
    } else {
        refund.unified_message
    };

    let refund = diesel_refund::Refund {
        unified_message: unified_translated_message,
        ..refund
    };

    Ok(refund.foreign_into())
}


pub struct CybersourceAuthValidateRequest {
    payment_information: PaymentInformation,
    client_reference_information: ClientReferenceInformation,
    consumer_authentication_information: CybersourceConsumerAuthInformationValidateRequest,
    order_information: OrderInformation,
}


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


File: crates/router/tests/connectors/bluesnap.rs

use std::str::FromStr;

use common_utils::pii::Email;
use hyperswitch_domain_models::address::{Address, AddressDetails};
use masking::Secret;
use router::types::{self, domain, storage::enums, ConnectorAuthType, PaymentAddress};

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

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

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

    fn get_name(&self) -> String {
        "bluesnap".to_string()
    }
}
fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    Some(types::PaymentsAuthorizeData {
        email: Some(Email::from_str("test@gmail.com").unwrap()),
        ..utils::PaymentAuthorizeType::default().0
    })
}
fn get_payment_info() -> Option<PaymentInfo> {
    Some(PaymentInfo {
        address: Some(PaymentAddress::new(
            None,
            Some(Address {
                address: Some(AddressDetails {
                    first_name: Some(Secret::new("joseph".to_string())),
                    last_name: Some(Secret::new("Doe".to_string())),
                    ..Default::default()
                }),
                phone: None,
                email: None,
            }),
            None,
            None,
        )),
        ..Default::default()
    })
}

// Cards Positive Tests
// Creates a payment using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_only_authorize_payment() {
    let response = CONNECTOR
        .authorize_payment(payment_method_details(), get_payment_info())
        .await
        .expect("Authorize payment response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized);
}

// Captures a payment using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(payment_method_details(), None, get_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).

#[serial_test::serial]
#[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_payment_info(),
        )
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_sync_authorized_payment() {
    let authorize_response = CONNECTOR
        .authorize_payment(payment_method_details(), get_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()
            }),
            None,
        )
        .await
        .expect("PSync response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
}

// Voids a payment using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[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_payment_info(),
        )
        .await
        .expect("Void payment response");
    assert_eq!(response.status, enums::AttemptStatus::Voided);
}

// Refunds a payment using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(payment_method_details(), None, None, get_payment_info())
        .await
        .unwrap();
    let rsync_response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            response.response.unwrap().connector_refund_id,
            None,
            None,
        )
        .await
        .unwrap();
    assert_eq!(
        rsync_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[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_payment_info(),
        )
        .await
        .unwrap();
    let rsync_response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            response.response.unwrap().connector_refund_id,
            None,
            None,
        )
        .await
        .unwrap();
    assert_eq!(
        rsync_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Synchronizes a refund using the manual capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_sync_manually_captured_refund() {
    let refund_response = CONNECTOR
        .capture_payment_and_refund(payment_method_details(), None, None, get_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            None,
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment using the automatic capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_make_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the automatic capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_sync_auto_captured_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_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(),
                ),
                ..Default::default()
            }),
            None,
        )
        .await
        .unwrap();
    assert_eq!(response.status, enums::AttemptStatus::Charged,);
}

// Refunds a payment using the automatic capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_refund_auto_captured_payment() {
    let response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_payment_info())
        .await
        .unwrap();
    let rsync_response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            response.response.unwrap().connector_refund_id,
            None,
            None,
        )
        .await
        .unwrap();
    assert_eq!(
        rsync_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the automatic capture flow (Non 3DS).

#[serial_test::serial]
#[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_payment_info(),
        )
        .await
        .unwrap();
    let rsync_response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            None,
        )
        .await
        .unwrap();
    assert_eq!(
        rsync_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_refund_succeeded_payment_multiple_times() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let transaction_id = utils::get_connector_transaction_id(authorize_response.response).unwrap();
    for _x in 0..2 {
        tokio::time::sleep(std::time::Duration::from_secs(5)).await; // to avoid 404 error
        let refund_response = CONNECTOR
            .refund_payment(
                transaction_id.clone(),
                Some(types::RefundsData {
                    refund_amount: 50,
                    ..utils::PaymentRefundType::default().0
                }),
                None,
            )
            .await
            .unwrap();
        let rsync_response = CONNECTOR
            .rsync_retry_till_status_matches(
                enums::RefundStatus::Success,
                refund_response.response.unwrap().connector_refund_id,
                None,
                None,
            )
            .await
            .unwrap();
        assert_eq!(
            rsync_response.response.unwrap().refund_status,
            enums::RefundStatus::Success,
        );
    }
}

// Synchronizes a refund using the automatic capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_sync_refund() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            None,
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment with incorrect CVC.

#[serial_test::serial]
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                email: Some(Email::from_str("test@gmail.com").unwrap()),
                payment_method_data: domain::PaymentMethodData::Card(domain::Card {
                    card_cvc: Secret::new("12345".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "VALIDATION_GENERAL_FAILURE".to_string(),
    );
}

// Creates a payment with incorrect expiry month.

#[serial_test::serial]
#[actix_web::test]
async fn should_fail_payment_for_invalid_exp_month() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                email: Some(Email::from_str("test@gmail.com").unwrap()),
                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_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "VALIDATION_GENERAL_FAILURE".to_string(),
    );
}

// Creates a payment with incorrect expiry year.

#[serial_test::serial]
#[actix_web::test]
async fn should_fail_payment_for_incorrect_expiry_year() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                email: Some(Email::from_str("test@gmail.com").unwrap()),
                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_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "VALIDATION_GENERAL_FAILURE".to_string(),
    );
}

// Voids a payment using automatic capture flow (Non 3DS).

#[serial_test::serial]
#[actix_web::test]
async fn should_fail_void_payment_for_auto_capture() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_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, None)
        .await
        .unwrap();
    assert_eq!(
        void_response.response.unwrap_err().message,
        "TRANSACTION_ALREADY_CAPTURED"
    );
}

// Captures a payment using invalid connector payment id.

#[serial_test::serial]
#[actix_web::test]
async fn should_fail_capture_for_invalid_payment() {
    let capture_response = CONNECTOR
        .capture_payment("123456789".to_string(), None, None)
        .await
        .unwrap();

    capture_response
        .response
        .unwrap_err()
        .message
        .contains("is not authorized to view transaction");
}

// Refunds a payment with refund amount higher than payment amount.

#[serial_test::serial]
#[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_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "REFUND_MAX_AMOUNT_FAILURE",
    );
}

// Connector dependent test cases goes here

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


pub struct DisputeEvidenceBlock {
    /// Evidence type
    pub evidence_type: EvidenceType,
    /// File metadata
    pub file_metadata_response: files::FileMetadataResponse,
}


/// fn set_error
    pub fn set_error(&mut self, error: serde_json::Value) {
        self.error = Some(error.to_string());
    }


pub struct SilverflowErrorResponse {
    pub error: SilverflowError,
}


impl api::PayoutRecipient for Ebanx {}


impl api::PaymentSession for Archipel {}

impl api::PaymentSession for for Archipel


pub struct SantanderAdditionalInfo {
    #[serde(rename = "nome")]
    pub name: String,
    #[serde(rename = "valor")]
    pub value: String,
}


impl api::PaymentSession for Silverflow {}

impl api::PaymentSession for for Silverflow


pub fn set_routing_event(&mut self, routing_event: routing_events::RoutingEvent) {
        self.routing_event = Some(routing_event);
    }


File: crates/external_services/src/hashicorp_vault/implementers.rs

//! Trait implementations for Hashicorp vault client

use common_utils::errors::CustomResult;
use error_stack::ResultExt;
use hyperswitch_interfaces::secrets_interface::{
    SecretManagementInterface, SecretsManagementError,
};
use masking::{ExposeInterface, Secret};

use crate::hashicorp_vault::core::{HashiCorpVault, Kv2};

#[async_trait::async_trait]
impl SecretManagementInterface for HashiCorpVault {
    async fn get_secret(
        &self,
        input: Secret<String>,
    ) -> CustomResult<Secret<String>, SecretsManagementError> {
        self.fetch::<Kv2, Secret<String>>(input.expose())
            .await
            .map(|val| val.expose().to_owned())
            .change_context(SecretsManagementError::FetchSecretFailed)
            .map(Into::into)
    }
}


pub struct FrmMetricsBucketValue {
    pub frm_triggered_attempts: Option<u64>,
    pub frm_blocked_rate: Option<f64>,
}


pub struct RecipientCreateRequest {
    pub name: String,
    pub account_data: RecipientAccountData,
    pub address: Option<RecipientCreateAddress>,
}


File: crates/router/src/routes/locker_migration.rs
 Public functions: 1

use actix_web::{web, HttpRequest, HttpResponse};
use router_env::Flow;

use super::AppState;
use crate::{
    core::{api_locking, locker_migration},
    services::{api, authentication as auth},
};

pub async fn rust_locker_migration(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<common_utils::id_type::MerchantId>,
) -> HttpResponse {
    let flow = Flow::RustLockerMigration;
    let merchant_id = path.into_inner();
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        &merchant_id,
        |state, _, _, _| locker_migration::rust_locker_migration(state, &merchant_id),
        &auth::AdminApiAuth,
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


Documentation: api-reference/v1/routing/routing--create.mdx
# Type: Doc File

---
openapi: post /routing
---


OpenAPI Block Path: paths."/payouts/list"
{
  "get": {
    "tags": [
      "Payouts"
    ],
    "summary": "Payouts - List",
    "operationId": "List payouts using generic constraints",
    "parameters": [
      {
        "name": "customer_id",
        "in": "query",
        "description": "The identifier for customer",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "starting_after",
        "in": "query",
        "description": "A cursor for use in pagination, fetch the next list after some object",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "ending_before",
        "in": "query",
        "description": "A cursor for use in pagination, fetch the previous list before some object",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "limit",
        "in": "query",
        "description": "limit on the number of objects to return",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "created",
        "in": "query",
        "description": "The time at which payout is created",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "time_range",
        "in": "query",
        "description": "The time range for which objects are needed. TimeRange has two fields start_time and end_time from which objects can be filtered as per required scenarios (created_at, time less than, greater than etc).",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    ],
    "responses": {
      "200": {
        "description": "Payouts listed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PayoutListResponse"
            }
          }
        }
      },
      "404": {
        "description": "Payout not found"
      }
    },
    "security": [
      {
        "api_key": []
      }
    ]
  },
  "post": {
    "tags": [
      "Payouts"
    ],
    "summary": "Payouts - List using filters",
    "operationId": "Filter payouts using specific constraints",
    "requestBody": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PayoutListFilterConstraints"
          }
        }
      },
      "required": true
    },
    "responses": {
      "200": {
        "description": "Payouts filtered",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PayoutListResponse"
            }
          }
        }
      },
      "404": {
        "description": "Payout not found"
      }
    },
    "security": [
      {
        "api_key": []
      }
    ]
  }
}


pub struct AccountHolder {
    #[serde(rename = "first-name")]
    pub first_name: Option<Secret<String>>,
    #[serde(rename = "last-name")]
    pub last_name: Option<Secret<String>>,
    pub email: Option<Email>,
    pub phone: Option<Secret<String>>,
    pub address: Option<Address>,
}


pub fn capture_status_from_transaction_state(getnet_status: GetnetPaymentStatus) -> AttemptStatus {
    match getnet_status {
        GetnetPaymentStatus::Success => AttemptStatus::Charged,
        GetnetPaymentStatus::InProgress => AttemptStatus::Pending,
        GetnetPaymentStatus::Failed => AttemptStatus::Authorized,
    }
}


pub async fn get_ephemeral_or_other_auth<T>(
    headers: &HeaderMap,
    is_merchant_flow: bool,
    payload: Option<&impl ClientSecretFetch>,
    api_auth: ApiKeyAuth,
) -> RouterResult<(
    Box<dyn AuthenticateAndFetch<AuthenticationData, T>>,
    api::AuthFlow,
    bool,
)>
where
    T: SessionStateInfo + Sync + Send,
    ApiKeyAuth: AuthenticateAndFetch<AuthenticationData, T>,
    PublishableKeyAuth: AuthenticateAndFetch<AuthenticationData, T>,
    EphemeralKeyAuth: AuthenticateAndFetch<AuthenticationData, T>,
{
    let api_key = get_api_key(headers)?;

    if api_key.starts_with("epk") {
        Ok((Box::new(EphemeralKeyAuth), api::AuthFlow::Client, true))
    } else if is_merchant_flow {
        Ok((
            Box::new(HeaderAuth(api_auth)),
            api::AuthFlow::Merchant,
            false,
        ))
    } else {
        let payload = payload.get_required_value("ClientSecretFetch")?;
        let (auth, auth_flow) = check_client_secret_and_get_auth(headers, payload, api_auth)?;
        Ok((auth, auth_flow, false))
    }
}


impl api::PaymentSession for Stax {}


pub struct Action {
    pub method: MethodType,
    pub url: String,
}


    fn build_request(
        &self,
        req: &AcceptDisputeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
        Ok(Some(
            RequestBuilder::new()
                .method(Method::Post)
                .url(&AcceptDisputeType::get_url(self, req, connectors)?)
                .attach_default_headers()
                .headers(AcceptDisputeType::get_headers(self, req, connectors)?)
                .set_body(AcceptDisputeType::get_request_body(self, req, connectors)?)
                .build(),
        ))
    }
    fn get_request_body(
        &self,
        req: &AcceptDisputeRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let connector_req = adyen::AdyenAcceptDisputeRequest::try_from(req)?;
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn handle_response(
        &self,
        data: &AcceptDisputeRouterData,
        _event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<AcceptDisputeRouterData, errors::ConnectorError> {
        let response: adyen::AdyenDisputeResponse = res
            .response
            .parse_struct("AdyenDisputeResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        RouterData::foreign_try_from((data, response))
            .change_context(errors::ConnectorError::ResponseHandlingFailed)
    }

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

impl ConnectorIntegration<Defend, DefendDisputeRequestData, DefendDisputeResponse> for Adyen {
    fn get_headers(
        &self,
        req: &DefendDisputeRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        let mut header = vec![(
            headers::CONTENT_TYPE.to_string(),
            DefendDisputeType::get_content_type(self).to_string().into(),
        )];
        let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
        header.append(&mut api_key);
        Ok(header)
    }

    fn get_url(
        &self,
        req: &DefendDisputeRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        let endpoint = build_env_specific_endpoint(
            connectors.adyen.dispute_base_url.as_str(),
            req.test_mode,
            &req.connector_meta_data,
        )?;
        Ok(format!(
            "{endpoint}ca/services/DisputeService/v30/defendDispute",
        ))
    }

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

    fn get_request_body(
        &self,
        req: &DefendDisputeRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let connector_req = adyen::AdyenDefendDisputeRequest::try_from(req)?;
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

    fn handle_response(
        &self,
        data: &DefendDisputeRouterData,
        _event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<DefendDisputeRouterData, errors::ConnectorError> {
        let response: adyen::AdyenDisputeResponse = res
            .response
            .parse_struct("AdyenDisputeResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        RouterData::foreign_try_from((data, response))
            .change_context(errors::ConnectorError::ResponseHandlingFailed)
    }

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

impl ConnectorIntegration<Evidence, SubmitEvidenceRequestData, SubmitEvidenceResponse> for Adyen {
    fn get_headers(
        &self,
        req: &SubmitEvidenceRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
        let mut header = vec![(
            headers::CONTENT_TYPE.to_string(),
            SubmitEvidenceType::get_content_type(self)
                .to_string()
                .into(),
        )];
        let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
        header.append(&mut api_key);
        Ok(header)
    }

    fn get_url(
        &self,
        req: &SubmitEvidenceRouterData,
        connectors: &Connectors,
    ) -> CustomResult<String, errors::ConnectorError> {
        let endpoint = build_env_specific_endpoint(
            connectors.adyen.dispute_base_url.as_str(),
            req.test_mode,
            &req.connector_meta_data,
        )?;
        Ok(format!(
            "{endpoint}ca/services/DisputeService/v30/supplyDefenseDocument",
        ))
    }

    fn get_request_body(
        &self,
        req: &SubmitEvidenceRouterData,
        _connectors: &Connectors,
    ) -> CustomResult<RequestContent, errors::ConnectorError> {
        let connector_req = adyen::Evidence::try_from(req)?;
        Ok(RequestContent::Json(Box::new(connector_req)))
    }

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

    fn handle_response(
        &self,
        data: &SubmitEvidenceRouterData,
        _event_builder: Option<&mut ConnectorEvent>,
        res: Response,
    ) -> CustomResult<SubmitEvidenceRouterData, errors::ConnectorError> {
        let response: adyen::AdyenDisputeResponse = res
            .response
            .parse_struct("AdyenDisputeResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
        RouterData::foreign_try_from((data, response))
            .change_context(errors::ConnectorError::ResponseHandlingFailed)
    }

    fn get_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        self.build_error_response(res, event_builder)
    }
}
impl UploadFile for Adyen {}
impl RetrieveFile for Adyen {}
impl ConnectorIntegration<Retrieve, RetrieveFileRequestData, RetrieveFileResponse> for Adyen {}
impl ConnectorIntegration<Upload, UploadFileRequestData, UploadFileResponse> for Adyen {}
#[async_trait::async_trait]
impl FileUpload for Adyen {
    fn validate_file_upload(
        &self,
        purpose: FilePurpose,
        file_size: i32,
        file_type: mime::Mime,
    ) -> CustomResult<(), errors::ConnectorError> {
        match purpose {
            FilePurpose::DisputeEvidence => {
                let supported_file_types =
                    ["image/jpeg", "image/jpg", "image/png", "application/pdf"];
                if !supported_file_types.contains(&file_type.to_string().as_str()) {
                    Err(errors::ConnectorError::FileValidationFailed {
                        reason: "file_type does not match JPEG, JPG, PNG, or PDF format".to_owned(),
                    })?
                }
                //10 MB
                if (file_type.to_string().as_str() == "image/jpeg"
                    || file_type.to_string().as_str() == "image/jpg"
                    || file_type.to_string().as_str() == "image/png")
                    && file_size > 10000000
                {
                    Err(errors::ConnectorError::FileValidationFailed {
                        reason: "file_size exceeded the max file size of 10MB for Image formats"
                            .to_owned(),
                    })?
                }
                //2 MB
                if file_type.to_string().as_str() == "application/pdf" && file_size > 2000000 {
                    Err(errors::ConnectorError::FileValidationFailed {
                        reason: "file_size exceeded the max file size of 2MB for PDF formats"
                            .to_owned(),
                    })?
                }
            }
        }
        Ok(())
    }
}

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

    let supported_capture_methods2 = vec![
        enums::CaptureMethod::Automatic,
        enums::CaptureMethod::Manual,
        enums::CaptureMethod::SequentialAutomatic,
    ];

    let supported_capture_methods3 = vec![
        enums::CaptureMethod::Automatic,
        enums::CaptureMethod::SequentialAutomatic,
    ];

    let supported_card_network = vec![
        common_enums::CardNetwork::AmericanExpress,
        common_enums::CardNetwork::CartesBancaires,
        common_enums::CardNetwork::UnionPay,
        common_enums::CardNetwork::DinersClub,
        common_enums::CardNetwork::Discover,
        common_enums::CardNetwork::Interac,
        common_enums::CardNetwork::JCB,
        common_enums::CardNetwork::Maestro,
        common_enums::CardNetwork::Mastercard,
        common_enums::CardNetwork::Visa,
    ];

    let mut adyen_supported_payment_methods = SupportedPaymentMethods::new();

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Card,
        PaymentMethodType::Credit,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: Some(
                api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                    api_models::feature_matrix::CardSpecificFeatures {
                        three_ds: common_enums::FeatureStatus::Supported,
                        no_three_ds: common_enums::FeatureStatus::Supported,
                        supported_card_networks: supported_card_network.clone(),
                    }
                }),
            ),
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Card,
        PaymentMethodType::Debit,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: Some(
                api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                    api_models::feature_matrix::CardSpecificFeatures {
                        three_ds: common_enums::FeatureStatus::Supported,
                        no_three_ds: common_enums::FeatureStatus::Supported,
                        supported_card_networks: supported_card_network.clone(),
                    }
                }),
            ),
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::GooglePay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::ApplePay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Paypal,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::AliPay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::AliPayHk,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::GoPay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::KakaoPay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Gcash,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Momo,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::TouchNGo,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::MbWay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::MobilePay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::WeChatPay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::SamsungPay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Paze,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Twint,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Vipps,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Dana,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Wallet,
        PaymentMethodType::Swish,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::Klarna,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );
    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::Affirm,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );
    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::AfterpayClearpay,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );
    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::PayBright,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );
    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::Walley,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );
    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::Alma,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );
    adyen_supported_payment_methods.add(
        enums::PaymentMethod::PayLater,
        PaymentMethodType::Atome,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::BancontactCard,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::Bizum,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::Blik,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::Eps,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::Ideal,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OnlineBankingCzechRepublic,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OnlineBankingFinland,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OnlineBankingPoland,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OnlineBankingSlovakia,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OnlineBankingFpx,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OnlineBankingThailand,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::OpenBankingUk,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankRedirect,
        PaymentMethodType::Trustly,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankDebit,
        PaymentMethodType::Ach,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankDebit,
        PaymentMethodType::Sepa,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods1.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankDebit,
        PaymentMethodType::Bacs,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::Supported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::PermataBankTransfer,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::BcaBankTransfer,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::BniVa,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::BriVa,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::CimbVa,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::DanamonVa,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::MandiriVa,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::BankTransfer,
        PaymentMethodType::Pix,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::CardRedirect,
        PaymentMethodType::Knet,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::CardRedirect,
        PaymentMethodType::Benefit,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::CardRedirect,
        PaymentMethodType::MomoAtm,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::Boleto,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::Alfamart,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::Indomaret,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::Oxxo,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::SevenEleven,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::Lawson,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::MiniStop,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::FamilyMart,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::Seicomart,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::Voucher,
        PaymentMethodType::PayEasy,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::NotSupported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::GiftCard,
        PaymentMethodType::PaySafeCard,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods3.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods.add(
        enums::PaymentMethod::GiftCard,
        PaymentMethodType::Givex,
        PaymentMethodDetails {
            mandates: enums::FeatureStatus::NotSupported,
            refunds: enums::FeatureStatus::Supported,
            supported_capture_methods: supported_capture_methods2.clone(),
            specific_features: None,
        },
    );

    adyen_supported_payment_methods
});

static ADYEN_CONNECTOR_INFO: ConnectorInfo = ConnectorInfo {
        display_name: "Adyen",
        description: "Adyen is a Dutch payment company with the status of an acquiring bank that allows businesses to accept e-commerce, mobile, and point-of-sale payments. It is listed on the stock exchange Euronext Amsterdam",
        connector_type: enums::HyperswitchConnectorCategory::PaymentGateway,
        integration_status: enums::ConnectorIntegrationStatus::Live,
    };

static ADYEN_SUPPORTED_WEBHOOK_FLOWS: &[enums::EventClass] = &[
    enums::EventClass::Payments,
    enums::EventClass::Refunds,
    enums::EventClass::Disputes,
    #[cfg(feature = "payouts")]
    enums::EventClass::Payouts,
    enums::EventClass::Mandates,
];

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

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

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