// File: crates/diesel_models/src/query/gsm.rs
// Module: diesel_models
// Public functions: 5

use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
use error_stack::report;

use crate::{
    errors, gsm::*, query::generics, schema::gateway_status_map::dsl, PgPooledConn, StorageResult,
};

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

impl GatewayStatusMap {
    pub async fn find(
        conn: &PgPooledConn,
        connector: String,
        flow: String,
        sub_flow: String,
        code: String,
        message: String,
    ) -> StorageResult<Self> {
        generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
            conn,
            dsl::connector
                .eq(connector)
                .and(dsl::flow.eq(flow))
                .and(dsl::sub_flow.eq(sub_flow))
                .and(dsl::code.eq(code))
                .and(dsl::message.eq(message)),
        )
        .await
    }

    pub async fn retrieve_decision(
        conn: &PgPooledConn,
        connector: String,
        flow: String,
        sub_flow: String,
        code: String,
        message: String,
    ) -> StorageResult<String> {
        Self::find(conn, connector, flow, sub_flow, code, message)
            .await
            .map(|item| item.decision)
    }

    pub async fn update(
        conn: &PgPooledConn,
        connector: String,
        flow: String,
        sub_flow: String,
        code: String,
        message: String,
        gsm: GatewayStatusMappingUpdate,
    ) -> StorageResult<Self> {
        generics::generic_update_with_results::<
            <Self as HasTable>::Table,
            GatewayStatusMapperUpdateInternal,
            _,
            _,
        >(
            conn,
            dsl::connector
                .eq(connector)
                .and(dsl::flow.eq(flow))
                .and(dsl::sub_flow.eq(sub_flow))
                .and(dsl::code.eq(code))
                .and(dsl::message.eq(message)),
            gsm.into(),
        )
        .await?
        .first()
        .cloned()
        .ok_or_else(|| {
            report!(errors::DatabaseError::NotFound)
                .attach_printable("Error while updating gsm entry")
        })
    }

    pub async fn delete(
        conn: &PgPooledConn,
        connector: String,
        flow: String,
        sub_flow: String,
        code: String,
        message: String,
    ) -> StorageResult<bool> {
        generics::generic_delete::<<Self as HasTable>::Table, _>(
            conn,
            dsl::connector
                .eq(connector)
                .and(dsl::flow.eq(flow))
                .and(dsl::sub_flow.eq(sub_flow))
                .and(dsl::code.eq(code))
                .and(dsl::message.eq(message)),
        )
        .await
    }
}


// Implementation: impl Default for for WiseHttpStatus
// File: crates/hyperswitch_connectors/src/connectors/wise/transformers.rs
// Module: hyperswitch_connectors
// Methods: 1 total (0 public)

impl Default for for WiseHttpStatus


// Function: construct_post_authentication_router_data
// File: crates/router/src/core/authentication/transformers.rs
// Module: router

pub fn construct_post_authentication_router_data(
    state: &SessionState,
    authentication_connector: String,
    business_profile: domain::Profile,
    merchant_connector_account: payments_helpers::MerchantConnectorAccountType,
    authentication_data: &storage::Authentication,
    payment_id: &common_utils::id_type::PaymentId,
) -> RouterResult<types::authentication::ConnectorPostAuthenticationRouterData>


// Struct: MetricsBucketResponse
// File: crates/api_models/src/analytics/payment_intents.rs
// Module: api_models
// Implementations: 0

pub struct MetricsBucketResponse


// Implementation: impl ConnectorSpecifications for for Itaubank
// File: crates/hyperswitch_connectors/src/connectors/itaubank.rs
// Module: hyperswitch_connectors
// Methods: 3 total (0 public)

impl ConnectorSpecifications for for Itaubank


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

pub struct DisputeOutcome


// File: crates/diesel_models/src/invoice.rs
// Module: diesel_models
// Public functions: 2
// Public structs: 3

use common_enums::connector_enums::{Connector, InvoiceStatus};
use common_utils::{id_type::GenerateId, pii::SecretSerdeValue, types::MinorUnit};
use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
use serde::{Deserialize, Serialize};

use crate::schema::invoice;

#[derive(Clone, Debug, Eq, Insertable, PartialEq, Serialize, Deserialize)]
#[diesel(table_name = invoice, check_for_backend(diesel::pg::Pg))]
pub struct InvoiceNew {
    pub id: common_utils::id_type::InvoiceId,
    pub subscription_id: common_utils::id_type::SubscriptionId,
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_id: common_utils::id_type::ProfileId,
    pub merchant_connector_id: common_utils::id_type::MerchantConnectorAccountId,
    pub payment_intent_id: Option<common_utils::id_type::PaymentId>,
    pub payment_method_id: Option<String>,
    pub customer_id: common_utils::id_type::CustomerId,
    pub amount: MinorUnit,
    pub currency: String,
    pub status: String,
    pub provider_name: Connector,
    pub metadata: Option<SecretSerdeValue>,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
}

#[derive(
    Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Selectable, Deserialize, Serialize,
)]
#[diesel(
    table_name = invoice,
    primary_key(id),
    check_for_backend(diesel::pg::Pg)
)]
pub struct Invoice {
    pub id: common_utils::id_type::InvoiceId,
    pub subscription_id: common_utils::id_type::SubscriptionId,
    pub merchant_id: common_utils::id_type::MerchantId,
    pub profile_id: common_utils::id_type::ProfileId,
    pub merchant_connector_id: common_utils::id_type::MerchantConnectorAccountId,
    pub payment_intent_id: Option<common_utils::id_type::PaymentId>,
    pub payment_method_id: Option<String>,
    pub customer_id: common_utils::id_type::CustomerId,
    pub amount: MinorUnit,
    pub currency: String,
    pub status: String,
    pub provider_name: Connector,
    pub metadata: Option<SecretSerdeValue>,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
}

#[derive(Clone, Debug, Eq, PartialEq, AsChangeset, Deserialize)]
#[diesel(table_name = invoice)]
pub struct InvoiceUpdate {
    pub status: Option<String>,
    pub payment_method_id: Option<String>,
    pub modified_at: time::PrimitiveDateTime,
}

impl InvoiceNew {
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        subscription_id: common_utils::id_type::SubscriptionId,
        merchant_id: common_utils::id_type::MerchantId,
        profile_id: common_utils::id_type::ProfileId,
        merchant_connector_id: common_utils::id_type::MerchantConnectorAccountId,
        payment_intent_id: Option<common_utils::id_type::PaymentId>,
        payment_method_id: Option<String>,
        customer_id: common_utils::id_type::CustomerId,
        amount: MinorUnit,
        currency: String,
        status: InvoiceStatus,
        provider_name: Connector,
        metadata: Option<SecretSerdeValue>,
    ) -> Self {
        let id = common_utils::id_type::InvoiceId::generate();
        let now = common_utils::date_time::now();
        Self {
            id,
            subscription_id,
            merchant_id,
            profile_id,
            merchant_connector_id,
            payment_intent_id,
            payment_method_id,
            customer_id,
            amount,
            currency,
            status: status.to_string(),
            provider_name,
            metadata,
            created_at: now,
            modified_at: now,
        }
    }
}

impl InvoiceUpdate {
    pub fn new(payment_method_id: Option<String>, status: Option<InvoiceStatus>) -> Self {
        Self {
            payment_method_id,
            status: status.map(|status| status.to_string()),
            modified_at: common_utils::date_time::now(),
        }
    }
}


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

pub fn perform_dynamic_routing_volume_split(
    splits: Vec<api_models::routing::RoutingVolumeSplit>,
    rng_seed: Option<&str>,
) -> RoutingResult<api_models::routing::RoutingVolumeSplit>


// Function: validate_and_get_payment_method_records
// File: crates/router/src/core/payment_methods/migration.rs
// Module: router

pub fn validate_and_get_payment_method_records(self) -> UpdateValidationResult


// Implementation: impl MerchantConnectorResponse
// File: crates/api_models/src/admin.rs
// Module: api_models
// Methods: 1 total (1 public)

impl MerchantConnectorResponse


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

impl Responder


// Implementation: impl api::PayoutEligibility for for Ebanx
// File: crates/hyperswitch_connectors/src/connectors/ebanx.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PayoutEligibility for for Ebanx


