// File: crates/diesel_models/src/business_profile.rs
// Module: diesel_models
// Public functions: 5
// Public structs: 16

use std::collections::{HashMap, HashSet};

use common_enums::{AuthenticationConnectors, UIWidgetFormLayout, VaultSdk};
use common_types::primitive_wrappers;
use common_utils::{encryption::Encryption, pii};
use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
use masking::Secret;
use time::Duration;

#[cfg(feature = "v1")]
use crate::schema::business_profile;
#[cfg(feature = "v2")]
use crate::schema_v2::business_profile;

/// Note: The order of fields in the struct is important.
/// This should be in the same order as the fields in the schema.rs file, otherwise the code will
/// not compile
/// If two adjacent columns have the same type, then the compiler will not throw any error, but the
/// fields read / written will be interchanged
#[cfg(feature = "v1")]
#[derive(Clone, Debug, Identifiable, Queryable, Selectable, router_derive::DebugAsDisplay)]
#[diesel(table_name = business_profile, primary_key(profile_id), check_for_backend(diesel::pg::Pg))]
pub struct Profile {
    pub profile_id: common_utils::id_type::ProfileId,
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_name: String,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub return_url: Option<String>,
    pub enable_payment_response_hash: bool,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: bool,
    pub webhook_details: Option<WebhookDetails>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub routing_algorithm: Option<serde_json::Value>,
    pub intent_fulfillment_time: Option<i64>,
    pub frm_routing_algorithm: Option<serde_json::Value>,
    pub payout_routing_algorithm: Option<serde_json::Value>,
    pub is_recon_enabled: bool,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub payment_link_config: Option<BusinessPaymentLinkConfig>,
    pub session_expiry: Option<i64>,
    pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
    pub payout_link_config: Option<BusinessPayoutLinkConfig>,
    pub is_extended_card_info_enabled: Option<bool>,
    pub extended_card_info_config: Option<pii::SecretSerdeValue>,
    pub is_connector_agnostic_mit_enabled: Option<bool>,
    pub use_billing_as_payment_method_billing: Option<bool>,
    pub collect_shipping_details_from_wallet_connector: Option<bool>,
    pub collect_billing_details_from_wallet_connector: Option<bool>,
    pub outgoing_webhook_custom_http_headers: Option<Encryption>,
    pub always_collect_billing_details_from_wallet_connector: Option<bool>,
    pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
    pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_tax_connector_enabled: Option<bool>,
    pub version: common_enums::ApiVersion,
    pub dynamic_routing_algorithm: Option<serde_json::Value>,
    pub is_network_tokenization_enabled: bool,
    pub is_auto_retries_enabled: Option<bool>,
    pub max_auto_retries_enabled: Option<i16>,
    pub always_request_extended_authorization:
        Option<primitive_wrappers::AlwaysRequestExtendedAuthorization>,
    pub is_click_to_pay_enabled: bool,
    pub authentication_product_ids:
        Option<common_types::payments::AuthenticationConnectorAccountMap>,
    pub card_testing_guard_config: Option<CardTestingGuardConfig>,
    pub card_testing_secret_key: Option<Encryption>,
    pub is_clear_pan_retries_enabled: bool,
    pub force_3ds_challenge: Option<bool>,
    pub is_debit_routing_enabled: bool,
    pub merchant_business_country: Option<common_enums::CountryAlpha2>,
    pub id: Option<common_utils::id_type::ProfileId>,
    pub is_iframe_redirection_enabled: Option<bool>,
    pub is_pre_network_tokenization_enabled: Option<bool>,
    pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
    pub merchant_country_code: Option<common_types::payments::MerchantCountryCode>,
    pub dispute_polling_interval: Option<primitive_wrappers::DisputePollingIntervalInHours>,
    pub is_manual_retry_enabled: Option<bool>,
    pub always_enable_overcapture: Option<primitive_wrappers::AlwaysEnableOvercaptureBool>,
    pub billing_processor_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_external_vault_enabled: Option<bool>,
    pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
}

#[cfg(feature = "v1")]
#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
#[diesel(table_name = business_profile, primary_key(profile_id))]
pub struct ProfileNew {
    pub profile_id: common_utils::id_type::ProfileId,
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_name: String,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub return_url: Option<String>,
    pub enable_payment_response_hash: bool,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: bool,
    pub webhook_details: Option<WebhookDetails>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub routing_algorithm: Option<serde_json::Value>,
    pub intent_fulfillment_time: Option<i64>,
    pub frm_routing_algorithm: Option<serde_json::Value>,
    pub payout_routing_algorithm: Option<serde_json::Value>,
    pub is_recon_enabled: bool,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub payment_link_config: Option<BusinessPaymentLinkConfig>,
    pub session_expiry: Option<i64>,
    pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
    pub payout_link_config: Option<BusinessPayoutLinkConfig>,
    pub is_extended_card_info_enabled: Option<bool>,
    pub extended_card_info_config: Option<pii::SecretSerdeValue>,
    pub is_connector_agnostic_mit_enabled: Option<bool>,
    pub use_billing_as_payment_method_billing: Option<bool>,
    pub collect_shipping_details_from_wallet_connector: Option<bool>,
    pub collect_billing_details_from_wallet_connector: Option<bool>,
    pub outgoing_webhook_custom_http_headers: Option<Encryption>,
    pub always_collect_billing_details_from_wallet_connector: Option<bool>,
    pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
    pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_tax_connector_enabled: Option<bool>,
    pub version: common_enums::ApiVersion,
    pub is_network_tokenization_enabled: bool,
    pub is_auto_retries_enabled: Option<bool>,
    pub max_auto_retries_enabled: Option<i16>,
    pub is_click_to_pay_enabled: bool,
    pub authentication_product_ids:
        Option<common_types::payments::AuthenticationConnectorAccountMap>,
    pub card_testing_guard_config: Option<CardTestingGuardConfig>,
    pub card_testing_secret_key: Option<Encryption>,
    pub is_clear_pan_retries_enabled: bool,
    pub force_3ds_challenge: Option<bool>,
    pub is_debit_routing_enabled: bool,
    pub merchant_business_country: Option<common_enums::CountryAlpha2>,
    pub id: Option<common_utils::id_type::ProfileId>,
    pub is_iframe_redirection_enabled: Option<bool>,
    pub is_pre_network_tokenization_enabled: Option<bool>,
    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
    pub merchant_country_code: Option<common_types::payments::MerchantCountryCode>,
    pub dispute_polling_interval: Option<primitive_wrappers::DisputePollingIntervalInHours>,
    pub is_manual_retry_enabled: Option<bool>,
    pub billing_processor_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_external_vault_enabled: Option<bool>,
    pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
}

#[cfg(feature = "v1")]
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
#[diesel(table_name = business_profile)]
pub struct ProfileUpdateInternal {
    pub profile_name: Option<String>,
    pub modified_at: time::PrimitiveDateTime,
    pub return_url: Option<String>,
    pub enable_payment_response_hash: Option<bool>,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: Option<bool>,
    pub webhook_details: Option<WebhookDetails>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub routing_algorithm: Option<serde_json::Value>,
    pub intent_fulfillment_time: Option<i64>,
    pub frm_routing_algorithm: Option<serde_json::Value>,
    pub payout_routing_algorithm: Option<serde_json::Value>,
    pub is_recon_enabled: Option<bool>,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub payment_link_config: Option<BusinessPaymentLinkConfig>,
    pub session_expiry: Option<i64>,
    pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
    pub payout_link_config: Option<BusinessPayoutLinkConfig>,
    pub is_extended_card_info_enabled: Option<bool>,
    pub extended_card_info_config: Option<pii::SecretSerdeValue>,
    pub is_connector_agnostic_mit_enabled: Option<bool>,
    pub use_billing_as_payment_method_billing: Option<bool>,
    pub collect_shipping_details_from_wallet_connector: Option<bool>,
    pub collect_billing_details_from_wallet_connector: Option<bool>,
    pub outgoing_webhook_custom_http_headers: Option<Encryption>,
    pub always_collect_billing_details_from_wallet_connector: Option<bool>,
    pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
    pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_tax_connector_enabled: Option<bool>,
    pub dynamic_routing_algorithm: Option<serde_json::Value>,
    pub is_network_tokenization_enabled: Option<bool>,
    pub is_auto_retries_enabled: Option<bool>,
    pub max_auto_retries_enabled: Option<i16>,
    pub always_request_extended_authorization:
        Option<primitive_wrappers::AlwaysRequestExtendedAuthorization>,
    pub is_click_to_pay_enabled: Option<bool>,
    pub authentication_product_ids:
        Option<common_types::payments::AuthenticationConnectorAccountMap>,
    pub card_testing_guard_config: Option<CardTestingGuardConfig>,
    pub card_testing_secret_key: Option<Encryption>,
    pub is_clear_pan_retries_enabled: Option<bool>,
    pub force_3ds_challenge: Option<bool>,
    pub is_debit_routing_enabled: Option<bool>,
    pub merchant_business_country: Option<common_enums::CountryAlpha2>,
    pub is_iframe_redirection_enabled: Option<bool>,
    pub is_pre_network_tokenization_enabled: Option<bool>,
    pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
    pub merchant_country_code: Option<common_types::payments::MerchantCountryCode>,
    pub dispute_polling_interval: Option<primitive_wrappers::DisputePollingIntervalInHours>,
    pub is_manual_retry_enabled: Option<bool>,
    pub always_enable_overcapture: Option<primitive_wrappers::AlwaysEnableOvercaptureBool>,
    pub billing_processor_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_external_vault_enabled: Option<bool>,
    pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
}

