        connector_response_reference_id: Option<String>,
        updated_by: String,
    },
    ConnectorResponse {
        connector_payment_id: Option<String>,
        connector: Option<String>,
        updated_by: String,
    },
    // IncrementalAuthorizationAmountUpdate {
    //     amount: MinorUnit,
    //     amount_capturable: MinorUnit,
    // },
    // AuthenticationUpdate {
    //     status: storage_enums::AttemptStatus,
    //     external_three_ds_authentication_attempted: Option<bool>,
    //     authentication_connector: Option<String>,
    //     authentication_id: Option<String>,
    //     updated_by: String,
    // },
    ManualUpdate {
        status: Option<storage_enums::AttemptStatus>,
        error_code: Option<String>,
        error_message: Option<String>,
        error_reason: Option<String>,
        updated_by: String,
        unified_code: Option<String>,
        unified_message: Option<String>,
        connector_payment_id: Option<String>,
    },
}

// TODO: uncomment fields as and when required
#[cfg(feature = "v2")]
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay, Serialize, Deserialize)]
#[diesel(table_name = payment_attempt)]
pub struct PaymentAttemptUpdateInternal {
    pub status: Option<storage_enums::AttemptStatus>,
    pub authentication_type: Option<storage_enums::AuthenticationType>,
    pub error_message: Option<String>,
    pub connector_payment_id: Option<ConnectorTransactionId>,
    pub connector_payment_data: Option<String>,
    pub payment_method_id: Option<id_type::GlobalPaymentMethodId>,
    pub cancellation_reason: Option<String>,
    pub modified_at: PrimitiveDateTime,
    pub browser_info: Option<serde_json::Value>,
    // payment_token: Option<String>,
    pub error_code: Option<String>,
    pub connector_metadata: Option<pii::SecretSerdeValue>,
    // payment_method_data: Option<serde_json::Value>,
    // payment_experience: Option<storage_enums::PaymentExperience>,
    // preprocessing_step_id: Option<String>,
    pub error_reason: Option<String>,
    pub connector_response_reference_id: Option<String>,
    // multiple_capture_count: Option<i16>,
    // pub surcharge_amount: Option<MinorUnit>,
    // tax_on_surcharge: Option<MinorUnit>,
    pub amount_capturable: Option<MinorUnit>,
    pub amount_to_capture: Option<MinorUnit>,
    pub updated_by: String,
    pub merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    pub connector: Option<String>,
    pub redirection_data: Option<RedirectForm>,
    // encoded_data: Option<String>,
    pub unified_code: Option<String>,
    pub unified_message: Option<String>,
    // external_three_ds_authentication_attempted: Option<bool>,
    // authentication_connector: Option<String>,
    // authentication_id: Option<String>,
    // fingerprint_id: Option<String>,
    // charge_id: Option<String>,
    // client_source: Option<String>,
    // client_version: Option<String>,
    // customer_acceptance: Option<pii::SecretSerdeValue>,
    // card_network: Option<String>,
    pub connector_token_details: Option<ConnectorTokenDetails>,
    pub feature_metadata: Option<PaymentAttemptFeatureMetadata>,
    pub network_decline_code: Option<String>,
    pub network_advice_code: Option<String>,
    pub network_error_message: Option<String>,
    pub connector_request_reference_id: Option<String>,
}

#[cfg(feature = "v2")]
impl PaymentAttemptUpdateInternal {
    pub fn apply_changeset(self, source: PaymentAttempt) -> PaymentAttempt {
        let Self {
            status,
            authentication_type,
            error_message,
            connector_payment_id,
            connector_payment_data,
            modified_at,
            browser_info,
            error_code,
            cancellation_reason,
            connector_metadata,
            error_reason,
            amount_capturable,
            amount_to_capture,
            updated_by,
            merchant_connector_id,
            connector,
            redirection_data,
            unified_code,
            unified_message,
            connector_token_details,
            feature_metadata,
            network_decline_code,
            network_advice_code,
            network_error_message,
            payment_method_id,
            connector_request_reference_id,
            connector_response_reference_id,
        } = self;

        PaymentAttempt {
            payment_id: source.payment_id,
            merchant_id: source.merchant_id,
            status: status.unwrap_or(source.status),
            connector: connector.or(source.connector),
            error_message: error_message.or(source.error_message),
            surcharge_amount: source.surcharge_amount,
            payment_method_id: payment_method_id.or(source.payment_method_id),
            authentication_type: authentication_type.unwrap_or(source.authentication_type),
            created_at: source.created_at,
            modified_at: common_utils::date_time::now(),
            last_synced: source.last_synced,
            cancellation_reason: source.cancellation_reason,
            amount_to_capture: amount_to_capture.or(source.amount_to_capture),
            browser_info: browser_info
                .and_then(|val| {
                    serde_json::from_value::<common_utils::types::BrowserInformation>(val).ok()
                })
                .or(source.browser_info),
            error_code: error_code.or(source.error_code),
            payment_token: source.payment_token,
            connector_metadata: connector_metadata.or(source.connector_metadata),
            payment_experience: source.payment_experience,
            payment_method_data: source.payment_method_data,
            preprocessing_step_id: source.preprocessing_step_id,
            error_reason: error_reason.or(source.error_reason),
            multiple_capture_count: source.multiple_capture_count,
            connector_response_reference_id: connector_response_reference_id
                .or(source.connector_response_reference_id),
            amount_capturable: amount_capturable.unwrap_or(source.amount_capturable),
            updated_by,
            merchant_connector_id: merchant_connector_id.or(source.merchant_connector_id),
            encoded_data: source.encoded_data,
            unified_code: unified_code.or(source.unified_code),
            unified_message: unified_message.or(source.unified_message),
            net_amount: source.net_amount,
            external_three_ds_authentication_attempted: source
                .external_three_ds_authentication_attempted,
            authentication_connector: source.authentication_connector,
            authentication_id: source.authentication_id,
            fingerprint_id: source.fingerprint_id,
            client_source: source.client_source,
            client_version: source.client_version,
            customer_acceptance: source.customer_acceptance,
            profile_id: source.profile_id,
            organization_id: source.organization_id,
            card_network: source.card_network,
            shipping_cost: source.shipping_cost,
            order_tax_amount: source.order_tax_amount,
            request_extended_authorization: source.request_extended_authorization,
            extended_authorization_applied: source.extended_authorization_applied,
            capture_before: source.capture_before,
            card_discovery: source.card_discovery,
            charges: source.charges,
            processor_merchant_id: source.processor_merchant_id,
            created_by: source.created_by,
            payment_method_type_v2: source.payment_method_type_v2,
            network_transaction_id: source.network_transaction_id,
            connector_payment_id: connector_payment_id.or(source.connector_payment_id),
            payment_method_subtype: source.payment_method_subtype,
            routing_result: source.routing_result,
            authentication_applied: source.authentication_applied,
            external_reference_id: source.external_reference_id,
            tax_on_surcharge: source.tax_on_surcharge,
            payment_method_billing_address: source.payment_method_billing_address,
            redirection_data: redirection_data.or(source.redirection_data),
            connector_payment_data: connector_payment_data.or(source.connector_payment_data),
            connector_token_details: connector_token_details.or(source.connector_token_details),
            id: source.id,
            feature_metadata: feature_metadata.or(source.feature_metadata),
            network_advice_code: network_advice_code.or(source.network_advice_code),
            network_decline_code: network_decline_code.or(source.network_decline_code),
            network_error_message: network_error_message.or(source.network_error_message),
            connector_request_reference_id: connector_request_reference_id
                .or(source.connector_request_reference_id),
            is_overcapture_enabled: source.is_overcapture_enabled,
            network_details: source.network_details,
            attempts_group_id: source.attempts_group_id,
            is_stored_credential: source.is_stored_credential,
        }
    }
}
#[cfg(feature = "v1")]
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
#[diesel(table_name = payment_attempt)]
pub struct PaymentAttemptUpdateInternal {
    pub amount: Option<MinorUnit>,
    pub net_amount: Option<MinorUnit>,
    pub currency: Option<storage_enums::Currency>,
    pub status: Option<storage_enums::AttemptStatus>,
    pub connector_transaction_id: Option<ConnectorTransactionId>,
    pub amount_to_capture: Option<MinorUnit>,
    pub connector: Option<Option<String>>,
    pub authentication_type: Option<storage_enums::AuthenticationType>,
    pub payment_method: Option<storage_enums::PaymentMethod>,
    pub error_message: Option<Option<String>>,
    pub payment_method_id: Option<String>,
    pub cancellation_reason: Option<String>,
    pub modified_at: PrimitiveDateTime,
    pub mandate_id: Option<String>,
    pub browser_info: Option<serde_json::Value>,
    pub payment_token: Option<String>,
    pub error_code: Option<Option<String>>,
    pub connector_metadata: Option<serde_json::Value>,
    pub payment_method_data: Option<serde_json::Value>,
    pub payment_method_type: Option<storage_enums::PaymentMethodType>,
    pub payment_experience: Option<storage_enums::PaymentExperience>,
    pub business_sub_label: Option<String>,
    pub straight_through_algorithm: Option<serde_json::Value>,
    pub preprocessing_step_id: Option<String>,
    pub error_reason: Option<Option<String>>,
    pub capture_method: Option<storage_enums::CaptureMethod>,
    pub connector_response_reference_id: Option<String>,
    pub multiple_capture_count: Option<i16>,
    pub surcharge_amount: Option<MinorUnit>,
    pub tax_amount: Option<MinorUnit>,
    pub amount_capturable: Option<MinorUnit>,
    pub updated_by: String,
    pub merchant_connector_id: Option<Option<id_type::MerchantConnectorAccountId>>,
    pub authentication_data: Option<serde_json::Value>,
    pub encoded_data: Option<String>,
    pub unified_code: Option<Option<String>>,
    pub unified_message: Option<Option<String>>,
    pub external_three_ds_authentication_attempted: Option<bool>,
    pub authentication_connector: Option<String>,
    pub authentication_id: Option<id_type::AuthenticationId>,
    pub fingerprint_id: Option<String>,
    pub payment_method_billing_address_id: Option<String>,
    pub client_source: Option<String>,
    pub client_version: Option<String>,
    pub customer_acceptance: Option<pii::SecretSerdeValue>,
    pub card_network: Option<String>,
    pub capture_before: Option<PrimitiveDateTime>,
    pub extended_authorization_applied: Option<ExtendedAuthorizationAppliedBool>,
    pub shipping_cost: Option<MinorUnit>,
    pub order_tax_amount: Option<MinorUnit>,
    pub connector_mandate_detail: Option<ConnectorMandateReferenceId>,
    pub processor_transaction_data: Option<String>,
    pub card_discovery: Option<common_enums::CardDiscovery>,
    pub charges: Option<common_types::payments::ConnectorChargeResponseData>,
    pub issuer_error_code: Option<String>,
    pub issuer_error_message: Option<String>,
    pub setup_future_usage_applied: Option<storage_enums::FutureUsage>,
    pub routing_approach: Option<storage_enums::RoutingApproach>,
    pub connector_request_reference_id: Option<String>,
    pub network_transaction_id: Option<String>,
    pub is_overcapture_enabled: Option<OvercaptureEnabledBool>,
    pub network_details: Option<NetworkDetails>,
    pub is_stored_credential: Option<bool>,
    pub request_extended_authorization: Option<RequestExtendedAuthorizationBool>,
}