// File: crates/router/src/core/webhooks/network_tokenization_incoming.rs
// Module: router
// Public functions: 8
// Public structs: 2

use std::str::FromStr;

use ::payment_methods::controller::PaymentMethodsController;
use api_models::webhooks::WebhookResponseTracker;
use async_trait::async_trait;
use common_utils::{
    crypto::Encryptable,
    ext_traits::{AsyncExt, ByteSliceExt, ValueExt},
    id_type,
};
use error_stack::{report, ResultExt};
use http::HeaderValue;
use masking::{ExposeInterface, Secret};
use serde::{Deserialize, Serialize};

use crate::{
    configs::settings,
    core::{
        errors::{self, CustomResult, RouterResult, StorageErrorExt},
        payment_methods::cards,
    },
    logger,
    routes::{app::SessionStateInfo, SessionState},
    types::{
        api, domain, payment_methods as pm_types,
        storage::{self, enums},
    },
    utils::{self as helper_utils, ext_traits::OptionExt},
};

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum NetworkTokenWebhookResponse {
    PanMetadataUpdate(pm_types::PanMetadataUpdateBody),
    NetworkTokenMetadataUpdate(pm_types::NetworkTokenMetaDataUpdateBody),
}

impl NetworkTokenWebhookResponse {
    fn get_network_token_requestor_ref_id(&self) -> String {
        match self {
            Self::PanMetadataUpdate(data) => data.card.card_reference.clone(),
            Self::NetworkTokenMetadataUpdate(data) => data.token.card_reference.clone(),
        }
    }

    pub fn get_response_data(self) -> Box<dyn NetworkTokenWebhookResponseExt> {
        match self {
            Self::PanMetadataUpdate(data) => Box::new(data),
            Self::NetworkTokenMetadataUpdate(data) => Box::new(data),
        }
    }

    pub async fn fetch_merchant_id_payment_method_id_customer_id_from_callback_mapper(
        &self,
        state: &SessionState,
    ) -> RouterResult<(id_type::MerchantId, String, id_type::CustomerId)> {
        let network_token_requestor_ref_id = &self.get_network_token_requestor_ref_id();

        let db = &*state.store;
        let callback_mapper_data = db
            .find_call_back_mapper_by_id(network_token_requestor_ref_id)
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to fetch callback mapper data")?;

        Ok(callback_mapper_data
            .data
            .get_network_token_webhook_details())
    }
}