#[cfg(feature = "v1")]
impl ProfileUpdateInternal {
    pub fn apply_changeset(self, source: Profile) -> Profile {
        let Self {
            profile_name,
            modified_at,
            return_url,
            enable_payment_response_hash,
            payment_response_hash_key,
            redirect_to_merchant_with_http_post,
            webhook_details,
            metadata,
            routing_algorithm,
            intent_fulfillment_time,
            frm_routing_algorithm,
            payout_routing_algorithm,
            is_recon_enabled,
            applepay_verified_domains,
            payment_link_config,
            session_expiry,
            authentication_connector_details,
            payout_link_config,
            is_extended_card_info_enabled,
            extended_card_info_config,
            is_connector_agnostic_mit_enabled,
            use_billing_as_payment_method_billing,
            collect_shipping_details_from_wallet_connector,
            collect_billing_details_from_wallet_connector,
            outgoing_webhook_custom_http_headers,
            always_collect_billing_details_from_wallet_connector,
            always_collect_shipping_details_from_wallet_connector,
            tax_connector_id,
            is_tax_connector_enabled,
            dynamic_routing_algorithm,
            is_network_tokenization_enabled,
            is_auto_retries_enabled,
            max_auto_retries_enabled,
            always_request_extended_authorization,
            is_click_to_pay_enabled,
            authentication_product_ids,
            card_testing_guard_config,
            card_testing_secret_key,
            is_clear_pan_retries_enabled,
            force_3ds_challenge,
            is_debit_routing_enabled,
            merchant_business_country,
            is_iframe_redirection_enabled,
            is_pre_network_tokenization_enabled,
            three_ds_decision_rule_algorithm,
            acquirer_config_map,
            merchant_category_code,
            merchant_country_code,
            dispute_polling_interval,
            is_manual_retry_enabled,
            always_enable_overcapture,
            is_external_vault_enabled,
            external_vault_connector_details,
            billing_processor_id,
        } = self;
        Profile {
            profile_id: source.profile_id,
            merchant_id: source.merchant_id,
            profile_name: profile_name.unwrap_or(source.profile_name),
            created_at: source.created_at,
            modified_at,
            return_url: return_url.or(source.return_url),
            enable_payment_response_hash: enable_payment_response_hash
                .unwrap_or(source.enable_payment_response_hash),
            payment_response_hash_key: payment_response_hash_key
                .or(source.payment_response_hash_key),
            redirect_to_merchant_with_http_post: redirect_to_merchant_with_http_post
                .unwrap_or(source.redirect_to_merchant_with_http_post),
            webhook_details: webhook_details.or(source.webhook_details),
            metadata: metadata.or(source.metadata),
            routing_algorithm: routing_algorithm.or(source.routing_algorithm),
            intent_fulfillment_time: intent_fulfillment_time.or(source.intent_fulfillment_time),
            frm_routing_algorithm: frm_routing_algorithm.or(source.frm_routing_algorithm),
            payout_routing_algorithm: payout_routing_algorithm.or(source.payout_routing_algorithm),
            is_recon_enabled: is_recon_enabled.unwrap_or(source.is_recon_enabled),
            applepay_verified_domains: applepay_verified_domains
                .or(source.applepay_verified_domains),
            payment_link_config: payment_link_config.or(source.payment_link_config),
            session_expiry: session_expiry.or(source.session_expiry),
            authentication_connector_details: authentication_connector_details
                .or(source.authentication_connector_details),
            payout_link_config: payout_link_config.or(source.payout_link_config),
            is_extended_card_info_enabled: is_extended_card_info_enabled
                .or(source.is_extended_card_info_enabled),
            is_connector_agnostic_mit_enabled: is_connector_agnostic_mit_enabled
                .or(source.is_connector_agnostic_mit_enabled),
            extended_card_info_config: extended_card_info_config
                .or(source.extended_card_info_config),
            use_billing_as_payment_method_billing: use_billing_as_payment_method_billing
                .or(source.use_billing_as_payment_method_billing),
            collect_shipping_details_from_wallet_connector:
                collect_shipping_details_from_wallet_connector
                    .or(source.collect_shipping_details_from_wallet_connector),
            collect_billing_details_from_wallet_connector:
                collect_billing_details_from_wallet_connector
                    .or(source.collect_billing_details_from_wallet_connector),
            outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
                .or(source.outgoing_webhook_custom_http_headers),
            always_collect_billing_details_from_wallet_connector:
                always_collect_billing_details_from_wallet_connector
                    .or(source.always_collect_billing_details_from_wallet_connector),
            always_collect_shipping_details_from_wallet_connector:
                always_collect_shipping_details_from_wallet_connector
                    .or(source.always_collect_shipping_details_from_wallet_connector),
            tax_connector_id: tax_connector_id.or(source.tax_connector_id),
            is_tax_connector_enabled: is_tax_connector_enabled.or(source.is_tax_connector_enabled),
            version: source.version,
            dynamic_routing_algorithm: dynamic_routing_algorithm
                .or(source.dynamic_routing_algorithm),
            is_network_tokenization_enabled: is_network_tokenization_enabled
                .unwrap_or(source.is_network_tokenization_enabled),
            is_auto_retries_enabled: is_auto_retries_enabled.or(source.is_auto_retries_enabled),
            max_auto_retries_enabled: max_auto_retries_enabled.or(source.max_auto_retries_enabled),
            always_request_extended_authorization: always_request_extended_authorization
                .or(source.always_request_extended_authorization),
            is_click_to_pay_enabled: is_click_to_pay_enabled
                .unwrap_or(source.is_click_to_pay_enabled),
            authentication_product_ids: authentication_product_ids
                .or(source.authentication_product_ids),
            card_testing_guard_config: card_testing_guard_config
                .or(source.card_testing_guard_config),
            card_testing_secret_key,
            is_clear_pan_retries_enabled: is_clear_pan_retries_enabled
                .unwrap_or(source.is_clear_pan_retries_enabled),
            force_3ds_challenge,
            id: source.id,
            is_debit_routing_enabled: is_debit_routing_enabled
                .unwrap_or(source.is_debit_routing_enabled),
            merchant_business_country: merchant_business_country
                .or(source.merchant_business_country),
            is_iframe_redirection_enabled: is_iframe_redirection_enabled
                .or(source.is_iframe_redirection_enabled),
            is_pre_network_tokenization_enabled: is_pre_network_tokenization_enabled
                .or(source.is_pre_network_tokenization_enabled),
            three_ds_decision_rule_algorithm: three_ds_decision_rule_algorithm
                .or(source.three_ds_decision_rule_algorithm),
            acquirer_config_map: acquirer_config_map.or(source.acquirer_config_map),
            merchant_category_code: merchant_category_code.or(source.merchant_category_code),
            merchant_country_code: merchant_country_code.or(source.merchant_country_code),
            dispute_polling_interval: dispute_polling_interval.or(source.dispute_polling_interval),
            is_manual_retry_enabled: is_manual_retry_enabled.or(source.is_manual_retry_enabled),
            always_enable_overcapture: always_enable_overcapture
                .or(source.always_enable_overcapture),
            is_external_vault_enabled: is_external_vault_enabled
                .or(source.is_external_vault_enabled),
            external_vault_connector_details: external_vault_connector_details
                .or(source.external_vault_connector_details),
            billing_processor_id: billing_processor_id.or(source.billing_processor_id),
        }
    }
}