#[cfg(feature = "v1")]
impl PaymentAttemptUpdateInternal {
    pub fn populate_derived_fields(self, source: &PaymentAttempt) -> Self {
        let mut update_internal = self;
        update_internal.net_amount = Some(
            update_internal.amount.unwrap_or(source.amount)
                + update_internal
                    .surcharge_amount
                    .or(source.surcharge_amount)
                    .unwrap_or(MinorUnit::new(0))
                + update_internal
                    .tax_amount
                    .or(source.tax_amount)
                    .unwrap_or(MinorUnit::new(0))
                + update_internal
                    .shipping_cost
                    .or(source.shipping_cost)
                    .unwrap_or(MinorUnit::new(0))
                + update_internal
                    .order_tax_amount
                    .or(source.order_tax_amount)
                    .unwrap_or(MinorUnit::new(0)),
        );
        update_internal.card_network = update_internal
            .payment_method_data
            .as_ref()
            .and_then(|data| data.as_object())
            .and_then(|card| card.get("card"))
            .and_then(|data| data.as_object())
            .and_then(|card| card.get("card_network"))
            .and_then(|network| network.as_str())
            .map(|network| network.to_string());
        update_internal
    }
}

#[cfg(feature = "v2")]
impl PaymentAttemptUpdate {
    pub fn apply_changeset(self, _source: PaymentAttempt) -> PaymentAttempt {
        todo!()
        // let PaymentAttemptUpdateInternal {
        //     net_amount,
        //     status,
        //     authentication_type,
        //     error_message,
        //     payment_method_id,
        //     cancellation_reason,
        //     modified_at: _,
        //     browser_info,
        //     payment_token,
        //     error_code,
        //     connector_metadata,
        //     payment_method_data,
        //     payment_experience,
        //     straight_through_algorithm,
        //     preprocessing_step_id,
        //     error_reason,
        //     connector_response_reference_id,
        //     multiple_capture_count,
        //     surcharge_amount,
        //     tax_amount,
        //     amount_capturable,
        //     updated_by,
        //     merchant_connector_id,
        //     authentication_data,
        //     encoded_data,
        //     unified_code,
        //     unified_message,
        //     external_three_ds_authentication_attempted,
        //     authentication_connector,
        //     authentication_id,
        //     payment_method_billing_address_id,
        //     fingerprint_id,
        //     charge_id,
        //     client_source,
        //     client_version,
        //     customer_acceptance,
        //     card_network,
        // } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source);
        // PaymentAttempt {
        //     net_amount: net_amount.or(source.net_amount),
        //     status: status.unwrap_or(source.status),
        //     authentication_type: authentication_type.or(source.authentication_type),
        //     error_message: error_message.unwrap_or(source.error_message),
        //     payment_method_id: payment_method_id.or(source.payment_method_id),
        //     cancellation_reason: cancellation_reason.or(source.cancellation_reason),
        //     modified_at: common_utils::date_time::now(),
        //     browser_info: browser_info.or(source.browser_info),
        //     payment_token: payment_token.or(source.payment_token),
        //     error_code: error_code.unwrap_or(source.error_code),
        //     connector_metadata: connector_metadata.or(source.connector_metadata),
        //     payment_method_data: payment_method_data.or(source.payment_method_data),
        //     payment_experience: payment_experience.or(source.payment_experience),
        //     straight_through_algorithm: straight_through_algorithm
        //         .or(source.straight_through_algorithm),
        //     preprocessing_step_id: preprocessing_step_id.or(source.preprocessing_step_id),
        //     error_reason: error_reason.unwrap_or(source.error_reason),
        //     connector_response_reference_id: connector_response_reference_id
        //         .or(source.connector_response_reference_id),
        //     multiple_capture_count: multiple_capture_count.or(source.multiple_capture_count),
        //     surcharge_amount: surcharge_amount.or(source.surcharge_amount),
        //     tax_amount: tax_amount.or(source.tax_amount),
        //     amount_capturable: amount_capturable.unwrap_or(source.amount_capturable),
        //     updated_by,
        //     merchant_connector_id: merchant_connector_id.unwrap_or(source.merchant_connector_id),
        //     authentication_data: authentication_data.or(source.authentication_data),
        //     encoded_data: encoded_data.or(source.encoded_data),
        //     unified_code: unified_code.unwrap_or(source.unified_code),
        //     unified_message: unified_message.unwrap_or(source.unified_message),
        //     external_three_ds_authentication_attempted: external_three_ds_authentication_attempted
        //         .or(source.external_three_ds_authentication_attempted),
        //     authentication_connector: authentication_connector.or(source.authentication_connector),
        //     authentication_id: authentication_id.or(source.authentication_id),
        //     payment_method_billing_address_id: payment_method_billing_address_id
        //         .or(source.payment_method_billing_address_id),
        //     fingerprint_id: fingerprint_id.or(source.fingerprint_id),
        //     charge_id: charge_id.or(source.charge_id),
        //     client_source: client_source.or(source.client_source),
        //     client_version: client_version.or(source.client_version),
        //     customer_acceptance: customer_acceptance.or(source.customer_acceptance),
        //     card_network: card_network.or(source.card_network),
        //     ..source
        // }
    }
}