pub fn get_network_token_resource_object(
    request_details: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::NetworkTokenizationError> {
    let response: NetworkTokenWebhookResponse = request_details
        .body
        .parse_struct("NetworkTokenWebhookResponse")
        .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
    Ok(Box::new(response))
}

#[async_trait]
pub trait NetworkTokenWebhookResponseExt {
    fn decrypt_payment_method_data(
        &self,
        payment_method: &domain::PaymentMethod,
    ) -> CustomResult<api::payment_methods::CardDetailFromLocker, errors::ApiErrorResponse>;

    async fn update_payment_method(
        &self,
        state: &SessionState,
        payment_method: &domain::PaymentMethod,
        merchant_context: &domain::MerchantContext,
    ) -> CustomResult<WebhookResponseTracker, errors::ApiErrorResponse>;
}

#[async_trait]
impl NetworkTokenWebhookResponseExt for pm_types::PanMetadataUpdateBody {
    fn decrypt_payment_method_data(
        &self,
        payment_method: &domain::PaymentMethod,
    ) -> CustomResult<api::payment_methods::CardDetailFromLocker, errors::ApiErrorResponse> {
        let decrypted_data = payment_method
            .payment_method_data
            .clone()
            .map(|payment_method_data| payment_method_data.into_inner().expose())
            .and_then(|val| {
                val.parse_value::<api::payment_methods::PaymentMethodsData>("PaymentMethodsData")
                    .map_err(|err| logger::error!(?err, "Failed to parse PaymentMethodsData"))
                    .ok()
            })
            .and_then(|pmd| match pmd {
                api::payment_methods::PaymentMethodsData::Card(token) => {
                    Some(api::payment_methods::CardDetailFromLocker::from(token))
                }
                _ => None,
            })
            .ok_or(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to obtain decrypted token object from db")?;
        Ok(decrypted_data)
    }

    async fn update_payment_method(
        &self,
        state: &SessionState,
        payment_method: &domain::PaymentMethod,
        merchant_context: &domain::MerchantContext,
    ) -> CustomResult<WebhookResponseTracker, errors::ApiErrorResponse> {
        let decrypted_data = self.decrypt_payment_method_data(payment_method)?;
        handle_metadata_update(
            state,
            &self.card,
            payment_method
                .locker_id
                .clone()
                .get_required_value("locker_id")
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Locker id is not found for the payment method")?,
            payment_method,
            merchant_context,
            decrypted_data,
            true,
        )
        .await
    }
}

#[async_trait]
impl NetworkTokenWebhookResponseExt for pm_types::NetworkTokenMetaDataUpdateBody {
    fn decrypt_payment_method_data(
        &self,
        payment_method: &domain::PaymentMethod,
    ) -> CustomResult<api::payment_methods::CardDetailFromLocker, errors::ApiErrorResponse> {
        let decrypted_data = payment_method
            .network_token_payment_method_data
            .clone()
            .map(|x| x.into_inner().expose())
            .and_then(|val| {
                val.parse_value::<api::payment_methods::PaymentMethodsData>("PaymentMethodsData")
                    .map_err(|err| logger::error!(?err, "Failed to parse PaymentMethodsData"))
                    .ok()
            })
            .and_then(|pmd| match pmd {
                api::payment_methods::PaymentMethodsData::Card(token) => {
                    Some(api::payment_methods::CardDetailFromLocker::from(token))
                }
                _ => None,
            })
            .ok_or(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to obtain decrypted token object from db")?;
        Ok(decrypted_data)
    }

    async fn update_payment_method(
        &self,
        state: &SessionState,
        payment_method: &domain::PaymentMethod,
        merchant_context: &domain::MerchantContext,
    ) -> CustomResult<WebhookResponseTracker, errors::ApiErrorResponse> {
        let decrypted_data = self.decrypt_payment_method_data(payment_method)?;
        handle_metadata_update(
            state,
            &self.token,
            payment_method
                .network_token_locker_id
                .clone()
                .get_required_value("locker_id")
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Locker id is not found for the payment method")?,
            payment_method,
            merchant_context,
            decrypted_data,
            true,
        )
        .await
    }
}

pub struct Authorization {
    header: Option<HeaderValue>,
}

impl Authorization {
    pub fn new(header: Option<&HeaderValue>) -> Self {
        Self {
            header: header.cloned(),
        }
    }

    pub async fn verify_webhook_source(
        self,
        nt_service: &settings::NetworkTokenizationService,
    ) -> CustomResult<(), errors::ApiErrorResponse> {
        let secret = nt_service.webhook_source_verification_key.clone();

        let source_verified = match self.header {
            Some(authorization_header) => match authorization_header.to_str() {
                Ok(header_value) => Ok(header_value == secret.expose()),
                Err(err) => {
                    logger::error!(?err, "Failed to parse authorization header");
                    Err(errors::ApiErrorResponse::WebhookAuthenticationFailed)
                }
            },
            None => Ok(false),
        }?;
        logger::info!(source_verified=?source_verified);

        helper_utils::when(!source_verified, || {
            Err(report!(
                errors::ApiErrorResponse::WebhookAuthenticationFailed
            ))
        })?;

        Ok(())
    }
}

#[allow(clippy::too_many_arguments)]
pub async fn handle_metadata_update(
    state: &SessionState,
    metadata: &pm_types::NetworkTokenRequestorData,
    locker_id: String,
    payment_method: &domain::PaymentMethod,
    merchant_context: &domain::MerchantContext,
    decrypted_data: api::payment_methods::CardDetailFromLocker,
    is_pan_update: bool,
) -> RouterResult<WebhookResponseTracker> {
    let merchant_id = merchant_context.get_merchant_account().get_id();
    let customer_id = &payment_method.customer_id;
    let payment_method_id = payment_method.get_id().clone();
    let status = payment_method.status;

    match metadata.is_update_required(decrypted_data) {
        false => {
            logger::info!(
                "No update required for payment method {} for locker_id {}",
                payment_method.get_id(),
                locker_id
            );
            Ok(WebhookResponseTracker::PaymentMethod {
                payment_method_id,
                status,
            })
        }
        true => {
            let mut card = cards::get_card_from_locker(state, customer_id, merchant_id, &locker_id)
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to fetch token information from the locker")?;

            card.card_exp_year = metadata.expiry_year.clone();
            card.card_exp_month = metadata.expiry_month.clone();

            let card_network = card
                .card_brand
                .clone()
                .map(|card_brand| enums::CardNetwork::from_str(&card_brand))
                .transpose()
                .change_context(errors::ApiErrorResponse::InvalidDataValue {
                    field_name: "card network",
                })
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Invalid Card Network stored in vault")?;

            let card_data = api::payment_methods::CardDetail::from((card, card_network));

            let payment_method_request: api::payment_methods::PaymentMethodCreate =
                PaymentMethodCreateWrapper::from((&card_data, payment_method)).get_inner();

            let pm_cards = cards::PmCards {
                state,
                merchant_context,
            };

            pm_cards
                .delete_card_from_locker(customer_id, merchant_id, &locker_id)
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to delete network token")?;

            let (res, _) = pm_cards
                .add_card_to_locker(payment_method_request, &card_data, customer_id, None)
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to add network token")?;

            let pm_details = res.card.as_ref().map(|card| {
                api::payment_methods::PaymentMethodsData::Card(
                    api::payment_methods::CardDetailsPaymentMethod::from((card.clone(), None)),
                )
            });
            let key_manager_state = state.into();

            let pm_data_encrypted: Option<Encryptable<Secret<serde_json::Value>>> = pm_details
                .async_map(|pm_card| {
                    cards::create_encrypted_data(
                        &key_manager_state,
                        merchant_context.get_merchant_key_store(),
                        pm_card,
                    )
                })
                .await
                .transpose()
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Unable to encrypt payment method data")?;

            let pm_update = if is_pan_update {
                storage::PaymentMethodUpdate::AdditionalDataUpdate {
                    locker_id: Some(res.payment_method_id),
                    payment_method_data: pm_data_encrypted.map(Into::into),
                    status: None,
                    payment_method: None,
                    payment_method_type: None,
                    payment_method_issuer: None,
                    network_token_requestor_reference_id: None,
                    network_token_locker_id: None,
                    network_token_payment_method_data: None,
                }
            } else {
                storage::PaymentMethodUpdate::AdditionalDataUpdate {
                    locker_id: None,
                    payment_method_data: None,
                    status: None,
                    payment_method: None,
                    payment_method_type: None,
                    payment_method_issuer: None,
                    network_token_requestor_reference_id: None,
                    network_token_locker_id: Some(res.payment_method_id),
                    network_token_payment_method_data: pm_data_encrypted.map(Into::into),
                }
            };
            let db = &*state.store;

            db.update_payment_method(
                &key_manager_state,
                merchant_context.get_merchant_key_store(),
                payment_method.clone(),
                pm_update,
                merchant_context.get_merchant_account().storage_scheme,
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Failed to update the payment method")?;

            Ok(WebhookResponseTracker::PaymentMethod {
                payment_method_id,
                status,
            })
        }
    }
}

pub struct PaymentMethodCreateWrapper(pub api::payment_methods::PaymentMethodCreate);

impl From<(&api::payment_methods::CardDetail, &domain::PaymentMethod)>
    for PaymentMethodCreateWrapper
{
    fn from(
        (data, payment_method): (&api::payment_methods::CardDetail, &domain::PaymentMethod),
    ) -> Self {
        Self(api::payment_methods::PaymentMethodCreate {
            customer_id: Some(payment_method.customer_id.clone()),
            payment_method: payment_method.payment_method,
            payment_method_type: payment_method.payment_method_type,
            payment_method_issuer: payment_method.payment_method_issuer.clone(),
            payment_method_issuer_code: payment_method.payment_method_issuer_code,
            metadata: payment_method.metadata.clone(),
            payment_method_data: None,
            connector_mandate_details: None,
            client_secret: None,
            billing: None,
            card: Some(data.clone()),
            card_network: data
                .card_network
                .clone()
                .map(|card_network| card_network.to_string()),
            bank_transfer: None,
            wallet: None,
            network_transaction_id: payment_method.network_transaction_id.clone(),
        })
    }
}

impl PaymentMethodCreateWrapper {
    fn get_inner(self) -> api::payment_methods::PaymentMethodCreate {
        self.0
    }
}

pub async fn fetch_merchant_account_for_network_token_webhooks(
    state: &SessionState,
    merchant_id: &id_type::MerchantId,
) -> RouterResult<domain::MerchantContext> {
    let db = &*state.store;
    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
        .change_context(errors::ApiErrorResponse::Unauthorized)
        .attach_printable("Failed to fetch merchant key store for the merchant id")?;

    let merchant_account = db
        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Failed to fetch merchant account for the merchant id")?;

    let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(domain::Context(
        merchant_account.clone(),
        key_store,
    )));

    Ok(merchant_context)
}

pub async fn fetch_payment_method_for_network_token_webhooks(
    state: &SessionState,
    merchant_account: &domain::MerchantAccount,
    key_store: &domain::MerchantKeyStore,
    payment_method_id: &str,
) -> RouterResult<domain::PaymentMethod> {
    let db = &*state.store;
    let key_manager_state = &(state).into();

    let payment_method = db
        .find_payment_method(
            key_manager_state,
            key_store,
            payment_method_id,
            merchant_account.storage_scheme,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::WebhookResourceNotFound)
        .attach_printable("Failed to fetch the payment method")?;

    Ok(payment_method)
}


// Struct: MerchantAccountCreate
// File: crates/api_models/src/admin.rs
// Module: api_models
// Implementations: 2

pub struct MerchantAccountCreate


// Struct: UsersConfigs
// File: crates/test_utils/src/connector_auth.rs
// Module: test_utils
// Implementations: 0

pub struct UsersConfigs


}

impl TryFrom<BluesnapWebhookObjectResource> for Value {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(details: BluesnapWebhookObjectResource) -> Result<Self, Self::Error> {
        let (card_transaction_type, processing_status, transaction_id) = match details
            .transaction_type
        {
            BluesnapWebhookEvents::Decline | BluesnapWebhookEvents::CcChargeFailed => Ok((
                BluesnapTxnType::Capture,
                BluesnapProcessingStatus::Fail,
                details.reference_number,
            )),
            BluesnapWebhookEvents::Charge => Ok((
                BluesnapTxnType::Capture,
                BluesnapProcessingStatus::Success,
                details.reference_number,
            )),
            BluesnapWebhookEvents::Chargeback | BluesnapWebhookEvents::ChargebackStatusChanged => {
                //It won't be consumed in dispute flow, so currently does not hold any significance
                return serde_json::to_value(details)
                    .change_context(errors::ConnectorError::WebhookBodyDecodingFailed);
            }
            BluesnapWebhookEvents::Refund => Ok((
                BluesnapTxnType::Refund,
                BluesnapProcessingStatus::Success,
                details
                    .reversal_ref_num
                    .ok_or(errors::ConnectorError::WebhookResourceObjectNotFound)?,
            )),
            BluesnapWebhookEvents::Unknown => {
                Err(errors::ConnectorError::WebhookResourceObjectNotFound)
            }
        }?;
        let sync_struct = BluesnapPaymentsResponse {
            processing_info: ProcessingInfoResponse {
                processing_status,
                authorization_code: None,
                network_transaction_id: None,
            },
            transaction_id,
            card_transaction_type,
        };
        serde_json::to_value(sync_struct)
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)
    }
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ErrorDetails {
    pub code: String,
    pub description: String,
    pub error_name: Option<String>,
}

#[derive(Default, Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapErrorResponse {
    pub message: Vec<ErrorDetails>,
}

#[derive(Default, Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapAuthErrorResponse {
    pub error_code: String,
    pub error_description: String,
    pub error_name: Option<String>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BluesnapErrors {
    Payment(BluesnapErrorResponse),
    Auth(BluesnapAuthErrorResponse),
    General(String),
}

fn get_card_holder_info(
    address: &AddressDetails,
    email: Email,
) -> CustomResult<Option<BluesnapCardHolderInfo>, errors::ConnectorError> {
    let first_name = address.get_first_name()?;
    Ok(Some(BluesnapCardHolderInfo {
        first_name: first_name.clone(),
        last_name: address.get_last_name().unwrap_or(first_name).clone(),
        email,
    }))
}

impl From<ErrorDetails> for utils::ErrorCodeAndMessage {
    fn from(error: ErrorDetails) -> Self {
        Self {
            error_code: error.code.to_string(),
            error_message: error.error_name.unwrap_or(error.code),
        }
    }
}

fn convert_metadata_to_request_metadata(metadata: Value) -> Vec<RequestMetadata> {
    let hashmap: HashMap<Option<String>, Option<Value>> =
        serde_json::from_str(&metadata.to_string()).unwrap_or(HashMap::new());
    let mut vector = Vec::<RequestMetadata>::new();
    for (key, value) in hashmap {
        vector.push(RequestMetadata {
            meta_key: key,
            meta_value: value.map(|field_value| field_value.to_string()),
            is_visible: Some(DISPLAY_METADATA.to_string()),
        });
    }
    vector
}


// Struct: CardTokenAdditionalData
// File: crates/api_models/src/payments/additional_info.rs
// Module: api_models
// Implementations: 0

pub struct CardTokenAdditionalData


                let error_details = ErrorDetails {
                    code,
                    message,
                    reason,
                    unified_code: None,
                    unified_message: None,
                    network_advice_code,
                    network_decline_code,
                    network_error_message,
                };

                PaymentAttemptUpdate::ErrorUpdate {
                    status: attempt_status,
                    error: error_details,
                    amount_capturable,
                    connector_payment_id: connector_transaction_id,
                    updated_by: storage_scheme.to_string(),
                }
            }
        }
    }

    fn get_attempt_status_for_db_update(
        &self,
        payment_data: &payments::PaymentCaptureData<router_flow_types::Capture>,
    ) -> common_enums::AttemptStatus {
        match self.status {
            common_enums::AttemptStatus::Charged => {
                let amount_captured = self
                    .get_captured_amount(payment_data)
                    .unwrap_or(MinorUnit::zero());
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();

                if amount_captured == total_amount {
                    common_enums::AttemptStatus::Charged
                } else {
                    common_enums::AttemptStatus::PartialCharged
                }
            }
            _ => self.status,
        }
    }

    fn get_amount_capturable(
        &self,
        payment_data: &payments::PaymentCaptureData<router_flow_types::Capture>,
    ) -> Option<MinorUnit> {
        // Based on the status of the response, we can determine the amount capturable
        let intent_status = common_enums::IntentStatus::from(self.status);
        match intent_status {
            // If the status is already succeeded / failed we cannot capture any more amount
            common_enums::IntentStatus::Succeeded
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Conflicted
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            // For these statuses, update the capturable amount when it reaches terminal / capturable state
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            // Invalid states for this flow
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture => {
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            // Invalid statues for this flow
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        }
    }

    fn get_captured_amount(
        &self,
        payment_data: &payments::PaymentCaptureData<router_flow_types::Capture>,
    ) -> Option<MinorUnit> {
        // Based on the status of the response, we can determine the amount capturable
        let intent_status = common_enums::IntentStatus::from(self.status);
        match intent_status {
            // If the status is succeeded then we have captured the whole amount
            common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
                let amount_to_capture = payment_data
                    .payment_attempt
                    .amount_details
                    .get_amount_to_capture();

                let amount_captured = amount_to_capture
                    .unwrap_or(payment_data.payment_attempt.amount_details.get_net_amount());

                Some(amount_captured)
            }
            // No amount is captured
            common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture => {
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            // For these statuses, update the amount captured when it reaches terminal state
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            // Invalid states for this flow
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            // Invalid statues for this flow
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => {
                todo!()
            }
        }
    }
}