/// Note: The order of fields in the struct is important.
/// This should be in the same order as the fields in the schema.rs file, otherwise the code will
/// not compile
/// If two adjacent columns have the same type, then the compiler will not throw any error, but the
/// fields read / written will be interchanged
#[cfg(feature = "v2")]
#[derive(Clone, Debug, Identifiable, Queryable, Selectable, router_derive::DebugAsDisplay)]
#[diesel(table_name = business_profile, primary_key(id), check_for_backend(diesel::pg::Pg))]
pub struct Profile {
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_name: String,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub return_url: Option<common_utils::types::Url>,
    pub enable_payment_response_hash: bool,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: bool,
    pub webhook_details: Option<WebhookDetails>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub is_recon_enabled: bool,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub payment_link_config: Option<BusinessPaymentLinkConfig>,
    pub session_expiry: Option<i64>,
    pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
    pub payout_link_config: Option<BusinessPayoutLinkConfig>,
    pub is_extended_card_info_enabled: Option<bool>,
    pub extended_card_info_config: Option<pii::SecretSerdeValue>,
    pub is_connector_agnostic_mit_enabled: Option<bool>,
    pub use_billing_as_payment_method_billing: Option<bool>,
    pub collect_shipping_details_from_wallet_connector: Option<bool>,
    pub collect_billing_details_from_wallet_connector: Option<bool>,
    pub outgoing_webhook_custom_http_headers: Option<Encryption>,
    pub always_collect_billing_details_from_wallet_connector: Option<bool>,
    pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
    pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_tax_connector_enabled: Option<bool>,
    pub version: common_enums::ApiVersion,
    pub dynamic_routing_algorithm: Option<serde_json::Value>,
    pub is_network_tokenization_enabled: bool,
    pub is_auto_retries_enabled: Option<bool>,
    pub max_auto_retries_enabled: Option<i16>,
    pub always_request_extended_authorization:
        Option<primitive_wrappers::AlwaysRequestExtendedAuthorization>,
    pub is_click_to_pay_enabled: bool,
    pub authentication_product_ids:
        Option<common_types::payments::AuthenticationConnectorAccountMap>,
    pub card_testing_guard_config: Option<CardTestingGuardConfig>,
    pub card_testing_secret_key: Option<Encryption>,
    pub is_clear_pan_retries_enabled: bool,
    pub force_3ds_challenge: Option<bool>,
    pub is_debit_routing_enabled: bool,
    pub merchant_business_country: Option<common_enums::CountryAlpha2>,
    pub id: common_utils::id_type::ProfileId,
    pub is_iframe_redirection_enabled: Option<bool>,
    pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
    pub merchant_country_code: Option<common_types::payments::MerchantCountryCode>,
    pub dispute_polling_interval: Option<primitive_wrappers::DisputePollingIntervalInHours>,
    pub is_manual_retry_enabled: Option<bool>,
    pub always_enable_overcapture: Option<primitive_wrappers::AlwaysEnableOvercaptureBool>,
    pub billing_processor_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_external_vault_enabled: Option<bool>,
    pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
    pub routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
    pub order_fulfillment_time: Option<i64>,
    pub order_fulfillment_time_origin: Option<common_enums::OrderFulfillmentTimeOrigin>,
    pub frm_routing_algorithm_id: Option<String>,
    pub payout_routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
    pub three_ds_decision_manager_config: Option<common_types::payments::DecisionManagerRecord>,
    pub should_collect_cvv_during_payment:
        Option<primitive_wrappers::ShouldCollectCvvDuringPayment>,
    pub revenue_recovery_retry_algorithm_type: Option<common_enums::RevenueRecoveryAlgorithmType>,
    pub revenue_recovery_retry_algorithm_data: Option<RevenueRecoveryAlgorithmData>,
    pub split_txns_enabled: Option<common_enums::SplitTxnsEnabled>,
}

impl Profile {
    #[cfg(feature = "v1")]
    pub fn get_id(&self) -> &common_utils::id_type::ProfileId {
        &self.profile_id
    }