#[cfg(feature = "v1")]
impl PaymentAttemptUpdate {
    pub fn apply_changeset(self, source: PaymentAttempt) -> PaymentAttempt {
        let PaymentAttemptUpdateInternal {
            amount,
            net_amount,
            currency,
            status,
            connector_transaction_id,
            amount_to_capture,
            connector,
            authentication_type,
            payment_method,
            error_message,
            payment_method_id,
            cancellation_reason,
            modified_at: _,
            mandate_id,
            browser_info,
            payment_token,
            error_code,
            connector_metadata,
            payment_method_data,
            payment_method_type,
            payment_experience,
            business_sub_label,
            straight_through_algorithm,
            preprocessing_step_id,
            error_reason,
            capture_method,
            connector_response_reference_id,
            multiple_capture_count,
            surcharge_amount,
            tax_amount,
            amount_capturable,
            updated_by,
            merchant_connector_id,
            authentication_data,
            encoded_data,
            unified_code,
            unified_message,
            external_three_ds_authentication_attempted,
            authentication_connector,
            authentication_id,
            payment_method_billing_address_id,
            fingerprint_id,
            client_source,
            client_version,
            customer_acceptance,
            card_network,
            shipping_cost,
            order_tax_amount,
            processor_transaction_data,
            connector_mandate_detail,
            capture_before,
            extended_authorization_applied,
            card_discovery,
            charges,
            issuer_error_code,
            issuer_error_message,
            setup_future_usage_applied,
            routing_approach,
            connector_request_reference_id,
            network_transaction_id,
            is_overcapture_enabled,
            network_details,
            is_stored_credential,
            request_extended_authorization,
        } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source);
        PaymentAttempt {
            amount: amount.unwrap_or(source.amount),
            net_amount: net_amount.or(source.net_amount),
            currency: currency.or(source.currency),
            status: status.unwrap_or(source.status),
            connector_transaction_id: connector_transaction_id.or(source.connector_transaction_id),
            amount_to_capture: amount_to_capture.or(source.amount_to_capture),
            connector: connector.unwrap_or(source.connector),
            authentication_type: authentication_type.or(source.authentication_type),
            payment_method: payment_method.or(source.payment_method),
            error_message: error_message.unwrap_or(source.error_message),
            payment_method_id: payment_method_id.or(source.payment_method_id),
            cancellation_reason: cancellation_reason.or(source.cancellation_reason),
            modified_at: common_utils::date_time::now(),
            mandate_id: mandate_id.or(source.mandate_id),
            browser_info: browser_info.or(source.browser_info),
            payment_token: payment_token.or(source.payment_token),
            error_code: error_code.unwrap_or(source.error_code),
            connector_metadata: connector_metadata.or(source.connector_metadata),
            payment_method_data: payment_method_data.or(source.payment_method_data),
            payment_method_type: payment_method_type.or(source.payment_method_type),
            payment_experience: payment_experience.or(source.payment_experience),
            business_sub_label: business_sub_label.or(source.business_sub_label),
            straight_through_algorithm: straight_through_algorithm
                .or(source.straight_through_algorithm),
            preprocessing_step_id: preprocessing_step_id.or(source.preprocessing_step_id),
            error_reason: error_reason.unwrap_or(source.error_reason),
            capture_method: capture_method.or(source.capture_method),
            connector_response_reference_id: connector_response_reference_id
                .or(source.connector_response_reference_id),
            multiple_capture_count: multiple_capture_count.or(source.multiple_capture_count),
            surcharge_amount: surcharge_amount.or(source.surcharge_amount),
            tax_amount: tax_amount.or(source.tax_amount),
            amount_capturable: amount_capturable.unwrap_or(source.amount_capturable),
            updated_by,
            merchant_connector_id: merchant_connector_id.unwrap_or(source.merchant_connector_id),
            authentication_data: authentication_data.or(source.authentication_data),
            encoded_data: encoded_data.or(source.encoded_data),
            unified_code: unified_code.unwrap_or(source.unified_code),
            unified_message: unified_message.unwrap_or(source.unified_message),
            external_three_ds_authentication_attempted: external_three_ds_authentication_attempted
                .or(source.external_three_ds_authentication_attempted),
            authentication_connector: authentication_connector.or(source.authentication_connector),
            authentication_id: authentication_id.or(source.authentication_id),
            payment_method_billing_address_id: payment_method_billing_address_id
                .or(source.payment_method_billing_address_id),
            fingerprint_id: fingerprint_id.or(source.fingerprint_id),
            client_source: client_source.or(source.client_source),
            client_version: client_version.or(source.client_version),
            customer_acceptance: customer_acceptance.or(source.customer_acceptance),
            card_network: card_network.or(source.card_network),
            shipping_cost: shipping_cost.or(source.shipping_cost),
            order_tax_amount: order_tax_amount.or(source.order_tax_amount),
            processor_transaction_data: processor_transaction_data
                .or(source.processor_transaction_data),
            connector_mandate_detail: connector_mandate_detail.or(source.connector_mandate_detail),
            capture_before: capture_before.or(source.capture_before),
            extended_authorization_applied: extended_authorization_applied
                .or(source.extended_authorization_applied),
            card_discovery: card_discovery.or(source.card_discovery),
            charges: charges.or(source.charges),
            issuer_error_code: issuer_error_code.or(source.issuer_error_code),
            issuer_error_message: issuer_error_message.or(source.issuer_error_message),
            setup_future_usage_applied: setup_future_usage_applied
                .or(source.setup_future_usage_applied),
            routing_approach: routing_approach.or(source.routing_approach),
            connector_request_reference_id: connector_request_reference_id
                .or(source.connector_request_reference_id),
            network_transaction_id: network_transaction_id.or(source.network_transaction_id),
            is_overcapture_enabled: is_overcapture_enabled.or(source.is_overcapture_enabled),
            network_details: network_details.or(source.network_details),
            is_stored_credential: is_stored_credential.or(source.is_stored_credential),
            request_extended_authorization: request_extended_authorization
                .or(source.request_extended_authorization),
            ..source
        }
    }
}