#[cfg(feature = "v2")]
impl
    TrackerPostUpdateObjects<
        router_flow_types::PSync,
        router_request_types::PaymentsSyncData,
        payments::PaymentStatusData<router_flow_types::PSync>,
    >
    for RouterData<
        router_flow_types::PSync,
        router_request_types::PaymentsSyncData,
        router_response_types::PaymentsResponseData,
    >
{
    fn get_payment_intent_update(
        &self,
        payment_data: &payments::PaymentStatusData<router_flow_types::PSync>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentIntentUpdate {
        let amount_captured = self.get_captured_amount(payment_data);
        match self.response {
            Ok(ref _response) => PaymentIntentUpdate::SyncUpdate {
                status: common_enums::IntentStatus::from(
                    self.get_attempt_status_for_db_update(payment_data),
                ),
                amount_captured,
                updated_by: storage_scheme.to_string(),
            },
            Err(ref error) => PaymentIntentUpdate::SyncUpdate {
                status: {
                    let attempt_status = match error.attempt_status {
                        // Use the status sent by connector in error_response if it's present
                        Some(status) => status,
                        None => match error.status_code {
                            200..=299 => common_enums::enums::AttemptStatus::Failure,
                            _ => self.status,
                        },
                    };
                    common_enums::IntentStatus::from(attempt_status)
                },
                amount_captured,
                updated_by: storage_scheme.to_string(),
            },
        }
    }

    fn get_payment_attempt_update(
        &self,
        payment_data: &payments::PaymentStatusData<router_flow_types::PSync>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentAttemptUpdate {
        let amount_capturable = self.get_amount_capturable(payment_data);

        match self.response {
            Ok(ref response_router_data) => match response_router_data {
                router_response_types::PaymentsResponseData::TransactionResponse { .. } => {
                    let attempt_status = self.get_attempt_status_for_db_update(payment_data);

                    PaymentAttemptUpdate::SyncUpdate {
                        status: attempt_status,
                        amount_capturable,
                        updated_by: storage_scheme.to_string(),
                    }
                }
                router_response_types::PaymentsResponseData::MultipleCaptureResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::SessionResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::SessionTokenResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::TransactionUnresolvedResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::TokenizationResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::ConnectorCustomerResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::ThreeDSEnrollmentResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::PreProcessingResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::IncrementalAuthorizationResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::PostProcessingResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::PaymentResourceUpdateResponse {
                    ..
                } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::PaymentsCreateOrderResponse {
                    ..
                } => todo!(),
            },
            Err(ref error_response) => {
                let ErrorResponse {
                    code,
                    message,
                    reason,
                    status_code: _,
                    attempt_status: _,
                    connector_transaction_id,
                    network_advice_code,
                    network_decline_code,
                    network_error_message,
                    connector_metadata: _,
                } = error_response.clone();

                let attempt_status = match error_response.attempt_status {
                    // Use the status sent by connector in error_response if it's present
                    Some(status) => status,
                    None => match error_response.status_code {
                        200..=299 => common_enums::enums::AttemptStatus::Failure,
                        _ => self.status,
                    },
                };

                let error_details = ErrorDetails {
                    code,
                    message,
                    reason,
                    unified_code: None,
                    unified_message: None,
                    network_advice_code,
                    network_decline_code,
                    network_error_message,
                };

                PaymentAttemptUpdate::ErrorUpdate {
                    status: attempt_status,
                    error: error_details,
                    amount_capturable,
                    connector_payment_id: connector_transaction_id,
                    updated_by: storage_scheme.to_string(),
                }
            }
        }
    }

    fn get_attempt_status_for_db_update(
        &self,
        payment_data: &payments::PaymentStatusData<router_flow_types::PSync>,
    ) -> common_enums::AttemptStatus {
        match self.status {
            common_enums::AttemptStatus::Charged => {
                let amount_captured = self
                    .get_captured_amount(payment_data)
                    .unwrap_or(MinorUnit::zero());

                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();

                if amount_captured == total_amount {
                    common_enums::AttemptStatus::Charged
                } else {
                    common_enums::AttemptStatus::PartialCharged
                }
            }
            _ => self.status,
        }
    }

    fn get_amount_capturable(
        &self,
        payment_data: &payments::PaymentStatusData<router_flow_types::PSync>,
    ) -> Option<MinorUnit> {
        let payment_attempt = &payment_data.payment_attempt;

        // Based on the status of the response, we can determine the amount capturable
        let intent_status = common_enums::IntentStatus::from(self.status);
        let amount_capturable_from_intent_status = match intent_status {
            // If the status is already succeeded / failed we cannot capture any more amount
            common_enums::IntentStatus::Succeeded
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Conflicted
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            // For these statuses, update the capturable amount when it reaches terminal / capturable state
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            // Invalid states for this flow
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture
            | common_enums::IntentStatus::PartiallyCaptured => {
                let total_amount = payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            // Invalid statues for this flow
            common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        };
        self.minor_amount_capturable
            .or(amount_capturable_from_intent_status)
    }

    fn get_captured_amount(
        &self,
        payment_data: &payments::PaymentStatusData<router_flow_types::PSync>,
    ) -> Option<MinorUnit> {
        let payment_attempt = &payment_data.payment_attempt;

        // Based on the status of the response, we can determine the amount capturable
        let intent_status = common_enums::IntentStatus::from(self.status);
        let amount_captured_from_intent_status = match intent_status {
            // If the status is succeeded then we have captured the whole amount or amount_to_capture
            common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
                let amount_to_capture = payment_attempt.amount_details.get_amount_to_capture();

                let amount_captured =
                    amount_to_capture.unwrap_or(payment_attempt.amount_details.get_net_amount());

                Some(amount_captured)
            }
            // No amount is captured
            common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            // For these statuses, update the amount captured when it reaches terminal state
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            // Invalid states for this flow
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture => {
                let total_amount = payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            // Invalid statues for this flow
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        };
        self.minor_amount_captured
            .or(amount_captured_from_intent_status)
            .or(Some(payment_data.payment_attempt.get_total_amount()))
    }
}

#[cfg(feature = "v2")]
impl
    TrackerPostUpdateObjects<
        router_flow_types::ExternalVaultProxy,
        router_request_types::ExternalVaultProxyPaymentsData,
        payments::PaymentConfirmData<router_flow_types::ExternalVaultProxy>,
    >
    for RouterData<
        router_flow_types::ExternalVaultProxy,
        router_request_types::ExternalVaultProxyPaymentsData,
        router_response_types::PaymentsResponseData,
    >
{
    fn get_payment_intent_update(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::ExternalVaultProxy>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentIntentUpdate {
        let amount_captured = self.get_captured_amount(payment_data);
        match self.response {
            Ok(ref _response) => PaymentIntentUpdate::ConfirmIntentPostUpdate {
                status: common_enums::IntentStatus::from(
                    self.get_attempt_status_for_db_update(payment_data),
                ),
                amount_captured,
                updated_by: storage_scheme.to_string(),
                feature_metadata: None,
            },
            Err(ref error) => PaymentIntentUpdate::ConfirmIntentPostUpdate {
                status: {
                    let attempt_status = match error.attempt_status {
                        // Use the status sent by connector in error_response if it's present
                        Some(status) => status,
                        None => match error.status_code {
                            500..=511 => common_enums::enums::AttemptStatus::Pending,
                            _ => common_enums::enums::AttemptStatus::Failure,
                        },
                    };
                    common_enums::IntentStatus::from(attempt_status)
                },
                amount_captured,
                updated_by: storage_scheme.to_string(),
                feature_metadata: None,
            },
        }
    }

    fn get_payment_attempt_update(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::ExternalVaultProxy>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentAttemptUpdate {
        let amount_capturable = self.get_amount_capturable(payment_data);

        match self.response {
            Ok(ref response_router_data) => match response_router_data {
                router_response_types::PaymentsResponseData::TransactionResponse {
                    resource_id,
                    redirection_data,
                    connector_metadata,
                    connector_response_reference_id,
                    ..
                } => {
                    let attempt_status = self.get_attempt_status_for_db_update(payment_data);

                    let connector_payment_id = match resource_id {
                        router_request_types::ResponseId::NoResponseId => None,
                        router_request_types::ResponseId::ConnectorTransactionId(id)
                        | router_request_types::ResponseId::EncodedData(id) => Some(id.to_owned()),
                    };

                    PaymentAttemptUpdate::ConfirmIntentResponse(Box::new(
                        payments::payment_attempt::ConfirmIntentResponseUpdate {
                            status: attempt_status,
                            connector_payment_id,
                            updated_by: storage_scheme.to_string(),
                            redirection_data: *redirection_data.clone(),
                            amount_capturable,
                            connector_metadata: connector_metadata.clone().map(Secret::new),
                            connector_token_details: response_router_data
                                .get_updated_connector_token_details(
                                    payment_data
                                        .payment_attempt
                                        .connector_token_details
                                        .as_ref()
                                        .and_then(|token_details| {
                                            token_details.get_connector_token_request_reference_id()
                                        }),
                                ),
                            connector_response_reference_id: connector_response_reference_id
                                .clone(),
                        },
                    ))
                }
                router_response_types::PaymentsResponseData::MultipleCaptureResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::SessionResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::SessionTokenResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::TransactionUnresolvedResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::TokenizationResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::ConnectorCustomerResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::ThreeDSEnrollmentResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::PreProcessingResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::IncrementalAuthorizationResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::PostProcessingResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::PaymentResourceUpdateResponse {
                    ..
                } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::PaymentsCreateOrderResponse {
                    ..
                } => todo!(),
            },
            Err(ref error_response) => {
                let ErrorResponse {
                    code,
                    message,
                    reason,
                    status_code: _,
                    attempt_status: _,
                    connector_transaction_id,
                    network_decline_code,
                    network_advice_code,
                    network_error_message,
                    connector_metadata,
                } = error_response.clone();

                let attempt_status = match error_response.attempt_status {
                    // Use the status sent by connector in error_response if it's present
                    Some(status) => status,
                    None => match error_response.status_code {
                        500..=511 => common_enums::enums::AttemptStatus::Pending,
                        _ => common_enums::enums::AttemptStatus::Failure,
                    },
                };
                let error_details = ErrorDetails {
                    code,
                    message,
                    reason,
                    unified_code: None,
                    unified_message: None,
                    network_advice_code,
                    network_decline_code,
                    network_error_message,
                };

                PaymentAttemptUpdate::ErrorUpdate {
                    status: attempt_status,
                    error: error_details,
                    amount_capturable,
                    connector_payment_id: connector_transaction_id,
                    updated_by: storage_scheme.to_string(),
                }
            }
        }
    }

    fn get_attempt_status_for_db_update(
        &self,
        _payment_data: &payments::PaymentConfirmData<router_flow_types::ExternalVaultProxy>,
    ) -> common_enums::AttemptStatus {
        // For this step, consider whatever status was given by the connector module
        // We do not need to check for amount captured or amount capturable here because we are authorizing the whole amount
        self.status
    }

    fn get_amount_capturable(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::ExternalVaultProxy>,
    ) -> Option<MinorUnit> {
        // Based on the status of the response, we can determine the amount capturable
        let intent_status = common_enums::IntentStatus::from(self.status);
        match intent_status {
            common_enums::IntentStatus::Succeeded
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Conflicted
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture => {
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        }
    }

    fn get_captured_amount(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::ExternalVaultProxy>,
    ) -> Option<MinorUnit> {
        // Based on the status of the response, we can determine the amount that was captured
        let intent_status = common_enums::IntentStatus::from(self.status);
        match intent_status {
            common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::CancelledPostCapture => Some(MinorUnit::zero()),
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        }
    }
}

#[cfg(feature = "v2")]
impl
    TrackerPostUpdateObjects<
        router_flow_types::SetupMandate,
        router_request_types::SetupMandateRequestData,
        payments::PaymentConfirmData<router_flow_types::SetupMandate>,
    >
    for RouterData<
        router_flow_types::SetupMandate,
        router_request_types::SetupMandateRequestData,
        router_response_types::PaymentsResponseData,
    >
{
    fn get_payment_intent_update(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::SetupMandate>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentIntentUpdate {
        let amount_captured = self.get_captured_amount(payment_data);
        match self.response {
            Ok(ref _response) => PaymentIntentUpdate::ConfirmIntentPostUpdate {
                status: common_enums::IntentStatus::from(
                    self.get_attempt_status_for_db_update(payment_data),
                ),
                amount_captured,
                updated_by: storage_scheme.to_string(),
                feature_metadata: None,
            },
            Err(ref error) => PaymentIntentUpdate::ConfirmIntentPostUpdate {
                status: error
                    .attempt_status
                    .map(common_enums::IntentStatus::from)
                    .unwrap_or(common_enums::IntentStatus::Failed),
                amount_captured,
                updated_by: storage_scheme.to_string(),
                feature_metadata: None,
            },
        }
    }

    fn get_payment_attempt_update(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::SetupMandate>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentAttemptUpdate {
        let amount_capturable = self.get_amount_capturable(payment_data);

        match self.response {
            Ok(ref response_router_data) => match response_router_data {
                router_response_types::PaymentsResponseData::TransactionResponse {
                    resource_id,
                    redirection_data,
                    connector_metadata,
                    ..
                } => {
                    let attempt_status = self.get_attempt_status_for_db_update(payment_data);

                    let connector_payment_id = match resource_id {
                        router_request_types::ResponseId::NoResponseId => None,
                        router_request_types::ResponseId::ConnectorTransactionId(id)
                        | router_request_types::ResponseId::EncodedData(id) => Some(id.to_owned()),
                    };

                    PaymentAttemptUpdate::ConfirmIntentResponse(Box::new(
                        payments::payment_attempt::ConfirmIntentResponseUpdate {
                            status: attempt_status,
                            connector_payment_id,
                            updated_by: storage_scheme.to_string(),
                            redirection_data: *redirection_data.clone(),
                            amount_capturable,
                            connector_metadata: connector_metadata.clone().map(Secret::new),
                            connector_token_details: response_router_data
                                .get_updated_connector_token_details(
                                    payment_data
                                        .payment_attempt
                                        .connector_token_details
                                        .as_ref()
                                        .and_then(|token_details| {
                                            token_details.get_connector_token_request_reference_id()
                                        }),
                                ),
                            connector_response_reference_id: None,
                        },
                    ))
                }
                router_response_types::PaymentsResponseData::MultipleCaptureResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::SessionResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::SessionTokenResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::TransactionUnresolvedResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::TokenizationResponse { .. } => todo!(),
                router_response_types::PaymentsResponseData::ConnectorCustomerResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::ThreeDSEnrollmentResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::PreProcessingResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::IncrementalAuthorizationResponse {
                    ..
                } => todo!(),
                router_response_types::PaymentsResponseData::PostProcessingResponse { .. } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::PaymentResourceUpdateResponse {
                    ..
                } => {
                    todo!()
                }
                router_response_types::PaymentsResponseData::PaymentsCreateOrderResponse {
                    ..
                } => todo!(),
            },
            Err(ref error_response) => {
                let ErrorResponse {
                    code,
                    message,
                    reason,
                    status_code: _,
                    attempt_status,
                    connector_transaction_id,
                    network_advice_code,
                    network_decline_code,
                    network_error_message,
                    connector_metadata: _,
                } = error_response.clone();
                let attempt_status = attempt_status.unwrap_or(self.status);

                let error_details = ErrorDetails {
                    code,
                    message,
                    reason,
                    unified_code: None,
                    unified_message: None,
                    network_advice_code,
                    network_decline_code,
                    network_error_message,
                };

                PaymentAttemptUpdate::ErrorUpdate {
                    status: attempt_status,
                    error: error_details,
                    amount_capturable,
                    connector_payment_id: connector_transaction_id,
                    updated_by: storage_scheme.to_string(),
                }
            }
        }
    }

    fn get_attempt_status_for_db_update(
        &self,
        _payment_data: &payments::PaymentConfirmData<router_flow_types::SetupMandate>,
    ) -> common_enums::AttemptStatus {
        // For this step, consider whatever status was given by the connector module
        // We do not need to check for amount captured or amount capturable here because we are authorizing the whole amount
        self.status
    }

    fn get_amount_capturable(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::SetupMandate>,
    ) -> Option<MinorUnit> {
        // Based on the status of the response, we can determine the amount capturable
        let intent_status = common_enums::IntentStatus::from(self.status);
        match intent_status {
            // If the status is already succeeded / failed we cannot capture any more amount
            // So set the amount capturable to zero
            common_enums::IntentStatus::Succeeded
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Conflicted
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            // For these statuses, update the capturable amount when it reaches terminal / capturable state
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            // Invalid states for this flow
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            // If status is requires capture, get the total amount that can be captured
            // This is in cases where the capture method will be `manual` or `manual_multiple`
            // We do not need to handle the case where amount_to_capture is provided here as it cannot be passed in authroize flow
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture => {
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            // Invalid statues for this flow, after doing authorization this state is invalid
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        }
    }

    fn get_captured_amount(
        &self,
        payment_data: &payments::PaymentConfirmData<router_flow_types::SetupMandate>,
    ) -> Option<MinorUnit> {
        // Based on the status of the response, we can determine the amount that was captured
        let intent_status = common_enums::IntentStatus::from(self.status);
        match intent_status {
            // If the status is succeeded then we have captured the whole amount
            // we need not check for `amount_to_capture` here because passing `amount_to_capture` when authorizing is not supported
            common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
                let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
                Some(total_amount)
            }
            // No amount is captured
            common_enums::IntentStatus::Cancelled
            | common_enums::IntentStatus::CancelledPostCapture
            | common_enums::IntentStatus::Failed
            | common_enums::IntentStatus::Expired => Some(MinorUnit::zero()),
            // For these statuses, update the amount captured when it reaches terminal state
            common_enums::IntentStatus::RequiresCustomerAction
            | common_enums::IntentStatus::RequiresMerchantAction
            | common_enums::IntentStatus::Processing => None,
            // Invalid states for this flow
            common_enums::IntentStatus::RequiresPaymentMethod
            | common_enums::IntentStatus::RequiresConfirmation => None,
            // No amount has been captured yet
            common_enums::IntentStatus::RequiresCapture
            | common_enums::IntentStatus::PartiallyAuthorizedAndRequiresCapture => {
                Some(MinorUnit::zero())
            }
            // Invalid statues for this flow
            common_enums::IntentStatus::PartiallyCaptured
            | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None,
        }
    }
}

#[cfg(feature = "v2")]
impl
    TrackerPostUpdateObjects<
        router_flow_types::Void,
        router_request_types::PaymentsCancelData,
        payments::PaymentCancelData<router_flow_types::Void>,
    >
    for RouterData<
        router_flow_types::Void,
        router_request_types::PaymentsCancelData,
        router_response_types::PaymentsResponseData,
    >
{
    fn get_payment_intent_update(
        &self,
        _payment_data: &payments::PaymentCancelData<router_flow_types::Void>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentIntentUpdate {
        let intent_status = common_enums::IntentStatus::from(self.status);
        PaymentIntentUpdate::VoidUpdate {
            status: intent_status,
            updated_by: storage_scheme.to_string(),
        }
    }

    fn get_payment_attempt_update(
        &self,
        payment_data: &payments::PaymentCancelData<router_flow_types::Void>,
        storage_scheme: common_enums::MerchantStorageScheme,
    ) -> PaymentAttemptUpdate {
        PaymentAttemptUpdate::VoidUpdate {
            status: self.status,
            cancellation_reason: payment_data.payment_attempt.cancellation_reason.clone(),
            updated_by: storage_scheme.to_string(),
        }
    }

    fn get_amount_capturable(
        &self,
        _payment_data: &payments::PaymentCancelData<router_flow_types::Void>,
    ) -> Option<MinorUnit> {
        // For void operations, no amount is capturable
        Some(MinorUnit::zero())
    }

    fn get_captured_amount(
        &self,
        _payment_data: &payments::PaymentCancelData<router_flow_types::Void>,
    ) -> Option<MinorUnit> {
        // For void operations, no amount is captured
        Some(MinorUnit::zero())
    }

    fn get_attempt_status_for_db_update(
        &self,
        _payment_data: &payments::PaymentCancelData<router_flow_types::Void>,
    ) -> common_enums::AttemptStatus {
        // For void operations, return Voided status
        common_enums::AttemptStatus::Voided
    }
}


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

pub fn list_payment_methods_for_session(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    profile: domain::Profile,
    payment_method_session_id: id_type::GlobalPaymentMethodSessionId,
) -> RouterResponse<api::PaymentMethodListResponseForSession>


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

impl api::PaymentAuthorize for for Chargebee


// Struct: DecisionManagerRecord
// File: crates/common_types/src/payments.rs
// Module: common_types
// Implementations: 1
// Traits: events::ApiEventMetric

// Documentation: DecisionManagerRecord

pub struct DecisionManagerRecord


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

pub struct BankAccount


// Struct: NmiMerchantDefinedField
// File: crates/hyperswitch_connectors/src/connectors/nmi/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 1

pub struct NmiMerchantDefinedField


// Struct: Vgs
// File: crates/hyperswitch_connectors/src/connectors/vgs.rs
// Module: hyperswitch_connectors
// Implementations: 19
// Traits: api::Payment, api::PaymentSession, api::ConnectorAccessToken, api::MandateSetup, api::PaymentAuthorize, api::PaymentSync, api::PaymentCapture, api::PaymentVoid, api::Refund, api::RefundExecute, api::RefundSync, api::PaymentToken, api::ExternalVaultInsert, api::ExternalVault, api::ExternalVaultRetrieve, ConnectorCommon, ConnectorValidation, webhooks::IncomingWebhook, ConnectorSpecifications

pub struct Vgs

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


// Function: set_routing_event
// File: crates/router/src/core/payments/routing/utils.rs
// Module: router

pub fn set_routing_event(&mut self, routing_event: routing_events::RoutingEvent)


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

impl api::PaymentAuthorize for for Phonepe


// Struct: PlacetopayNextActionRequest
// File: crates/hyperswitch_connectors/src/connectors/placetopay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PlacetopayNextActionRequest


// Module Structure
// File: crates/router/src/utils/connector_onboarding.rs
// Module: router

// Public submodules:
pub mod paypal;


// Function: get_four_digit_expiry_year
// File: crates/common_types/src/payments.rs
// Module: common_types

// Documentation: Get the four-digit expiration year from the Apple Pay pre-decrypt data

pub fn get_four_digit_expiry_year(&self) -> Secret<String>


// File: crates/hyperswitch_domain_models/src/router_request_types/unified_authentication_service.rs
// Module: hyperswitch_domain_models
// Public structs: 16

use api_models::payments::DeviceChannel;
use common_enums::MerchantCategoryCode;
use common_types::payments::MerchantCountryCode;
use common_utils::types::MinorUnit;
use masking::Secret;

use crate::address::Address;

#[derive(Clone, Debug)]
pub struct UasPreAuthenticationRequestData {
    pub service_details: Option<CtpServiceDetails>,
    pub transaction_details: Option<TransactionDetails>,
    pub payment_details: Option<PaymentDetails>,
    pub authentication_info: Option<AuthenticationInfo>,
    pub merchant_details: Option<MerchantDetails>,
    pub billing_address: Option<Address>,
    pub acquirer_bin: Option<String>,
    pub acquirer_merchant_id: Option<String>,
}

#[derive(Debug, Clone)]
pub struct MerchantDetails {
    pub merchant_id: Option<String>,
    pub merchant_name: Option<String>,
    pub merchant_category_code: Option<MerchantCategoryCode>,
    pub merchant_country_code: Option<MerchantCountryCode>,
    pub endpoint_prefix: Option<String>,
    pub three_ds_requestor_url: Option<String>,
    pub three_ds_requestor_id: Option<String>,
    pub three_ds_requestor_name: Option<String>,
    pub notification_url: Option<url::Url>,
}

#[derive(Clone, Debug, PartialEq, serde::Serialize)]
pub struct AuthenticationInfo {
    pub authentication_type: Option<String>,
    pub authentication_reasons: Option<Vec<String>>,
    pub consent_received: bool,
    pub is_authenticated: bool,
    pub locale: Option<String>,
    pub supported_card_brands: Option<String>,
    pub encrypted_payload: Option<Secret<String>>,
}
#[derive(Clone, Debug)]
pub struct UasAuthenticationRequestData {
    pub browser_details: Option<super::BrowserInformation>,
    pub transaction_details: TransactionDetails,
    pub pre_authentication_data: super::authentication::PreAuthenticationData,
    pub return_url: Option<String>,
    pub sdk_information: Option<api_models::payments::SdkInformation>,
    pub email: Option<common_utils::pii::Email>,
    pub threeds_method_comp_ind: api_models::payments::ThreeDsCompletionIndicator,
    pub webhook_url: String,
}

#[derive(Clone, Debug, serde::Serialize)]
pub struct CtpServiceDetails {
    pub service_session_ids: Option<ServiceSessionIds>,
    pub payment_details: Option<PaymentDetails>,
}

#[derive(Debug, Clone, serde::Serialize)]
pub struct PaymentDetails {
    pub pan: cards::CardNumber,
    pub digital_card_id: Option<String>,
    pub payment_data_type: Option<String>,
    pub encrypted_src_card_details: Option<String>,
    pub card_expiry_month: Secret<String>,
    pub card_expiry_year: Secret<String>,
    pub cardholder_name: Option<Secret<String>>,
    pub card_token_number: Option<Secret<String>>,
    pub account_type: Option<common_enums::PaymentMethodType>,
    pub card_cvc: Option<Secret<String>>,
}

#[derive(Clone, serde::Deserialize, Debug, serde::Serialize)]
pub struct ServiceSessionIds {
    pub correlation_id: Option<String>,
    pub merchant_transaction_id: Option<String>,
    pub x_src_flow_id: Option<String>,
}

#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct TransactionDetails {
    pub amount: Option<MinorUnit>,
    pub currency: Option<common_enums::Currency>,
    pub device_channel: Option<DeviceChannel>,
    pub message_category: Option<super::authentication::MessageCategory>,
}

#[derive(Clone, Debug)]
pub struct UasPostAuthenticationRequestData {
    pub threeds_server_transaction_id: Option<String>,
}

#[derive(Debug, Clone)]
pub enum UasAuthenticationResponseData {
    PreAuthentication {
        authentication_details: PreAuthenticationDetails,
    },
    Authentication {
        authentication_details: AuthenticationDetails,
    },
    PostAuthentication {
        authentication_details: PostAuthenticationDetails,
    },
    Confirmation {},
}

#[derive(Debug, Clone, serde::Serialize)]
pub struct PreAuthenticationDetails {
    pub threeds_server_transaction_id: Option<String>,
    pub maximum_supported_3ds_version: Option<common_utils::types::SemanticVersion>,
    pub connector_authentication_id: Option<String>,
    pub three_ds_method_data: Option<String>,
    pub three_ds_method_url: Option<String>,
    pub message_version: Option<common_utils::types::SemanticVersion>,
    pub connector_metadata: Option<serde_json::Value>,
    pub directory_server_id: Option<String>,
}

#[derive(Debug, Clone)]
pub struct AuthenticationDetails {
    pub authn_flow_type: super::authentication::AuthNFlowType,
    pub authentication_value: Option<Secret<String>>,
    pub trans_status: common_enums::TransactionStatus,
    pub connector_metadata: Option<serde_json::Value>,
    pub ds_trans_id: Option<String>,
    pub eci: Option<String>,
    pub challenge_code: Option<String>,
    pub challenge_cancel: Option<String>,
    pub challenge_code_reason: Option<String>,
    pub message_extension: Option<common_utils::pii::SecretSerdeValue>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct PostAuthenticationDetails {
    pub eci: Option<String>,
    pub token_details: Option<TokenDetails>,
    pub dynamic_data_details: Option<DynamicData>,
    pub trans_status: Option<common_enums::TransactionStatus>,
    pub challenge_cancel: Option<String>,
    pub challenge_code_reason: Option<String>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct TokenDetails {
    pub payment_token: cards::CardNumber,
    pub payment_account_reference: String,
    pub token_expiration_month: Secret<String>,
    pub token_expiration_year: Secret<String>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct DynamicData {
    pub dynamic_data_value: Option<Secret<String>>,
    pub dynamic_data_type: Option<String>,
    pub ds_trans_id: Option<String>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct UasConfirmationRequestData {
    pub x_src_flow_id: Option<String>,
    pub transaction_amount: MinorUnit,
    pub transaction_currency: common_enums::Currency,
    // Type of event associated with the checkout. Valid values are: - 01 - Authorise - 02 - Capture - 03 - Refund - 04 - Cancel - 05 - Fraud - 06 - Chargeback - 07 - Other
    pub checkout_event_type: Option<String>,
    pub checkout_event_status: Option<String>,
    pub confirmation_status: Option<String>,
    pub confirmation_reason: Option<String>,
    pub confirmation_timestamp: Option<String>,
    // Authorisation code associated with an approved transaction.
    pub network_authorization_code: Option<String>,
    // The unique authorisation related tracing value assigned by a Payment Network and provided in an authorisation response. Required only when checkoutEventType=01. If checkoutEventType=01 and the value of networkTransactionIdentifier is unknown, please pass UNAVLB
    pub network_transaction_identifier: Option<String>,
    pub correlation_id: Option<String>,
    pub merchant_transaction_id: Option<String>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ThreeDsMetaData {
    pub merchant_category_code: Option<MerchantCategoryCode>,
    pub merchant_country_code: Option<MerchantCountryCode>,
    pub merchant_name: Option<String>,
    pub endpoint_prefix: String,
    pub three_ds_requestor_name: Option<String>,
    pub three_ds_requestor_id: Option<String>,
    pub merchant_configuration_id: Option<String>,
}


// Struct: VgsInsertResponse
// File: crates/hyperswitch_connectors/src/connectors/vgs/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct VgsInsertResponse


// Function: is_three_ds_authentication
// File: crates/common_enums/src/enums.rs
// Module: common_enums

pub fn is_three_ds_authentication(self) -> bool


// Struct: TokenioPaymentsRequest
// File: crates/hyperswitch_connectors/src/connectors/tokenio/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct TokenioPaymentsRequest


// Struct: ShoppingCart
// File: crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ShoppingCart


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

impl api::PaymentVoid for for Forte


// Struct: SubscriptionNew
// File: crates/diesel_models/src/subscription.rs
// Module: diesel_models
// Implementations: 1

pub struct SubscriptionNew


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

pub struct GetCardToken


// Function: execute
// File: crates/analytics/src/opensearch.rs
// Module: analytics

pub fn execute(
        &self,
        query_builder: OpenSearchQueryBuilder,
    ) -> CustomResult<Response, OpenSearchError>


// File: crates/common_utils/src/types/primitive_wrappers.rs
// Module: common_utils
// Public functions: 1
// Public structs: 3

pub(crate) mod bool_wrappers {
    use serde::{Deserialize, Serialize};

    /// Bool that represents if Extended Authorization is Applied or not
    #[derive(
        Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, diesel::expression::AsExpression,
    )]
    #[diesel(sql_type = diesel::sql_types::Bool)]
    pub struct ExtendedAuthorizationAppliedBool(bool);
    impl From<bool> for ExtendedAuthorizationAppliedBool {
        fn from(value: bool) -> Self {
            Self(value)
        }
    }
    impl<DB> diesel::serialize::ToSql<diesel::sql_types::Bool, DB> for ExtendedAuthorizationAppliedBool
    where
        DB: diesel::backend::Backend,
        bool: diesel::serialize::ToSql<diesel::sql_types::Bool, DB>,
    {
        fn to_sql<'b>(
            &'b self,
            out: &mut diesel::serialize::Output<'b, '_, DB>,
        ) -> diesel::serialize::Result {
            self.0.to_sql(out)
        }
    }
    impl<DB> diesel::deserialize::FromSql<diesel::sql_types::Bool, DB>
        for ExtendedAuthorizationAppliedBool
    where
        DB: diesel::backend::Backend,
        bool: diesel::deserialize::FromSql<diesel::sql_types::Bool, DB>,
    {
        fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result<Self> {
            bool::from_sql(value).map(Self)
        }
    }

    /// Bool that represents if Extended Authorization is Requested or not
    #[derive(
        Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, diesel::expression::AsExpression,
    )]
    #[diesel(sql_type = diesel::sql_types::Bool)]
    pub struct RequestExtendedAuthorizationBool(bool);
    impl From<bool> for RequestExtendedAuthorizationBool {
        fn from(value: bool) -> Self {
            Self(value)
        }
    }
    impl RequestExtendedAuthorizationBool {
        /// returns the inner bool value
        pub fn is_true(&self) -> bool {
            self.0
        }
    }
    impl<DB> diesel::serialize::ToSql<diesel::sql_types::Bool, DB> for RequestExtendedAuthorizationBool
    where
        DB: diesel::backend::Backend,
        bool: diesel::serialize::ToSql<diesel::sql_types::Bool, DB>,
    {
        fn to_sql<'b>(
            &'b self,
            out: &mut diesel::serialize::Output<'b, '_, DB>,
        ) -> diesel::serialize::Result {
            self.0.to_sql(out)
        }
    }
    impl<DB> diesel::deserialize::FromSql<diesel::sql_types::Bool, DB>
        for RequestExtendedAuthorizationBool
    where
        DB: diesel::backend::Backend,
        bool: diesel::deserialize::FromSql<diesel::sql_types::Bool, DB>,
    {
        fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result<Self> {
            bool::from_sql(value).map(Self)
        }
    }

    /// Bool that represents if Extended Authorization is always Requested or not
    #[derive(
        Clone, Copy, Debug, Eq, PartialEq, diesel::expression::AsExpression, Serialize, Deserialize,
    )]
    #[diesel(sql_type = diesel::sql_types::Bool)]
    pub struct AlwaysRequestExtendedAuthorization(bool);
    impl<DB> diesel::serialize::ToSql<diesel::sql_types::Bool, DB>
        for AlwaysRequestExtendedAuthorization
    where
        DB: diesel::backend::Backend,
        bool: diesel::serialize::ToSql<diesel::sql_types::Bool, DB>,
    {
        fn to_sql<'b>(
            &'b self,
            out: &mut diesel::serialize::Output<'b, '_, DB>,
        ) -> diesel::serialize::Result {
            self.0.to_sql(out)
        }
    }
    impl<DB> diesel::deserialize::FromSql<diesel::sql_types::Bool, DB>
        for AlwaysRequestExtendedAuthorization
    where
        DB: diesel::backend::Backend,
        bool: diesel::deserialize::FromSql<diesel::sql_types::Bool, DB>,
    {
        fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result<Self> {
            bool::from_sql(value).map(Self)
        }
    }
}


// Struct: KafkaRefund
// File: crates/router/src/services/kafka/refund.rs
// Module: router
// Implementations: 3
// Traits: super::KafkaMessage

pub struct KafkaRefund<'a>


// File: crates/euclid/src/backend/inputs.rs
// Module: euclid
// Public structs: 7

use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};

use crate::{
    enums,
    frontend::dir::enums::{CustomerDeviceDisplaySize, CustomerDevicePlatform, CustomerDeviceType},
};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MandateData {
    pub mandate_acceptance_type: Option<enums::MandateAcceptanceType>,
    pub mandate_type: Option<enums::MandateType>,
    pub payment_type: Option<enums::PaymentType>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaymentMethodInput {
    pub payment_method: Option<enums::PaymentMethod>,
    pub payment_method_type: Option<enums::PaymentMethodType>,
    pub card_network: Option<enums::CardNetwork>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaymentInput {
    pub amount: common_utils::types::MinorUnit,
    pub currency: enums::Currency,
    pub authentication_type: Option<enums::AuthenticationType>,
    pub card_bin: Option<String>,
    pub capture_method: Option<enums::CaptureMethod>,
    pub business_country: Option<enums::Country>,
    pub billing_country: Option<enums::Country>,
    pub business_label: Option<String>,
    pub setup_future_usage: Option<enums::SetupFutureUsage>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AcquirerDataInput {
    pub country: Option<enums::Country>,
    pub fraud_rate: Option<f64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomerDeviceDataInput {
    pub platform: Option<CustomerDevicePlatform>,
    pub device_type: Option<CustomerDeviceType>,
    pub display_size: Option<CustomerDeviceDisplaySize>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IssuerDataInput {
    pub name: Option<String>,
    pub country: Option<enums::Country>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackendInput {
    pub metadata: Option<FxHashMap<String, String>>,
    pub payment: PaymentInput,
    pub payment_method: PaymentMethodInput,
    pub acquirer_data: Option<AcquirerDataInput>,
    pub customer_device_data: Option<CustomerDeviceDataInput>,
    pub issuer_data: Option<IssuerDataInput>,
    pub mandate: MandateData,
}


// Function: url
// File: crates/common_utils/src/request.rs
// Module: common_utils

pub fn url(mut self, url: &str) -> Self