    #[cfg(feature = "v2")]
    pub fn get_id(&self) -> &common_utils::id_type::ProfileId {
        &self.id
    }
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
#[diesel(table_name = business_profile, primary_key(profile_id))]
pub struct ProfileNew {
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_name: String,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub return_url: Option<common_utils::types::Url>,
    pub enable_payment_response_hash: bool,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: bool,
    pub webhook_details: Option<WebhookDetails>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub is_recon_enabled: bool,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub payment_link_config: Option<BusinessPaymentLinkConfig>,
    pub session_expiry: Option<i64>,
    pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
    pub payout_link_config: Option<BusinessPayoutLinkConfig>,
    pub is_extended_card_info_enabled: Option<bool>,
    pub extended_card_info_config: Option<pii::SecretSerdeValue>,
    pub is_connector_agnostic_mit_enabled: Option<bool>,
    pub use_billing_as_payment_method_billing: Option<bool>,
    pub collect_shipping_details_from_wallet_connector: Option<bool>,
    pub collect_billing_details_from_wallet_connector: Option<bool>,
    pub outgoing_webhook_custom_http_headers: Option<Encryption>,
    pub always_collect_billing_details_from_wallet_connector: Option<bool>,
    pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
    pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_tax_connector_enabled: Option<bool>,
    pub version: common_enums::ApiVersion,
    pub is_network_tokenization_enabled: bool,
    pub is_auto_retries_enabled: Option<bool>,
    pub max_auto_retries_enabled: Option<i16>,
    pub is_click_to_pay_enabled: bool,
    pub authentication_product_ids:
        Option<common_types::payments::AuthenticationConnectorAccountMap>,
    pub card_testing_guard_config: Option<CardTestingGuardConfig>,
    pub card_testing_secret_key: Option<Encryption>,
    pub is_clear_pan_retries_enabled: Option<bool>,
    pub is_debit_routing_enabled: bool,
    pub merchant_business_country: Option<common_enums::CountryAlpha2>,
    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
    pub merchant_country_code: Option<common_types::payments::MerchantCountryCode>,
    pub billing_processor_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
    pub order_fulfillment_time: Option<i64>,
    pub order_fulfillment_time_origin: Option<common_enums::OrderFulfillmentTimeOrigin>,
    pub frm_routing_algorithm_id: Option<String>,
    pub payout_routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
    pub three_ds_decision_manager_config: Option<common_types::payments::DecisionManagerRecord>,
    pub should_collect_cvv_during_payment:
        Option<primitive_wrappers::ShouldCollectCvvDuringPayment>,
    pub id: common_utils::id_type::ProfileId,
    pub revenue_recovery_retry_algorithm_type: Option<common_enums::RevenueRecoveryAlgorithmType>,
    pub revenue_recovery_retry_algorithm_data: Option<RevenueRecoveryAlgorithmData>,
    pub is_iframe_redirection_enabled: Option<bool>,
    pub is_external_vault_enabled: Option<bool>,
    pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
    pub split_txns_enabled: Option<common_enums::SplitTxnsEnabled>,
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
#[diesel(table_name = business_profile)]
pub struct ProfileUpdateInternal {
    pub profile_name: Option<String>,
    pub modified_at: time::PrimitiveDateTime,
    pub return_url: Option<common_utils::types::Url>,
    pub enable_payment_response_hash: Option<bool>,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: Option<bool>,
    pub webhook_details: Option<WebhookDetails>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub is_recon_enabled: Option<bool>,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub payment_link_config: Option<BusinessPaymentLinkConfig>,
    pub session_expiry: Option<i64>,
    pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
    pub payout_link_config: Option<BusinessPayoutLinkConfig>,
    pub is_extended_card_info_enabled: Option<bool>,
    pub extended_card_info_config: Option<pii::SecretSerdeValue>,
    pub is_connector_agnostic_mit_enabled: Option<bool>,
    pub use_billing_as_payment_method_billing: Option<bool>,
    pub collect_shipping_details_from_wallet_connector: Option<bool>,
    pub collect_billing_details_from_wallet_connector: Option<bool>,
    pub outgoing_webhook_custom_http_headers: Option<Encryption>,
    pub always_collect_billing_details_from_wallet_connector: Option<bool>,
    pub always_collect_shipping_details_from_wallet_connector: Option<bool>,
    pub tax_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub is_tax_connector_enabled: Option<bool>,
    pub is_network_tokenization_enabled: Option<bool>,
    pub is_auto_retries_enabled: Option<bool>,
    pub max_auto_retries_enabled: Option<i16>,
    pub is_click_to_pay_enabled: Option<bool>,
    pub authentication_product_ids:
        Option<common_types::payments::AuthenticationConnectorAccountMap>,
    pub card_testing_guard_config: Option<CardTestingGuardConfig>,
    pub card_testing_secret_key: Option<Encryption>,
    pub is_clear_pan_retries_enabled: Option<bool>,
    pub is_debit_routing_enabled: Option<bool>,
    pub merchant_business_country: Option<common_enums::CountryAlpha2>,
    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
    pub merchant_country_code: Option<common_types::payments::MerchantCountryCode>,
    pub billing_processor_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
    pub routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
    pub order_fulfillment_time: Option<i64>,
    pub order_fulfillment_time_origin: Option<common_enums::OrderFulfillmentTimeOrigin>,
    pub frm_routing_algorithm_id: Option<String>,
    pub payout_routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
    pub default_fallback_routing: Option<pii::SecretSerdeValue>,
    pub three_ds_decision_manager_config: Option<common_types::payments::DecisionManagerRecord>,
    pub should_collect_cvv_during_payment:
        Option<primitive_wrappers::ShouldCollectCvvDuringPayment>,
    pub revenue_recovery_retry_algorithm_type: Option<common_enums::RevenueRecoveryAlgorithmType>,
    pub revenue_recovery_retry_algorithm_data: Option<RevenueRecoveryAlgorithmData>,
    pub is_iframe_redirection_enabled: Option<bool>,
    pub is_external_vault_enabled: Option<bool>,
    pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
    pub split_txns_enabled: Option<common_enums::SplitTxnsEnabled>,
}

#[cfg(feature = "v2")]
impl ProfileUpdateInternal {
    pub fn apply_changeset(self, source: Profile) -> Profile {
        let Self {
            profile_name,
            modified_at,
            return_url,
            enable_payment_response_hash,
            payment_response_hash_key,
            redirect_to_merchant_with_http_post,
            webhook_details,
            metadata,
            is_recon_enabled,
            applepay_verified_domains,
            payment_link_config,
            session_expiry,
            authentication_connector_details,
            payout_link_config,
            is_extended_card_info_enabled,
            extended_card_info_config,
            is_connector_agnostic_mit_enabled,
            use_billing_as_payment_method_billing,
            collect_shipping_details_from_wallet_connector,
            collect_billing_details_from_wallet_connector,
            outgoing_webhook_custom_http_headers,
            always_collect_billing_details_from_wallet_connector,
            always_collect_shipping_details_from_wallet_connector,
            tax_connector_id,
            is_tax_connector_enabled,
            billing_processor_id,
            routing_algorithm_id,
            order_fulfillment_time,
            order_fulfillment_time_origin,
            frm_routing_algorithm_id,
            payout_routing_algorithm_id,
            default_fallback_routing,
            should_collect_cvv_during_payment,
            is_network_tokenization_enabled,
            is_auto_retries_enabled,
            max_auto_retries_enabled,
            is_click_to_pay_enabled,
            authentication_product_ids,
            three_ds_decision_manager_config,
            card_testing_guard_config,
            card_testing_secret_key,
            is_clear_pan_retries_enabled,
            is_debit_routing_enabled,
            merchant_business_country,
            revenue_recovery_retry_algorithm_type,
            revenue_recovery_retry_algorithm_data,
            is_iframe_redirection_enabled,
            is_external_vault_enabled,
            external_vault_connector_details,
            merchant_category_code,
            merchant_country_code,
            split_txns_enabled,
        } = self;
        Profile {
            id: source.id,
            merchant_id: source.merchant_id,
            profile_name: profile_name.unwrap_or(source.profile_name),
            created_at: source.created_at,
            modified_at,
            return_url: return_url.or(source.return_url),
            enable_payment_response_hash: enable_payment_response_hash
                .unwrap_or(source.enable_payment_response_hash),
            payment_response_hash_key: payment_response_hash_key
                .or(source.payment_response_hash_key),
            redirect_to_merchant_with_http_post: redirect_to_merchant_with_http_post
                .unwrap_or(source.redirect_to_merchant_with_http_post),
            webhook_details: webhook_details.or(source.webhook_details),
            metadata: metadata.or(source.metadata),
            is_recon_enabled: is_recon_enabled.unwrap_or(source.is_recon_enabled),
            applepay_verified_domains: applepay_verified_domains
                .or(source.applepay_verified_domains),
            payment_link_config: payment_link_config.or(source.payment_link_config),
            session_expiry: session_expiry.or(source.session_expiry),
            authentication_connector_details: authentication_connector_details
                .or(source.authentication_connector_details),
            payout_link_config: payout_link_config.or(source.payout_link_config),
            is_extended_card_info_enabled: is_extended_card_info_enabled
                .or(source.is_extended_card_info_enabled),
            is_connector_agnostic_mit_enabled: is_connector_agnostic_mit_enabled
                .or(source.is_connector_agnostic_mit_enabled),
            extended_card_info_config: extended_card_info_config
                .or(source.extended_card_info_config),
            use_billing_as_payment_method_billing: use_billing_as_payment_method_billing
                .or(source.use_billing_as_payment_method_billing),
            collect_shipping_details_from_wallet_connector:
                collect_shipping_details_from_wallet_connector
                    .or(source.collect_shipping_details_from_wallet_connector),
            collect_billing_details_from_wallet_connector:
                collect_billing_details_from_wallet_connector
                    .or(source.collect_billing_details_from_wallet_connector),
            outgoing_webhook_custom_http_headers: outgoing_webhook_custom_http_headers
                .or(source.outgoing_webhook_custom_http_headers),
            always_collect_billing_details_from_wallet_connector:
                always_collect_billing_details_from_wallet_connector
                    .or(always_collect_billing_details_from_wallet_connector),
            always_collect_shipping_details_from_wallet_connector:
                always_collect_shipping_details_from_wallet_connector
                    .or(always_collect_shipping_details_from_wallet_connector),
            tax_connector_id: tax_connector_id.or(source.tax_connector_id),
            is_tax_connector_enabled: is_tax_connector_enabled.or(source.is_tax_connector_enabled),
            routing_algorithm_id: routing_algorithm_id.or(source.routing_algorithm_id),
            order_fulfillment_time: order_fulfillment_time.or(source.order_fulfillment_time),
            order_fulfillment_time_origin: order_fulfillment_time_origin
                .or(source.order_fulfillment_time_origin),
            frm_routing_algorithm_id: frm_routing_algorithm_id.or(source.frm_routing_algorithm_id),
            payout_routing_algorithm_id: payout_routing_algorithm_id
                .or(source.payout_routing_algorithm_id),
            default_fallback_routing: default_fallback_routing.or(source.default_fallback_routing),
            should_collect_cvv_during_payment: should_collect_cvv_during_payment
                .or(source.should_collect_cvv_during_payment),
            version: source.version,
            dynamic_routing_algorithm: None,
            is_network_tokenization_enabled: is_network_tokenization_enabled
                .unwrap_or(source.is_network_tokenization_enabled),
            is_auto_retries_enabled: is_auto_retries_enabled.or(source.is_auto_retries_enabled),
            max_auto_retries_enabled: max_auto_retries_enabled.or(source.max_auto_retries_enabled),
            always_request_extended_authorization: None,
            is_click_to_pay_enabled: is_click_to_pay_enabled
                .unwrap_or(source.is_click_to_pay_enabled),
            authentication_product_ids: authentication_product_ids
                .or(source.authentication_product_ids),
            three_ds_decision_manager_config: three_ds_decision_manager_config
                .or(source.three_ds_decision_manager_config),
            card_testing_guard_config: card_testing_guard_config
                .or(source.card_testing_guard_config),
            card_testing_secret_key: card_testing_secret_key.or(source.card_testing_secret_key),
            is_clear_pan_retries_enabled: is_clear_pan_retries_enabled
                .unwrap_or(source.is_clear_pan_retries_enabled),
            force_3ds_challenge: None,
            is_debit_routing_enabled: is_debit_routing_enabled
                .unwrap_or(source.is_debit_routing_enabled),
            merchant_business_country: merchant_business_country
                .or(source.merchant_business_country),
            revenue_recovery_retry_algorithm_type: revenue_recovery_retry_algorithm_type
                .or(source.revenue_recovery_retry_algorithm_type),
            revenue_recovery_retry_algorithm_data: revenue_recovery_retry_algorithm_data
                .or(source.revenue_recovery_retry_algorithm_data),
            is_iframe_redirection_enabled: is_iframe_redirection_enabled
                .or(source.is_iframe_redirection_enabled),
            is_external_vault_enabled: is_external_vault_enabled
                .or(source.is_external_vault_enabled),
            external_vault_connector_details: external_vault_connector_details
                .or(source.external_vault_connector_details),
            three_ds_decision_rule_algorithm: None,
            acquirer_config_map: None,
            merchant_category_code: merchant_category_code.or(source.merchant_category_code),
            merchant_country_code: merchant_country_code.or(source.merchant_country_code),
            dispute_polling_interval: None,
            split_txns_enabled: split_txns_enabled.or(source.split_txns_enabled),
            is_manual_retry_enabled: None,


    surcharge_amount: Option<MinorUnit>,
    /// tax on surcharge amount
    tax_on_surcharge: Option<MinorUnit>,
}

#[cfg(feature = "v2")]
pub struct AmountDetailsSetter {
    pub order_amount: Amount,
    pub currency: common_enums::Currency,
    pub shipping_cost: Option<MinorUnit>,
    pub order_tax_amount: Option<MinorUnit>,
    pub skip_external_tax_calculation: common_enums::TaxCalculationOverride,
    pub skip_surcharge_calculation: common_enums::SurchargeCalculationOverride,
    pub surcharge_amount: Option<MinorUnit>,
    pub tax_on_surcharge: Option<MinorUnit>,
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)]
pub struct AmountDetailsResponse {
    /// The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and 1 for 1¥ since ¥ is a zero-decimal currency. Read more about [the Decimal and Non-Decimal Currencies](https://github.com/juspay/hyperswitch/wiki/Decimal-and-Non%E2%80%90Decimal-Currencies)
    #[schema(value_type = u64, example = 6540)]
    pub order_amount: MinorUnit,
    /// The currency of the order
    #[schema(example = "USD", value_type = Currency)]
    pub currency: common_enums::Currency,
    /// The shipping cost of the order. This has to be collected from the merchant
    pub shipping_cost: Option<MinorUnit>,
    /// Tax amount related to the order. This will be calculated by the external tax provider
    pub order_tax_amount: Option<MinorUnit>,
    /// The action to whether calculate tax by calling external tax provider or not
    #[schema(value_type = TaxCalculationOverride)]
    pub external_tax_calculation: common_enums::TaxCalculationOverride,
    /// The action to whether calculate surcharge or not
    #[schema(value_type = SurchargeCalculationOverride)]
    pub surcharge_calculation: common_enums::SurchargeCalculationOverride,
    /// The surcharge amount to be added to the order, collected from the merchant
    pub surcharge_amount: Option<MinorUnit>,
    /// tax on surcharge amount
    pub tax_on_surcharge: Option<MinorUnit>,
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)]
pub struct PaymentAmountDetailsResponse {
    /// The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and 1 for 1¥ since ¥ is a zero-decimal currency. Read more about [the Decimal and Non-Decimal Currencies](https://github.com/juspay/hyperswitch/wiki/Decimal-and-Non%E2%80%90Decimal-Currencies)
    #[schema(value_type = u64, example = 6540)]
    #[serde(default, deserialize_with = "amount::deserialize")]
    pub order_amount: MinorUnit,
    /// The currency of the order
    #[schema(example = "USD", value_type = Currency)]
    pub currency: common_enums::Currency,
    /// The shipping cost of the order. This has to be collected from the merchant
    pub shipping_cost: Option<MinorUnit>,
    /// Tax amount related to the order. This will be calculated by the external tax provider
    pub order_tax_amount: Option<MinorUnit>,
    /// The action to whether calculate tax by calling external tax provider or not
    #[schema(value_type = TaxCalculationOverride)]
    pub external_tax_calculation: common_enums::TaxCalculationOverride,
    /// The action to whether calculate surcharge or not
    #[schema(value_type = SurchargeCalculationOverride)]
    pub surcharge_calculation: common_enums::SurchargeCalculationOverride,
    /// The surcharge amount to be added to the order, collected from the merchant
    pub surcharge_amount: Option<MinorUnit>,
    /// tax on surcharge amount
    pub tax_on_surcharge: Option<MinorUnit>,
    /// The total amount of the order including tax, surcharge and shipping cost
    pub net_amount: MinorUnit,
    /// The amount that was requested to be captured for this payment
    pub amount_to_capture: Option<MinorUnit>,
    /// The amount that can be captured on the payment. Either in one go or through multiple captures.
    /// This is applicable in case the capture method was either `manual` or `manual_multiple`
    pub amount_capturable: MinorUnit,
    /// The amount that was captured for this payment. This is the sum of all the captures done on this payment
    pub amount_captured: Option<MinorUnit>,
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]

pub struct PaymentAttemptAmountDetails {
    /// The total amount of the order including tax, surcharge and shipping cost
    pub net_amount: MinorUnit,
    /// The amount that was requested to be captured for this payment
    pub amount_to_capture: Option<MinorUnit>,
    /// Surcharge amount for the payment attempt.
    /// This is either derived by surcharge rules, or sent by the merchant
    pub surcharge_amount: Option<MinorUnit>,
    /// Tax amount for the payment attempt
    /// This is either derived by surcharge rules, or sent by the merchant
    pub tax_on_surcharge: Option<MinorUnit>,
    /// The total amount that can be captured for this payment attempt.
    pub amount_capturable: MinorUnit,
    /// Shipping cost for the payment attempt.
    /// Shipping cost for the payment attempt.
    pub shipping_cost: Option<MinorUnit>,
    /// Tax amount for the order.
    /// This is either derived by calling an external tax processor, or sent by the merchant
    pub order_tax_amount: Option<MinorUnit>,
}

#[cfg(feature = "v2")]
impl AmountDetails {
    pub fn new(amount_details_setter: AmountDetailsSetter) -> Self {
        Self {
            order_amount: amount_details_setter.order_amount,
            currency: amount_details_setter.currency,
            shipping_cost: amount_details_setter.shipping_cost,
            order_tax_amount: amount_details_setter.order_tax_amount,
            skip_external_tax_calculation: amount_details_setter.skip_external_tax_calculation,
            skip_surcharge_calculation: amount_details_setter.skip_surcharge_calculation,
            surcharge_amount: amount_details_setter.surcharge_amount,
            tax_on_surcharge: amount_details_setter.tax_on_surcharge,
        }
    }
    pub fn order_amount(&self) -> Amount {
        self.order_amount
    }
    pub fn currency(&self) -> common_enums::Currency {
        self.currency
    }
    pub fn shipping_cost(&self) -> Option<MinorUnit> {
        self.shipping_cost
    }
    pub fn order_tax_amount(&self) -> Option<MinorUnit> {
        self.order_tax_amount
    }
    pub fn skip_external_tax_calculation(&self) -> common_enums::TaxCalculationOverride {
        self.skip_external_tax_calculation
    }
    pub fn skip_surcharge_calculation(&self) -> common_enums::SurchargeCalculationOverride {
        self.skip_surcharge_calculation
    }
    pub fn surcharge_amount(&self) -> Option<MinorUnit> {
        self.surcharge_amount
    }
    pub fn tax_on_surcharge(&self) -> Option<MinorUnit> {
        self.tax_on_surcharge
    }
}

#[cfg(feature = "v2")]
impl AmountDetailsUpdate {
    pub fn order_amount(&self) -> Option<Amount> {
        self.order_amount
    }
    pub fn currency(&self) -> Option<common_enums::Currency> {
        self.currency
    }
    pub fn shipping_cost(&self) -> Option<MinorUnit> {
        self.shipping_cost
    }
    pub fn order_tax_amount(&self) -> Option<MinorUnit> {
        self.order_tax_amount
    }
    pub fn skip_external_tax_calculation(&self) -> Option<common_enums::TaxCalculationOverride> {
        self.skip_external_tax_calculation
    }
    pub fn skip_surcharge_calculation(&self) -> Option<common_enums::SurchargeCalculationOverride> {
        self.skip_surcharge_calculation
    }
    pub fn surcharge_amount(&self) -> Option<MinorUnit> {
        self.surcharge_amount
    }
    pub fn tax_on_surcharge(&self) -> Option<MinorUnit> {
        self.tax_on_surcharge
    }
}
#[cfg(feature = "v1")]
#[derive(
    Default,
    Debug,
    serde::Deserialize,
    serde::Serialize,
    Clone,
    ToSchema,
    router_derive::PolymorphicSchema,
    router_derive::ValidateSchema,
)]
#[generate_schemas(PaymentsCreateRequest, PaymentsUpdateRequest, PaymentsConfirmRequest)]
#[serde(deny_unknown_fields)]
pub struct PaymentsRequest {
    /// The primary amount for the payment, provided in the lowest denomination of the specified currency (e.g., 6540 for $65.40 USD). This field is mandatory for creating a payment.
    #[schema(value_type = Option<u64>, example = 6540)]
    #[serde(default, deserialize_with = "amount::deserialize_option")]
    #[mandatory_in(PaymentsCreateRequest = u64)]
    // Makes the field mandatory in PaymentsCreateRequest
    pub amount: Option<Amount>,

