// File: crates/diesel_models/src/dynamic_routing_stats.rs
// Module: diesel_models
// Public structs: 3

use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};

use crate::schema::dynamic_routing_stats;

#[derive(Clone, Debug, Eq, Insertable, PartialEq)]
#[diesel(table_name = dynamic_routing_stats)]
pub struct DynamicRoutingStatsNew {
    pub payment_id: common_utils::id_type::PaymentId,
    pub attempt_id: String,
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_id: common_utils::id_type::ProfileId,
    pub amount: common_utils::types::MinorUnit,
    pub success_based_routing_connector: String,
    pub payment_connector: String,
    pub currency: Option<common_enums::Currency>,
    pub payment_method: Option<common_enums::PaymentMethod>,
    pub capture_method: Option<common_enums::CaptureMethod>,
    pub authentication_type: Option<common_enums::AuthenticationType>,
    pub payment_status: common_enums::AttemptStatus,
    pub conclusive_classification: common_enums::SuccessBasedRoutingConclusiveState,
    pub created_at: time::PrimitiveDateTime,
    pub payment_method_type: Option<common_enums::PaymentMethodType>,
    pub global_success_based_connector: Option<String>,
}

#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Selectable, Insertable)]
#[diesel(table_name = dynamic_routing_stats, primary_key(attempt_id, merchant_id), check_for_backend(diesel::pg::Pg))]
pub struct DynamicRoutingStats {
    pub payment_id: common_utils::id_type::PaymentId,
    pub attempt_id: String,
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_id: common_utils::id_type::ProfileId,
    pub amount: common_utils::types::MinorUnit,
    pub success_based_routing_connector: String,
    pub payment_connector: String,
    pub currency: Option<common_enums::Currency>,
    pub payment_method: Option<common_enums::PaymentMethod>,
    pub capture_method: Option<common_enums::CaptureMethod>,
    pub authentication_type: Option<common_enums::AuthenticationType>,
    pub payment_status: common_enums::AttemptStatus,
    pub conclusive_classification: common_enums::SuccessBasedRoutingConclusiveState,
    pub created_at: time::PrimitiveDateTime,
    pub payment_method_type: Option<common_enums::PaymentMethodType>,
    pub global_success_based_connector: Option<String>,
}

#[derive(
    Clone, Debug, Eq, PartialEq, AsChangeset, router_derive::DebugAsDisplay, serde::Deserialize,
)]
#[diesel(table_name = dynamic_routing_stats)]
pub struct DynamicRoutingStatsUpdate {
    pub amount: common_utils::types::MinorUnit,
    pub success_based_routing_connector: String,
    pub payment_connector: String,
    pub currency: Option<common_enums::Currency>,
    pub payment_method: Option<common_enums::PaymentMethod>,
    pub capture_method: Option<common_enums::CaptureMethod>,
    pub authentication_type: Option<common_enums::AuthenticationType>,
    pub payment_status: common_enums::AttemptStatus,
    pub conclusive_classification: common_enums::SuccessBasedRoutingConclusiveState,
    pub payment_method_type: Option<common_enums::PaymentMethodType>,
    pub global_success_based_connector: Option<String>,
}


// Implementation: impl api::PaymentSync for for Bluecode
// File: crates/hyperswitch_connectors/src/connectors/bluecode.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSync for for Bluecode


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

// Public submodules:
pub mod transformers;


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

impl ConnectorCommon for for Plaid


// Struct: TtlForExtendedCardInfo
// File: crates/api_models/src/admin.rs
// Module: api_models
// Implementations: 2
// Traits: Default, std::ops::Deref

pub struct TtlForExtendedCardInfo


// File: crates/router/src/core/relay/utils.rs
// Module: router
// Public functions: 1

use std::str::FromStr;

use common_utils::{ext_traits::OptionExt, id_type};
use error_stack::ResultExt;
use hyperswitch_domain_models::{router_data::ErrorResponse, types};

use crate::{
    core::payments,
    db::{
        domain,
        errors::{self, RouterResult},
    },
    routes::SessionState,
};

const IRRELEVANT_PAYMENT_INTENT_ID: &str = "irrelevant_payment_intent_id";

const IRRELEVANT_PAYMENT_ATTEMPT_ID: &str = "irrelevant_payment_attempt_id";

pub async fn construct_relay_refund_router_data<F>(
    state: &SessionState,
    merchant_id: &id_type::MerchantId,
    connector_account: &domain::MerchantConnectorAccount,
    relay_record: &hyperswitch_domain_models::relay::Relay,
) -> RouterResult<types::RefundsRouterData<F>> {
    let connector_auth_type = connector_account
        .get_connector_account_details()
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Failed while parsing value for ConnectorAuthType")?;

    #[cfg(feature = "v2")]
    let connector_name = &connector_account.connector_name.to_string();

    #[cfg(feature = "v1")]
    let connector_name = &connector_account.connector_name;

    let webhook_url = Some(payments::helpers::create_webhook_url(
        &state.base_url.clone(),
        merchant_id,
        connector_account.get_id().get_string_repr(),
    ));

    let supported_connector = &state
        .conf
        .multiple_api_version_supported_connectors
        .supported_connectors;

    let connector_enum = api_models::enums::Connector::from_str(connector_name)
        .change_context(errors::ConnectorError::InvalidConnectorName)
        .change_context(errors::ApiErrorResponse::InvalidDataValue {
            field_name: "connector",
        })
        .attach_printable_lazy(|| format!("unable to parse connector name {connector_name:?}"))?;

    let connector_api_version = if supported_connector.contains(&connector_enum) {
        state
            .store
            .find_config_by_key(&format!("connector_api_version_{connector_name}"))
            .await
            .map(|value| value.config)
            .ok()
    } else {
        None
    };

    let hyperswitch_domain_models::relay::RelayData::Refund(relay_refund_data) = relay_record
        .request_data
        .clone()
        .get_required_value("refund relay data")
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Failed to obtain relay data to construct relay refund data")?;

    let relay_id_string = relay_record.id.get_string_repr().to_string();

    let router_data = hyperswitch_domain_models::router_data::RouterData {
        flow: std::marker::PhantomData,
        merchant_id: merchant_id.clone(),
        customer_id: None,
        tenant_id: state.tenant.tenant_id.clone(),
        connector: connector_name.to_string(),
        payment_id: IRRELEVANT_PAYMENT_INTENT_ID.to_string(),
        attempt_id: IRRELEVANT_PAYMENT_ATTEMPT_ID.to_string(),
        status: common_enums::AttemptStatus::Charged,
        payment_method: common_enums::PaymentMethod::default(),
        connector_auth_type,
        description: None,
        address: hyperswitch_domain_models::payment_address::PaymentAddress::default(),
        auth_type: common_enums::AuthenticationType::default(),
        connector_meta_data: connector_account.metadata.clone(),
        connector_wallets_details: None,
        amount_captured: None,
        payment_method_status: None,
        minor_amount_captured: None,
        request: hyperswitch_domain_models::router_request_types::RefundsData {
            refund_id: relay_id_string.clone(),
            connector_transaction_id: relay_record.connector_resource_id.clone(),
            refund_amount: relay_refund_data.amount.get_amount_as_i64(),
            minor_refund_amount: relay_refund_data.amount,
            currency: relay_refund_data.currency,
            payment_amount: relay_refund_data.amount.get_amount_as_i64(),
            minor_payment_amount: relay_refund_data.amount,
            webhook_url,
            connector_metadata: None,
            refund_connector_metadata: None,
            reason: relay_refund_data.reason,
            connector_refund_id: relay_record.connector_reference_id.clone(),
            browser_info: None,
            split_refunds: None,
            integrity_object: None,
            refund_status: common_enums::RefundStatus::from(relay_record.status),
            merchant_account_id: None,
            merchant_config_currency: None,
            capture_method: None,
            additional_payment_method_data: None,
        },

        response: Err(ErrorResponse::default()),
        access_token: None,
        session_token: None,
        reference_id: None,
        payment_method_token: None,
        connector_customer: None,
        recurring_mandate_payment_data: None,
        preprocessing_id: None,
        connector_request_reference_id: relay_id_string.clone(),
        #[cfg(feature = "payouts")]
        payout_method_data: None,
        #[cfg(feature = "payouts")]
        quote_id: None,
        test_mode: connector_account.get_connector_test_mode(),
        payment_method_balance: None,
        connector_api_version,
        connector_http_status_code: None,
        external_latency: None,
        apple_pay_flow: None,
        frm_metadata: None,
        refund_id: Some(relay_id_string),
        dispute_id: None,
        connector_response: None,
        integrity_check: Ok(()),
        additional_merchant_data: None,
        header_payload: None,
        connector_mandate_request_reference_id: None,
        authentication_id: None,
        psd2_sca_exemption_type: None,
        raw_connector_response: None,
        is_payment_id_from_merchant: None,
        l2_l3_data: None,
        minor_amount_capturable: None,
    };

    Ok(router_data)
}