#[cfg(feature = "v2")]
impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
    fn from(payment_attempt_update: PaymentAttemptUpdate) -> Self {
        match payment_attempt_update {
            PaymentAttemptUpdate::ResponseUpdate {
                status,
                connector,
                connector_payment_id,
                authentication_type,
                payment_method_id,
                connector_metadata,
                payment_token,
                error_code,
                error_message,
                error_reason,
                connector_response_reference_id,
                amount_capturable,
                updated_by,
                unified_code,
                unified_message,
            } => {
                let (connector_payment_id, connector_payment_data) = connector_payment_id
                    .map(ConnectorTransactionId::form_id_and_data)
                    .map(|(txn_id, txn_data)| (Some(txn_id), txn_data))
                    .unwrap_or((None, None));

                Self {
                    status: Some(status),
                    connector,
                    connector_payment_id,
                    connector_payment_data,
                    authentication_type,
                    payment_method_id,
                    connector_metadata,
                    error_code: error_code.flatten(),
                    error_message: error_message.flatten(),
                    error_reason: error_reason.flatten(),
                    connector_response_reference_id,
                    amount_capturable,
                    updated_by,
                    unified_code: unified_code.flatten(),
                    unified_message: unified_message.flatten(),
                    modified_at: common_utils::date_time::now(),
                    browser_info: None,
                    amount_to_capture: None,
                    merchant_connector_id: None,
                    redirection_data: None,
                    connector_token_details: None,
                    feature_metadata: None,
                    network_decline_code: None,
                    network_advice_code: None,
                    network_error_message: None,
                    connector_request_reference_id: None,
                    cancellation_reason: None,
                }
            }
            PaymentAttemptUpdate::ErrorUpdate {
                connector,
                status,
                error_code,
                error_message,
                error_reason,
                amount_capturable,
                updated_by,
                unified_code,
                unified_message,
                connector_payment_id,
                authentication_type,
            } => {
                let (connector_payment_id, connector_payment_data) = connector_payment_id
                    .map(ConnectorTransactionId::form_id_and_data)
                    .map(|(txn_id, txn_data)| (Some(txn_id), txn_data))
                    .unwrap_or((None, None));

                Self {
                    connector,
                    status: Some(status),
                    error_code: error_code.flatten(),
                    error_message: error_message.flatten(),
                    error_reason: error_reason.flatten(),
                    amount_capturable,
                    updated_by,
                    unified_code: unified_code.flatten(),
                    unified_message: unified_message.flatten(),
                    connector_payment_id,
                    connector_payment_data,
                    authentication_type,
                    modified_at: common_utils::date_time::now(),
                    payment_method_id: None,
                    browser_info: None,
                    connector_metadata: None,
                    amount_to_capture: None,
                    merchant_connector_id: None,
                    redirection_data: None,
                    connector_token_details: None,
                    feature_metadata: None,
                    network_decline_code: None,
                    network_advice_code: None,
                    network_error_message: None,
                    connector_request_reference_id: None,
                    connector_response_reference_id: None,
                    cancellation_reason: None,
                }
            }
            PaymentAttemptUpdate::UnresolvedResponseUpdate {
                status,
                connector,
                connector_payment_id,
                payment_method_id,
                error_code,
                error_message,
                error_reason,
                connector_response_reference_id,
                updated_by,
            } => {
                let (connector_payment_id, connector_payment_data) = connector_payment_id
                    .map(ConnectorTransactionId::form_id_and_data)
                    .map(|(txn_id, txn_data)| (Some(txn_id), txn_data))
                    .unwrap_or((None, None));

                Self {
                    status: Some(status),
                    connector,
                    connector_payment_id,
                    connector_payment_data,
                    payment_method_id,
                    error_code: error_code.flatten(),
                    error_message: error_message.flatten(),
                    error_reason: error_reason.flatten(),
                    connector_response_reference_id,
                    updated_by,
                    modified_at: common_utils::date_time::now(),
                    authentication_type: None,
                    browser_info: None,
                    connector_metadata: None,
                    amount_capturable: None,
                    amount_to_capture: None,
                    merchant_connector_id: None,
                    redirection_data: None,
                    unified_code: None,
                    unified_message: None,
                    connector_token_details: None,
                    feature_metadata: None,
                    network_decline_code: None,
                    network_advice_code: None,
                    network_error_message: None,
                    connector_request_reference_id: None,
                    cancellation_reason: None,
                }
            }
            PaymentAttemptUpdate::PreprocessingUpdate {
                status,
                payment_method_id,
                connector_metadata,
                preprocessing_step_id,
                connector_payment_id,
                connector_response_reference_id,
                updated_by,
            } => {
                let (connector_payment_id, connector_payment_data) = connector_payment_id
                    .map(ConnectorTransactionId::form_id_and_data)
                    .map(|(txn_id, txn_data)| (Some(txn_id), txn_data))
                    .unwrap_or((None, None));

                Self {
                    status: Some(status),
                    payment_method_id,
                    connector_metadata,
                    connector_payment_id,
                    connector_payment_data,
                    connector_response_reference_id,
                    updated_by,
                    modified_at: common_utils::date_time::now(),
                    authentication_type: None,
                    error_message: None,
                    browser_info: None,
                    error_code: None,
                    error_reason: None,
                    amount_capturable: None,
                    amount_to_capture: None,
                    merchant_connector_id: None,
                    connector: None,
                    redirection_data: None,
                    unified_code: None,
                    unified_message: None,
                    connector_token_details: None,
                    feature_metadata: None,
                    network_decline_code: None,
                    network_advice_code: None,
                    network_error_message: None,
                    connector_request_reference_id: None,
                    cancellation_reason: None,
                }
            }
            PaymentAttemptUpdate::ConnectorResponse {
                connector_payment_id,
                connector,
                updated_by,
            } => {
                let (connector_payment_id, connector_payment_data) = connector_payment_id
                    .map(ConnectorTransactionId::form_id_and_data)
                    .map(|(txn_id, txn_data)| (Some(txn_id), txn_data))
                    .unwrap_or((None, None));

                Self {
                    connector_payment_id,
                    connector_payment_data,
                    connector,
                    updated_by,
                    modified_at: common_utils::date_time::now(),
                    status: None,
                    authentication_type: None,
                    error_message: None,
                    payment_method_id: None,
                    browser_info: None,
                    error_code: None,
                    connector_metadata: None,
                    error_reason: None,
                    amount_capturable: None,
                    amount_to_capture: None,
                    merchant_connector_id: None,
                    redirection_data: None,
                    unified_code: None,
                    unified_message: None,
                    connector_token_details: None,
                    feature_metadata: None,
                    network_decline_code: None,
                    network_advice_code: None,
                    network_error_message: None,
                    connector_request_reference_id: None,
                    connector_response_reference_id: None,
                    cancellation_reason: None,
                }
            }
            PaymentAttemptUpdate::ManualUpdate {
                status,
                error_code,
                error_message,
                error_reason,
                updated_by,
                unified_code,
                unified_message,
                connector_payment_id,
            } => {
                let (connector_payment_id, connector_payment_data) = connector_payment_id
                    .map(ConnectorTransactionId::form_id_and_data)
                    .map(|(txn_id, txn_data)| (Some(txn_id), txn_data))
                    .unwrap_or((None, None));

                Self {
                    status,
                    error_code,
                    error_message,
                    error_reason,
                    updated_by,
                    unified_code,
                    unified_message,
                    connector_payment_id,
                    connector_payment_data,
                    modified_at: common_utils::date_time::now(),
                    authentication_type: None,
                    payment_method_id: None,
                    browser_info: None,
                    connector_metadata: None,
                    amount_capturable: None,
                    amount_to_capture: None,
                    merchant_connector_id: None,
                    connector: None,
                    redirection_data: None,
                    connector_token_details: None,
                    feature_metadata: None,
                    network_decline_code: None,
                    network_advice_code: None,
                    network_error_message: None,
                    connector_request_reference_id: None,
                    connector_response_reference_id: None,
                    cancellation_reason: None,
                }
            }
        }
        // match payment_attempt_update {
        //     PaymentAttemptUpdate::Update {
        //         amount,
        //         currency,
        //         status,
        //         // connector_transaction_id,
        //         authentication_type,
        //         payment_method,
        //         payment_token,
        //         payment_method_data,
        //         payment_method_type,
        //         payment_experience,
        //         business_sub_label,
        //         amount_to_capture,
        //         capture_method,
        //         surcharge_amount,
        //         tax_amount,
        //         fingerprint_id,
        //         updated_by,
        //         payment_method_billing_address_id,
        //     } => Self {
        //         status: Some(status),
        //         // connector_transaction_id,
        //         authentication_type,
        //         payment_token,
        //         modified_at: common_utils::date_time::now(),
        //         payment_method_data,
        //         payment_experience,
        //         surcharge_amount,
        //         tax_amount,
        //         fingerprint_id,
        //         payment_method_billing_address_id,
        //         updated_by,
        //         net_amount: None,
        //         error_message: None,
        //         payment_method_id: None,
        //         cancellation_reason: None,
        //         browser_info: None,
        //         error_code: None,
        //         connector_metadata: None,
        //         straight_through_algorithm: None,
        //         preprocessing_step_id: None,
        //         error_reason: None,
        //         connector_response_reference_id: None,
        //         multiple_capture_count: None,
        //         amount_capturable: None,
        //         merchant_connector_id: None,
        //         authentication_data: None,
        //         encoded_data: None,
        //         unified_code: None,
        //         unified_message: None,
        //         external_three_ds_authentication_attempted: None,
        //         authentication_connector: None,
        //         authentication_id: None,
        //         charge_id: None,
        //         client_source: None,
        //         client_version: None,
        //         customer_acceptance: None,
        //         card_network: None,
        //     },
        //     PaymentAttemptUpdate::AuthenticationTypeUpdate {
        //         authentication_type,
        //         updated_by,
        //     } => Self {
        //         authentication_type: Some(authentication_type),
        //         modified_at: common_utils::date_time::now(),
        //         updated_by,
        //         net_amount: None,
        //         status: None,
        //         error_message: None,
        //         payment_method_id: None,
        //         cancellation_reason: None,
        //         browser_info: None,
        //         payment_token: None,
        //         error_code: None,
        //         connector_metadata: None,
        //         payment_method_data: None,
        //         payment_experience: None,
        //         straight_through_algorithm: None,
        //         preprocessing_step_id: None,
        //         error_reason: None,
        //         connector_response_reference_id: None,
        //         multiple_capture_count: None,
        //         surcharge_amount: None,
        //         tax_amount: None,
        //         amount_capturable: None,
        //         merchant_connector_id: None,
        //         authentication_data: None,
        //         encoded_data: None,
        //         unified_code: None,
        //         unified_message: None,
        //         external_three_ds_authentication_attempted: None,
        //         authentication_connector: None,
        //         authentication_id: None,
        //         fingerprint_id: None,
        //         payment_method_billing_address_id: None,
        //         charge_id: None,
        //         client_source: None,
        //         client_version: None,
        //         customer_acceptance: None,
        //         card_network: None,
        //     },
        //     PaymentAttemptUpdate::ConfirmUpdate {
        //         amount,
        //         currency,
        //         authentication_type,
        //         capture_method,
        //         status,
        //         payment_method,
        //         browser_info,
        //         connector,
        //         payment_token,
        //         payment_method_data,
        //         payment_method_type,
        //         payment_experience,
        //         business_sub_label,
        //         straight_through_algorithm,
        //         error_code,
        //         error_message,
        //         amount_capturable,
        //         updated_by,
        //         merchant_connector_id,
        //         surcharge_amount,
        //         tax_amount,
        //         external_three_ds_authentication_attempted,
        //         authentication_connector,
        //         authentication_id,
        //         payment_method_billing_address_id,
        //         fingerprint_id,
        //         payment_method_id,
        //         client_source,
        //         client_version,
        //         customer_acceptance,
        //     } => Self {
        //         authentication_type,
        //         status: Some(status),
        //         modified_at: common_utils::date_time::now(),
        //         browser_info,
        //         payment_token,
        //         payment_method_data,
        //         payment_experience,
        //         straight_through_algorithm,
        //         error_code,
        //         error_message,
        //         amount_capturable,
        //         updated_by,
        //         merchant_connector_id: merchant_connector_id.map(Some),
        //         surcharge_amount,
        //         tax_amount,
        //         external_three_ds_authentication_attempted,
        //         authentication_connector,
        //         authentication_id,
        //         payment_method_billing_address_id,
        //         fingerprint_id,
        //         payment_method_id,
        //         client_source,
        //         client_version,
        //         customer_acceptance,
        //         net_amount: None,
        //         cancellation_reason: None,
        //         connector_metadata: None,
        //         preprocessing_step_id: None,
        //         error_reason: None,
        //         connector_response_reference_id: None,
        //         multiple_capture_count: None,
        //         authentication_data: None,
        //         encoded_data: None,
        //         unified_code: None,
        //         unified_message: None,
        //         charge_id: None,
        //         card_network: None,
        //     },
        //     PaymentAttemptUpdate::VoidUpdate {
        //         status,
        //         cancellation_reason,
        //         updated_by,
        //     } => Self {
        //         status: Some(status),
        //         cancellation_reason,
        //         modified_at: common_utils::date_time::now(),
        //         updated_by,
        //         net_amount: None,
        //         authentication_type: None,
        //         error_message: None,
        //         payment_method_id: None,
        //         browser_info: None,
        //         payment_token: None,
        //         error_code: None,
        //         connector_metadata: None,
        //         payment_method_data: None,
        //         payment_experience: None,
        //         straight_through_algorithm: None,
        //         preprocessing_step_id: None,
        //         error_reason: None,
        //         connector_response_reference_id: None,
        //         multiple_capture_count: None,
        //         surcharge_amount: None,
        //         tax_amount: None,
        //         amount_capturable: None,
        //         merchant_connector_id: None,


// File: crates/router/src/core/recon.rs
// Module: router
// Public functions: 4

use api_models::recon as recon_api;
#[cfg(feature = "email")]
use common_utils::{ext_traits::AsyncExt, types::user::ThemeLineage};
use error_stack::ResultExt;
#[cfg(feature = "email")]
use masking::{ExposeInterface, PeekInterface, Secret};

#[cfg(feature = "email")]
use crate::{
    consts, services::email::types as email_types, types::domain, utils::user::theme as theme_utils,
};
use crate::{
    core::errors::{self, RouterResponse, UserErrors, UserResponse},
    services::{api as service_api, authentication},
    types::{
        api::{self as api_types, enums},
        storage,
        transformers::ForeignTryFrom,
    },
    utils::user as user_utils,
    SessionState,
};

#[allow(unused_variables)]
pub async fn send_recon_request(
    state: SessionState,
    auth_data: authentication::AuthenticationDataWithUser,
) -> RouterResponse<recon_api::ReconStatusResponse> {
    #[cfg(not(feature = "email"))]
    return Ok(service_api::ApplicationResponse::Json(
        recon_api::ReconStatusResponse {
            recon_status: enums::ReconStatus::NotRequested,
        },
    ));

    #[cfg(feature = "email")]
    {
        let user_in_db = &auth_data.user;
        let merchant_id = auth_data.merchant_account.get_id().clone();

        let theme = theme_utils::get_most_specific_theme_using_lineage(
            &state.clone(),
            ThemeLineage::Merchant {
                tenant_id: state.tenant.tenant_id.clone(),
                org_id: auth_data.merchant_account.get_org_id().clone(),
                merchant_id: merchant_id.clone(),
            },
        )
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable(format!(
            "Failed to fetch theme for merchant_id = {merchant_id:?}",
        ))?;

        let user_email = user_in_db.email.clone();
        let email_contents = email_types::ProFeatureRequest {
            feature_name: consts::RECON_FEATURE_TAG.to_string(),
            merchant_id: merchant_id.clone(),
            user_name: domain::UserName::new(user_in_db.name.clone())
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to form username")?,
            user_email: domain::UserEmail::from_pii_email(user_email.clone())
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to convert recipient's email to UserEmail")?,
            recipient_email: domain::UserEmail::from_pii_email(
                state.conf.email.recon_recipient_email.clone(),
            )
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to convert recipient's email to UserEmail")?,
            subject: format!(
                "{} {}",
                consts::EMAIL_SUBJECT_DASHBOARD_FEATURE_REQUEST,
                user_email.expose().peek()
            ),
            theme_id: theme.as_ref().map(|theme| theme.theme_id.clone()),
            theme_config: theme
                .map(|theme| theme.email_config())
                .unwrap_or(state.conf.theme.email_config.clone()),
        };
        state
            .email_client
            .compose_and_send_email(
                user_utils::get_base_url(&state),
                Box::new(email_contents),
                state.conf.proxy.https_url.as_ref(),
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to compose and send email for ProFeatureRequest [Recon]")
            .async_and_then(|_| async {
                let updated_merchant_account = storage::MerchantAccountUpdate::ReconUpdate {
                    recon_status: enums::ReconStatus::Requested,
                };
                let db = &*state.store;
                let key_manager_state = &(&state).into();

                let response = db
                    .update_merchant(
                        key_manager_state,
                        auth_data.merchant_account,
                        updated_merchant_account,
                        &auth_data.key_store,
                    )
                    .await
                    .change_context(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable_lazy(|| {
                        format!("Failed while updating merchant's recon status: {merchant_id:?}")
                    })?;

                Ok(service_api::ApplicationResponse::Json(
                    recon_api::ReconStatusResponse {
                        recon_status: response.recon_status,
                    },
                ))
            })
            .await
    }
}

pub async fn generate_recon_token(
    state: SessionState,
    user_with_role: authentication::UserFromTokenWithRoleInfo,
) -> RouterResponse<recon_api::ReconTokenResponse> {
    let user = user_with_role.user;
    let token = authentication::ReconToken::new_token(
        user.user_id.clone(),
        user.merchant_id.clone(),
        &state.conf,
        user.org_id.clone(),
        user.profile_id.clone(),
        user.tenant_id,
        user_with_role.role_info,
    )
    .await
    .change_context(errors::ApiErrorResponse::InternalServerError)
    .attach_printable_lazy(|| {
        format!(
            "Failed to create recon token for params [user_id, org_id, mid, pid] [{}, {:?}, {:?}, {:?}]",
            user.user_id, user.org_id, user.merchant_id, user.profile_id,
        )
    })?;

    Ok(service_api::ApplicationResponse::Json(
        recon_api::ReconTokenResponse {
            token: token.into(),
        },
    ))
}

pub async fn recon_merchant_account_update(
    state: SessionState,
    auth: authentication::AuthenticationData,
    req: recon_api::ReconUpdateMerchantRequest,
) -> RouterResponse<api_types::MerchantAccountResponse> {
    let db = &*state.store;
    let key_manager_state = &(&state).into();

    let updated_merchant_account = storage::MerchantAccountUpdate::ReconUpdate {
        recon_status: req.recon_status,
    };
    let merchant_id = auth.merchant_account.get_id().clone();

    let updated_merchant_account = db
        .update_merchant(
            key_manager_state,
            auth.merchant_account.clone(),
            updated_merchant_account,
            &auth.key_store,
        )
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable_lazy(|| {
            format!("Failed while updating merchant's recon status: {merchant_id:?}")
        })?;

    #[cfg(feature = "email")]
    {
        let user_email = &req.user_email.clone();

        let theme = theme_utils::get_most_specific_theme_using_lineage(
            &state.clone(),
            ThemeLineage::Merchant {
                tenant_id: state.tenant.tenant_id.clone(),
                org_id: auth.merchant_account.get_org_id().clone(),
                merchant_id: merchant_id.clone(),
            },
        )
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable(format!(
            "Failed to fetch theme for merchant_id = {merchant_id:?}",
        ))?;

        let email_contents = email_types::ReconActivation {
            recipient_email: domain::UserEmail::from_pii_email(user_email.clone())
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable(
                    "Failed to convert recipient's email to UserEmail from pii::Email",
                )?,
            user_name: domain::UserName::new(Secret::new("HyperSwitch User".to_string()))
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to form username")?,
            subject: consts::EMAIL_SUBJECT_APPROVAL_RECON_REQUEST,
            theme_id: theme.as_ref().map(|theme| theme.theme_id.clone()),
            theme_config: theme
                .map(|theme| theme.email_config())
                .unwrap_or(state.conf.theme.email_config.clone()),
        };
        if req.recon_status == enums::ReconStatus::Active {
            let _ = state
                .email_client
                .compose_and_send_email(
                    user_utils::get_base_url(&state),
                    Box::new(email_contents),
                    state.conf.proxy.https_url.as_ref(),
                )
                .await
                .inspect_err(|err| {
                    router_env::logger::error!(
                        "Failed to compose and send email notifying them of recon activation: {}",
                        err
                    )
                })
                .change_context(UserErrors::InternalServerError)
                .attach_printable("Failed to compose and send email for ReconActivation");
        }
    }

    Ok(service_api::ApplicationResponse::Json(
        api_types::MerchantAccountResponse::foreign_try_from(updated_merchant_account)
            .change_context(errors::ApiErrorResponse::InvalidDataValue {
                field_name: "merchant_account",
            })?,
    ))
}

pub async fn verify_recon_token(
    state: SessionState,
    user_with_role: authentication::UserFromTokenWithRoleInfo,
) -> UserResponse<recon_api::VerifyTokenResponse> {
    let user = user_with_role.user;
    let user_in_db = user
        .get_user_from_db(&state)
        .await
        .attach_printable_lazy(|| {
            format!(
                "Failed to fetch the user from DB for user_id - {}",
                user.user_id
            )
        })?;

    let acl = user_with_role.role_info.get_recon_acl();
    let optional_acl_str = serde_json::to_string(&acl)
        .inspect_err(|err| router_env::logger::error!("Failed to serialize acl to string: {}", err))
        .change_context(UserErrors::InternalServerError)
        .attach_printable("Failed to serialize acl to string. Using empty ACL")
        .ok();

    Ok(service_api::ApplicationResponse::Json(
        recon_api::VerifyTokenResponse {
            merchant_id: user.merchant_id.to_owned(),
            user_email: user_in_db.0.email,
            acl: optional_acl_str,
        },
    ))
}


// Struct: CeleroCardResponse
// File: crates/hyperswitch_connectors/src/connectors/celero/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CeleroCardResponse


// Struct: ClickhouseClient
// File: crates/analytics/src/clickhouse.rs
// Module: analytics
// Implementations: 27
// Traits: HealthCheck, AnalyticsDataSource, super::payments::filters::PaymentFilterAnalytics, super::payments::metrics::PaymentMetricAnalytics, super::payments::distribution::PaymentDistributionAnalytics, super::payment_intents::filters::PaymentIntentFilterAnalytics, super::payment_intents::metrics::PaymentIntentMetricAnalytics, super::refunds::metrics::RefundMetricAnalytics, super::refunds::filters::RefundFilterAnalytics, super::refunds::distribution::RefundDistributionAnalytics, super::frm::metrics::FrmMetricAnalytics, super::frm::filters::FrmFilterAnalytics, super::sdk_events::filters::SdkEventFilterAnalytics, super::sdk_events::metrics::SdkEventMetricAnalytics, super::sdk_events::events::SdkEventsFilterAnalytics, super::active_payments::metrics::ActivePaymentsMetricAnalytics, super::auth_events::metrics::AuthEventMetricAnalytics, super::auth_events::filters::AuthEventFilterAnalytics, super::api_event::events::ApiLogsFilterAnalytics, super::api_event::filters::ApiEventFilterAnalytics, super::api_event::metrics::ApiEventMetricAnalytics, super::connector_events::events::ConnectorEventLogAnalytics, super::routing_events::events::RoutingEventLogAnalytics, super::outgoing_webhook_event::events::OutgoingWebhookLogsFilterAnalytics, super::disputes::filters::DisputeFilterAnalytics, super::disputes::metrics::DisputeMetricAnalytics

pub struct ClickhouseClient


// File: crates/analytics/src/frm/accumulator.rs
// Module: analytics
// Public functions: 1
// Public structs: 3

use api_models::analytics::frm::FrmMetricsBucketValue;
use common_enums::enums as storage_enums;

use super::metrics::FrmMetricRow;
#[derive(Debug, Default)]
pub struct FrmMetricsAccumulator {
    pub frm_triggered_attempts: TriggeredAttemptsAccumulator,
    pub frm_blocked_rate: BlockedRateAccumulator,
}

#[derive(Debug, Default)]
#[repr(transparent)]
pub struct TriggeredAttemptsAccumulator {
    pub count: Option<i64>,
}

#[derive(Debug, Default)]
pub struct BlockedRateAccumulator {
    pub fraud: i64,
    pub total: i64,
}

pub trait FrmMetricAccumulator {
    type MetricOutput;

    fn add_metrics_bucket(&mut self, metrics: &FrmMetricRow);

    fn collect(self) -> Self::MetricOutput;
}

impl FrmMetricAccumulator for TriggeredAttemptsAccumulator {
    type MetricOutput = Option<u64>;
    #[inline]
    fn add_metrics_bucket(&mut self, metrics: &FrmMetricRow) {
        self.count = match (self.count, metrics.count) {
            (None, None) => None,
            (None, i @ Some(_)) | (i @ Some(_), None) => i,
            (Some(a), Some(b)) => Some(a + b),
        }
    }
    #[inline]
    fn collect(self) -> Self::MetricOutput {
        self.count.and_then(|i| u64::try_from(i).ok())
    }
}

impl FrmMetricAccumulator for BlockedRateAccumulator {
    type MetricOutput = Option<f64>;

    fn add_metrics_bucket(&mut self, metrics: &FrmMetricRow) {
        if let Some(ref frm_status) = metrics.frm_status {
            if frm_status.as_ref() == &storage_enums::FraudCheckStatus::Fraud {
                self.fraud += metrics.count.unwrap_or_default();
            }
        };
        self.total += metrics.count.unwrap_or_default();
    }

    fn collect(self) -> Self::MetricOutput {
        if self.total <= 0 {
            None
        } else {
            Some(
                f64::from(u32::try_from(self.fraud).ok()?) * 100.0
                    / f64::from(u32::try_from(self.total).ok()?),
            )
        }
    }
}

impl FrmMetricsAccumulator {
    pub fn collect(self) -> FrmMetricsBucketValue {
        FrmMetricsBucketValue {
            frm_blocked_rate: self.frm_blocked_rate.collect(),
            frm_triggered_attempts: self.frm_triggered_attempts.collect(),
        }
    }
}


// Implementation: impl Tokenio
// File: crates/hyperswitch_connectors/src/connectors/tokenio.rs
// Module: hyperswitch_connectors
// Methods: 6 total (1 public)

impl Tokenio


// Struct: CancelResponse
// File: crates/hyperswitch_connectors/src/connectors/braintree/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CancelResponse


// Struct: AuthenticationDataWithoutProfile
// File: crates/router/src/services/authentication.rs
// Module: router
// Implementations: 0

pub struct AuthenticationDataWithoutProfile


// File: crates/router/src/routes/hypersense.rs
// Module: router
// Public functions: 3

use actix_web::{web, HttpRequest, HttpResponse};
use api_models::external_service_auth as external_service_auth_api;
use router_env::Flow;

use super::AppState;
use crate::{
    core::{api_locking, external_service_auth},
    services::{
        api,
        authentication::{self, ExternalServiceType},
    },
};

pub async fn get_hypersense_token(state: web::Data<AppState>, req: HttpRequest) -> HttpResponse {
    let flow = Flow::HypersenseTokenRequest;
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        (),
        |state, user, _, _| {
            external_service_auth::generate_external_token(
                state,
                user,
                ExternalServiceType::Hypersense,
            )
        },
        &authentication::DashboardNoPermissionAuth,
        api_locking::LockAction::NotApplicable,
    ))
    .await
}

pub async fn signout_hypersense_token(
    state: web::Data<AppState>,
    http_req: HttpRequest,
    json_payload: web::Json<external_service_auth_api::ExternalSignoutTokenRequest>,
) -> HttpResponse {
    let flow = Flow::HypersenseSignoutToken;
    Box::pin(api::server_wrap(
        flow,
        state.clone(),
        &http_req,
        json_payload.into_inner(),
        |state, _: (), json_payload, _| {
            external_service_auth::signout_external_token(state, json_payload)
        },
        &authentication::NoAuth,
        api_locking::LockAction::NotApplicable,
    ))
    .await
}

pub async fn verify_hypersense_token(
    state: web::Data<AppState>,
    http_req: HttpRequest,
    json_payload: web::Json<external_service_auth_api::ExternalVerifyTokenRequest>,
) -> HttpResponse {
    let flow = Flow::HypersenseVerifyToken;
    Box::pin(api::server_wrap(
        flow,
        state.clone(),
        &http_req,
        json_payload.into_inner(),
        |state, _: (), json_payload, _| {
            external_service_auth::verify_external_token(
                state,
                json_payload,
                ExternalServiceType::Hypersense,
            )
        },
        &authentication::NoAuth,
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


// Implementation: impl NuveiPaymentResponseData
// File: crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs
// Module: hyperswitch_connectors
// Methods: 2 total (2 public)

impl NuveiPaymentResponseData


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

pub struct CustomerRequest


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

impl api::PaymentSync for for Paybox


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

pub fn enable_dynamic_routing_algorithm(
    state: &SessionState,
    key_store: domain::MerchantKeyStore,
    business_profile: domain::Profile,
    feature_to_enable: routing_types::DynamicRoutingFeatures,
    dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef,
    dynamic_routing_type: routing_types::DynamicRoutingType,
    payload: Option<routing_types::DynamicRoutingPayload>,
) -> RouterResult<ApplicationResponse<routing_types::RoutingDictionaryRecord>>


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

pub struct AuthorizedotnetTransactionResponse


// Struct: IndonesianBankTransferData
// File: crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct IndonesianBankTransferData


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

impl PaymentMethodsEnabled


// Implementation: impl ExternalAuthentication for for Gpayments
// File: crates/hyperswitch_connectors/src/connectors/gpayments.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl ExternalAuthentication for for Gpayments


// Struct: NovalnetApplePay
// File: crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NovalnetApplePay


// Implementation: impl FromStr for for DBEnumWrapper
// File: crates/analytics/src/types.rs
// Module: analytics
// Methods: 1 total (0 public)

impl FromStr for for DBEnumWrapper


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

pub fn create(conf: &KafkaSettings) -> MQResult<Self>


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

pub struct PaymentAccountCardInformation


// Struct: TokenizationResponse
// File: crates/hyperswitch_domain_models/src/tokenization.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct TokenizationResponse


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

pub fn get_search_results(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<GetSearchRequest>,
        index: web::Path<SearchIndex>,
    ) -> impl Responder


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

impl api::PaymentToken for for Wellsfargopayout


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

impl api::RefundSync for for Nomupay


// Implementation: impl ChargebeeCustomer
// File: crates/hyperswitch_connectors/src/connectors/chargebee/transformers.rs
// Module: hyperswitch_connectors
// Methods: 1 total (1 public)

impl ChargebeeCustomer


// Struct: OrderData
// File: crates/router/src/types/payment_methods.rs
// Module: router
// Implementations: 0

pub struct OrderData


// Function: insert_in_v2
// File: crates/router/src/types/domain/user.rs
// Module: router

pub fn insert_in_v2(self, state: &SessionState) -> UserResult<UserRole>


// Function: get_transaction_type
// File: crates/api_models/src/admin.rs
// Module: api_models

pub fn get_transaction_type(&self) -> api_enums::TransactionType


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

impl webhooks::IncomingWebhook for for Affirm


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

pub struct RefundResponse


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

impl api::Refund for for Moneris


// Struct: KafkaPaymentIntent
// File: crates/router/src/services/kafka/payment_intent.rs
// Module: router
// Implementations: 4
// Traits: super::KafkaMessage

pub struct KafkaPaymentIntent<'a>


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

pub fn new() -> &'static Self


// Struct: FetchRoutingConfig
// File: crates/api_models/src/open_router.rs
// Module: api_models
// Implementations: 0

pub struct FetchRoutingConfig


// File: crates/router/src/workflows/payment_method_status_update.rs
// Module: router
// Public structs: 1

use common_utils::ext_traits::ValueExt;
use error_stack::ResultExt;
use scheduler::{
    consumer::types::process_data, utils as pt_utils, workflows::ProcessTrackerWorkflow,
};

use crate::{
    errors,
    logger::error,
    routes::SessionState,
    types::storage::{self, PaymentMethodStatusTrackingData},
};
pub struct PaymentMethodStatusUpdateWorkflow;

#[async_trait::async_trait]
impl ProcessTrackerWorkflow<SessionState> for PaymentMethodStatusUpdateWorkflow {
    #[cfg(feature = "v1")]
    async fn execute_workflow<'a>(
        &'a self,
        state: &'a SessionState,
        process: storage::ProcessTracker,
    ) -> Result<(), errors::ProcessTrackerError> {
        let db = &*state.store;
        let tracking_data: PaymentMethodStatusTrackingData = process
            .tracking_data
            .clone()
            .parse_value("PaymentMethodStatusTrackingData")?;

        let retry_count = process.retry_count;
        let pm_id = tracking_data.payment_method_id;
        let prev_pm_status = tracking_data.prev_status;
        let curr_pm_status = tracking_data.curr_status;
        let merchant_id = tracking_data.merchant_id;
        let key_manager_state = &state.into();
        let key_store = state
            .store
            .get_merchant_key_store_by_merchant_id(
                key_manager_state,
                &merchant_id,
                &state.store.get_master_key().to_vec().into(),
            )
            .await?;

        let merchant_account = db
            .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
            .await?;

        let payment_method = db
            .find_payment_method(
                &(state.into()),
                &key_store,
                &pm_id,
                merchant_account.storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Unable to decode billing address")?;

        if payment_method.status != prev_pm_status {
            return db
                .as_scheduler()
                .finish_process_with_business_status(process, "PROCESS_ALREADY_COMPLETED")
                .await
                .map_err(Into::<errors::ProcessTrackerError>::into);
        }

        let pm_update = storage::PaymentMethodUpdate::StatusUpdate {
            status: Some(curr_pm_status),
        };

        let res = db
            .update_payment_method(
                &(state.into()),
                &key_store,
                payment_method,
                pm_update,
                merchant_account.storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Unable to update payment method");

        if let Ok(_pm) = res {
            db.as_scheduler()
                .finish_process_with_business_status(process, "COMPLETED_BY_PT")
                .await?;
        } else {
            let mapping = process_data::PaymentMethodsPTMapping::default();
            let time_delta = if retry_count == 0 {
                Some(mapping.default_mapping.start_after)
            } else {
                pt_utils::get_delay(retry_count + 1, &mapping.default_mapping.frequencies)
            };

            let schedule_time = pt_utils::get_time_from_delta(time_delta);

            match schedule_time {
                Some(s_time) => db
                    .as_scheduler()
                    .retry_process(process, s_time)
                    .await
                    .map_err(Into::<errors::ProcessTrackerError>::into)?,
                None => db
                    .as_scheduler()
                    .finish_process_with_business_status(process, "RETRIES_EXCEEDED")
                    .await
                    .map_err(Into::<errors::ProcessTrackerError>::into)?,
            };
        };

        Ok(())
    }

    #[cfg(feature = "v2")]
    async fn execute_workflow<'a>(
        &'a self,
        _state: &'a SessionState,
        _process: storage::ProcessTracker,
    ) -> Result<(), errors::ProcessTrackerError> {
        todo!()
    }
    async fn error_handler<'a>(
        &'a self,
        _state: &'a SessionState,
        process: storage::ProcessTracker,
        _error: errors::ProcessTrackerError,
    ) -> errors::CustomResult<(), errors::ProcessTrackerError> {
        error!(%process.id, "Failed while executing workflow");
        Ok(())
    }
}


// Implementation: impl api::PaymentSession for for Authipay
// File: crates/hyperswitch_connectors/src/connectors/authipay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSession for for Authipay


// File: crates/diesel_models/src/query/user_authentication_method.rs
// Module: diesel_models
// Public functions: 6

use diesel::{associations::HasTable, ExpressionMethods};

use crate::{
    query::generics, schema::user_authentication_methods::dsl, user_authentication_method::*,
    PgPooledConn, StorageResult,
};

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

impl UserAuthenticationMethod {
    pub async fn get_user_authentication_method_by_id(
        conn: &PgPooledConn,
        id: &str,
    ) -> StorageResult<Self> {
        generics::generic_find_by_id::<<Self as HasTable>::Table, _, _>(conn, id.to_owned()).await
    }

    pub async fn list_user_authentication_methods_for_auth_id(
        conn: &PgPooledConn,
        auth_id: &str,
    ) -> StorageResult<Vec<Self>> {
        generics::generic_filter::<<Self as HasTable>::Table, _, _, _>(
            conn,
            dsl::auth_id.eq(auth_id.to_owned()),
            None,
            None,
            Some(dsl::last_modified_at.asc()),
        )
        .await
    }

    pub async fn list_user_authentication_methods_for_owner_id(
        conn: &PgPooledConn,
        owner_id: &str,
    ) -> StorageResult<Vec<Self>> {
        generics::generic_filter::<<Self as HasTable>::Table, _, _, _>(
            conn,
            dsl::owner_id.eq(owner_id.to_owned()),
            None,
            None,
            Some(dsl::last_modified_at.asc()),
        )
        .await
    }

    pub async fn update_user_authentication_method(
        conn: &PgPooledConn,
        id: &str,
        user_authentication_method_update: UserAuthenticationMethodUpdate,
    ) -> StorageResult<Self> {
        generics::generic_update_with_unique_predicate_get_result::<
            <Self as HasTable>::Table,
            _,
            _,
            _,
        >(
            conn,
            dsl::id.eq(id.to_owned()),
            OrgAuthenticationMethodUpdateInternal::from(user_authentication_method_update),
        )
        .await
    }

    pub async fn list_user_authentication_methods_for_email_domain(
        conn: &PgPooledConn,
        email_domain: &str,
    ) -> StorageResult<Vec<Self>> {
        generics::generic_filter::<<Self as HasTable>::Table, _, _, _>(
            conn,
            dsl::email_domain.eq(email_domain.to_owned()),
            None,
            None,
            Some(dsl::last_modified_at.asc()),
        )
        .await
    }
}


// Function: payments_operation_core
// File: crates/router/src/core/payments.rs
// Module: router

pub fn payments_operation_core<F, Req, Op, FData, D>(
    state: &SessionState,
    req_state: ReqState,
    merchant_context: domain::MerchantContext,
    profile: &domain::Profile,
    operation: Op,
    req: Req,
    get_tracker_response: operations::GetTrackerResponse<D>,
    call_connector_action: CallConnectorAction,
    header_payload: HeaderPayload,
) -> RouterResult<(
    D,
    Req,
    Option<domain::Customer>,
    Option<u16>,
    Option<u128>,
    common_types::domain::ConnectorResponseData,
)>
where
    F: Send + Clone + Sync,
    Req: Send + Sync + Authenticate,
    Op: Operation<F, Req, Data = D> + Send + Sync,
    D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,

    // To create connector flow specific interface data
    D: ConstructFlowSpecificData<F, FData, router_types::PaymentsResponseData>,
    RouterData<F, FData, router_types::PaymentsResponseData>: Feature<F, FData>,

    // To construct connector flow specific api
    dyn api::Connector:
        services::api::ConnectorIntegration<F, FData, router_types::PaymentsResponseData>,

    RouterData<F, FData, router_types::PaymentsResponseData>:
        hyperswitch_domain_models::router_data::TrackerPostUpdateObjects<F, FData, D>,

    // To perform router related operation for PaymentResponse
    PaymentResponse: Operation<F, FData, Data = D>,
    FData: Send + Sync + Clone,


// Struct: WellsfargoConsumerAuthInformation
// File: crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct WellsfargoConsumerAuthInformation


// Function: profile_update
// File: crates/router/src/routes/profiles.rs
// Module: router

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


// Struct: CalSuccessRateConfigEventRequest
// File: crates/router/src/core/payments/routing/utils.rs
// Module: router
// Implementations: 0

pub struct CalSuccessRateConfigEventRequest


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

pub fn get_lookup_key_from_locker(
    state: &routes::SessionState,
    payment_token: &str,
    pm: &domain::PaymentMethod,
    merchant_key_store: &domain::MerchantKeyStore,
) -> errors::RouterResult<api::CardDetailFromLocker>


// Struct: CoBadgedCardNetworks
// File: crates/api_models/src/open_router.rs
// Module: api_models
// Implementations: 1

pub struct CoBadgedCardNetworks


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

impl EventNew


// Function: skip
// File: crates/router/src/types/domain/user/decision_manager.rs
// Module: router

pub fn skip(self, user: UserFromStorage, state: &SessionState) -> UserResult<Self>