    /// Total tax amount applicable to the order, in the lowest denomination of the currency.
    #[schema(value_type = Option<i64>, example = 6540)]
    pub order_tax_amount: Option<MinorUnit>,

    /// The three-letter ISO 4217 currency code (e.g., "USD", "EUR") for the payment amount. This field is mandatory for creating a payment.
    #[schema(example = "USD", value_type = Option<Currency>)]
    #[mandatory_in(PaymentsCreateRequest = Currency)]
    pub currency: Option<api_enums::Currency>,

    /// The amount to be captured from the user's payment method, in the lowest denomination. If not provided, and `capture_method` is `automatic`, the full payment `amount` will be captured. If `capture_method` is `manual`, this can be specified in the `/capture` call. Must be less than or equal to the authorized amount.
    #[schema(value_type = Option<i64>, example = 6540)]
    pub amount_to_capture: Option<MinorUnit>,

    /// The shipping cost for the payment. This is required for tax calculation in some regions.
    #[schema(value_type = Option<i64>, example = 6540)]
    pub shipping_cost: Option<MinorUnit>,

    /// Optional. A merchant-provided unique identifier for the payment, contains 30 characters long (e.g., "pay_mbabizu24mvu3mela5njyhpit4"). If provided, it ensures idempotency for the payment creation request. If omitted, Hyperswitch generates a unique ID for the payment.
    #[schema(
        value_type = Option<String>,
        min_length = 30,
        max_length = 30,
        example = "pay_mbabizu24mvu3mela5njyhpit4"
    )]
    #[serde(default, deserialize_with = "payment_id_type::deserialize_option")]
    pub payment_id: Option<PaymentIdType>,

    /// This is an identifier for the merchant account. This is inferred from the API key
    /// provided during the request
    #[schema(max_length = 255, example = "merchant_1668273825", value_type = Option<String>)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub merchant_id: Option<id_type::MerchantId>,

    /// Details of the routing configuration for that payment
    #[schema(value_type = Option<StraightThroughAlgorithm>, example = json!({
        "type": "single",
        "data": {"connector": "stripe", "merchant_connector_id": "mca_123"}
    }))]
    pub routing: Option<serde_json::Value>,

    /// This allows to manually select a connector with which the payment can go through.
    #[schema(value_type = Option<Vec<Connector>>, max_length = 255, example = json!(["stripe", "adyen"]))]
    pub connector: Option<Vec<api_enums::Connector>>,

    #[schema(value_type = Option<CaptureMethod>, example = "automatic")]
    pub capture_method: Option<api_enums::CaptureMethod>,

    #[schema(value_type = Option<AuthenticationType>, example = "no_three_ds", default = "three_ds")]
    pub authentication_type: Option<api_enums::AuthenticationType>,

    /// The billing details of the payment. This address will be used for invoicing.
    pub billing: Option<Address>,

    /// A timestamp (ISO 8601 code) that determines when the payment should be captured.
    /// Providing this field will automatically set `capture` to true
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub capture_on: Option<PrimitiveDateTime>,

    /// If set to `true`, Hyperswitch attempts to confirm and authorize the payment immediately after creation, provided sufficient payment method details are included. If `false` or omitted (default is `false`), the payment is created with a status such as `requires_payment_method` or `requires_confirmation`, and a separate `POST /payments/{payment_id}/confirm` call is necessary to proceed with authorization.
    #[schema(default = false, example = true)]
    pub confirm: Option<bool>,

    /// Passing this object creates a new customer or attaches an existing customer to the payment
    pub customer: Option<CustomerDetails>,

    /// The identifier for the customer
    #[schema(value_type = Option<String>, max_length = 64, min_length = 1, example = "cus_y3oqhf46pyzuxjbcn2giaqnb44")]
    pub customer_id: Option<id_type::CustomerId>,

    /// The customer's email address.
    /// This field will be deprecated soon, use the customer object instead
    #[schema(max_length = 255, value_type = Option<String>, example = "johntest@test.com", deprecated)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub email: Option<Email>,

    /// The customer's name.
    /// This field will be deprecated soon, use the customer object instead.
    #[schema(value_type = Option<String>, max_length = 255, example = "John Test", deprecated)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub name: Option<Secret<String>>,

    /// The customer's phone number
    /// This field will be deprecated soon, use the customer object instead
    #[schema(value_type = Option<String>, max_length = 255, example = "9123456789", deprecated)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub phone: Option<Secret<String>>,

    /// The country code for the customer phone number
    /// This field will be deprecated soon, use the customer object instead
    #[schema(max_length = 255, example = "+1", deprecated)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub phone_country_code: Option<String>,

    /// Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. When making a recurring payment by passing a mandate_id, this parameter is mandatory
    #[schema(example = true)]
    pub off_session: Option<bool>,

    /// An arbitrary string attached to the payment. Often useful for displaying to users or for your own internal record-keeping.
    #[schema(example = "It's my first payment request")]
    pub description: Option<String>,

    /// The URL to redirect the customer to after they complete the payment process or authentication. This is crucial for flows that involve off-site redirection (e.g., 3DS, some bank redirects, wallet payments).
    #[schema(value_type = Option<String>, example = "https://hyperswitch.io", max_length = 2048)]
    pub return_url: Option<Url>,

    #[schema(value_type = Option<FutureUsage>, example = "off_session")]
    pub setup_future_usage: Option<api_enums::FutureUsage>,

    #[schema(example = "bank_transfer")]
    #[serde(with = "payment_method_data_serde", default)]
    pub payment_method_data: Option<PaymentMethodDataRequest>,

    #[schema(value_type = Option<PaymentMethod>, example = "card")]
    pub payment_method: Option<api_enums::PaymentMethod>,

    /// As Hyperswitch tokenises the sensitive details about the payments method, it provides the payment_token as a reference to a stored payment method, ensuring that the sensitive details are not exposed in any manner.
    #[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
    pub payment_token: Option<String>,

    /// This is used along with the payment_token field while collecting during saved card payments. This field will be deprecated soon, use the payment_method_data.card_token object instead
    #[schema(value_type = Option<String>, deprecated)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub card_cvc: Option<Secret<String>>,

    /// The shipping address for the payment
    pub shipping: Option<Address>,

    /// For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.
    #[schema(max_length = 255, example = "Hyperswitch Router")]
    pub statement_descriptor_name: Option<String>,

    /// Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 22 characters for the concatenated descriptor.
    #[schema(max_length = 255, example = "Payment for shoes purchase")]
    pub statement_descriptor_suffix: Option<String>,

    /// Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount
    #[schema(value_type = Option<Vec<OrderDetailsWithAmount>>, example = r#"[{
        "product_name": "Apple iPhone 16",
        "quantity": 1,
        "amount" : 69000
        "product_img_link" : "https://dummy-img-link.com"
    }]"#)]
    pub order_details: Option<Vec<OrderDetailsWithAmount>>,

    /// It's a token used for client side verification.
    #[schema(example = "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo")]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest)]
    pub client_secret: Option<String>,

    /// Passing this object during payments creates a mandate. The mandate_type sub object is passed by the server.
    pub mandate_data: Option<MandateData>,

    /// This "CustomerAcceptance" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client.
    #[schema(value_type = Option<CustomerAcceptance>)]
    pub customer_acceptance: Option<common_payments_types::CustomerAcceptance>,

    /// A unique identifier to link the payment to a mandate. To do Recurring payments after a mandate has been created, pass the mandate_id instead of payment_method_data
    #[schema(max_length = 64, example = "mandate_iwer89rnjef349dni3")]
    #[remove_in(PaymentsUpdateRequest)]
    pub mandate_id: Option<String>,

    /// Additional details required by 3DS 2.0
    #[schema(value_type = Option<BrowserInformation>, example = r#"{
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled":true
    }"#)]
    pub browser_info: Option<serde_json::Value>,

    /// To indicate the type of payment experience that the payment method would go through
    #[schema(value_type = Option<PaymentExperience>, example = "redirect_to_url")]
    pub payment_experience: Option<api_enums::PaymentExperience>,

    /// Can be used to specify the Payment Method Type
    #[schema(value_type = Option<PaymentMethodType>, example = "google_pay")]
    pub payment_method_type: Option<api_enums::PaymentMethodType>,

    /// Business country of the merchant for this payment.
    /// To be deprecated soon. Pass the profile_id instead
    #[schema(value_type = Option<CountryAlpha2>, example = "US")]
    #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest)]
    pub business_country: Option<api_enums::CountryAlpha2>,

    /// Business label of the merchant for this payment.
    /// To be deprecated soon. Pass the profile_id instead
    #[schema(example = "food")]
    #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest)]
    pub business_label: Option<String>,

    #[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
    pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,

    /// Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent
    #[schema(value_type = Option<Vec<PaymentMethodType>>)]
    pub allowed_payment_method_types: Option<Vec<api_enums::PaymentMethodType>>,

    /// Business sub label for the payment
    #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest, PaymentsCreateRequest)]
    pub business_sub_label: Option<String>,

    /// Denotes the retry action
    #[schema(value_type = Option<RetryAction>)]
    #[remove_in(PaymentsCreateRequest)]
    pub retry_action: Option<api_enums::RetryAction>,

    /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
    #[schema(value_type = Option<Object>, example = r#"{ "udf1": "some-value", "udf2": "some-value" }"#)]
    pub metadata: Option<serde_json::Value>,

    /// Some connectors like Apple pay, Airwallex and Noon might require some additional information, find specific details in the child attributes below.
    pub connector_metadata: Option<ConnectorMetadata>,

    /// Additional data that might be required by hyperswitch based on the requested features by the merchants.
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub feature_metadata: Option<FeatureMetadata>,

    /// Whether to generate the payment link for this payment or not (if applicable)
    #[schema(default = false, example = true)]
    pub payment_link: Option<bool>,

    #[schema(value_type = Option<PaymentCreatePaymentLinkConfig>)]
    pub payment_link_config: Option<PaymentCreatePaymentLinkConfig>,

    /// Custom payment link config id set at business profile, send only if business_specific_configs is configured
    pub payment_link_config_id: Option<String>,

    /// The business profile to be used for this payment, if not passed the default business profile associated with the merchant account will be used. It is mandatory in case multiple business profiles have been set up.
    #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest)]
    #[schema(value_type = Option<String>)]
    pub profile_id: Option<id_type::ProfileId>,

    #[remove_in(PaymentsConfirmRequest)]
    #[schema(value_type = Option<RequestSurchargeDetails>)]
    pub surcharge_details: Option<RequestSurchargeDetails>,

    /// The type of the payment that differentiates between normal and various types of mandate payments
    #[schema(value_type = Option<PaymentType>)]
    pub payment_type: Option<api_enums::PaymentType>,

    ///Request an incremental authorization, i.e., increase the authorized amount on a confirmed payment before you capture it.
    pub request_incremental_authorization: Option<bool>,

    ///Will be used to expire client secret after certain amount of time to be supplied in seconds
    ///(900) for 15 mins
    #[schema(example = 900)]
    pub session_expiry: Option<u32>,

    /// Additional data related to some frm(Fraud Risk Management) connectors
    #[schema(value_type = Option<Object>, example = r#"{ "coverage_request" : "fraud", "fulfillment_method" : "delivery" }"#)]
    pub frm_metadata: Option<pii::SecretSerdeValue>,

    /// Whether to perform external authentication (if applicable)
    #[schema(example = true)]
    pub request_external_three_ds_authentication: Option<bool>,

    /// Details required for recurring payment
    pub recurring_details: Option<RecurringDetails>,

    /// Fee information to be charged on the payment being collected
    #[schema(value_type = Option<SplitPaymentsRequest>)]
    pub split_payments: Option<common_types::payments::SplitPaymentsRequest>,

    /// Optional boolean value to extent authorization period of this payment
    ///
    /// capture method must be manual or manual_multiple
    #[schema(value_type = Option<bool>, default = false)]
    pub request_extended_authorization: Option<RequestExtendedAuthorizationBool>,

    /// Your unique identifier for this payment or order. This ID helps you reconcile payments on your system. If provided, it is passed to the connector if supported.
    #[schema(
        value_type = Option<String>,
        max_length = 255,
        example = "Custom_Order_id_123"
    )]
    pub merchant_order_reference_id: Option<String>,

    /// Whether to calculate tax for this payment intent
    pub skip_external_tax_calculation: Option<bool>,

    /// Choose what kind of sca exemption is required for this payment
    #[schema(value_type = Option<ScaExemptionType>)]
    pub psd2_sca_exemption_type: Option<api_enums::ScaExemptionType>,

    /// Service details for click to pay external authentication
    #[schema(value_type = Option<CtpServiceDetails>)]
    pub ctp_service_details: Option<CtpServiceDetails>,

    /// Indicates if 3ds challenge is forced
    pub force_3ds_challenge: Option<bool>,

    /// Indicates if 3DS method data was successfully completed or not
    pub threeds_method_comp_ind: Option<ThreeDsCompletionIndicator>,

    /// Indicates if the redirection has to open in the iframe
    pub is_iframe_redirection_enabled: Option<bool>,

    /// If enabled, provides whole connector response
    pub all_keys_required: Option<bool>,

    /// Indicates whether the `payment_id` was provided by the merchant
    /// This value is inferred internally based on the request
    #[serde(skip_deserializing)]
    #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest, PaymentsConfirmRequest)]
    pub is_payment_id_from_merchant: bool,

    /// Indicates how the payment was initiated (e.g., ecommerce, mail, or telephone).
    #[schema(value_type = Option<PaymentChannel>)]
    pub payment_channel: Option<common_enums::PaymentChannel>,

    /// Your tax status for this order or transaction.
    #[schema(value_type = Option<TaxStatus>)]
    pub tax_status: Option<api_enums::TaxStatus>,

    /// Total amount of the discount you have applied to the order or transaction.
    #[schema(value_type = Option<i64>, example = 6540)]
    pub discount_amount: Option<MinorUnit>,

    /// Tax amount applied to shipping charges.
    pub shipping_amount_tax: Option<MinorUnit>,

    /// Duty or customs fee amount for international transactions.
    pub duty_amount: Option<MinorUnit>,

    /// Date the payer placed the order.
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub order_date: Option<PrimitiveDateTime>,

    /// Allow partial authorization for this payment
    #[schema(value_type = Option<bool>, default = false)]
    pub enable_partial_authorization: Option<primitive_wrappers::EnablePartialAuthorizationBool>,

    /// Boolean indicating whether to enable overcapture for this payment
    #[remove_in(PaymentsConfirmRequest)]
    #[schema(value_type = Option<bool>, example = true)]
    pub enable_overcapture: Option<primitive_wrappers::EnableOvercaptureBool>,

    /// Boolean flag indicating whether this payment method is stored and has been previously used for payments
    #[schema(value_type = Option<bool>, example = true)]
    pub is_stored_credential: Option<bool>,
}