// Implementation: impl super::behaviour::Conversion for for MerchantAccount
// File: crates/hyperswitch_domain_models/src/merchant_account.rs
// Module: hyperswitch_domain_models
// Methods: 3 total (0 public)

impl super::behaviour::Conversion for for MerchantAccount


// Implementation: impl ThreeDSRequestor
// File: crates/hyperswitch_connectors/src/connectors/netcetera/netcetera_types.rs
// Module: hyperswitch_connectors
// Methods: 1 total (1 public)

impl ThreeDSRequestor


// Struct: UnifiedTranslationsUpdate
// File: crates/diesel_models/src/unified_translations.rs
// Module: diesel_models
// Implementations: 0

pub struct UnifiedTranslationsUpdate


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

impl api::PaymentAuthorize for for Thunes


// Function: into_inner
// File: crates/diesel_models/src/api_keys.rs
// Module: diesel_models

pub fn into_inner(self) -> String


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

pub fn get_string_val(
        &self,
        params: &Vec<routing_types::DynamicRoutingConfigParams>,
    ) -> String


// File: crates/router/src/events/outgoing_webhook_logs.rs
// Module: router
// Public functions: 1
// Public structs: 1

use api_models::{enums::EventType as OutgoingWebhookEventType, webhooks::OutgoingWebhookContent};
use common_enums::WebhookDeliveryAttempt;
use serde::Serialize;
use serde_json::Value;
use time::OffsetDateTime;

use super::EventType;
use crate::services::kafka::KafkaMessage;

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub struct OutgoingWebhookEvent {
    tenant_id: common_utils::id_type::TenantId,
    merchant_id: common_utils::id_type::MerchantId,
    event_id: String,
    event_type: OutgoingWebhookEventType,
    #[serde(flatten)]
    content: Option<OutgoingWebhookEventContent>,
    is_error: bool,
    error: Option<Value>,
    created_at_timestamp: i128,
    initial_attempt_id: Option<String>,
    status_code: Option<u16>,
    delivery_attempt: Option<WebhookDeliveryAttempt>,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "outgoing_webhook_event_type", rename_all = "snake_case")]
pub enum OutgoingWebhookEventContent {
    #[cfg(feature = "v1")]
    Payment {
        payment_id: common_utils::id_type::PaymentId,
        content: Value,
    },
    #[cfg(feature = "v2")]
    Payment {
        payment_id: common_utils::id_type::GlobalPaymentId,
        content: Value,
    },
    Payout {
        payout_id: common_utils::id_type::PayoutId,
        content: Value,
    },
    #[cfg(feature = "v1")]
    Refund {
        payment_id: common_utils::id_type::PaymentId,
        refund_id: String,
        content: Value,
    },
    #[cfg(feature = "v2")]
    Refund {
        payment_id: common_utils::id_type::GlobalPaymentId,
        refund_id: common_utils::id_type::GlobalRefundId,
        content: Value,
    },
    #[cfg(feature = "v1")]
    Dispute {
        payment_id: common_utils::id_type::PaymentId,
        attempt_id: String,
        dispute_id: String,
        content: Value,
    },
    #[cfg(feature = "v2")]
    Dispute {
        payment_id: common_utils::id_type::GlobalPaymentId,
        attempt_id: String,
        dispute_id: String,
        content: Value,
    },
    Mandate {
        payment_method_id: String,
        mandate_id: String,
        content: Value,
    },
}
pub trait OutgoingWebhookEventMetric {
    fn get_outgoing_webhook_event_content(&self) -> Option<OutgoingWebhookEventContent>;
}

