// File: crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs
// Module: hyperswitch_connectors
// Public structs: 40

use std::collections::HashMap;

use api_models::{
    payments::{
        AmountInfo, ApplePayPaymentRequest, ApplePaySessionResponse,
        ApplepayCombinedSessionTokenData, ApplepaySessionTokenData, ApplepaySessionTokenMetadata,
        ApplepaySessionTokenResponse, NextActionCall, NoThirdPartySdkSessionResponse,
        SdkNextAction, SessionToken,
    },
    webhooks::IncomingWebhookEvent,
};
use base64::Engine;
use common_enums::{enums, CountryAlpha2};
use common_utils::{
    consts::{APPLEPAY_VALIDATION_URL, BASE64_ENGINE},
    errors::CustomResult,
    ext_traits::{ByteSliceExt, Encode, OptionExt, StringExt, ValueExt},
    pii::Email,
    types::{FloatMajorUnit, StringMajorUnit},
};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
    address::AddressDetails,
    payment_method_data::{self, PaymentMethodData, WalletData},
    router_data::{ConnectorAuthType, RouterData},
    router_flow_types::refunds::{Execute, RSync},
    router_request_types::ResponseId,
    router_response_types::{PaymentsResponseData, RefundsResponseData},
    types,
};
use hyperswitch_interfaces::errors;
use masking::{ExposeInterface, PeekInterface, Secret};
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::{
    types::{PaymentsSessionResponseRouterData, RefundsResponseRouterData, ResponseRouterData},
    utils::{
        self, AddressDetailsData, ApplePay, CardData as _, ForeignTryFrom,
        PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData, RouterData as _,
    },
};

const DISPLAY_METADATA: &str = "Y";

#[derive(Debug, Serialize)]
pub struct BluesnapRouterData<T> {
    pub amount: StringMajorUnit,
    pub router_data: T,
}