#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct CtpServiceDetails {
    /// merchant transaction id
    pub merchant_transaction_id: Option<String>,
    /// network transaction correlation id
    pub correlation_id: Option<String>,
    /// session transaction flow id
    pub x_src_flow_id: Option<String>,
    /// provider Eg: Visa, Mastercard
    #[schema(value_type = Option<CtpServiceProvider>)]
    pub provider: Option<api_enums::CtpServiceProvider>,
    /// Encrypted payload
    #[schema(value_type = Option<String>)]
    pub encrypted_payload: Option<Secret<String>>,
}

impl CtpServiceDetails {
    pub fn is_network_confirmation_call_required(&self) -> bool {
        self.provider == Some(api_enums::CtpServiceProvider::Mastercard)
    }
}

#[cfg(feature = "v1")]
/// Checks if the inner values of two options are equal
/// Returns true if values are not equal, returns false in other cases
fn are_optional_values_invalid<T: PartialEq>(
    first_option: Option<&T>,
    second_option: Option<&T>,
) -> bool {
    match (first_option, second_option) {
        (Some(first_option), Some(second_option)) => first_option != second_option,
        _ => false,
    }
}

#[cfg(feature = "v1")]
impl PaymentsRequest {
    /// Get the customer id
    ///
    /// First check the id for `customer.id`
    /// If not present, check for `customer_id` at the root level
    pub fn get_customer_id(&self) -> Option<&id_type::CustomerId> {
        self.customer_id
            .as_ref()
            .or(self.customer.as_ref().map(|customer| &customer.id))
    }