#[cfg(feature = "v1")]
impl OutgoingWebhookEventMetric for OutgoingWebhookContent {
    fn get_outgoing_webhook_event_content(&self) -> Option<OutgoingWebhookEventContent> {
        match self {
            Self::PaymentDetails(payment_payload) => Some(OutgoingWebhookEventContent::Payment {
                payment_id: payment_payload.payment_id.clone(),
                content: masking::masked_serialize(&payment_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            Self::RefundDetails(refund_payload) => Some(OutgoingWebhookEventContent::Refund {
                payment_id: refund_payload.payment_id.clone(),
                refund_id: refund_payload.get_refund_id_as_string(),
                content: masking::masked_serialize(&refund_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            Self::DisputeDetails(dispute_payload) => Some(OutgoingWebhookEventContent::Dispute {
                payment_id: dispute_payload.payment_id.clone(),
                attempt_id: dispute_payload.attempt_id.clone(),
                dispute_id: dispute_payload.dispute_id.clone(),
                content: masking::masked_serialize(&dispute_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            Self::MandateDetails(mandate_payload) => Some(OutgoingWebhookEventContent::Mandate {
                payment_method_id: mandate_payload.payment_method_id.clone(),
                mandate_id: mandate_payload.mandate_id.clone(),
                content: masking::masked_serialize(&mandate_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            #[cfg(feature = "payouts")]
            Self::PayoutDetails(payout_payload) => Some(OutgoingWebhookEventContent::Payout {
                payout_id: payout_payload.payout_id.clone(),
                content: masking::masked_serialize(&payout_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
        }
    }
}

#[cfg(feature = "v2")]
impl OutgoingWebhookEventMetric for OutgoingWebhookContent {
    fn get_outgoing_webhook_event_content(&self) -> Option<OutgoingWebhookEventContent> {
        match self {
            Self::PaymentDetails(payment_payload) => Some(OutgoingWebhookEventContent::Payment {
                payment_id: payment_payload.id.clone(),
                content: masking::masked_serialize(&payment_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            Self::RefundDetails(refund_payload) => Some(OutgoingWebhookEventContent::Refund {
                payment_id: refund_payload.payment_id.clone(),
                refund_id: refund_payload.id.clone(),
                content: masking::masked_serialize(&refund_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            Self::DisputeDetails(dispute_payload) => {
                //TODO: add support for dispute outgoing webhook
                todo!()
            }
            Self::MandateDetails(mandate_payload) => Some(OutgoingWebhookEventContent::Mandate {
                payment_method_id: mandate_payload.payment_method_id.clone(),
                mandate_id: mandate_payload.mandate_id.clone(),
                content: masking::masked_serialize(&mandate_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
            #[cfg(feature = "payouts")]
            Self::PayoutDetails(payout_payload) => Some(OutgoingWebhookEventContent::Payout {
                payout_id: payout_payload.payout_id.clone(),
                content: masking::masked_serialize(&payout_payload)
                    .unwrap_or(serde_json::json!({"error":"failed to serialize"})),
            }),
        }
    }
}

impl OutgoingWebhookEvent {
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        tenant_id: common_utils::id_type::TenantId,
        merchant_id: common_utils::id_type::MerchantId,
        event_id: String,
        event_type: OutgoingWebhookEventType,
        content: Option<OutgoingWebhookEventContent>,
        error: Option<Value>,
        initial_attempt_id: Option<String>,
        status_code: Option<u16>,
        delivery_attempt: Option<WebhookDeliveryAttempt>,
    ) -> Self {
        Self {
            tenant_id,
            merchant_id,
            event_id,
            event_type,
            content,
            is_error: error.is_some(),
            error,
            created_at_timestamp: OffsetDateTime::now_utc().unix_timestamp_nanos() / 1_000_000,
            initial_attempt_id,
            status_code,
            delivery_attempt,
        }
    }
}

impl KafkaMessage for OutgoingWebhookEvent {
    fn event_type(&self) -> EventType {
        EventType::OutgoingWebhookLogs
    }

    fn key(&self) -> String {
        self.event_id.clone()
    }
}


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

pub struct NetworkSpecificFields


// Struct: ChargeResponseData
// File: crates/hyperswitch_connectors/src/connectors/boku/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ChargeResponseData


// Function: new
// File: crates/hyperswitch_domain_models/src/merchant_connector_account.rs
// Module: hyperswitch_domain_models

pub fn new(
        hash_map: HashMap<id_type::MerchantConnectorAccountId, String>,
    ) -> Result<Self, api_error_response::ApiErrorResponse>


// Function: server
// File: crates/router/src/routes/app.rs
// Module: router

pub fn server(state: AppState) -> Scope


// Struct: NetworkResponse
// File: crates/hyperswitch_connectors/src/connectors/jpmorgan/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NetworkResponse


// Function: api_key_revoke
// File: crates/openapi/src/routes/api_keys.rs
// Module: openapi

pub fn api_key_revoke()


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

impl api::PaymentVoid for for Wise


// Function: custom_json_error_handler
// File: crates/router/src/utils.rs
// Module: router

pub fn custom_json_error_handler(err: JsonPayloadError, _req: &HttpRequest) -> Error


// Function: get_single_profile_id
// File: crates/router/src/utils/user_role.rs
// Module: router

pub fn get_single_profile_id(
    state: &SessionState,
    user_role: &UserRole,
    merchant_id: &id_type::MerchantId,
) -> UserResult<id_type::ProfileId>


// Struct: RefundMetricRow
// File: crates/analytics/src/refunds/metrics.rs
// Module: analytics
// Implementations: 0

pub struct RefundMetricRow


// Struct: ConnectorWalletDetails
// File: crates/api_models/src/admin.rs
// Module: api_models
// Implementations: 0

pub struct ConnectorWalletDetails


// Implementation: impl Refund for for Wellsfargo
// File: crates/hyperswitch_connectors/src/connectors/wellsfargo.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl Refund for for Wellsfargo


// Struct: StripePaymentIntentListResponse
// File: crates/router/src/compatibility/stripe/payment_intents/types.rs
// Module: router
// Implementations: 0

pub struct StripePaymentIntentListResponse


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

impl ConnectorCommon for for Finix


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

pub struct TokenizedCard


// Implementation: impl RedisConnInterface for for RedisStore
// File: crates/storage_impl/src/redis.rs
// Module: storage_impl
// Methods: 1 total (0 public)

impl RedisConnInterface for for RedisStore


// Struct: ArchipelRefundOrder
// File: crates/hyperswitch_connectors/src/connectors/archipel/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ArchipelRefundOrder


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

impl api::PaymentToken for for Fiuu


// Struct: ElavonAuthType
// File: crates/hyperswitch_connectors/src/connectors/elavon/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ElavonAuthType


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

impl api::PaymentSync for for Airwallex


// Struct: CapturePaymentData
// File: crates/hyperswitch_connectors/src/connectors/getnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CapturePaymentData


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

pub struct StripebillingInvoiceObject


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

pub struct SurchargePercentage


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

pub struct PaymentMethodCollectLinkResponse


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

// Documentation: Panics if `json_payload` array does not contain one `GetPaymentIntentMetricRequest` element.

pub fn get_org_payment_intent_metrics(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<[GetPaymentIntentMetricRequest; 1]>,
    ) -> impl Responder


// Struct: NmiVaultResponse
// File: crates/hyperswitch_connectors/src/connectors/nmi/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NmiVaultResponse


// Implementation: impl PaymentsResponseScheme
// File: crates/hyperswitch_connectors/src/connectors/worldpay/response.rs
// Module: hyperswitch_connectors
// Methods: 1 total (1 public)

impl PaymentsResponseScheme


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

pub struct DeutschebankThreeDSInitializeRequestMeansOfPayment


// Struct: BillingAddress
// File: crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 1
// Traits: AddressConstructor

pub struct BillingAddress


// Struct: EbanxPayoutDetails
// File: crates/hyperswitch_connectors/src/connectors/ebanx/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct EbanxPayoutDetails


// Implementation: impl MockDb
// File: crates/storage_impl/src/mock_db.rs
// Module: storage_impl
// Methods: 5 total (0 public)

impl MockDb


// Struct: EliminationRoutingAlgorithm
// File: crates/api_models/src/routing.rs
// Module: api_models
// Implementations: 3
// Traits: DynamicRoutingAlgoAccessor

pub struct EliminationRoutingAlgorithm


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

impl Mifinity


// File: crates/analytics/src/refunds/distribution/sessionized_distribution.rs
// Module: analytics

mod refund_error_message;
mod refund_reason;

pub(super) use refund_error_message::RefundErrorMessage;
pub(super) use refund_reason::RefundReason;

pub use super::{RefundDistribution, RefundDistributionAnalytics, RefundDistributionRow};


// Implementation: impl ConnectorCommon for for Fiservemea
// File: crates/hyperswitch_connectors/src/connectors/fiservemea.rs
// Module: hyperswitch_connectors
// Methods: 5 total (0 public)

impl ConnectorCommon for for Fiservemea


// Function: get_sync_process_schedule_time
// File: crates/router/src/workflows/dispute_list.rs
// Module: router

pub fn get_sync_process_schedule_time(
    db: &dyn StorageInterface,
    connector: &str,
    merchant_id: &common_utils::id_type::MerchantId,
    retry_count: i32,
) -> Result<Option<time::PrimitiveDateTime>, errors::ProcessTrackerError>


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

impl ConnectorMetadata


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

pub struct VantivSyncErrorResponse


// Function: insert
// File: crates/diesel_models/src/query/user_key_store.rs
// Module: diesel_models

pub fn insert(self, conn: &PgPooledConn) -> StorageResult<UserKeyStore>


// Module Structure
// File: crates/external_services/src/email.rs
// Module: external_services

// Public submodules:
pub mod ses;
pub mod smtp;
pub mod no_email;


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

impl api::PaymentCapture for for Trustpayments


// Struct: ZenRouterData
// File: crates/hyperswitch_connectors/src/connectors/zen/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ZenRouterData<T>


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

pub struct DeutschebankCaptureRequest


// Function: profile_acquirer_update
// File: crates/router/src/routes/profile_acquirer.rs
// Module: router

pub fn profile_acquirer_update(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<(
        common_utils::id_type::ProfileId,
        common_utils::id_type::ProfileAcquirerId,
    )


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

impl RetrieveFile for for Stripe


// File: crates/analytics/src/refunds/metrics/sessionized_metrics/refund_success_rate.rs
// Module: analytics

use std::collections::HashSet;

use api_models::analytics::{
    refunds::{RefundDimensions, RefundFilters, RefundMetricsBucketIdentifier},
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::RefundMetricRow;
use crate::{
    enums::AuthInfo,
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, SeriesBucket, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
};
#[derive(Default)]
pub(crate) struct RefundSuccessRate {}

#[async_trait::async_trait]
impl<T> super::RefundMetric<T> for RefundSuccessRate
where
    T: AnalyticsDataSource + super::RefundMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        dimensions: &[RefundDimensions],
        auth: &AuthInfo,
        filters: &RefundFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(RefundMetricsBucketIdentifier, RefundMetricRow)>>
    where
        T: AnalyticsDataSource + super::RefundMetricAnalytics,
    {
        let mut query_builder = QueryBuilder::new(AnalyticsCollection::RefundSessionized);
        let mut dimensions = dimensions.to_vec();

        dimensions.push(RefundDimensions::RefundStatus);

        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()?;

        filters.set_filter_clause(&mut query_builder).switch()?;

        auth.set_filter_clause(&mut query_builder).switch()?;

        time_range.set_filter_clause(&mut query_builder).switch()?;

        for dim in dimensions.iter() {
            query_builder.add_group_by_clause(dim).switch()?;
        }

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

        query_builder
            .execute_query::<RefundMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    RefundMetricsBucketIdentifier::new(
                        i.currency.as_ref().map(|i| i.0),
                        None,
                        i.connector.clone(),
                        i.refund_type.as_ref().map(|i| i.0.to_string()),
                        i.profile_id.clone(),
                        i.refund_reason.clone(),
                        i.refund_error_message.clone(),
                        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<(RefundMetricsBucketIdentifier, RefundMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


// Struct: LinkTokenCreateRequest
// File: crates/api_models/src/pm_auth.rs
// Module: api_models
// Implementations: 0

pub struct LinkTokenCreateRequest


// Implementation: impl MerchantAccount
// File: crates/hyperswitch_domain_models/src/merchant_account.rs
// Module: hyperswitch_domain_models
// Methods: 6 total (6 public)

impl MerchantAccount


// Struct: ToggleDynamicRoutingWrapper
// File: crates/api_models/src/routing.rs
// Module: api_models
// Implementations: 0

pub struct ToggleDynamicRoutingWrapper


// Implementation: impl std::ops::Deref for for ConnectorCustomerMap
// File: crates/common_types/src/customers.rs
// Module: common_types
// Methods: 1 total (0 public)

impl std::ops::Deref for for ConnectorCustomerMap


// File: crates/router/src/core/payments/flows/external_proxy_flow.rs
// Module: router

use std::str::FromStr;

use async_trait::async_trait;
use common_enums as enums;
use common_utils::{id_type, ucs_types, ucs_types::UcsReferenceId};
use error_stack::ResultExt;
use external_services::grpc_client;
#[cfg(feature = "v2")]
use hyperswitch_domain_models::payments::PaymentConfirmData;
use hyperswitch_domain_models::{
    errors::api_error_response::ApiErrorResponse, payments as domain_payments,
};
use masking::ExposeInterface;
use unified_connector_service_client::payments as payments_grpc;

use super::{ConstructFlowSpecificData, Feature};
use crate::{
    core::{
        errors::{ConnectorErrorExt, RouterResult},
        mandate,
        payments::{
            self, access_token, customers, helpers, tokenization, transformers, PaymentData,
        },
        unified_connector_service::{self, ucs_logging_wrapper},
    },
    logger,
    routes::{metrics, SessionState},
    services::{self, api::ConnectorValidation},
    types::{
        self, api, domain,
        transformers::{ForeignFrom, ForeignTryFrom},
    },
    utils::OptionExt,
};

#[cfg(feature = "v2")]
#[async_trait]
impl
    ConstructFlowSpecificData<
        api::ExternalVaultProxy,
        types::ExternalVaultProxyPaymentsData,
        types::PaymentsResponseData,
    > for PaymentConfirmData<api::ExternalVaultProxy>
{
    async fn construct_router_data<'a>(
        &self,
        state: &SessionState,
        connector_id: &str,
        merchant_context: &domain::MerchantContext,
        customer: &Option<domain::Customer>,
        merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
        merchant_recipient_data: Option<types::MerchantRecipientData>,
        header_payload: Option<domain_payments::HeaderPayload>,
    ) -> RouterResult<
        types::RouterData<
            api::ExternalVaultProxy,
            types::ExternalVaultProxyPaymentsData,
            types::PaymentsResponseData,
        >,
    > {
        Box::pin(
            transformers::construct_external_vault_proxy_payment_router_data(
                state,
                self.clone(),
                connector_id,
                merchant_context,
                customer,
                merchant_connector_account,
                merchant_recipient_data,
                header_payload,
            ),
        )
        .await
    }
}

#[async_trait]
impl Feature<api::ExternalVaultProxy, types::ExternalVaultProxyPaymentsData>
    for types::ExternalVaultProxyPaymentsRouterData
{
    async fn decide_flows<'a>(
        mut self,
        state: &SessionState,
        connector: &api::ConnectorData,
        call_connector_action: payments::CallConnectorAction,
        connector_request: Option<services::Request>,
        business_profile: &domain::Profile,
        header_payload: domain_payments::HeaderPayload,
        return_raw_connector_response: Option<bool>,
    ) -> RouterResult<Self> {
        let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
            api::ExternalVaultProxy,
            types::ExternalVaultProxyPaymentsData,
            types::PaymentsResponseData,
        > = connector.connector.get_connector_integration();

        logger::debug!(auth_type=?self.auth_type);
        let mut auth_router_data = services::execute_connector_processing_step(
            state,
            connector_integration,
            &self,
            call_connector_action.clone(),
            connector_request,
            return_raw_connector_response,
        )
        .await
        .to_payment_failed_response()?;

        // External vault proxy doesn't use integrity checks
        auth_router_data.integrity_check = Ok(());
        metrics::PAYMENT_COUNT.add(1, &[]);

        Ok(auth_router_data)
    }

    async fn add_access_token<'a>(
        &self,
        state: &SessionState,
        connector: &api::ConnectorData,
        merchant_context: &domain::MerchantContext,
        creds_identifier: Option<&str>,
    ) -> RouterResult<types::AddAccessTokenResult> {
        access_token::add_access_token(state, connector, merchant_context, self, creds_identifier)
            .await
    }

    async fn add_session_token<'a>(
        self,
        state: &SessionState,
        connector: &api::ConnectorData,
    ) -> RouterResult<Self>
    where
        Self: Sized,
    {
        let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
            api::AuthorizeSessionToken,
            types::AuthorizeSessionTokenData,
            types::PaymentsResponseData,
        > = connector.connector.get_connector_integration();
        let authorize_data = &types::PaymentsAuthorizeSessionTokenRouterData::foreign_from((
            &self,
            types::AuthorizeSessionTokenData::foreign_from(&self),
        ));
        let resp = services::execute_connector_processing_step(
            state,
            connector_integration,
            authorize_data,
            payments::CallConnectorAction::Trigger,
            None,
            None,
        )
        .await
        .to_payment_failed_response()?;
        let mut router_data = self;
        router_data.session_token = resp.session_token;
        Ok(router_data)
    }

    async fn add_payment_method_token<'a>(
        &mut self,
        state: &SessionState,
        connector: &api::ConnectorData,
        tokenization_action: &payments::TokenizationAction,
        should_continue_payment: bool,
    ) -> RouterResult<types::PaymentMethodTokenResult> {
        let request = self.request.clone();
        tokenization::add_payment_method_token(
            state,
            connector,
            tokenization_action,
            self,
            types::PaymentMethodTokenizationData::try_from(request)?,
            should_continue_payment,
        )
        .await
    }

    async fn preprocessing_steps<'a>(
        self,
        state: &SessionState,
        connector: &api::ConnectorData,
    ) -> RouterResult<Self> {
        todo!()
    }

    async fn postprocessing_steps<'a>(
        self,
        state: &SessionState,
        connector: &api::ConnectorData,
    ) -> RouterResult<Self> {
        todo!()
    }

    async fn create_connector_customer<'a>(
        &self,
        state: &SessionState,
        connector: &api::ConnectorData,
    ) -> RouterResult<Option<String>> {
        customers::create_connector_customer(
            state,
            connector,
            self,
            types::ConnectorCustomerData::try_from(self)?,
        )
        .await
    }

    async fn build_flow_specific_connector_request(
        &mut self,
        state: &SessionState,
        connector: &api::ConnectorData,
        call_connector_action: payments::CallConnectorAction,
    ) -> RouterResult<(Option<services::Request>, bool)> {
        match call_connector_action {
            payments::CallConnectorAction::Trigger => {
                connector
                    .connector
                    .validate_connector_against_payment_request(
                        self.request.capture_method,
                        self.payment_method,
                        self.request.payment_method_type,
                    )
                    .to_payment_failed_response()?;

                // Check if the connector supports mandate payment
                // if the payment_method_type does not support mandate for the given connector, downgrade the setup future usage to on session
                if self.request.setup_future_usage
                    == Some(diesel_models::enums::FutureUsage::OffSession)
                    && !self
                        .request
                        .payment_method_type
                        .and_then(|payment_method_type| {
                            state
                                .conf
                                .mandates
                                .supported_payment_methods
                                .0
                                .get(&enums::PaymentMethod::from(payment_method_type))
                                .and_then(|supported_pm_for_mandates| {
                                    supported_pm_for_mandates.0.get(&payment_method_type).map(
                                        |supported_connector_for_mandates| {
                                            supported_connector_for_mandates
                                                .connector_list
                                                .contains(&connector.connector_name)
                                        },
                                    )
                                })
                        })
                        .unwrap_or(false)
                {
                    // downgrade the setup future usage to on session
                    self.request.setup_future_usage =
                        Some(diesel_models::enums::FutureUsage::OnSession);
                };

                // External vault proxy doesn't use regular payment method validation
                // Skip mandate payment validation for external vault proxy

                let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
                    api::ExternalVaultProxy,
                    types::ExternalVaultProxyPaymentsData,
                    types::PaymentsResponseData,
                > = connector.connector.get_connector_integration();

                metrics::EXECUTE_PRETASK_COUNT.add(
                    1,
                    router_env::metric_attributes!(
                        ("connector", connector.connector_name.to_string()),
                        ("flow", format!("{:?}", api::ExternalVaultProxy)),
                    ),
                );

                logger::debug!(completed_pre_tasks=?true);

                // External vault proxy always proceeds
                Ok((
                    connector_integration
                        .build_request(self, &state.conf.connectors)
                        .to_payment_failed_response()?,
                    true,
                ))
            }
            _ => Ok((None, true)),
        }
    }

    async fn create_order_at_connector(
        &mut self,
        state: &SessionState,
        connector: &api::ConnectorData,
        should_continue_payment: bool,
    ) -> RouterResult<Option<types::CreateOrderResult>> {
        if connector
            .connector_name
            .requires_order_creation_before_payment(self.payment_method)
            && should_continue_payment
        {
            let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
                api::CreateOrder,
                types::CreateOrderRequestData,
                types::PaymentsResponseData,
            > = connector.connector.get_connector_integration();

            let request_data = types::CreateOrderRequestData::try_from(self.request.clone())?;

            let response_data: Result<types::PaymentsResponseData, types::ErrorResponse> =
                Err(types::ErrorResponse::default());

            let createorder_router_data =
                helpers::router_data_type_conversion::<_, api::CreateOrder, _, _, _, _>(
                    self.clone(),
                    request_data,
                    response_data,
                );

            let resp = services::execute_connector_processing_step(
                state,
                connector_integration,
                &createorder_router_data,
                payments::CallConnectorAction::Trigger,
                None,
                None,
            )
            .await
            .to_payment_failed_response()?;

            let create_order_resp = match resp.response {
                Ok(res) => {
                    if let types::PaymentsResponseData::PaymentsCreateOrderResponse { order_id } =
                        res
                    {
                        Ok(order_id)
                    } else {
                        Err(error_stack::report!(ApiErrorResponse::InternalServerError)
                            .attach_printable(format!(
                                "Unexpected response format from connector: {res:?}",
                            )))?
                    }
                }
                Err(error) => Err(error),
            };

            Ok(Some(types::CreateOrderResult {
                create_order_result: create_order_resp,
            }))
        } else {
            // If the connector does not require order creation, return None
            Ok(None)
        }
    }

    fn update_router_data_with_create_order_response(
        &mut self,
        create_order_result: types::CreateOrderResult,
    ) {
        match create_order_result.create_order_result {
            Ok(order_id) => {
                self.request.order_id = Some(order_id.clone()); // ? why this is assigned here and ucs also wants this to populate data
                self.response =
                    Ok(types::PaymentsResponseData::PaymentsCreateOrderResponse { order_id });
            }
            Err(err) => {
                self.response = Err(err.clone());
            }
        }
    }

    #[cfg(feature = "v2")]
    async fn call_unified_connector_service_with_external_vault_proxy<'a>(
        &mut self,
        state: &SessionState,
        header_payload: &domain_payments::HeaderPayload,
        lineage_ids: grpc_client::LineageIds,
        merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
        external_vault_merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
        merchant_context: &domain::MerchantContext,
    ) -> RouterResult<()> {
        let client = state
            .grpc_client
            .unified_connector_service_client
            .clone()
            .ok_or(ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to fetch Unified Connector Service client")?;

        let payment_authorize_request =
            payments_grpc::PaymentServiceAuthorizeRequest::foreign_try_from(&*self)
                .change_context(ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to construct Payment Authorize Request")?;

        let connector_auth_metadata =
            unified_connector_service::build_unified_connector_service_auth_metadata(
                merchant_connector_account,
                merchant_context,
            )
            .change_context(ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to construct request metadata")?;

        let external_vault_proxy_metadata =
            unified_connector_service::build_unified_connector_service_external_vault_proxy_metadata(
                external_vault_merchant_connector_account
            )
            .change_context(ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to construct external vault proxy metadata")?;
        let merchant_order_reference_id = header_payload
            .x_reference_id
            .clone()
            .map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
            .transpose()
            .inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
            .ok()
            .flatten()
            .map(ucs_types::UcsReferenceId::Payment);
        let headers_builder = state
            .get_grpc_headers_ucs()
            .external_vault_proxy_metadata(Some(external_vault_proxy_metadata))
            .merchant_reference_id(merchant_order_reference_id)
            .lineage_ids(lineage_ids);
        let updated_router_data = Box::pin(ucs_logging_wrapper(
            self.clone(),
            state,
            payment_authorize_request.clone(),
            headers_builder,
            |mut router_data, payment_authorize_request, grpc_headers| async move {
                let response = client
                    .payment_authorize(
                        payment_authorize_request,
                        connector_auth_metadata,
                        grpc_headers,
                    )
                    .await
                    .change_context(ApiErrorResponse::InternalServerError)
                    .attach_printable("Failed to authorize payment")?;

                let payment_authorize_response = response.into_inner();

                let (router_data_response, status_code) =
                    unified_connector_service::handle_unified_connector_service_response_for_payment_authorize(
                        payment_authorize_response.clone(),
                    )
                    .change_context(ApiErrorResponse::InternalServerError)
                    .attach_printable("Failed to deserialize UCS response")?;

                let router_data_response = router_data_response.map(|(response, status)|{
                    router_data.status = status;
                    response
                });
                router_data.response = router_data_response;
                router_data.raw_connector_response = payment_authorize_response
                    .raw_connector_response
                    .clone()
                    .map(masking::Secret::new);
                router_data.connector_http_status_code = Some(status_code);

                Ok((router_data, payment_authorize_response))
            }
        )).await?;

        // Copy back the updated data
        *self = updated_router_data;
        Ok(())
    }
}


// File: crates/router/src/types/storage/subscription.rs
// Module: router

pub use diesel_models::subscription::{Subscription, SubscriptionNew, SubscriptionUpdate};


// Function: is_internal_api_key_merchant_id_profile_id_auth
// File: crates/router/src/services/authentication.rs
// Module: router

pub fn is_internal_api_key_merchant_id_profile_id_auth(
    headers: &HeaderMap,
    internal_api_key_auth: settings::InternalMerchantIdProfileIdAuthSettings,
) -> bool


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

use common_utils::id_type;

/// The request body for verification of merchant (everything except domain_names are prefilled)
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApplepayMerchantVerificationConfigs {
    pub domain_names: Vec<String>,
    pub encrypt_to: String,
    pub partner_internal_merchant_identifier: String,
    pub partner_merchant_name: String,
}

/// The derivation point for domain names from request body
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ApplepayMerchantVerificationRequest {
    pub domain_names: Vec<String>,
    pub merchant_connector_account_id: id_type::MerchantConnectorAccountId,
}

/// Response to be sent for the verify/applepay api
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ApplepayMerchantResponse {
    pub status_message: String,
}

/// QueryParams to be send by the merchant for fetching the verified domains
#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ApplepayGetVerifiedDomainsParam {
    pub merchant_id: id_type::MerchantId,
    pub merchant_connector_account_id: id_type::MerchantConnectorAccountId,
}
/// Response to be sent for derivation of the already verified domains
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ApplepayVerifiedDomainsResponse {
    pub verified_domains: Vec<String>,
}


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

impl api::RefundSync for for Fiserv


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

pub fn get_oidc_sso_redirect_url(state: &SessionState, provider: &str) -> String


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

pub struct ReversalInformation


// Struct: PayPalWalletData
// File: crates/hyperswitch_domain_models/src/payment_method_data.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct PayPalWalletData


// Struct: AdyenBankAccountIdentification
// File: crates/hyperswitch_connectors/src/connectors/adyenplatform/transformers/payouts.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct AdyenBankAccountIdentification


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

impl Subscription


// Struct: ChatResponse
// File: crates/api_models/src/chat.rs
// Module: api_models
// Implementations: 0

pub struct ChatResponse


// Struct: HipayTokenResponse
// File: crates/hyperswitch_connectors/src/connectors/hipay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct HipayTokenResponse


// Struct: MonerisPaymentsResponse
// File: crates/hyperswitch_connectors/src/connectors/moneris/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct MonerisPaymentsResponse


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

pub fn get_profile_connector_events(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Query<api_models::analytics::connector_events::ConnectorEventsRequest>,
    ) -> impl Responder


// Trait: Lift
// File: crates/hyperswitch_domain_models/src/type_encryption.rs
// Module: hyperswitch_domain_models

pub trait Lift<U>


// Implementation: impl common_utils::events::ApiEventMetric for for EphemeralKeyCreateResponse
// File: crates/api_models/src/ephemeral_key.rs
// Module: api_models
// Methods: 1 total (0 public)

impl common_utils::events::ApiEventMetric for for EphemeralKeyCreateResponse


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

pub struct PaypalSellerPayableBreakdown


// File: crates/euclid/src/dssa.rs
// Module: euclid

//! Domain Specific Static Analyzer
pub mod analyzer;
pub mod graph;
pub mod state_machine;
pub mod truth;
pub mod types;
pub mod utils;


// Struct: DeRoutableConnectorChoice
// File: crates/api_models/src/routing.rs
// Module: api_models
// Implementations: 0

pub struct DeRoutableConnectorChoice


// Function: is_normal
// File: crates/masking/src/maskable.rs
// Module: masking

// Documentation: returns `false` otherwise.

pub fn is_normal(&self) -> bool


// Struct: NuveiPaymentSyncRequest
// File: crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NuveiPaymentSyncRequest


// File: crates/common_utils/src/lib.rs
// Module: common_utils
// Public functions: 18
// Public structs: 4

#![warn(missing_docs, missing_debug_implementations)]
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR" ), "/", "README.md"))]

use masking::{PeekInterface, Secret};

pub mod access_token;
pub mod consts;
pub mod crypto;
pub mod custom_serde;
#[allow(missing_docs)] // Todo: add docs
pub mod encryption;
pub mod errors;
#[allow(missing_docs)] // Todo: add docs
pub mod events;
pub mod ext_traits;
pub mod fp_utils;
/// Used for hashing
pub mod hashing;
pub mod id_type;
#[cfg(feature = "keymanager")]
pub mod keymanager;
pub mod link_utils;
pub mod macros;
#[cfg(feature = "metrics")]
pub mod metrics;
pub mod new_type;
pub mod payout_method_utils;
pub mod pii;
#[allow(missing_docs)] // Todo: add docs
pub mod request;
#[cfg(feature = "signals")]
pub mod signals;
pub mod transformers;
pub mod types;
/// Unified Connector Service (UCS) interface definitions.
///
/// This module defines types and traits for interacting with the Unified Connector Service.
/// It includes reference ID types for payments and refunds, and a trait for extracting
/// UCS reference information from requests.
pub mod ucs_types;
pub mod validation;

pub use base64_serializer::Base64Serializer;

/// Date-time utilities.
pub mod date_time {
    #[cfg(feature = "async_ext")]
    use std::time::Instant;
    use std::{marker::PhantomData, num::NonZeroU8};

    use masking::{Deserialize, Serialize};
    use time::{
        format_description::{
            well_known::iso8601::{Config, EncodedConfig, Iso8601, TimePrecision},
            BorrowedFormatItem,
        },
        OffsetDateTime, PrimitiveDateTime,
    };

    /// Enum to represent date formats
    #[derive(Debug)]
    pub enum DateFormat {
        /// Format the date in 20191105081132 format
        YYYYMMDDHHmmss,
        /// Format the date in 20191105 format
        YYYYMMDD,
        /// Format the date in 201911050811 format
        YYYYMMDDHHmm,
        /// Format the date in 05112019081132 format
        DDMMYYYYHHmmss,
    }

    /// Create a new [`PrimitiveDateTime`] with the current date and time in UTC.
    pub fn now() -> PrimitiveDateTime {
        let utc_date_time = OffsetDateTime::now_utc();
        PrimitiveDateTime::new(utc_date_time.date(), utc_date_time.time())
    }

    /// Convert from OffsetDateTime to PrimitiveDateTime
    pub fn convert_to_pdt(offset_time: OffsetDateTime) -> PrimitiveDateTime {
        PrimitiveDateTime::new(offset_time.date(), offset_time.time())
    }

    /// Return the UNIX timestamp of the current date and time in UTC
    pub fn now_unix_timestamp() -> i64 {
        OffsetDateTime::now_utc().unix_timestamp()
    }

    /// Calculate execution time for a async block in milliseconds
    #[cfg(feature = "async_ext")]
    pub async fn time_it<T, Fut: futures::Future<Output = T>, F: FnOnce() -> Fut>(
        block: F,
    ) -> (T, f64) {
        let start = Instant::now();
        let result = block().await;
        (result, start.elapsed().as_secs_f64() * 1000f64)
    }

    /// Return the given date and time in UTC with the given format Eg: format: YYYYMMDDHHmmss Eg: 20191105081132
    pub fn format_date(
        date: PrimitiveDateTime,
        format: DateFormat,
    ) -> Result<String, time::error::Format> {
        let format = <&[BorrowedFormatItem<'_>]>::from(format);
        date.format(&format)
    }

    /// Return the current date and time in UTC with the format [year]-[month]-[day]T[hour]:[minute]:[second].mmmZ Eg: 2023-02-15T13:33:18.898Z
    pub fn date_as_yyyymmddthhmmssmmmz() -> Result<String, time::error::Format> {
        const ISO_CONFIG: EncodedConfig = Config::DEFAULT
            .set_time_precision(TimePrecision::Second {
                decimal_digits: NonZeroU8::new(3),
            })
            .encode();
        now().assume_utc().format(&Iso8601::<ISO_CONFIG>)
    }

    /// Return the current date and time in UTC formatted as "ddd, DD MMM YYYY HH:mm:ss GMT".
    pub fn now_rfc7231_http_date() -> Result<String, time::error::Format> {
        let now_utc = OffsetDateTime::now_utc();
        // Desired format: ddd, DD MMM YYYY HH:mm:ss GMT
        // Example: Fri, 23 May 2025 06:19:35 GMT
        let format = time::macros::format_description!(
            "[weekday repr:short], [day padding:zero] [month repr:short] [year repr:full] [hour padding:zero repr:24]:[minute padding:zero]:[second padding:zero] GMT"
        );
        now_utc.format(&format)
    }

    impl From<DateFormat> for &[BorrowedFormatItem<'_>] {
        fn from(format: DateFormat) -> Self {
            match format {
                DateFormat::YYYYMMDDHHmmss => time::macros::format_description!("[year repr:full][month padding:zero repr:numerical][day padding:zero][hour padding:zero repr:24][minute padding:zero][second padding:zero]"),
                DateFormat::YYYYMMDD => time::macros::format_description!("[year repr:full][month padding:zero repr:numerical][day padding:zero]"),
                DateFormat::YYYYMMDDHHmm => time::macros::format_description!("[year repr:full][month padding:zero repr:numerical][day padding:zero][hour padding:zero repr:24][minute padding:zero]"),
                DateFormat::DDMMYYYYHHmmss => time::macros::format_description!("[day padding:zero][month padding:zero repr:numerical][year repr:full][hour padding:zero repr:24][minute padding:zero][second padding:zero]"),
            }
        }
    }

    /// Format the date in 05112019 format
    #[derive(Debug, Clone)]
    pub struct DDMMYYYY;
    /// Format the date in 20191105 format
    #[derive(Debug, Clone)]
    pub struct YYYYMMDD;
    /// Format the date in 20191105081132 format
    #[derive(Debug, Clone)]
    pub struct YYYYMMDDHHmmss;

    /// To serialize the date in Dateformats like YYYYMMDDHHmmss, YYYYMMDD, DDMMYYYY
    #[derive(Debug, Deserialize, Clone)]
    pub struct DateTime<T: TimeStrategy> {
        inner: PhantomData<T>,
        value: PrimitiveDateTime,
    }

    impl<T: TimeStrategy> From<PrimitiveDateTime> for DateTime<T> {
        fn from(value: PrimitiveDateTime) -> Self {
            Self {
                inner: PhantomData,
                value,
            }
        }
    }

    /// Time strategy for the Date, Eg: YYYYMMDDHHmmss, YYYYMMDD, DDMMYYYY
    pub trait TimeStrategy {
        /// Stringify the date as per the Time strategy
        fn fmt(input: &PrimitiveDateTime, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
    }

    impl<T: TimeStrategy> Serialize for DateTime<T> {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            serializer.collect_str(self)
        }
    }

    impl<T: TimeStrategy> std::fmt::Display for DateTime<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            T::fmt(&self.value, f)
        }
    }

    impl TimeStrategy for DDMMYYYY {
        fn fmt(input: &PrimitiveDateTime, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            let year = input.year();
            #[allow(clippy::as_conversions)]
            let month = input.month() as u8;
            let day = input.day();
            let output = format!("{day:02}{month:02}{year}");
            f.write_str(&output)
        }
    }

    impl TimeStrategy for YYYYMMDD {
        fn fmt(input: &PrimitiveDateTime, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            let year = input.year();
            #[allow(clippy::as_conversions)]
            let month: u8 = input.month() as u8;
            let day = input.day();
            let output = format!("{year}{month:02}{day:02}");
            f.write_str(&output)
        }
    }

    impl TimeStrategy for YYYYMMDDHHmmss {
        fn fmt(input: &PrimitiveDateTime, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            let year = input.year();
            #[allow(clippy::as_conversions)]
            let month = input.month() as u8;
            let day = input.day();
            let hour = input.hour();
            let minute = input.minute();
            let second = input.second();
            let output = format!("{year}{month:02}{day:02}{hour:02}{minute:02}{second:02}");
            f.write_str(&output)
        }
    }
}

/// Generate a nanoid with the given prefix and length
#[inline]
pub fn generate_id(length: usize, prefix: &str) -> String {
    format!("{}_{}", prefix, nanoid::nanoid!(length, &consts::ALPHABETS))
}

/// Generate a ReferenceId with the default length with the given prefix
fn generate_ref_id_with_default_length<const MAX_LENGTH: u8, const MIN_LENGTH: u8>(
    prefix: &str,
) -> id_type::LengthId<MAX_LENGTH, MIN_LENGTH> {
    id_type::LengthId::<MAX_LENGTH, MIN_LENGTH>::new(prefix)
}

/// Generate a customer id with default length, with prefix as `cus`
pub fn generate_customer_id_of_default_length() -> id_type::CustomerId {
    use id_type::GenerateId;

    id_type::CustomerId::generate()
}

/// Generate a organization id with default length, with prefix as `org`
pub fn generate_organization_id_of_default_length() -> id_type::OrganizationId {
    use id_type::GenerateId;

    id_type::OrganizationId::generate()
}

/// Generate a profile id with default length, with prefix as `pro`
pub fn generate_profile_id_of_default_length() -> id_type::ProfileId {
    use id_type::GenerateId;

    id_type::ProfileId::generate()
}

/// Generate a routing id with default length, with prefix as `routing`
pub fn generate_routing_id_of_default_length() -> id_type::RoutingId {
    use id_type::GenerateId;

    id_type::RoutingId::generate()
}
/// Generate a merchant_connector_account id with default length, with prefix as `mca`
pub fn generate_merchant_connector_account_id_of_default_length(
) -> id_type::MerchantConnectorAccountId {
    use id_type::GenerateId;

    id_type::MerchantConnectorAccountId::generate()
}

/// Generate a profile_acquirer id with default length, with prefix as `mer_acq`
pub fn generate_profile_acquirer_id_of_default_length() -> id_type::ProfileAcquirerId {
    use id_type::GenerateId;

    id_type::ProfileAcquirerId::generate()
}

/// Generate a nanoid with the given prefix and a default length
#[inline]
pub fn generate_id_with_default_len(prefix: &str) -> String {
    let len: usize = consts::ID_LENGTH;
    format!("{}_{}", prefix, nanoid::nanoid!(len, &consts::ALPHABETS))
}

/// Generate a time-ordered (time-sortable) unique identifier using the current time
#[inline]
pub fn generate_time_ordered_id(prefix: &str) -> String {
    format!("{prefix}_{}", uuid::Uuid::now_v7().as_simple())
}

/// Generate a time-ordered (time-sortable) unique identifier using the current time without prefix
#[inline]
pub fn generate_time_ordered_id_without_prefix() -> String {
    uuid::Uuid::now_v7().as_simple().to_string()
}

/// Generate a nanoid with the specified length
#[inline]
pub fn generate_id_with_len(length: usize) -> String {
    nanoid::nanoid!(length, &consts::ALPHABETS)
}
#[allow(missing_docs)]
pub trait DbConnectionParams {
    fn get_username(&self) -> &str;
    fn get_password(&self) -> Secret<String>;
    fn get_host(&self) -> &str;
    fn get_port(&self) -> u16;
    fn get_dbname(&self) -> &str;
    fn get_database_url(&self, schema: &str) -> String {
        format!(
            "postgres://{}:{}@{}:{}/{}?application_name={}&options=-c search_path%3D{}",
            self.get_username(),
            self.get_password().peek(),
            self.get_host(),
            self.get_port(),
            self.get_dbname(),
            schema,
            schema,
        )
    }
}

// Can't add doc comments for macro invocations, neither does the macro allow it.
#[allow(missing_docs)]
mod base64_serializer {
    use base64_serde::base64_serde_type;

    base64_serde_type!(pub Base64Serializer, crate::consts::BASE64_ENGINE);
}

#[cfg(test)]
mod nanoid_tests {
    #![allow(clippy::unwrap_used)]
    use super::*;
    use crate::{
        consts::{
            MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH,
        },
        id_type::AlphaNumericId,
    };

    #[test]
    fn test_generate_id_with_alphanumeric_id() {
        let alphanumeric_id = AlphaNumericId::from(generate_id(10, "def").into());
        assert!(alphanumeric_id.is_ok())
    }

    #[test]
    fn test_generate_merchant_ref_id_with_default_length() {
        let ref_id = id_type::LengthId::<
            MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH,
            MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH,
        >::from(generate_id_with_default_len("def").into());

        assert!(ref_id.is_ok())
    }
}

/// Module for tokenization-related functionality
///
/// This module provides types and functions for handling tokenized payment data,
/// including response structures and token generation utilities.
#[cfg(all(feature = "v2", feature = "tokenization_v2"))]
pub mod tokenization;


// Function: get_flow
// File: crates/router/src/services/email/types.rs
// Module: router

pub fn get_flow(&self) -> domain::Origin


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

impl Responder


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

impl auth_service::AuthServiceExchangeToken for for Plaid


// Struct: AciCancelRequest
// File: crates/hyperswitch_connectors/src/connectors/aci/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct AciCancelRequest


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

impl ConnectorValidation for for Adyen


// Implementation: impl api::Refund for for Billwerk
// File: crates/hyperswitch_connectors/src/connectors/billwerk.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Refund for for Billwerk


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

impl api::PaymentCapture for for Tokenex


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

pub struct RazorpaySyncResponse


// Function: get_type
// File: crates/euclid/src/frontend/ast.rs
// Module: euclid

pub fn get_type(&self) -> DataType


// Function: supports_instant_payout
// File: crates/common_enums/src/connector_enums.rs
// Module: common_enums

pub fn supports_instant_payout(self, payout_method: Option<PayoutType>) -> bool


// Function: server
// File: crates/router/src/routes/app.rs
// Module: router

pub fn server(state: AppState) -> Scope


// Struct: HealthCheckClient
// File: crates/external_services/src/grpc_client/health_check_client.rs
// Module: external_services
// Implementations: 1

pub struct HealthCheckClient


// Implementation: impl IncomingWebhook for for Datatrans
// File: crates/hyperswitch_connectors/src/connectors/datatrans.rs
// Module: hyperswitch_connectors
// Methods: 3 total (0 public)

impl IncomingWebhook for for Datatrans


// Implementation: impl super::payments::metrics::PaymentMetricAnalytics for for ClickhouseClient
// File: crates/analytics/src/clickhouse.rs
// Module: analytics
// Methods: 0 total (0 public)

impl super::payments::metrics::PaymentMetricAnalytics for for ClickhouseClient


// Implementation: impl api::ConnectorAccessToken for for Thunes
// File: crates/hyperswitch_connectors/src/connectors/thunes.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::ConnectorAccessToken for for Thunes


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

pub struct NexixpayNonMandatePaymentRequest


// Function: get_id
// File: crates/router/src/services/kafka/payment_intent_event.rs
// Module: router

pub fn get_id(&self) -> &id_type::PaymentId


// Function: get_default_routing_configs_from_profile
// File: crates/router/src/core/admin.rs
// Module: router

pub fn get_default_routing_configs_from_profile(
        &self,
    ) -> RouterResult<routing_types::ProfileDefaultRoutingConfig>


// Struct: UpdateMetadata
// File: crates/hyperswitch_domain_models/src/router_flow_types/payments.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct UpdateMetadata


// Function: is_true
// File: crates/common_types/src/primitive_wrappers.rs
// Module: common_types

// Documentation: returns the inner bool value

pub fn is_true(&self) -> bool


// File: crates/router/tests/customers.rs
// Module: router

#![allow(clippy::unwrap_used, clippy::print_stdout)]

mod utils;

// setting the connector in environment variables doesn't work when run in parallel. Neither does passing the paymentid
// do we'll test refund and payment in same tests and later implement thread_local variables.
// When test-connector feature is enabled, you can pass the connector name in description

#[actix_web::test]
#[ignore]
// verify the API-KEY/merchant id has stripe as first choice
async fn customer_success() {
    Box::pin(utils::setup()).await;

    let customer_id = format!("customer_{}", uuid::Uuid::new_v4());
    let api_key = ("API-KEY", "MySecretApiKey");
    let name = "Doe";
    let new_name = "new Doe";

    let request = serde_json::json!({
        "customer_id" : customer_id,
        "name" : name,
    });

    let update_request = serde_json::json!({
        "name" : new_name,
    });

    let client = awc::Client::default();
    let mut response;
    let mut response_body;

    // create customer
    response = client
        .post("http://127.0.0.1:8080/customers")
        .insert_header(api_key)
        .send_json(&request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("customer-create: {response:?} : {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::OK);

    // retrieve customer
    response = client
        .get(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send()
        .await
        .unwrap();
    response_body = response.body().await;
    println!("customer-retrieve: {response:?} =:= {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::OK);

    // update customer
    response = client
        .post(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send_json(&update_request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("customer-update: {response:?} =:= {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::OK);

    // delete customer
    response = client
        .delete(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send()
        .await
        .unwrap();
    response_body = response.body().await;
    println!("customer-delete : {response:?} =:= {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::OK);
}

#[actix_web::test]
#[ignore]
// verify the API-KEY/merchant id has stripe as first choice
async fn customer_failure() {
    Box::pin(utils::setup()).await;

    let customer_id = format!("customer_{}", uuid::Uuid::new_v4());
    let api_key = ("api-key", "MySecretApiKey");

    let mut request = serde_json::json!({
        "email" : "abcd",
    });

    let client = awc::Client::default();
    let mut response;
    let mut response_body;

    // insert the customer with invalid email when id not found
    response = client
        .post("http://127.0.0.1:8080/customers")
        .insert_header(api_key)
        .send_json(&request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(
        response.status(),
        awc::http::StatusCode::UNPROCESSABLE_ENTITY
    );

    // retrieve a customer with customer id which is not in DB
    response = client
        .post(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send()
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::BAD_REQUEST);

    // update customer id with customer id which is not in DB
    response = client
        .post(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send_json(&request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(
        response.status(),
        awc::http::StatusCode::UNPROCESSABLE_ENTITY
    );

    // delete a customer with customer id which is not in DB
    response = client
        .delete(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send()
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::BAD_REQUEST);

    // email validation for customer update
    request = serde_json::json!({ "customer_id": customer_id });

    response = client
        .post("http://127.0.0.1:8080/customers")
        .insert_header(api_key)
        .send_json(&request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(response.status(), awc::http::StatusCode::OK);

    request = serde_json::json!({
        "email": "abch"
    });
    response = client
        .post(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send_json(&request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(
        response.status(),
        awc::http::StatusCode::UNPROCESSABLE_ENTITY
    );

    // address validation
    request = serde_json::json!({
        "email": "abch"
    });
    response = client
        .post(format!("http://127.0.0.1:8080/customers/{customer_id}"))
        .insert_header(api_key)
        .send_json(&request)
        .await
        .unwrap();
    response_body = response.body().await;
    println!("{response:?} : {response_body:?}");
    assert_eq!(
        response.status(),
        awc::http::StatusCode::UNPROCESSABLE_ENTITY
    );
}


// Struct: BankDetails
// File: crates/hyperswitch_connectors/src/connectors/aci/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct BankDetails


// File: crates/openapi/src/routes/gsm.rs
// Module: openapi
// Public functions: 4

/// Gsm - Create
///
/// Creates a GSM (Global Status Mapping) Rule. A GSM rule is used to map a connector's error message/error code combination during a particular payments flow/sub-flow to Hyperswitch's unified status/error code/error message combination. It is also used to decide the next action in the flow - retry/requeue/do_default
#[utoipa::path(
    post,
    path = "/gsm",
    request_body(
        content = GsmCreateRequest,
    ),
    responses(
        (status = 200, description = "Gsm created", body = GsmResponse),
        (status = 400, description = "Missing Mandatory fields")
    ),
    tag = "Gsm",
    operation_id = "Create Gsm Rule",
    security(("admin_api_key" = [])),
)]
pub async fn create_gsm_rule() {}

/// Gsm - Get
///
/// Retrieves a Gsm Rule
#[utoipa::path(
    post,
    path = "/gsm/get",
    request_body(
        content = GsmRetrieveRequest,
    ),
    responses(
        (status = 200, description = "Gsm retrieved", body = GsmResponse),
        (status = 400, description = "Missing Mandatory fields")
    ),
    tag = "Gsm",
    operation_id = "Retrieve Gsm Rule",
    security(("admin_api_key" = [])),
)]
pub async fn get_gsm_rule() {}

/// Gsm - Update
///
/// Updates a Gsm Rule
#[utoipa::path(
    post,
    path = "/gsm/update",
    request_body(
        content = GsmUpdateRequest,
    ),
    responses(
        (status = 200, description = "Gsm updated", body = GsmResponse),
        (status = 400, description = "Missing Mandatory fields")
    ),
    tag = "Gsm",
    operation_id = "Update Gsm Rule",
    security(("admin_api_key" = [])),
)]
pub async fn update_gsm_rule() {}

/// Gsm - Delete
///
/// Deletes a Gsm Rule
#[utoipa::path(
    post,
    path = "/gsm/delete",
    request_body(
        content = GsmDeleteRequest,
    ),
    responses(
        (status = 200, description = "Gsm deleted", body = GsmDeleteResponse),
        (status = 400, description = "Missing Mandatory fields")
    ),
    tag = "Gsm",
    operation_id = "Delete Gsm Rule",
    security(("admin_api_key" = [])),
)]
pub async fn delete_gsm_rule() {}


// Implementation: impl PayoutsUpdate
// File: crates/diesel_models/src/payouts.rs
// Module: diesel_models
// Methods: 1 total (1 public)

impl PayoutsUpdate


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

impl Responder


// Struct: UnlockStatusResponse
// File: crates/api_models/src/revenue_recovery_data_backfill.rs
// Module: api_models
// Implementations: 1
// Traits: ApiEventMetric

pub struct UnlockStatusResponse


// Function: upsert_decision_manager_config
// File: crates/router/src/routes/routing.rs
// Module: router

pub fn upsert_decision_manager_config(
    state: web::Data<AppState>,
    req: HttpRequest,
    json_payload: web::Json<api_models::conditional_configs::DecisionManagerRequest>,
) -> impl Responder


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

pub fn new() -> &'static Self


// Struct: ProcessDisputeWorkflow
// File: crates/router/src/workflows/process_dispute.rs
// Module: router
// Implementations: 0

pub struct ProcessDisputeWorkflow


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

pub struct CreateRefundRequest


// Struct: PaymentProcessingMetaData
// File: crates/hyperswitch_connectors/src/connectors/amazonpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaymentProcessingMetaData


// Struct: CardToken
// File: crates/hyperswitch_domain_models/src/payment_method_data.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct CardToken


// Function: process_env_mappings
// File: crates/router/src/routes/app.rs
// Module: router

pub fn process_env_mappings(
        mappings: Option<HashMap<String, String>>,
    ) -> Option<serde_json::Value>


// Struct: NuveiTransactionSyncResponseDetails
// File: crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NuveiTransactionSyncResponseDetails


// Struct: Store
// File: crates/storage_impl/src/database/store.rs
// Module: storage_impl
// Implementations: 1
// Traits: DatabaseStore

pub struct Store


// Implementation: impl ConnectorAccessToken for for DummyConnector
// File: crates/hyperswitch_connectors/src/connectors/dummyconnector.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl ConnectorAccessToken for for DummyConnector


// Struct: DefaultSdkType
// File: crates/hyperswitch_connectors/src/connectors/netcetera/netcetera_types.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct DefaultSdkType