impl<T> TryFrom<(StringMajorUnit, T)> for BluesnapRouterData<T> {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from((amount, item): (StringMajorUnit, T)) -> Result<Self, Self::Error> {
        Ok(Self {
            amount,
            router_data: item,
        })
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapPaymentsRequest {
    amount: StringMajorUnit,
    #[serde(flatten)]
    payment_method: PaymentMethodDetails,
    currency: enums::Currency,
    card_transaction_type: BluesnapTxnType,
    transaction_fraud_info: Option<TransactionFraudInfo>,
    card_holder_info: Option<BluesnapCardHolderInfo>,
    merchant_transaction_id: Option<String>,
    transaction_meta_data: Option<BluesnapMetadata>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapMetadata {
    meta_data: Vec<RequestMetadata>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestMetadata {
    meta_key: Option<String>,
    meta_value: Option<String>,
    is_visible: Option<String>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapCardHolderInfo {
    first_name: Secret<String>,
    last_name: Secret<String>,
    email: Email,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionFraudInfo {
    fraud_session_id: String,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapCreateWalletToken {
    wallet_type: String,
    validation_url: Secret<String>,
    domain_name: String,
    display_name: Option<String>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapThreeDSecureInfo {
    three_d_secure_reference_id: String,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum PaymentMethodDetails {
    CreditCard(Card),
    Wallet(BluesnapWallet),
}

#[derive(Default, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Card {
    card_number: cards::CardNumber,
    expiration_month: Secret<String>,
    expiration_year: Secret<String>,
    security_code: Secret<String>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapWallet {
    wallet_type: BluesnapWalletTypes,
    encoded_payment_token: Secret<String>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapGooglePayObject {
    payment_method_data: utils::GooglePayWalletData,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum BluesnapWalletTypes {
    GooglePay,
    ApplePay,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EncodedPaymentToken {
    billing_contact: BillingDetails,
    token: ApplepayPaymentData,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BillingDetails {
    country_code: Option<CountryAlpha2>,
    address_lines: Option<Vec<Secret<String>>>,
    family_name: Option<Secret<String>>,
    given_name: Option<Secret<String>>,
    postal_code: Option<Secret<String>>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ApplepayPaymentData {
    payment_data: ApplePayEncodedPaymentData,
    payment_method: ApplepayPaymentMethod,
    transaction_identifier: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ApplepayPaymentMethod {
    display_name: String,
    network: String,
    #[serde(rename = "type")]
    pm_type: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ApplePayEncodedPaymentData {
    data: String,
    header: Option<ApplepayHeader>,
    signature: String,
    version: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ApplepayHeader {
    ephemeral_public_key: Secret<String>,
    public_key_hash: Secret<String>,
    transaction_id: Secret<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct BluesnapConnectorMetaData {
    pub merchant_id: common_utils::id_type::MerchantId,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapPaymentsTokenRequest {
    cc_number: cards::CardNumber,
    exp_date: Secret<String>,
}

impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>>
    for BluesnapPaymentsTokenRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BluesnapRouterData<&types::PaymentsAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        match item.router_data.request.payment_method_data {
            PaymentMethodData::Card(ref ccard) => Ok(Self {
                cc_number: ccard.card_number.clone(),
                exp_date: ccard.get_expiry_date_as_mmyyyy("/"),
            }),
            PaymentMethodData::Wallet(_)
            | PaymentMethodData::PayLater(_)
            | PaymentMethodData::BankRedirect(_)
            | PaymentMethodData::BankDebit(_)
            | PaymentMethodData::BankTransfer(_)
            | PaymentMethodData::Crypto(_)
            | PaymentMethodData::MandatePayment
            | PaymentMethodData::Reward
            | PaymentMethodData::RealTimePayment(_)
            | PaymentMethodData::MobilePayment(_)
            | PaymentMethodData::Upi(_)
            | PaymentMethodData::CardRedirect(_)
            | PaymentMethodData::Voucher(_)
            | PaymentMethodData::GiftCard(_)
            | PaymentMethodData::OpenBanking(_)
            | PaymentMethodData::CardToken(_)
            | PaymentMethodData::NetworkToken(_)
            | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                Err(errors::ConnectorError::NotImplemented(
                    "Selected payment method via Token flow through bluesnap".to_string(),
                )
                .into())
            }
        }
    }
}

impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> for BluesnapPaymentsRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BluesnapRouterData<&types::PaymentsAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        let auth_mode = match item.router_data.request.capture_method {
            Some(enums::CaptureMethod::Manual) => BluesnapTxnType::AuthOnly,
            _ => BluesnapTxnType::AuthCapture,
        };
        let transaction_meta_data =
            item.router_data
                .request
                .metadata
                .as_ref()
                .map(|metadata| BluesnapMetadata {
                    meta_data: convert_metadata_to_request_metadata(metadata.to_owned()),
                });

        let (payment_method, card_holder_info) = match item
            .router_data
            .request
            .payment_method_data
            .clone()
        {
            PaymentMethodData::Card(ref ccard) => Ok((
                PaymentMethodDetails::CreditCard(Card {
                    card_number: ccard.card_number.clone(),
                    expiration_month: ccard.card_exp_month.clone(),
                    expiration_year: ccard.get_expiry_year_4_digit(),
                    security_code: ccard.card_cvc.clone(),
                }),
                get_card_holder_info(
                    item.router_data.get_billing_address()?,
                    item.router_data.request.get_email()?,
                )?,
            )),
            PaymentMethodData::Wallet(wallet_data) => match wallet_data {
                WalletData::GooglePay(payment_method_data) => {
                    let gpay_ecrypted_object = BluesnapGooglePayObject {
                        payment_method_data: utils::GooglePayWalletData::try_from(
                            payment_method_data,
                        )
                        .change_context(errors::ConnectorError::RequestEncodingFailed)?,
                    }
                    .encode_to_string_of_json()
                    .change_context(errors::ConnectorError::RequestEncodingFailed)?;
                    Ok((
                        PaymentMethodDetails::Wallet(BluesnapWallet {
                            wallet_type: BluesnapWalletTypes::GooglePay,
                            encoded_payment_token: Secret::new(
                                BASE64_ENGINE.encode(gpay_ecrypted_object),
                            ),
                        }),
                        None,
                    ))
                }
                WalletData::ApplePay(payment_method_data) => {
                    let apple_pay_payment_data =
                        payment_method_data.get_applepay_decoded_payment_data()?;
                    let apple_pay_payment_data: ApplePayEncodedPaymentData = apple_pay_payment_data
                        .expose()
                        .as_bytes()
                        .parse_struct("ApplePayEncodedPaymentData")
                        .change_context(errors::ConnectorError::InvalidWalletToken {
                            wallet_name: "Apple Pay".to_string(),
                        })?;

                    let billing = item.router_data.get_billing()?.to_owned();

                    let billing_address = billing
                        .address
                        .get_required_value("billing_address")
                        .change_context(errors::ConnectorError::MissingRequiredField {
                            field_name: "billing",
                        })?;

                    let mut address = Vec::new();
                    if let Some(add) = billing_address.line1.to_owned() {
                        address.push(add)
                    }
                    if let Some(add) = billing_address.line2.to_owned() {
                        address.push(add)
                    }
                    if let Some(add) = billing_address.line3.to_owned() {
                        address.push(add)
                    }

                    let apple_pay_object = EncodedPaymentToken {
                        token: ApplepayPaymentData {
                            payment_data: apple_pay_payment_data,
                            payment_method: payment_method_data.payment_method.to_owned().into(),
                            transaction_identifier: payment_method_data.transaction_identifier,
                        },
                        billing_contact: BillingDetails {
                            country_code: billing_address.country,
                            address_lines: Some(address),
                            family_name: billing_address.last_name.to_owned(),
                            given_name: billing_address.first_name.to_owned(),
                            postal_code: billing_address.zip,
                        },
                    }
                    .encode_to_string_of_json()
                    .change_context(errors::ConnectorError::RequestEncodingFailed)?;

                    Ok((
                        PaymentMethodDetails::Wallet(BluesnapWallet {
                            wallet_type: BluesnapWalletTypes::ApplePay,
                            encoded_payment_token: Secret::new(
                                BASE64_ENGINE.encode(apple_pay_object),
                            ),
                        }),
                        get_card_holder_info(
                            item.router_data.get_billing_address()?,
                            item.router_data.request.get_email()?,
                        )?,
                    ))
                }
                WalletData::AliPayQr(_)
                | WalletData::AliPayRedirect(_)
                | WalletData::AliPayHkRedirect(_)
                | WalletData::AmazonPay(_)
                | WalletData::AmazonPayRedirect(_)
                | WalletData::Paysera(_)
                | WalletData::Skrill(_)
                | WalletData::BluecodeRedirect {}
                | WalletData::MomoRedirect(_)
                | WalletData::KakaoPayRedirect(_)
                | WalletData::GoPayRedirect(_)
                | WalletData::GcashRedirect(_)
                | WalletData::ApplePayRedirect(_)
                | WalletData::ApplePayThirdPartySdk(_)
                | WalletData::DanaRedirect {}
                | WalletData::GooglePayRedirect(_)
                | WalletData::GooglePayThirdPartySdk(_)
                | WalletData::MbWayRedirect(_)
                | WalletData::MobilePayRedirect(_)
                | WalletData::PaypalRedirect(_)
                | WalletData::PaypalSdk(_)
                | WalletData::Paze(_)
                | WalletData::SamsungPay(_)
                | WalletData::TwintRedirect {}
                | WalletData::VippsRedirect {}
                | WalletData::TouchNGoRedirect(_)
                | WalletData::WeChatPayRedirect(_)
                | WalletData::CashappQr(_)
                | WalletData::SwishQr(_)
                | WalletData::WeChatPayQr(_)
                | WalletData::Mifinity(_)
                | WalletData::RevolutPay(_) => Err(errors::ConnectorError::NotImplemented(
                    utils::get_unimplemented_payment_method_error_message("bluesnap"),
                )),
            },
            PaymentMethodData::PayLater(_)
            | PaymentMethodData::BankRedirect(_)
            | PaymentMethodData::BankDebit(_)
            | PaymentMethodData::BankTransfer(_)
            | PaymentMethodData::Crypto(_)
            | PaymentMethodData::MandatePayment
            | PaymentMethodData::Reward
            | PaymentMethodData::RealTimePayment(_)
            | PaymentMethodData::MobilePayment(_)
            | PaymentMethodData::Upi(_)
            | PaymentMethodData::CardRedirect(_)
            | PaymentMethodData::Voucher(_)
            | PaymentMethodData::GiftCard(_)
            | PaymentMethodData::OpenBanking(_)
            | PaymentMethodData::CardToken(_)
            | PaymentMethodData::NetworkToken(_)
            | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                Err(errors::ConnectorError::NotImplemented(
                    utils::get_unimplemented_payment_method_error_message("bluesnap"),
                ))
            }
        }?;
        Ok(Self {
            amount: item.amount.to_owned(),
            payment_method,
            currency: item.router_data.request.currency,
            card_transaction_type: auth_mode,
            transaction_fraud_info: Some(TransactionFraudInfo {
                fraud_session_id: item.router_data.payment_id.clone(),
            }),
            card_holder_info,
            merchant_transaction_id: Some(item.router_data.connector_request_reference_id.clone()),
            transaction_meta_data,
        })
    }
}

impl From<payment_method_data::ApplepayPaymentMethod> for ApplepayPaymentMethod {
    fn from(item: payment_method_data::ApplepayPaymentMethod) -> Self {
        Self {
            display_name: item.display_name,
            network: item.network,
            pm_type: item.pm_type,
        }
    }
}

impl TryFrom<&types::PaymentsSessionRouterData> for BluesnapCreateWalletToken {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::PaymentsSessionRouterData) -> Result<Self, Self::Error> {
        let apple_pay_metadata = item.get_connector_meta()?.expose();
        let applepay_metadata = apple_pay_metadata
            .clone()
            .parse_value::<ApplepayCombinedSessionTokenData>("ApplepayCombinedSessionTokenData")
            .map(|combined_metadata| {
                ApplepaySessionTokenMetadata::ApplePayCombined(combined_metadata.apple_pay_combined)
            })
            .or_else(|_| {
                apple_pay_metadata
                    .parse_value::<ApplepaySessionTokenData>("ApplepaySessionTokenData")
                    .map(|old_metadata| {
                        ApplepaySessionTokenMetadata::ApplePay(old_metadata.apple_pay)
                    })
            })
            .change_context(errors::ConnectorError::ParsingFailed)?;
        let session_token_data = match applepay_metadata {
            ApplepaySessionTokenMetadata::ApplePay(apple_pay_data) => {
                Ok(apple_pay_data.session_token_data)
            }
            ApplepaySessionTokenMetadata::ApplePayCombined(_apple_pay_combined_data) => {
                Err(errors::ConnectorError::FlowNotSupported {
                    flow: "apple pay combined".to_string(),
                    connector: "bluesnap".to_string(),
                })
            }
        }?;
        let domain_name = session_token_data.initiative_context.ok_or(
            errors::ConnectorError::MissingRequiredField {
                field_name: "apple pay initiative_context",
            },
        )?;

        Ok(Self {
            wallet_type: "APPLE_PAY".to_string(),
            validation_url: APPLEPAY_VALIDATION_URL.to_string().into(),
            domain_name,
            display_name: Some(session_token_data.display_name),
        })
    }
}

impl
    ForeignTryFrom<(
        PaymentsSessionResponseRouterData<BluesnapWalletTokenResponse>,
        StringMajorUnit,
    )> for types::PaymentsSessionRouterData
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn foreign_try_from(
        (item, apple_pay_amount): (
            PaymentsSessionResponseRouterData<BluesnapWalletTokenResponse>,
            StringMajorUnit,
        ),
    ) -> Result<Self, Self::Error> {
        let response = &item.response;

        let wallet_token = BASE64_ENGINE
            .decode(response.wallet_token.clone().expose())
            .change_context(errors::ConnectorError::ResponseHandlingFailed)?;

        let session_response: NoThirdPartySdkSessionResponse = wallet_token
            .parse_struct("NoThirdPartySdkSessionResponse")
            .change_context(errors::ConnectorError::ParsingFailed)?;

        let metadata = item.data.get_connector_meta()?.expose();
        let applepay_metadata = metadata
            .clone()
            .parse_value::<ApplepayCombinedSessionTokenData>("ApplepayCombinedSessionTokenData")
            .map(|combined_metadata| {
                ApplepaySessionTokenMetadata::ApplePayCombined(combined_metadata.apple_pay_combined)
            })
            .or_else(|_| {
                metadata
                    .parse_value::<ApplepaySessionTokenData>("ApplepaySessionTokenData")
                    .map(|old_metadata| {
                        ApplepaySessionTokenMetadata::ApplePay(old_metadata.apple_pay)
                    })
            })
            .change_context(errors::ConnectorError::ParsingFailed)?;

        let (payment_request_data, session_token_data) = match applepay_metadata {
            ApplepaySessionTokenMetadata::ApplePayCombined(_apple_pay_combined) => {
                Err(errors::ConnectorError::FlowNotSupported {
                    flow: "apple pay combined".to_string(),
                    connector: "bluesnap".to_string(),
                })
            }
            ApplepaySessionTokenMetadata::ApplePay(apple_pay) => {
                Ok((apple_pay.payment_request_data, apple_pay.session_token_data))
            }
        }?;

        Ok(Self {
            response: Ok(PaymentsResponseData::SessionResponse {
                session_token: SessionToken::ApplePay(Box::new(ApplepaySessionTokenResponse {
                    session_token_data: Some(ApplePaySessionResponse::NoThirdPartySdk(
                        session_response,
                    )),
                    payment_request_data: Some(ApplePayPaymentRequest {
                        country_code: item.data.get_billing_country()?,
                        currency_code: item.data.request.currency,
                        total: AmountInfo {
                            label: payment_request_data.label,
                            total_type: Some("final".to_string()),
                            amount: apple_pay_amount,
                        },
                        merchant_capabilities: Some(payment_request_data.merchant_capabilities),
                        supported_networks: Some(payment_request_data.supported_networks),
                        merchant_identifier: Some(session_token_data.merchant_identifier),
                        required_billing_contact_fields: None,
                        required_shipping_contact_fields: None,
                        recurring_payment_request: None,
                    }),
                    connector: "bluesnap".to_string(),
                    delayed_session_token: false,
                    sdk_next_action: {
                        SdkNextAction {
                            next_action: NextActionCall::Confirm,
                        }
                    },
                    connector_reference_id: None,
                    connector_sdk_public_key: None,
                    connector_merchant_id: None,
                })),
            }),
            ..item.data
        })
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapCompletePaymentsRequest {
    amount: StringMajorUnit,
    currency: enums::Currency,
    card_transaction_type: BluesnapTxnType,
    pf_token: Secret<String>,
    three_d_secure: Option<BluesnapThreeDSecureInfo>,
    transaction_fraud_info: Option<TransactionFraudInfo>,
    card_holder_info: Option<BluesnapCardHolderInfo>,
    merchant_transaction_id: Option<String>,
    transaction_meta_data: Option<BluesnapMetadata>,
}

impl TryFrom<&BluesnapRouterData<&types::PaymentsCompleteAuthorizeRouterData>>
    for BluesnapCompletePaymentsRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BluesnapRouterData<&types::PaymentsCompleteAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        let redirection_response: BluesnapRedirectionResponse = item
            .router_data
            .request
            .redirect_response
            .as_ref()
            .and_then(|res| res.payload.to_owned())
            .ok_or(errors::ConnectorError::MissingConnectorRedirectionPayload {
                field_name: "request.redirect_response.payload",
            })?
            .parse_value("BluesnapRedirectionResponse")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

        let transaction_meta_data =
            item.router_data
                .request
                .metadata
                .as_ref()
                .map(|metadata| BluesnapMetadata {
                    meta_data: convert_metadata_to_request_metadata(metadata.to_owned()),
                });

        let token = item
            .router_data
            .request
            .redirect_response
            .clone()
            .and_then(|res| res.params.to_owned())
            .ok_or(errors::ConnectorError::MissingConnectorRedirectionPayload {
                field_name: "request.redirect_response.params",
            })?
            .peek()
            .split_once('=')
            .ok_or(errors::ConnectorError::MissingConnectorRedirectionPayload {
                field_name: "request.redirect_response.params.paymentToken",
            })?
            .1
            .to_string();

        let redirection_result: BluesnapThreeDsResult = redirection_response
            .authentication_response
            .parse_struct("BluesnapThreeDsResult")
            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

        let auth_mode = match item.router_data.request.capture_method {
            Some(enums::CaptureMethod::Manual) => BluesnapTxnType::AuthOnly,
            _ => BluesnapTxnType::AuthCapture,
        };
        Ok(Self {
            amount: item.amount.to_owned(),
            currency: item.router_data.request.currency,
            card_transaction_type: auth_mode,
            three_d_secure: Some(BluesnapThreeDSecureInfo {
                three_d_secure_reference_id: redirection_result
                    .three_d_secure
                    .ok_or(errors::ConnectorError::MissingConnectorRedirectionPayload {
                        field_name: "three_d_secure_reference_id",
                    })?
                    .three_d_secure_reference_id,
            }),
            transaction_fraud_info: Some(TransactionFraudInfo {
                fraud_session_id: item.router_data.payment_id.clone(),
            }),
            card_holder_info: get_card_holder_info(
                item.router_data.get_billing_address()?,
                item.router_data.request.get_email()?,
            )?,
            merchant_transaction_id: Some(item.router_data.connector_request_reference_id.clone()),
            pf_token: Secret::new(token),
            transaction_meta_data,
        })
    }
}

#[derive(Debug, Deserialize)]
pub struct BluesnapRedirectionResponse {
    pub authentication_response: String,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapThreeDsResult {
    three_d_secure: Option<BluesnapThreeDsReference>,
    pub status: String,
    pub code: Option<String>,
    pub info: Option<RedirectErrorMessage>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RedirectErrorMessage {
    pub errors: Option<Vec<String>>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapThreeDsReference {
    three_d_secure_reference_id: String,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapVoidRequest {
    card_transaction_type: BluesnapTxnType,
    transaction_id: String,
}

impl TryFrom<&types::PaymentsCancelRouterData> for BluesnapVoidRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
        let card_transaction_type = BluesnapTxnType::AuthReversal;
        let transaction_id = item.request.connector_transaction_id.to_string();
        Ok(Self {
            card_transaction_type,
            transaction_id,
        })
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapCaptureRequest {
    card_transaction_type: BluesnapTxnType,
    transaction_id: String,
    amount: Option<StringMajorUnit>,
}

impl TryFrom<&BluesnapRouterData<&types::PaymentsCaptureRouterData>> for BluesnapCaptureRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BluesnapRouterData<&types::PaymentsCaptureRouterData>,
    ) -> Result<Self, Self::Error> {
        let card_transaction_type = BluesnapTxnType::Capture;
        let transaction_id = item
            .router_data
            .request
            .connector_transaction_id
            .to_string();
        Ok(Self {
            card_transaction_type,
            transaction_id,
            amount: Some(item.amount.to_owned()),
        })
    }
}

// Auth Struct
pub struct BluesnapAuthType {
    pub(super) api_key: Secret<String>,
    pub(super) key1: Secret<String>,
}

impl TryFrom<&ConnectorAuthType> for BluesnapAuthType {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        if let ConnectorAuthType::BodyKey { api_key, key1 } = auth_type {
            Ok(Self {
                api_key: api_key.to_owned(),
                key1: key1.to_owned(),
            })
        } else {
            Err(errors::ConnectorError::FailedToObtainAuthType.into())
        }
    }
}

// PaymentsResponse
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum BluesnapTxnType {
    AuthOnly,
    AuthCapture,
    AuthReversal,
    Capture,
    Refund,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum BluesnapProcessingStatus {
    #[serde(alias = "success")]
    Success,
    #[default]
    #[serde(alias = "pending")]
    Pending,
    #[serde(alias = "fail")]
    Fail,
    #[serde(alias = "pending_merchant_review")]
    PendingMerchantReview,
}

impl ForeignTryFrom<(BluesnapTxnType, BluesnapProcessingStatus)> for enums::AttemptStatus {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn foreign_try_from(
        item: (BluesnapTxnType, BluesnapProcessingStatus),
    ) -> Result<Self, Self::Error> {
        let (item_txn_status, item_processing_status) = item;
        Ok(match item_processing_status {
            BluesnapProcessingStatus::Success => match item_txn_status {
                BluesnapTxnType::AuthOnly => Self::Authorized,
                BluesnapTxnType::AuthReversal => Self::Voided,
                BluesnapTxnType::AuthCapture | BluesnapTxnType::Capture => Self::Charged,
                BluesnapTxnType::Refund => Self::Charged,
            },
            BluesnapProcessingStatus::Pending | BluesnapProcessingStatus::PendingMerchantReview => {
                Self::Pending
            }
            BluesnapProcessingStatus::Fail => Self::Failure,
        })
    }
}

impl From<BluesnapProcessingStatus> for enums::RefundStatus {
    fn from(item: BluesnapProcessingStatus) -> Self {
        match item {
            BluesnapProcessingStatus::Success => Self::Success,
            BluesnapProcessingStatus::Pending => Self::Pending,
            BluesnapProcessingStatus::PendingMerchantReview => Self::ManualReview,
            BluesnapProcessingStatus::Fail => Self::Failure,
        }
    }
}

impl From<BluesnapRefundStatus> for enums::RefundStatus {
    fn from(item: BluesnapRefundStatus) -> Self {
        match item {
            BluesnapRefundStatus::Success => Self::Success,
            BluesnapRefundStatus::Pending => Self::Pending,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapPaymentsResponse {
    pub processing_info: ProcessingInfoResponse,
    pub transaction_id: String,
    pub card_transaction_type: BluesnapTxnType,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapWalletTokenResponse {
    wallet_type: String,
    wallet_token: Secret<String>,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Refund {
    refund_transaction_id: String,
    amount: StringMajorUnit,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProcessingInfoResponse {
    pub processing_status: BluesnapProcessingStatus,
    pub authorization_code: Option<String>,
    pub network_transaction_id: Option<Secret<String>>,
}

impl<F, T> TryFrom<ResponseRouterData<F, BluesnapPaymentsResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, BluesnapPaymentsResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            status: enums::AttemptStatus::foreign_try_from((
                item.response.card_transaction_type,
                item.response.processing_info.processing_status,
            ))?,
            response: Ok(PaymentsResponseData::TransactionResponse {
                resource_id: ResponseId::ConnectorTransactionId(
                    item.response.transaction_id.clone(),
                ),
                redirection_data: Box::new(None),
                mandate_reference: Box::new(None),
                connector_metadata: None,
                network_txn_id: None,
                connector_response_reference_id: Some(item.response.transaction_id),
                incremental_authorization_allowed: None,
                charges: None,
            }),
            ..item.data
        })
    }
}

#[derive(Default, Debug, Serialize)]
pub struct BluesnapRefundRequest {
    amount: Option<StringMajorUnit>,
    reason: Option<String>,
}

impl<F> TryFrom<&BluesnapRouterData<&types::RefundsRouterData<F>>> for BluesnapRefundRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &BluesnapRouterData<&types::RefundsRouterData<F>>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            reason: item.router_data.request.reason.clone(),
            amount: Some(item.amount.to_owned()),
        })
    }
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum BluesnapRefundStatus {
    Success,
    #[default]
    Pending,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RefundResponse {
    refund_transaction_id: i32,
    refund_status: BluesnapRefundStatus,
}

impl TryFrom<RefundsResponseRouterData<RSync, BluesnapPaymentsResponse>>
    for types::RefundsRouterData<RSync>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<RSync, BluesnapPaymentsResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.transaction_id.clone(),
                refund_status: enums::RefundStatus::from(
                    item.response.processing_info.processing_status,
                ),
            }),
            ..item.data
        })
    }
}

impl TryFrom<RefundsResponseRouterData<Execute, RefundResponse>>
    for types::RefundsRouterData<Execute>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<Execute, RefundResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.refund_transaction_id.to_string(),
                refund_status: enums::RefundStatus::from(item.response.refund_status),
            }),
            ..item.data
        })
    }
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapWebhookBody {
    pub merchant_transaction_id: String,
    pub reference_number: String,
    pub transaction_type: BluesnapWebhookEvents,
    pub reversal_ref_num: Option<String>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapWebhookObjectEventType {
    transaction_type: BluesnapWebhookEvents,
    cb_status: Option<BluesnapChargebackStatus>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum BluesnapChargebackStatus {
    #[serde(alias = "New")]
    New,
    #[serde(alias = "Working")]
    Working,
    #[serde(alias = "Closed")]
    Closed,
    #[serde(alias = "Completed_Lost")]
    CompletedLost,
    #[serde(alias = "Completed_Pending")]
    CompletedPending,
    #[serde(alias = "Completed_Won")]
    CompletedWon,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum BluesnapWebhookEvents {
    Decline,
    CcChargeFailed,
    Charge,
    Refund,
    Chargeback,
    ChargebackStatusChanged,
    #[serde(other)]
    Unknown,
}

impl TryFrom<BluesnapWebhookObjectEventType> for IncomingWebhookEvent {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(details: BluesnapWebhookObjectEventType) -> Result<Self, Self::Error> {
        match details.transaction_type {
            BluesnapWebhookEvents::Decline | BluesnapWebhookEvents::CcChargeFailed => {
                Ok(Self::PaymentIntentFailure)
            }
            BluesnapWebhookEvents::Charge => Ok(Self::PaymentIntentSuccess),
            BluesnapWebhookEvents::Refund => Ok(Self::RefundSuccess),
            BluesnapWebhookEvents::Chargeback | BluesnapWebhookEvents::ChargebackStatusChanged => {
                match details
                    .cb_status
                    .ok_or(errors::ConnectorError::WebhookEventTypeNotFound)?
                {
                    BluesnapChargebackStatus::New | BluesnapChargebackStatus::Working => {
                        Ok(Self::DisputeOpened)
                    }
                    BluesnapChargebackStatus::Closed => Ok(Self::DisputeExpired),
                    BluesnapChargebackStatus::CompletedLost => Ok(Self::DisputeLost),
                    BluesnapChargebackStatus::CompletedPending => Ok(Self::DisputeChallenged),
                    BluesnapChargebackStatus::CompletedWon => Ok(Self::DisputeWon),
                }
            }
            BluesnapWebhookEvents::Unknown => Ok(Self::EventNotSupported),
        }
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapDisputeWebhookBody {
    pub invoice_charge_amount: FloatMajorUnit,
    pub currency: enums::Currency,
    pub reversal_reason: Option<String>,
    pub reversal_ref_num: String,
    pub cb_status: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapWebhookObjectResource {
    reference_number: String,
    transaction_type: BluesnapWebhookEvents,
    reversal_ref_num: Option<String>,
}

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


// Implementation: impl Tokenizable for for SetupMandateRequestData
// File: crates/router/src/types.rs
// Module: router
// Methods: 1 total (0 public)

impl Tokenizable for for SetupMandateRequestData


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

impl Responder


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

impl api::PaymentSync for for Shift4


// Implementation: impl ConfigInterface for for KafkaStore
// File: crates/router/src/db/kafka_store.rs
// Module: router
// Methods: 7 total (0 public)

impl ConfigInterface for for KafkaStore


    }

    #[cfg(feature = "v1")]
    fn get_payment_intent_profile_id(&self) -> Option<&id_type::ProfileId> {
        self.payment_intent.profile_id.as_ref()
    }

    #[cfg(feature = "v2")]
    fn get_payment_intent_profile_id(&self) -> Option<&id_type::ProfileId> {
        Some(&self.payment_intent.profile_id)
    }

    fn get_currency(&self) -> storage_enums::Currency {
        self.currency
    }

    fn get_amount(&self) -> api::Amount {
        self.amount
    }

    fn get_payment_attempt_connector(&self) -> Option<&str> {
        self.payment_attempt.connector.as_deref()
    }

    fn get_billing_address(&self) -> Option<hyperswitch_domain_models::address::Address> {
        self.address.get_payment_method_billing().cloned()
    }

    fn get_payment_method_data(&self) -> Option<&domain::PaymentMethodData> {
        self.payment_method_data.as_ref()
    }

    fn get_sessions_token(&self) -> Vec<api::SessionToken> {
        self.sessions_token.clone()
    }

    fn get_token_data(&self) -> Option<&storage::PaymentTokenData> {
        self.token_data.as_ref()
    }

    fn get_mandate_connector(&self) -> Option<&MandateConnectorDetails> {
        self.mandate_connector.as_ref()
    }

    fn get_force_sync(&self) -> Option<bool> {
        self.force_sync
    }

    fn get_all_keys_required(&self) -> Option<bool> {
        self.all_keys_required
    }

    fn get_whole_connector_response(&self) -> Option<Secret<String>> {
        self.whole_connector_response.clone()
    }

    #[cfg(feature = "v1")]
    fn get_capture_method(&self) -> Option<enums::CaptureMethod> {
        self.payment_attempt.capture_method
    }

    #[cfg(feature = "v1")]
    fn get_vault_operation(&self) -> Option<&domain_payments::VaultOperation> {
        self.vault_operation.as_ref()
    }

    fn get_connector_customer_id(&self) -> Option<String> {
        self.connector_customer_id.clone()
    }

    fn get_click_to_pay_service_details(&self) -> Option<&api_models::payments::CtpServiceDetails> {
        self.service_details.as_ref()
    }

    fn get_is_manual_retry_enabled(&self) -> Option<bool> {
        self.is_manual_retry_enabled
    }

    // #[cfg(feature = "v2")]
    // fn get_capture_method(&self) -> Option<enums::CaptureMethod> {
    //     Some(self.payment_intent.capture_method)
    // }

    // #[cfg(feature = "v2")]
    // fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> {
    //     todo!();
    // }
}

#[cfg(feature = "v1")]
impl<F: Clone> OperationSessionSetters<F> for PaymentData<F> {
    // Setters Implementation
    fn set_payment_intent(&mut self, payment_intent: storage::PaymentIntent) {
        self.payment_intent = payment_intent;
    }

    fn set_payment_attempt(&mut self, payment_attempt: storage::PaymentAttempt) {
        self.payment_attempt = payment_attempt;
    }

    fn set_payment_method_data(&mut self, payment_method_data: Option<domain::PaymentMethodData>) {
        self.payment_method_data = payment_method_data;
    }

    fn set_payment_method_token(&mut self, payment_method_token: Option<PaymentMethodToken>) {
        self.payment_method_token = payment_method_token;
    }

    fn set_payment_method_id_in_attempt(&mut self, payment_method_id: Option<String>) {
        self.payment_attempt.payment_method_id = payment_method_id;
    }

    fn set_email_if_not_present(&mut self, email: pii::Email) {
        self.email = self.email.clone().or(Some(email));
    }

    fn set_pm_token(&mut self, token: String) {
        self.pm_token = Some(token);
    }

    fn set_connector_customer_id(&mut self, customer_id: Option<String>) {
        self.connector_customer_id = customer_id;
    }

    fn push_sessions_token(&mut self, token: api::SessionToken) {
        self.sessions_token.push(token);
    }

    fn set_surcharge_details(&mut self, surcharge_details: Option<types::SurchargeDetails>) {
        self.surcharge_details = surcharge_details;
    }

    fn set_merchant_connector_id_in_attempt(
        &mut self,
        merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    ) {
        self.payment_attempt.merchant_connector_id = merchant_connector_id;
    }

    fn set_card_network(&mut self, card_network: enums::CardNetwork) {
        match &mut self.payment_method_data {
            Some(domain::PaymentMethodData::Card(card)) => {
                logger::debug!("Setting card network: {:?}", card_network);
                card.card_network = Some(card_network);
            }
            Some(domain::PaymentMethodData::Wallet(wallet_data)) => match wallet_data {
                hyperswitch_domain_models::payment_method_data::WalletData::ApplePay(wallet) => {
                    logger::debug!("Setting Apple Pay card network: {:?}", card_network);
                    wallet.payment_method.network = card_network.to_string();
                }
                _ => {
                    logger::debug!("Wallet type does not support setting card network.");
                }
            },
            _ => {
                logger::warn!("Payment method data does not support setting card network.");
            }
        }
    }

    fn set_co_badged_card_data(
        &mut self,
        debit_routing_output: &api_models::open_router::DebitRoutingOutput,
    ) {
        let co_badged_card_data =
            api_models::payment_methods::CoBadgedCardData::from(debit_routing_output);
        let card_type = debit_routing_output
            .card_type
            .clone()
            .to_string()
            .to_uppercase();
        if let Some(domain::PaymentMethodData::Card(card)) = &mut self.payment_method_data {
            card.co_badged_card_data = Some(co_badged_card_data);
            card.card_type = Some(card_type);
            logger::debug!("set co-badged card data in payment method data");
        };
    }

    #[cfg(feature = "v1")]
    fn set_capture_method_in_attempt(&mut self, capture_method: enums::CaptureMethod) {
        self.payment_attempt.capture_method = Some(capture_method);
    }

    fn set_frm_message(&mut self, frm_message: FraudCheck) {
        self.frm_message = Some(frm_message);
    }

    fn set_payment_intent_status(&mut self, status: storage_enums::IntentStatus) {
        self.payment_intent.status = status;
    }

    fn set_authentication_type_in_attempt(
        &mut self,
        authentication_type: Option<enums::AuthenticationType>,
    ) {
        self.payment_attempt.authentication_type = authentication_type;
    }

    fn set_recurring_mandate_payment_data(
        &mut self,
        recurring_mandate_payment_data:
            hyperswitch_domain_models::router_data::RecurringMandatePaymentData,
    ) {
        self.recurring_mandate_payment_data = Some(recurring_mandate_payment_data);
    }

    fn set_mandate_id(&mut self, mandate_id: api_models::payments::MandateIds) {
        self.mandate_id = Some(mandate_id);
    }

    #[cfg(feature = "v1")]
    fn set_setup_future_usage_in_payment_intent(
        &mut self,
        setup_future_usage: storage_enums::FutureUsage,
    ) {
        self.payment_intent.setup_future_usage = Some(setup_future_usage);
    }

    #[cfg(feature = "v2")]
    fn set_setup_future_usage_in_payment_intent(
        &mut self,
        setup_future_usage: storage_enums::FutureUsage,
    ) {
        self.payment_intent.setup_future_usage = setup_future_usage;
    }

    #[cfg(feature = "v1")]
    fn set_straight_through_algorithm_in_payment_attempt(
        &mut self,
        straight_through_algorithm: serde_json::Value,
    ) {
        self.payment_attempt.straight_through_algorithm = Some(straight_through_algorithm);
    }

    fn set_connector_in_payment_attempt(&mut self, connector: Option<String>) {
        self.payment_attempt.connector = connector;
    }

    fn set_vault_operation(&mut self, vault_operation: domain_payments::VaultOperation) {
        self.vault_operation = Some(vault_operation);
    }

    fn set_routing_approach_in_attempt(
        &mut self,
        routing_approach: Option<enums::RoutingApproach>,
    ) {
        self.payment_attempt.routing_approach = routing_approach;
    }

    fn set_connector_response_reference_id(&mut self, reference_id: Option<String>) {
        self.payment_attempt.connector_response_reference_id = reference_id;
    }

    fn set_connector_request_reference_id_in_payment_attempt(
        &mut self,
        connector_request_reference_id: String,
    ) {
        self.payment_attempt.connector_request_reference_id = Some(connector_request_reference_id);
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionGetters<F> for PaymentIntentData<F> {
    fn get_payment_attempt(&self) -> &storage::PaymentAttempt {
        todo!()
    }
    #[cfg(feature = "v2")]
    fn list_payments_attempts(&self) -> &Vec<storage::PaymentAttempt> {
        todo!()
    }

    fn get_client_secret(&self) -> &Option<Secret<String>> {
        &self.client_secret
    }

    fn get_payment_intent(&self) -> &storage::PaymentIntent {
        &self.payment_intent
    }

    fn get_payment_method_info(&self) -> Option<&domain::PaymentMethod> {
        todo!()
    }

    fn get_payment_method_token(&self) -> Option<&PaymentMethodToken> {
        todo!()
    }

    fn get_mandate_id(&self) -> Option<&payments_api::MandateIds> {
        todo!()
    }

    // what is this address find out and not required remove this
    fn get_address(&self) -> &PaymentAddress {
        todo!()
    }

    fn get_creds_identifier(&self) -> Option<&str> {
        todo!()
    }

    fn get_token(&self) -> Option<&str> {
        todo!()
    }

    fn get_multiple_capture_data(&self) -> Option<&types::MultipleCaptureData> {
        todo!()
    }

    fn get_payment_link_data(&self) -> Option<api_models::payments::PaymentLinkResponse> {
        todo!()
    }

    fn get_ephemeral_key(&self) -> Option<ephemeral_key::EphemeralKey> {
        todo!()
    }

    fn get_setup_mandate(&self) -> Option<&MandateData> {
        todo!()
    }

    fn get_poll_config(&self) -> Option<router_types::PollConfig> {
        todo!()
    }

    fn get_authentication(
        &self,
    ) -> Option<&hyperswitch_domain_models::router_request_types::authentication::AuthenticationStore>
    {
        todo!()
    }

    fn get_frm_message(&self) -> Option<FraudCheck> {
        todo!()
    }

    fn get_refunds(&self) -> Vec<diesel_refund::Refund> {
        todo!()
    }

    fn get_disputes(&self) -> Vec<storage::Dispute> {
        todo!()
    }

    fn get_authorizations(&self) -> Vec<diesel_models::authorization::Authorization> {
        todo!()
    }

    fn get_attempts(&self) -> Option<Vec<storage::PaymentAttempt>> {
        todo!()
    }

    fn get_recurring_details(&self) -> Option<&RecurringDetails> {
        todo!()
    }

    fn get_payment_intent_profile_id(&self) -> Option<&id_type::ProfileId> {
        Some(&self.payment_intent.profile_id)
    }

    fn get_currency(&self) -> storage_enums::Currency {
        self.payment_intent.amount_details.currency
    }

    fn get_amount(&self) -> api::Amount {
        todo!()
    }

    fn get_payment_attempt_connector(&self) -> Option<&str> {
        todo!()
    }

    fn get_merchant_connector_id_in_attempt(&self) -> Option<id_type::MerchantConnectorAccountId> {
        todo!()
    }

    fn get_connector_customer_id(&self) -> Option<String> {
        self.connector_customer_id.clone()
    }

    fn get_merchant_connector_details(
        &self,
    ) -> Option<common_types::domain::MerchantConnectorAuthDetails> {
        todo!()
    }

    fn get_billing_address(&self) -> Option<hyperswitch_domain_models::address::Address> {
        todo!()
    }

    fn get_payment_method_data(&self) -> Option<&domain::PaymentMethodData> {
        todo!()
    }

    fn get_sessions_token(&self) -> Vec<api::SessionToken> {
        self.sessions_token.clone()
    }

    fn get_token_data(&self) -> Option<&storage::PaymentTokenData> {
        todo!()
    }

    fn get_mandate_connector(&self) -> Option<&MandateConnectorDetails> {
        todo!()
    }

    fn get_force_sync(&self) -> Option<bool> {
        todo!()
    }

    fn get_capture_method(&self) -> Option<enums::CaptureMethod> {
        todo!()
    }

    fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> {
        todo!();
    }

    fn get_pre_routing_result(
        &self,
    ) -> Option<HashMap<enums::PaymentMethodType, domain::PreRoutingConnectorChoice>> {
        None
    }

    fn get_optional_external_vault_session_details(&self) -> Option<api::VaultSessionDetails> {
        self.vault_session_details.clone()
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionSetters<F> for PaymentIntentData<F> {
    fn set_prerouting_algorithm_in_payment_intent(
        &mut self,
        straight_through_algorithm: storage::PaymentRoutingInfo,
    ) {
        self.payment_intent.prerouting_algorithm = Some(straight_through_algorithm);
    }
    // Setters Implementation
    fn set_payment_intent(&mut self, payment_intent: storage::PaymentIntent) {
        self.payment_intent = payment_intent;
    }
    fn set_client_secret(&mut self, client_secret: Option<Secret<String>>) {
        self.client_secret = client_secret;
    }
    fn set_payment_attempt(&mut self, _payment_attempt: storage::PaymentAttempt) {
        todo!()
    }

    fn set_payment_method_data(&mut self, _payment_method_data: Option<domain::PaymentMethodData>) {
        todo!()
    }

    fn set_payment_method_token(&mut self, _payment_method_token: Option<PaymentMethodToken>) {
        todo!()
    }

    fn set_payment_method_id_in_attempt(&mut self, _payment_method_id: Option<String>) {
        todo!()
    }

    fn set_card_network(&mut self, card_network: enums::CardNetwork) {
        todo!()
    }

    fn set_co_badged_card_data(
        &mut self,
        debit_routing_output: &api_models::open_router::DebitRoutingOutput,
    ) {
        todo!()
    }

    fn set_email_if_not_present(&mut self, _email: pii::Email) {
        todo!()
    }

    fn set_pm_token(&mut self, _token: String) {
        todo!()
    }

    fn set_connector_customer_id(&mut self, customer_id: Option<String>) {
        self.connector_customer_id = customer_id;
    }

    fn push_sessions_token(&mut self, token: api::SessionToken) {
        self.sessions_token.push(token);
    }

    fn set_surcharge_details(&mut self, _surcharge_details: Option<types::SurchargeDetails>) {
        todo!()
    }

    fn set_merchant_connector_id_in_attempt(
        &mut self,
        merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    ) {
        todo!()
    }

    fn set_frm_message(&mut self, _frm_message: FraudCheck) {
        todo!()
    }

    fn set_payment_intent_status(&mut self, status: storage_enums::IntentStatus) {
        self.payment_intent.status = status;
    }

    fn set_authentication_type_in_attempt(
        &mut self,
        _authentication_type: Option<enums::AuthenticationType>,
    ) {
        todo!()
    }

    fn set_recurring_mandate_payment_data(
        &mut self,
        _recurring_mandate_payment_data:
            hyperswitch_domain_models::router_data::RecurringMandatePaymentData,
    ) {
        todo!()
    }

    fn set_mandate_id(&mut self, _mandate_id: api_models::payments::MandateIds) {
        todo!()
    }

    fn set_setup_future_usage_in_payment_intent(
        &mut self,
        setup_future_usage: storage_enums::FutureUsage,
    ) {
        self.payment_intent.setup_future_usage = setup_future_usage;
    }

    fn set_connector_in_payment_attempt(&mut self, _connector: Option<String>) {
        todo!()
    }

    fn set_connector_request_reference_id(&mut self, reference_id: Option<String>) {
        todo!()
    }

    fn set_connector_response_reference_id(&mut self, reference_id: Option<String>) {
        todo!()
    }

    fn set_vault_session_details(
        &mut self,
        vault_session_details: Option<api::VaultSessionDetails>,
    ) {
        self.vault_session_details = vault_session_details;
    }

    fn set_routing_approach_in_attempt(
        &mut self,
        routing_approach: Option<enums::RoutingApproach>,
    ) {
        todo!()
    }

    fn set_connector_request_reference_id_in_payment_attempt(
        &mut self,
        connector_request_reference_id: String,
    ) {
        todo!()
    }

    fn set_cancellation_reason(&mut self, cancellation_reason: Option<String>) {
        todo!()
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionGetters<F> for PaymentConfirmData<F> {
    fn get_payment_attempt(&self) -> &storage::PaymentAttempt {
        &self.payment_attempt
    }
    #[cfg(feature = "v2")]
    fn list_payments_attempts(&self) -> &Vec<storage::PaymentAttempt> {
        todo!()
    }
    fn get_client_secret(&self) -> &Option<Secret<String>> {
        todo!()
    }

    fn get_payment_intent(&self) -> &storage::PaymentIntent {
        &self.payment_intent
    }

    fn get_merchant_connector_details(
        &self,
    ) -> Option<common_types::domain::MerchantConnectorAuthDetails> {
        self.merchant_connector_details.clone()
    }

    fn get_payment_method_info(&self) -> Option<&domain::PaymentMethod> {
        todo!()
    }

    fn get_payment_method_token(&self) -> Option<&PaymentMethodToken> {
        todo!()
    }

    fn get_mandate_id(&self) -> Option<&payments_api::MandateIds> {
        todo!()
    }

    fn get_address(&self) -> &PaymentAddress {
        &self.payment_address
    }

    fn get_creds_identifier(&self) -> Option<&str> {
        None
    }

    fn get_token(&self) -> Option<&str> {
        todo!()
    }

    fn get_multiple_capture_data(&self) -> Option<&types::MultipleCaptureData> {
        todo!()
    }

    fn get_payment_link_data(&self) -> Option<api_models::payments::PaymentLinkResponse> {
        todo!()
    }

    fn get_ephemeral_key(&self) -> Option<ephemeral_key::EphemeralKey> {
        todo!()
    }

    fn get_setup_mandate(&self) -> Option<&MandateData> {
        todo!()
    }

    fn get_poll_config(&self) -> Option<router_types::PollConfig> {
        todo!()
    }

    fn get_authentication(
        &self,
    ) -> Option<&hyperswitch_domain_models::router_request_types::authentication::AuthenticationStore>
    {
        todo!()
    }

    fn get_frm_message(&self) -> Option<FraudCheck> {
        todo!()
    }

    fn get_refunds(&self) -> Vec<diesel_refund::Refund> {
        todo!()
    }

    fn get_disputes(&self) -> Vec<storage::Dispute> {
        todo!()
    }

    fn get_authorizations(&self) -> Vec<diesel_models::authorization::Authorization> {
        todo!()
    }

    fn get_attempts(&self) -> Option<Vec<storage::PaymentAttempt>> {
        todo!()
    }

    fn get_recurring_details(&self) -> Option<&RecurringDetails> {
        todo!()
    }

    fn get_payment_intent_profile_id(&self) -> Option<&id_type::ProfileId> {
        Some(&self.payment_intent.profile_id)
    }

    fn get_currency(&self) -> storage_enums::Currency {
        self.payment_intent.amount_details.currency
    }

    fn get_amount(&self) -> api::Amount {
        todo!()
    }

    fn get_payment_attempt_connector(&self) -> Option<&str> {
        self.payment_attempt.connector.as_deref()
    }

    fn get_merchant_connector_id_in_attempt(&self) -> Option<id_type::MerchantConnectorAccountId> {
        self.payment_attempt.merchant_connector_id.clone()
    }

    fn get_connector_customer_id(&self) -> Option<String> {
        todo!()
    }

    fn get_billing_address(&self) -> Option<hyperswitch_domain_models::address::Address> {
        todo!()
    }

    fn get_payment_method_data(&self) -> Option<&domain::PaymentMethodData> {
        self.payment_method_data.as_ref()
    }

    fn get_sessions_token(&self) -> Vec<api::SessionToken> {
        todo!()
    }

    fn get_token_data(&self) -> Option<&storage::PaymentTokenData> {
        todo!()
    }

    fn get_mandate_connector(&self) -> Option<&MandateConnectorDetails> {
        todo!()
    }

    fn get_force_sync(&self) -> Option<bool> {
        todo!()
    }

    fn get_capture_method(&self) -> Option<enums::CaptureMethod> {
        todo!()
    }

    fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> {
        Some(&self.payment_attempt)
    }

    fn get_pre_routing_result(
        &self,
    ) -> Option<HashMap<enums::PaymentMethodType, domain::PreRoutingConnectorChoice>> {
        self.get_payment_intent()
            .prerouting_algorithm
            .clone()
            .and_then(|pre_routing_algorithm| pre_routing_algorithm.pre_routing_results)
    }

    fn get_optional_external_vault_session_details(&self) -> Option<api::VaultSessionDetails> {
        todo!()
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionSetters<F> for PaymentConfirmData<F> {
    #[cfg(feature = "v2")]
    fn set_prerouting_algorithm_in_payment_intent(
        &mut self,
        straight_through_algorithm: storage::PaymentRoutingInfo,
    ) {
        self.payment_intent.prerouting_algorithm = Some(straight_through_algorithm);
    }
    // Setters Implementation
    fn set_payment_intent(&mut self, payment_intent: storage::PaymentIntent) {
        self.payment_intent = payment_intent;
    }
    fn set_client_secret(&mut self, client_secret: Option<Secret<String>>) {
        todo!()
    }
    fn set_payment_attempt(&mut self, payment_attempt: storage::PaymentAttempt) {
        self.payment_attempt = payment_attempt;
    }

    fn set_payment_method_data(&mut self, _payment_method_data: Option<domain::PaymentMethodData>) {
        todo!()
    }

    fn set_payment_method_token(&mut self, _payment_method_token: Option<PaymentMethodToken>) {
        todo!()
    }

    fn set_payment_method_id_in_attempt(&mut self, _payment_method_id: Option<String>) {
        todo!()
    }

    fn set_email_if_not_present(&mut self, _email: pii::Email) {
        todo!()
    }

    fn set_pm_token(&mut self, _token: String) {
        todo!()
    }

    fn set_connector_customer_id(&mut self, _customer_id: Option<String>) {
        // TODO: handle this case. Should we add connector_customer_id in paymentConfirmData?
    }

    fn push_sessions_token(&mut self, _token: api::SessionToken) {
        todo!()
    }

    fn set_card_network(&mut self, card_network: enums::CardNetwork) {
        todo!()
    }

    fn set_co_badged_card_data(
        &mut self,
        debit_routing_output: &api_models::open_router::DebitRoutingOutput,
    ) {
        todo!()
    }

    fn set_surcharge_details(&mut self, _surcharge_details: Option<types::SurchargeDetails>) {
        todo!()
    }

    #[track_caller]
    fn set_merchant_connector_id_in_attempt(
        &mut self,
        merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    ) {
        self.payment_attempt.merchant_connector_id = merchant_connector_id;
    }

    fn set_frm_message(&mut self, _frm_message: FraudCheck) {
        todo!()
    }

    fn set_payment_intent_status(&mut self, status: storage_enums::IntentStatus) {
        self.payment_intent.status = status;
    }

    fn set_authentication_type_in_attempt(
        &mut self,
        _authentication_type: Option<enums::AuthenticationType>,
    ) {
        todo!()
    }

    fn set_recurring_mandate_payment_data(
        &mut self,
        _recurring_mandate_payment_data:
            hyperswitch_domain_models::router_data::RecurringMandatePaymentData,
    ) {
        todo!()
    }

    fn set_mandate_id(&mut self, _mandate_id: api_models::payments::MandateIds) {
        todo!()
    }

    fn set_setup_future_usage_in_payment_intent(
        &mut self,
        setup_future_usage: storage_enums::FutureUsage,
    ) {
        self.payment_intent.setup_future_usage = setup_future_usage;
    }

    fn set_connector_in_payment_attempt(&mut self, connector: Option<String>) {
        self.payment_attempt.connector = connector;
    }

    fn set_connector_request_reference_id(&mut self, reference_id: Option<String>) {
        self.payment_attempt.connector_request_reference_id = reference_id;
    }

    fn set_connector_response_reference_id(&mut self, reference_id: Option<String>) {
        self.payment_attempt.connector_response_reference_id = reference_id;
    }

    fn set_vault_session_details(
        &mut self,
        external_vault_session_details: Option<api::VaultSessionDetails>,
    ) {
        todo!()
    }

    fn set_routing_approach_in_attempt(
        &mut self,
        routing_approach: Option<enums::RoutingApproach>,
    ) {
        todo!()
    }

    fn set_connector_request_reference_id_in_payment_attempt(
        &mut self,
        connector_request_reference_id: String,
    ) {
        todo!()
    }

    fn set_cancellation_reason(&mut self, cancellation_reason: Option<String>) {
        todo!()
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionGetters<F> for PaymentStatusData<F> {
    #[track_caller]
    fn get_payment_attempt(&self) -> &storage::PaymentAttempt {
        &self.payment_attempt
    }
    #[cfg(feature = "v2")]
    fn list_payments_attempts(&self) -> &Vec<storage::PaymentAttempt> {
        todo!()
    }
    fn get_client_secret(&self) -> &Option<Secret<String>> {
        todo!()
    }
    fn get_payment_intent(&self) -> &storage::PaymentIntent {
        &self.payment_intent
    }

    fn get_merchant_connector_details(
        &self,
    ) -> Option<common_types::domain::MerchantConnectorAuthDetails> {
        self.merchant_connector_details.clone()
    }

    fn get_payment_method_info(&self) -> Option<&domain::PaymentMethod> {
        todo!()
    }

    fn get_payment_method_token(&self) -> Option<&PaymentMethodToken> {
        todo!()
    }

    fn get_mandate_id(&self) -> Option<&payments_api::MandateIds> {
        todo!()
    }

    fn get_address(&self) -> &PaymentAddress {
        &self.payment_address
    }

    fn get_creds_identifier(&self) -> Option<&str> {
        None
    }

    fn get_token(&self) -> Option<&str> {
        todo!()
    }

    fn get_multiple_capture_data(&self) -> Option<&types::MultipleCaptureData> {
        todo!()
    }

    fn get_payment_link_data(&self) -> Option<api_models::payments::PaymentLinkResponse> {
        todo!()
    }

    fn get_ephemeral_key(&self) -> Option<ephemeral_key::EphemeralKey> {
        todo!()
    }

    fn get_setup_mandate(&self) -> Option<&MandateData> {
        todo!()
    }

    fn get_poll_config(&self) -> Option<router_types::PollConfig> {
        todo!()
    }

    fn get_authentication(
        &self,
    ) -> Option<&hyperswitch_domain_models::router_request_types::authentication::AuthenticationStore>
    {
        todo!()
    }

    fn get_frm_message(&self) -> Option<FraudCheck> {
        todo!()
    }

    fn get_refunds(&self) -> Vec<diesel_refund::Refund> {
        todo!()
    }

    fn get_disputes(&self) -> Vec<storage::Dispute> {
        todo!()
    }

    fn get_authorizations(&self) -> Vec<diesel_models::authorization::Authorization> {
        todo!()
    }

    fn get_attempts(&self) -> Option<Vec<storage::PaymentAttempt>> {
        todo!()
    }

    fn get_recurring_details(&self) -> Option<&RecurringDetails> {
        todo!()
    }

    fn get_payment_intent_profile_id(&self) -> Option<&id_type::ProfileId> {
        Some(&self.payment_intent.profile_id)
    }

    fn get_currency(&self) -> storage_enums::Currency {
        self.payment_intent.amount_details.currency
    }

    fn get_amount(&self) -> api::Amount {
        todo!()
    }

    fn get_payment_attempt_connector(&self) -> Option<&str> {
        todo!()
    }

    fn get_merchant_connector_id_in_attempt(&self) -> Option<id_type::MerchantConnectorAccountId> {
        todo!()
    }

    fn get_connector_customer_id(&self) -> Option<String> {
        todo!()
    }

    fn get_billing_address(&self) -> Option<hyperswitch_domain_models::address::Address> {
        todo!()
    }

    fn get_payment_method_data(&self) -> Option<&domain::PaymentMethodData> {
        todo!()
    }

    fn get_sessions_token(&self) -> Vec<api::SessionToken> {
        todo!()
    }

    fn get_token_data(&self) -> Option<&storage::PaymentTokenData> {
        todo!()
    }

    fn get_mandate_connector(&self) -> Option<&MandateConnectorDetails> {
        todo!()
    }

    fn get_force_sync(&self) -> Option<bool> {
        todo!()
    }

    fn get_capture_method(&self) -> Option<enums::CaptureMethod> {
        todo!()
    }

    fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> {
        Some(&self.payment_attempt)
    }

    fn get_pre_routing_result(
        &self,
    ) -> Option<HashMap<enums::PaymentMethodType, domain::PreRoutingConnectorChoice>> {
        None
    }

    fn get_optional_external_vault_session_details(&self) -> Option<api::VaultSessionDetails> {
        todo!()
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionSetters<F> for PaymentStatusData<F> {
    #[cfg(feature = "v2")]
    fn set_prerouting_algorithm_in_payment_intent(
        &mut self,
        straight_through_algorithm: storage::PaymentRoutingInfo,
    ) {
        self.payment_intent.prerouting_algorithm = Some(straight_through_algorithm);
    }
    fn set_payment_intent(&mut self, payment_intent: storage::PaymentIntent) {
        self.payment_intent = payment_intent;
    }
    fn set_client_secret(&mut self, client_secret: Option<Secret<String>>) {
        todo!()
    }
    fn set_payment_attempt(&mut self, payment_attempt: storage::PaymentAttempt) {
        self.payment_attempt = payment_attempt;
    }

    fn set_payment_method_data(&mut self, _payment_method_data: Option<domain::PaymentMethodData>) {
        todo!()
    }

    fn set_payment_method_token(&mut self, _payment_method_token: Option<PaymentMethodToken>) {
        todo!()
    }

    fn set_payment_method_id_in_attempt(&mut self, _payment_method_id: Option<String>) {
        todo!()
    }

    fn set_email_if_not_present(&mut self, _email: pii::Email) {
        todo!()
    }

    fn set_card_network(&mut self, card_network: enums::CardNetwork) {
        todo!()
    }

    fn set_co_badged_card_data(
        &mut self,
        debit_routing_output: &api_models::open_router::DebitRoutingOutput,
    ) {
        todo!()
    }

    fn set_pm_token(&mut self, _token: String) {
        todo!()
    }

    fn set_connector_customer_id(&mut self, _customer_id: Option<String>) {
        // TODO: handle this case. Should we add connector_customer_id in paymentConfirmData?
    }

    fn push_sessions_token(&mut self, _token: api::SessionToken) {
        todo!()
    }

    fn set_surcharge_details(&mut self, _surcharge_details: Option<types::SurchargeDetails>) {
        todo!()
    }

    #[track_caller]
    fn set_merchant_connector_id_in_attempt(
        &mut self,
        merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    ) {
        todo!()
    }

    fn set_frm_message(&mut self, _frm_message: FraudCheck) {
        todo!()
    }

    fn set_payment_intent_status(&mut self, status: storage_enums::IntentStatus) {
        self.payment_intent.status = status;
    }

    fn set_authentication_type_in_attempt(
        &mut self,
        _authentication_type: Option<enums::AuthenticationType>,
    ) {
        todo!()
    }

    fn set_recurring_mandate_payment_data(
        &mut self,
        _recurring_mandate_payment_data:
            hyperswitch_domain_models::router_data::RecurringMandatePaymentData,
    ) {
        todo!()
    }

    fn set_mandate_id(&mut self, _mandate_id: api_models::payments::MandateIds) {
        todo!()
    }

    fn set_setup_future_usage_in_payment_intent(
        &mut self,
        setup_future_usage: storage_enums::FutureUsage,
    ) {
        self.payment_intent.setup_future_usage = setup_future_usage;
    }

    fn set_connector_in_payment_attempt(&mut self, connector: Option<String>) {
        self.payment_attempt.connector = connector;
    }

    fn set_connector_request_reference_id(&mut self, reference_id: Option<String>) {
        todo!()
    }

    fn set_connector_response_reference_id(&mut self, reference_id: Option<String>) {
        todo!()
    }

    fn set_vault_session_details(
        &mut self,
        external_vault_session_details: Option<api::VaultSessionDetails>,
    ) {
        todo!()
    }
    fn set_routing_approach_in_attempt(
        &mut self,
        routing_approach: Option<enums::RoutingApproach>,
    ) {
        todo!()
    }

    fn set_connector_request_reference_id_in_payment_attempt(
        &mut self,
        connector_request_reference_id: String,
    ) {
        todo!()
    }

    fn set_cancellation_reason(&mut self, cancellation_reason: Option<String>) {
        todo!()
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> OperationSessionGetters<F> for PaymentCaptureData<F> {
    #[track_caller]
    fn get_payment_attempt(&self) -> &storage::PaymentAttempt {
        &self.payment_attempt
    }
    #[cfg(feature = "v2")]
    fn list_payments_attempts(&self) -> &Vec<storage::PaymentAttempt> {
        todo!()
    }
    fn get_client_secret(&self) -> &Option<Secret<String>> {
        todo!()
    }
    fn get_payment_intent(&self) -> &storage::PaymentIntent {
        &self.payment_intent
    }

    fn get_merchant_connector_details(
        &self,
    ) -> Option<common_types::domain::MerchantConnectorAuthDetails> {
        todo!()
    }

    fn get_payment_method_info(&self) -> Option<&domain::PaymentMethod> {
        todo!()
    }


// Implementation: impl ConnectorValidation for for Helcim
// File: crates/hyperswitch_connectors/src/connectors/helcim.rs
// Module: hyperswitch_connectors
// Methods: 1 total (0 public)

impl ConnectorValidation for for Helcim


// Struct: TokenizationNew
// File: crates/diesel_models/src/tokenization.rs
// Module: diesel_models
// Implementations: 0

pub struct TokenizationNew


// Struct: CybersourceConsumerAuthInformation
// File: crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CybersourceConsumerAuthInformation


// File: crates/router/tests/connectors/breadpay.rs
// Module: router

use hyperswitch_domain_models::payment_method_data::{Card, PaymentMethodData};
use masking::Secret;
use router::types::{self, api, storage::enums};
use test_utils::connector_auth;

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

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

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

    fn get_name(&self) -> String {
        "breadpay".to_string()
    }
}

static CONNECTOR: BreadpayTest = BreadpayTest {};

fn get_default_payment_info() -> Option<utils::PaymentInfo> {
    None
}

fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    None
}

// Cards Positive Tests
// Creates a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_only_authorize_payment() {
    let response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized);
}

// Captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info())
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Partially captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(
            payment_method_details(),
            Some(types::PaymentsCaptureData {
                amount_to_capture: 50,
                ..utils::PaymentCaptureType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_authorized_payment() {
    let authorize_response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Authorized,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("PSync response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
}

// Voids a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_void_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_void_payment(
            payment_method_details(),
            Some(types::PaymentsCancelData {
                connector_transaction_id: String::from(""),
                cancellation_reason: Some("requested_by_customer".to_string()),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Void payment response");
    assert_eq!(response.status, enums::AttemptStatus::Voided);
}

// Refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Synchronizes a refund using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_manually_captured_refund() {
    let refund_response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_make_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_auto_captured_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Charged,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                capture_method: Some(enums::CaptureMethod::Automatic),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(response.status, enums::AttemptStatus::Charged,);
}

// Refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_auto_captured_payment() {
    let response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_succeeded_payment() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        refund_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_succeeded_payment_multiple_times() {
    CONNECTOR
        .make_payment_and_multiple_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await;
}

// Synchronizes a refund using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_refund() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Cards Negative scenarios
// Creates a payment with incorrect CVC.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_cvc: Secret::new("12345".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's security code is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry month.
#[actix_web::test]
async fn should_fail_payment_for_invalid_exp_month() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_exp_month: Secret::new("20".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration month is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry year.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_expiry_year() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_exp_year: Secret::new("2000".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration year is invalid.".to_string(),
    );
}

// Voids a payment using automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_fail_void_payment_for_auto_capture() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let void_response = CONNECTOR
        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        void_response.response.unwrap_err().message,
        "You cannot cancel this PaymentIntent because it has a status of succeeded."
    );
}

// Captures a payment using invalid connector payment id.
#[actix_web::test]
async fn should_fail_capture_for_invalid_payment() {
    let capture_response = CONNECTOR
        .capture_payment("123456789".to_string(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        capture_response.response.unwrap_err().message,
        String::from("No such payment_intent: '123456789'")
    );
}

// Refunds a payment with refund amount higher than payment amount.
#[actix_web::test]
async fn should_fail_for_refund_amount_higher_than_payment_amount() {
    let response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 150,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Refund amount (₹1.50) is greater than charge amount (₹1.00)",
    );
}

// Connector dependent test cases goes here

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


// Trait: RouterDataConversion
// File: crates/hyperswitch_interfaces/src/connector_integration_interface.rs
// Module: hyperswitch_interfaces

// Documentation: RouterDataConversion trait  This trait must be implemented for conversion between Router data and RouterDataV2

pub trait RouterDataConversion<T, Req: Clone, Resp: Clone>


// Trait: RefundMetricAnalytics
// File: crates/analytics/src/refunds/metrics.rs
// Module: analytics

pub trait RefundMetricAnalytics: LoadRow<RefundMetricRow>


// Function: exchange_token
// File: crates/router/src/routes/pm_auth.rs
// Module: router

pub fn exchange_token(
    state: web::Data<AppState>,
    req: HttpRequest,
    json_payload: web::Json<api_types::pm_auth::ExchangeTokenCreateRequest>,
) -> impl Responder


// Struct: GooglePayPredecrypt
// File: crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct GooglePayPredecrypt


// Struct: CreateUserAuthenticationMethodRequest
// File: crates/api_models/src/user.rs
// Module: api_models
// Implementations: 0

pub struct CreateUserAuthenticationMethodRequest


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

impl api::Refund for for HyperswitchVault


// Trait: ActivePaymentsMetricAccumulator
// File: crates/analytics/src/active_payments/accumulator.rs
// Module: analytics

pub trait ActivePaymentsMetricAccumulator


// Struct: ConnectorAgnosticMitChoice
// File: crates/api_models/src/admin.rs
// Module: api_models
// Implementations: 1
// Traits: common_utils::events::ApiEventMetric

pub struct ConnectorAgnosticMitChoice


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

pub fn filter_network_transaction_id_flow_supported_connectors(
        self,
        nit_connectors: HashSet<String>,
    ) -> Self


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

pub fn generate_merchant_authentication_report(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<ReportRequest>,
    ) -> impl Responder


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

pub fn execute_authentication_token<
    F: Clone + 'static,
    Req: Debug + Clone + 'static,
    Res: Debug + Clone + 'static,
>(
    state: &SessionState,
    connector: &api_types::ConnectorData,
    router_data: &types::RouterData<F, Req, Res>,
) -> RouterResult<Option<types::AccessTokenAuthenticationResponse>>


// Struct: WiseRecipientCreateResponse
// File: crates/hyperswitch_connectors/src/connectors/wise/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct WiseRecipientCreateResponse


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

pub fn get_merchant_refund_filters(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<GetRefundFilterRequest>,
    ) -> impl Responder


// Function: prefix_for_env
// File: crates/router_env/src/env.rs
// Module: router_env

// Documentation: Three letter (lowercase) prefix corresponding to the current environment. Either `dev`, `snd` or `prd`.

pub fn prefix_for_env() -> &'static str


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

pub fn update_payment_methods(
    state: &SessionState,
    payment_methods: Vec<pm_api::UpdatePaymentMethodRecord>,
    merchant_id: &id_type::MerchantId,
    merchant_context: &merchant_context::MerchantContext,
) -> PmMigrationResult<Vec<pm_api::PaymentMethodUpdateResponse>>


// Function: extract_card_network
// File: crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
// Module: hyperswitch_domain_models

pub fn extract_card_network(&self) -> Option<common_enums::CardNetwork>


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

impl webhooks::IncomingWebhook for for Opayo


// Struct: WebhookAmount
// File: crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct WebhookAmount


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

pub use diesel_models::user::*;


// Struct: TokeniseCreditCardResponse
// File: crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct TokeniseCreditCardResponse


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

impl api::PaymentToken for for Aci


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

pub fn internal_call_connector_service_prerequisites<F, RouterDReq, ApiRequest, D>(
    state: &SessionState,
    merchant_context: &domain::MerchantContext,
    connector: api::ConnectorData,
    operation: &BoxedOperation<'_, F, ApiRequest, D>,
    payment_data: &mut D,
    business_profile: &domain::Profile,
) -> RouterResult<(
    domain::MerchantConnectorAccountTypeDetails,
    RouterData<F, RouterDReq, router_types::PaymentsResponseData>,
)>
where
    F: Send + Clone + Sync,
    RouterDReq: Send + Sync,

    // To create connector flow specific interface data
    D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,
    D: ConstructFlowSpecificData<F, RouterDReq, router_types::PaymentsResponseData>,
    RouterData<F, RouterDReq, router_types::PaymentsResponseData>: Feature<F, RouterDReq> + Send,
    // To construct connector flow specific api
    dyn api::Connector:
        services::api::ConnectorIntegration<F, RouterDReq, router_types::PaymentsResponseData>,


// Implementation: impl ArchipelErrorMessageWithHttpCode
// File: crates/hyperswitch_connectors/src/connectors/archipel/transformers.rs
// Module: hyperswitch_connectors
// Methods: 1 total (0 public)

impl ArchipelErrorMessageWithHttpCode


// Struct: Invoice
// File: crates/diesel_models/src/invoice.rs
// Module: diesel_models
// Implementations: 0

pub struct Invoice


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

pub struct AutomationConfigs


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

pub struct GooglePayPaymentMethodInfo