    pub fn validate_and_get_request_extended_authorization(
        &self,
    ) -> common_utils::errors::CustomResult<Option<RequestExtendedAuthorizationBool>, ValidationError>
    {
        self.request_extended_authorization
            .as_ref()
            .map(|request_extended_authorization| {
                request_extended_authorization.validate_field_and_get(self)
            })
            .transpose()
    }

    /// Checks if the customer details are passed in both places
    /// If they are passed in both places, check for both the values to be equal
    /// Or else, return the field which has inconsistent data
    pub fn validate_customer_details_in_request(&self) -> Option<Vec<&str>> {
        if let Some(CustomerDetails {
            id,
            name,
            email,
            phone,
            phone_country_code,
            ..
        }) = self.customer.as_ref()
        {
            let invalid_fields = [
                are_optional_values_invalid(self.customer_id.as_ref(), Some(id))
                    .then_some("customer_id and customer.id"),
                are_optional_values_invalid(self.email.as_ref(), email.as_ref())
                    .then_some("email and customer.email"),
                are_optional_values_invalid(self.name.as_ref(), name.as_ref())
                    .then_some("name and customer.name"),
                are_optional_values_invalid(self.phone.as_ref(), phone.as_ref())
                    .then_some("phone and customer.phone"),
                are_optional_values_invalid(
                    self.phone_country_code.as_ref(),
                    phone_country_code.as_ref(),
                )
                .then_some("phone_country_code and customer.phone_country_code"),
            ]
            .into_iter()
            .flatten()
            .collect::<Vec<_>>();

            if invalid_fields.is_empty() {
                None
            } else {
                Some(invalid_fields)
            }
        } else {
            None
        }
    }

    pub fn get_feature_metadata_as_value(
        &self,
    ) -> common_utils::errors::CustomResult<
        Option<serde_json::Value>,
        common_utils::errors::ParsingError,
    > {
        self.feature_metadata
            .as_ref()
            .map(Encode::encode_to_value)
            .transpose()
    }

    pub fn get_connector_metadata_as_value(
        &self,
    ) -> common_utils::errors::CustomResult<
        Option<serde_json::Value>,
        common_utils::errors::ParsingError,
    > {
        self.connector_metadata
            .as_ref()
            .map(Encode::encode_to_value)
            .transpose()
    }

    pub fn get_allowed_payment_method_types_as_value(
        &self,
    ) -> common_utils::errors::CustomResult<
        Option<serde_json::Value>,
        common_utils::errors::ParsingError,
    > {
        self.allowed_payment_method_types
            .as_ref()
            .map(Encode::encode_to_value)
            .transpose()
    }

    pub fn get_order_details_as_value(
        &self,
    ) -> common_utils::errors::CustomResult<
        Option<Vec<pii::SecretSerdeValue>>,
        common_utils::errors::ParsingError,
    > {
        self.order_details
            .as_ref()
            .map(|od| {
                od.iter()
                    .map(|order| order.encode_to_value().map(Secret::new))
                    .collect::<Result<Vec<_>, _>>()
            })
            .transpose()
    }
    pub fn validate_stored_credential(
        &self,
    ) -> common_utils::errors::CustomResult<(), ValidationError> {
        if self.is_stored_credential == Some(false)
            && (self.recurring_details.is_some()
                || self.payment_token.is_some()
                || self.mandate_id.is_some())
        {
            Err(ValidationError::InvalidValue {
                message:
                    "is_stored_credential should be true when reusing stored payment method data"
                        .to_string(),
            }
            .into())
        } else {
            Ok(())
        }
    }
}

#[cfg(feature = "v1")]
#[cfg(test)]
mod payments_request_test {
    use common_utils::generate_customer_id_of_default_length;

    use super::*;

    #[test]
    fn test_valid_case_where_customer_details_are_passed_only_once() {
        let customer_id = generate_customer_id_of_default_length();
        let payments_request = PaymentsRequest {
            customer_id: Some(customer_id),
            ..Default::default()
        };

        assert!(payments_request
            .validate_customer_details_in_request()
            .is_none());
    }

    #[test]
    fn test_valid_case_where_customer_id_is_passed_in_both_places() {
        let customer_id = generate_customer_id_of_default_length();

        let customer_object = CustomerDetails {
            id: customer_id.clone(),
            name: None,
            email: None,
            phone: None,
            phone_country_code: None,
            tax_registration_id: None,
        };

        let payments_request = PaymentsRequest {
            customer_id: Some(customer_id),
            customer: Some(customer_object),
            ..Default::default()
        };

        assert!(payments_request
            .validate_customer_details_in_request()
            .is_none());
    }

    #[test]
    fn test_invalid_case_where_customer_id_is_passed_in_both_places() {
        let customer_id = generate_customer_id_of_default_length();
        let another_customer_id = generate_customer_id_of_default_length();

        let customer_object = CustomerDetails {
            id: customer_id.clone(),
            name: None,
            email: None,
            phone: None,
            phone_country_code: None,
            tax_registration_id: None,
        };

        let payments_request = PaymentsRequest {
            customer_id: Some(another_customer_id),
            customer: Some(customer_object),
            ..Default::default()
        };

        assert_eq!(
            payments_request.validate_customer_details_in_request(),
            Some(vec!["customer_id and customer.id"])
        );
    }
}

/// Details of surcharge applied on this payment, if applicable
#[derive(
    Default, Debug, Clone, serde::Serialize, serde::Deserialize, Copy, ToSchema, PartialEq,
)]
pub struct RequestSurchargeDetails {


// Struct: EventListConstraints
// File: crates/api_models/src/webhook_events.rs
// Module: api_models
// Implementations: 0

pub struct EventListConstraints


// Struct: ThunesRouterData
// File: crates/hyperswitch_connectors/src/connectors/thunes/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ThunesRouterData<T>


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

pub struct Card


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

pub fn list_payment_methods(
    state: routes::SessionState,
    merchant_context: domain::MerchantContext,
    mut req: api::PaymentMethodListRequest,
) -> errors::RouterResponse<api::PaymentMethodListResponse>


// File: crates/api_models/src/feature_matrix.rs
// Module: api_models
// Public structs: 5

use std::collections::HashSet;

use serde::{Deserialize, Serialize};
use utoipa::ToSchema;

#[derive(Default, Debug, Deserialize, Serialize, Clone, ToSchema)]
pub struct FeatureMatrixRequest {
    // List of connectors for which the feature matrix is requested
    #[schema(value_type = Option<Vec<Connector>>)]
    pub connectors: Option<Vec<common_enums::connector_enums::Connector>>,
}

#[derive(Debug, Clone, ToSchema, Serialize)]
pub struct CardSpecificFeatures {
    /// Indicates whether three_ds card payments are supported
    #[schema(value_type = FeatureStatus)]
    pub three_ds: common_enums::FeatureStatus,
    /// Indicates whether non three_ds card payments are supported
    #[schema(value_type = FeatureStatus)]
    pub no_three_ds: common_enums::FeatureStatus,
    /// List of supported card networks
    #[schema(value_type = Vec<CardNetwork>)]
    pub supported_card_networks: Vec<common_enums::CardNetwork>,
}

#[derive(Debug, Clone, ToSchema, Serialize)]
#[serde(untagged)]
pub enum PaymentMethodSpecificFeatures {
    /// Card specific features
    Card(CardSpecificFeatures),
}

#[derive(Debug, ToSchema, Serialize)]
pub struct SupportedPaymentMethod {
    /// The payment method supported by the connector
    #[schema(value_type = PaymentMethod)]
    pub payment_method: common_enums::PaymentMethod,
    /// The payment method type supported by the connector
    #[schema(value_type = PaymentMethodType)]
    pub payment_method_type: common_enums::PaymentMethodType,
    /// The display name of the payment method type
    pub payment_method_type_display_name: String,
    /// Indicates whether the payment method supports mandates via the connector
    #[schema(value_type = FeatureStatus)]
    pub mandates: common_enums::FeatureStatus,
    /// Indicates whether the payment method supports refunds via the connector
    #[schema(value_type = FeatureStatus)]
    pub refunds: common_enums::FeatureStatus,
    /// List of supported capture methods supported by the payment method type
    #[schema(value_type = Vec<CaptureMethod>)]
    pub supported_capture_methods: Vec<common_enums::CaptureMethod>,
    /// Information on the Payment method specific payment features
    #[serde(flatten)]
    pub payment_method_specific_features: Option<PaymentMethodSpecificFeatures>,
    /// List of countries supported by the payment method type via the connector
    #[schema(value_type = Option<HashSet<CountryAlpha3>>)]
    pub supported_countries: Option<HashSet<common_enums::CountryAlpha3>>,
    /// List of currencies supported by the payment method type via the connector
    #[schema(value_type = Option<HashSet<Currency>>)]
    pub supported_currencies: Option<HashSet<common_enums::Currency>>,
}

#[derive(Debug, ToSchema, Serialize)]
pub struct ConnectorFeatureMatrixResponse {
    /// The name of the connector
    pub name: String,
    /// The display name of the connector
    pub display_name: String,
    /// The description of the connector
    pub description: String,
    /// The category of the connector
    #[schema(value_type = HyperswitchConnectorCategory, example = "payment_gateway")]
    pub category: common_enums::HyperswitchConnectorCategory,
    /// The integration status of the connector
    #[schema(value_type = ConnectorIntegrationStatus, example = "live")]
    pub integration_status: common_enums::ConnectorIntegrationStatus,
    /// The list of payment methods supported by the connector
    pub supported_payment_methods: Option<Vec<SupportedPaymentMethod>>,
    /// The list of webhook flows supported by the connector
    #[schema(value_type = Option<Vec<EventClass>>)]
    pub supported_webhook_flows: Option<Vec<common_enums::EventClass>>,
}

#[derive(Debug, Serialize, ToSchema)]
pub struct FeatureMatrixListResponse {
    /// The number of connectors included in the response
    pub connector_count: usize,
    // The list of payments response objects
    pub connectors: Vec<ConnectorFeatureMatrixResponse>,
}

impl common_utils::events::ApiEventMetric for FeatureMatrixListResponse {}
impl common_utils::events::ApiEventMetric for FeatureMatrixRequest {}


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

pub struct Redirect


// Struct: HyperswitchVaultErrorResponse
// File: crates/hyperswitch_connectors/src/connectors/hyperswitch_vault/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct HyperswitchVaultErrorResponse


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

pub struct Phonepe

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


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

impl api::MandateSetup for for Payeezy


// Implementation: impl super::api_event::events::ApiLogsFilterAnalytics for for ClickhouseClient
// File: crates/analytics/src/clickhouse.rs
// Module: analytics
// Methods: 0 total (0 public)

impl super::api_event::events::ApiLogsFilterAnalytics for for ClickhouseClient