            .clone()
            .ok_or_else(missing_field_err("order_details"))
    }

    fn get_card(&self) -> Result<Card, Error> {
        match self.payment_method_data.clone() {
            PaymentMethodData::Card(card) => Ok(card),
            _ => Err(missing_field_err("card")()),
        }
    }

    fn get_complete_authorize_url(&self) -> Result<String, Error> {
        self.complete_authorize_url
            .clone()
            .ok_or_else(missing_field_err("complete_authorize_url"))
    }

    fn connector_mandate_id(&self) -> Option<String> {
        self.mandate_id
            .as_ref()
            .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
                Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => {
                    connector_mandate_ids.get_connector_mandate_id()
                }
                Some(payments::MandateReferenceId::NetworkMandateId(_))
                | None
                | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None,
            })
    }
    fn is_mandate_payment(&self) -> bool {
        ((self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && (self.setup_future_usage == Some(FutureUsage::OffSession)))
            || self
                .mandate_id
                .as_ref()
                .and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref())
                .is_some()
    }
    fn get_webhook_url(&self) -> Result<String, Error> {
        self.webhook_url
            .clone()
            .ok_or_else(missing_field_err("webhook_url"))
    }
    fn get_router_return_url(&self) -> Result<String, Error> {
        self.router_return_url
            .clone()
            .ok_or_else(missing_field_err("return_url"))
    }
    fn is_wallet(&self) -> bool {
        matches!(self.payment_method_data, PaymentMethodData::Wallet(_))
    }
    fn is_card(&self) -> bool {
        matches!(self.payment_method_data, PaymentMethodData::Card(_))
    }

    fn get_payment_method_type(&self) -> Result<enums::PaymentMethodType, Error> {
        self.payment_method_type
            .to_owned()
            .ok_or_else(missing_field_err("payment_method_type"))
    }

    fn get_connector_mandate_id(&self) -> Result<String, Error> {
        self.connector_mandate_id()
            .ok_or_else(missing_field_err("connector_mandate_id"))
    }
    fn get_ip_address_as_optional(&self) -> Option<Secret<String, IpAddress>> {
        self.browser_info.clone().and_then(|browser_info| {
            browser_info
                .ip_address
                .map(|ip| Secret::new(ip.to_string()))
        })
    }
    fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error> {
        let ip_address = self
            .browser_info
            .clone()
            .and_then(|browser_info| browser_info.ip_address);

        let val = ip_address.ok_or_else(missing_field_err("browser_info.ip_address"))?;

        Ok(Secret::new(val.to_string()))
    }
    fn get_optional_user_agent(&self) -> Option<String> {
        self.browser_info
            .clone()
            .and_then(|browser_info| browser_info.user_agent)
    }
    fn get_original_amount(&self) -> i64 {
        self.surcharge_details
            .as_ref()
            .map(|surcharge_details| surcharge_details.original_amount.get_amount_as_i64())
            .unwrap_or(self.amount)
    }
    fn get_surcharge_amount(&self) -> Option<i64> {
        self.surcharge_details
            .as_ref()
            .map(|surcharge_details| surcharge_details.surcharge_amount.get_amount_as_i64())
    }
    fn get_tax_on_surcharge_amount(&self) -> Option<i64> {
        self.surcharge_details.as_ref().map(|surcharge_details| {
            surcharge_details
                .tax_on_surcharge_amount
                .get_amount_as_i64()
        })
    }
    fn get_total_surcharge_amount(&self) -> Option<i64> {
        self.surcharge_details.as_ref().map(|surcharge_details| {
            surcharge_details
                .get_total_surcharge_amount()
                .get_amount_as_i64()
        })
    }

    fn is_customer_initiated_mandate_payment(&self) -> bool {
        (self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && self.setup_future_usage == Some(FutureUsage::OffSession)
    }

    fn get_metadata_as_object(&self) -> Option<pii::SecretSerdeValue> {
        self.metadata.clone().and_then(|meta_data| match meta_data {
            Value::Null
            | Value::Bool(_)
            | Value::Number(_)
            | Value::String(_)
            | Value::Array(_) => None,
            Value::Object(_) => Some(meta_data.into()),
        })
    }

    fn get_authentication_data(&self) -> Result<AuthenticationData, Error> {
        self.authentication_data
            .clone()
            .ok_or_else(missing_field_err("authentication_data"))
    }

    fn get_customer_name(&self) -> Result<Secret<String>, Error> {
        self.customer_name
            .clone()
            .ok_or_else(missing_field_err("customer_name"))
    }

    fn get_card_holder_name_from_additional_payment_method_data(
        &self,
    ) -> Result<Secret<String>, Error> {
        match &self.additional_payment_method_data {
            Some(payments::AdditionalPaymentData::Card(card_data)) => Ok(card_data
                .card_holder_name
                .clone()
                .ok_or_else(|| errors::ConnectorError::MissingRequiredField {
                    field_name: "card_holder_name",
                })?),
            _ => Err(errors::ConnectorError::MissingRequiredFields {
                field_names: vec!["card_holder_name"],
            }
            .into()),
        }
    }
    /// Attempts to retrieve the connector mandate reference ID as a `Result<String, Error>`.
    fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error> {
        self.mandate_id
            .as_ref()
            .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
                Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => {
                    connector_mandate_ids.get_connector_mandate_request_reference_id()
                }
                Some(payments::MandateReferenceId::NetworkMandateId(_))
                | None
                | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None,
            })
            .ok_or_else(missing_field_err("connector_mandate_request_reference_id"))
    }
    fn is_cit_mandate_payment(&self) -> bool {
        (self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && self.setup_future_usage == Some(FutureUsage::OffSession)
    }
    fn get_optional_network_transaction_id(&self) -> Option<String> {
        self.mandate_id
            .as_ref()
            .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
                Some(payments::MandateReferenceId::NetworkMandateId(network_transaction_id)) => {
                    Some(network_transaction_id.clone())
                }
                Some(payments::MandateReferenceId::ConnectorMandateId(_))
                | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_))
                | None => None,
            })
    }
    fn get_optional_email(&self) -> Option<Email> {
        self.email.clone()
    }
    fn get_card_network_from_additional_payment_method_data(
        &self,
    ) -> Result<enums::CardNetwork, Error> {
        match &self.additional_payment_method_data {
            Some(payments::AdditionalPaymentData::Card(card_data)) => Ok(card_data
                .card_network
                .clone()
                .ok_or_else(|| errors::ConnectorError::MissingRequiredField {
                    field_name: "card_network",
                })?),
            _ => Err(errors::ConnectorError::MissingRequiredFields {
                field_names: vec!["card_network"],
            }
            .into()),
        }
    }
    fn get_connector_testing_data(&self) -> Option<pii::SecretSerdeValue> {
        self.connector_testing_data.clone()
    }

    fn get_order_id(&self) -> Result<String, errors::ConnectorError> {
        self.order_id
            .to_owned()
            .ok_or(errors::ConnectorError::RequestEncodingFailed)
    }

    fn get_card_mandate_info(&self) -> Result<CardMandateInfo, Error> {
        match &self.additional_payment_method_data {
            Some(payments::AdditionalPaymentData::Card(card_data)) => Ok(CardMandateInfo {
                card_exp_month: card_data.card_exp_month.clone().ok_or_else(|| {
                    errors::ConnectorError::MissingRequiredField {
                        field_name: "card_exp_month",
                    }
                })?,
                card_exp_year: card_data.card_exp_year.clone().ok_or_else(|| {
                    errors::ConnectorError::MissingRequiredField {
                        field_name: "card_exp_year",
                    }
                })?,
            }),
            _ => Err(errors::ConnectorError::MissingRequiredFields {
                field_names: vec!["card_exp_month", "card_exp_year"],
            }
            .into()),
        }
    }
}

pub trait PaymentsCaptureRequestData {
    fn get_optional_language_from_browser_info(&self) -> Option<String>;
    fn is_multiple_capture(&self) -> bool;
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn get_webhook_url(&self) -> Result<String, Error>;
}

impl PaymentsCaptureRequestData for PaymentsCaptureData {
    fn is_multiple_capture(&self) -> bool {
        self.multiple_capture_data.is_some()
    }
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn get_optional_language_from_browser_info(&self) -> Option<String> {
        self.browser_info
            .clone()
            .and_then(|browser_info| browser_info.language)
    }
    fn get_webhook_url(&self) -> Result<String, Error> {
        self.webhook_url
            .clone()
            .ok_or_else(missing_field_err("webhook_url"))
    }
}

pub trait PaymentsSyncRequestData {
    fn is_auto_capture(&self) -> Result<bool, Error>;
    fn get_connector_transaction_id(&self) -> CustomResult<String, errors::ConnectorError>;
}

impl PaymentsSyncRequestData for PaymentsSyncData {
    fn is_auto_capture(&self) -> Result<bool, Error> {
        match self.capture_method {
            Some(enums::CaptureMethod::Automatic)
            | Some(enums::CaptureMethod::SequentialAutomatic)
            | None => Ok(true),
            Some(enums::CaptureMethod::Manual) => Ok(false),
            Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()),
        }
    }
    fn get_connector_transaction_id(&self) -> CustomResult<String, errors::ConnectorError> {
        match self.connector_transaction_id.clone() {
            ResponseId::ConnectorTransactionId(txn_id) => Ok(txn_id),
            _ => Err(
                common_utils::errors::ValidationError::IncorrectValueProvided {
                    field_name: "connector_transaction_id",
                },
            )
            .attach_printable("Expected connector transaction ID not found")
            .change_context(errors::ConnectorError::MissingConnectorTransactionID)?,
        }
    }
}

pub trait PaymentsPostSessionTokensRequestData {
    fn is_auto_capture(&self) -> Result<bool, Error>;
}

impl PaymentsPostSessionTokensRequestData for PaymentsPostSessionTokensData {
    fn is_auto_capture(&self) -> Result<bool, Error> {
        match self.capture_method {
            Some(enums::CaptureMethod::Automatic)
            | None
            | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true),
            Some(enums::CaptureMethod::Manual) => Ok(false),
            Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()),
        }
    }
}

pub trait PaymentsCancelRequestData {
    fn get_optional_language_from_browser_info(&self) -> Option<String>;
    fn get_amount(&self) -> Result<i64, Error>;
    fn get_currency(&self) -> Result<enums::Currency, Error>;
    fn get_cancellation_reason(&self) -> Result<String, Error>;
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn get_webhook_url(&self) -> Result<String, Error>;
}

impl PaymentsCancelRequestData for PaymentsCancelData {
    fn get_amount(&self) -> Result<i64, Error> {
        self.amount.ok_or_else(missing_field_err("amount"))
    }
    fn get_currency(&self) -> Result<enums::Currency, Error> {
        self.currency.ok_or_else(missing_field_err("currency"))
    }
    fn get_cancellation_reason(&self) -> Result<String, Error> {
        self.cancellation_reason
            .clone()
            .ok_or_else(missing_field_err("cancellation_reason"))
    }
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn get_optional_language_from_browser_info(&self) -> Option<String> {
        self.browser_info
            .clone()
            .and_then(|browser_info| browser_info.language)
    }
    fn get_webhook_url(&self) -> Result<String, Error> {
        self.webhook_url
            .clone()
            .ok_or_else(missing_field_err("webhook_url"))
    }
}

pub trait RefundsRequestData {
    fn get_optional_language_from_browser_info(&self) -> Option<String>;
    fn get_connector_refund_id(&self) -> Result<String, Error>;
    fn get_webhook_url(&self) -> Result<String, Error>;
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn get_connector_metadata(&self) -> Result<Value, Error>;
}

impl RefundsRequestData for RefundsData {
    #[track_caller]
    fn get_connector_refund_id(&self) -> Result<String, Error> {
        self.connector_refund_id
            .clone()
            .get_required_value("connector_refund_id")
            .change_context(errors::ConnectorError::MissingConnectorTransactionID)
    }
    fn get_webhook_url(&self) -> Result<String, Error> {
        self.webhook_url
            .clone()
            .ok_or_else(missing_field_err("webhook_url"))
    }
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn get_optional_language_from_browser_info(&self) -> Option<String> {
        self.browser_info
            .clone()
            .and_then(|browser_info| browser_info.language)
    }
    fn get_connector_metadata(&self) -> Result<Value, Error> {
        self.connector_metadata
            .clone()
            .ok_or_else(missing_field_err("connector_metadata"))
    }
}

pub trait PaymentsSetupMandateRequestData {
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn get_email(&self) -> Result<Email, Error>;
    fn get_router_return_url(&self) -> Result<String, Error>;
    fn is_card(&self) -> bool;
    fn get_return_url(&self) -> Result<String, Error>;
    fn get_webhook_url(&self) -> Result<String, Error>;
    fn get_optional_language_from_browser_info(&self) -> Option<String>;
    fn get_complete_authorize_url(&self) -> Result<String, Error>;
    fn is_auto_capture(&self) -> Result<bool, Error>;
    fn is_customer_initiated_mandate_payment(&self) -> bool;
}

impl PaymentsSetupMandateRequestData for SetupMandateRequestData {
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn get_email(&self) -> Result<Email, Error> {
        self.email.clone().ok_or_else(missing_field_err("email"))
    }
    fn get_router_return_url(&self) -> Result<String, Error> {
        self.router_return_url
            .clone()
            .ok_or_else(missing_field_err("router_return_url"))
    }
    fn is_card(&self) -> bool {
        matches!(self.payment_method_data, PaymentMethodData::Card(_))
    }
    fn get_return_url(&self) -> Result<String, Error> {
        self.router_return_url
            .clone()
            .ok_or_else(missing_field_err("return_url"))
    }
    fn get_webhook_url(&self) -> Result<String, Error> {
        self.webhook_url
            .clone()
            .ok_or_else(missing_field_err("webhook_url"))
    }
    fn get_optional_language_from_browser_info(&self) -> Option<String> {
        self.browser_info
            .clone()
            .and_then(|browser_info| browser_info.language)
    }
    fn get_complete_authorize_url(&self) -> Result<String, Error> {
        self.complete_authorize_url
            .clone()
            .ok_or_else(missing_field_err("complete_authorize_url"))
    }
    fn is_auto_capture(&self) -> Result<bool, Error> {
        match self.capture_method {
            Some(enums::CaptureMethod::Automatic)
            | Some(enums::CaptureMethod::SequentialAutomatic)
            | None => Ok(true),
            Some(enums::CaptureMethod::Manual) => Ok(false),
            Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()),
        }
    }
    fn is_customer_initiated_mandate_payment(&self) -> bool {
        (self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && self.setup_future_usage == Some(FutureUsage::OffSession)
    }
}

pub trait PaymentMethodTokenizationRequestData {
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn is_mandate_payment(&self) -> bool;
}

impl PaymentMethodTokenizationRequestData for PaymentMethodTokenizationData {
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn is_mandate_payment(&self) -> bool {
        ((self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && (self.setup_future_usage == Some(FutureUsage::OffSession)))
            || self
                .mandate_id
                .as_ref()
                .and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref())
                .is_some()
    }
}

pub trait PaymentsCompleteAuthorizeRequestData {
    fn is_auto_capture(&self) -> Result<bool, Error>;
    fn get_email(&self) -> Result<Email, Error>;
    fn get_redirect_response_payload(&self) -> Result<pii::SecretSerdeValue, Error>;
    fn get_complete_authorize_url(&self) -> Result<String, Error>;
    fn is_mandate_payment(&self) -> bool;
    fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error>;
    fn is_cit_mandate_payment(&self) -> bool;
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn get_threeds_method_comp_ind(&self) -> Result<payments::ThreeDsCompletionIndicator, Error>;
}

impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData {
    fn is_auto_capture(&self) -> Result<bool, Error> {
        match self.capture_method {
            Some(enums::CaptureMethod::Automatic)
            | Some(enums::CaptureMethod::SequentialAutomatic)
            | None => Ok(true),
            Some(enums::CaptureMethod::Manual) => Ok(false),
            Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()),
        }
    }
    fn get_email(&self) -> Result<Email, Error> {
        self.email.clone().ok_or_else(missing_field_err("email"))
    }
    fn get_redirect_response_payload(&self) -> Result<pii::SecretSerdeValue, Error> {
        self.redirect_response
            .as_ref()
            .and_then(|res| res.payload.to_owned())
            .ok_or(
                errors::ConnectorError::MissingConnectorRedirectionPayload {
                    field_name: "request.redirect_response.payload",
                }
                .into(),
            )
    }
    fn get_complete_authorize_url(&self) -> Result<String, Error> {
        self.complete_authorize_url
            .clone()
            .ok_or_else(missing_field_err("complete_authorize_url"))
    }
    fn is_mandate_payment(&self) -> bool {
        ((self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && self.setup_future_usage == Some(FutureUsage::OffSession))
            || self
                .mandate_id
                .as_ref()
                .and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref())
                .is_some()
    }
    /// Attempts to retrieve the connector mandate reference ID as a `Result<String, Error>`.
    fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error> {
        self.mandate_id
            .as_ref()
            .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
                Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => {
                    connector_mandate_ids.get_connector_mandate_request_reference_id()
                }
                Some(payments::MandateReferenceId::NetworkMandateId(_))
                | None
                | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None,
            })
            .ok_or_else(missing_field_err("connector_mandate_request_reference_id"))
    }
    fn is_cit_mandate_payment(&self) -> bool {
        (self.customer_acceptance.is_some() || self.setup_mandate_details.is_some())
            && self.setup_future_usage == Some(FutureUsage::OffSession)
    }
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn get_threeds_method_comp_ind(&self) -> Result<payments::ThreeDsCompletionIndicator, Error> {
        self.threeds_method_comp_ind
            .clone()
            .ok_or_else(missing_field_err("threeds_method_comp_ind"))
    }
}
pub trait AddressData {
    fn get_optional_full_name(&self) -> Option<Secret<String>>;
    fn get_email(&self) -> Result<Email, Error>;
    fn get_phone_with_country_code(&self) -> Result<Secret<String>, Error>;
    fn get_optional_first_name(&self) -> Option<Secret<String>>;
    fn get_optional_last_name(&self) -> Option<Secret<String>>;
}

impl AddressData for Address {
    fn get_optional_full_name(&self) -> Option<Secret<String>> {
        self.address
            .as_ref()
            .and_then(|billing_address| billing_address.get_optional_full_name())
    }

    fn get_email(&self) -> Result<Email, Error> {
        self.email.clone().ok_or_else(missing_field_err("email"))
    }

    fn get_phone_with_country_code(&self) -> Result<Secret<String>, Error> {
        self.phone
            .clone()
            .map(|phone_details| phone_details.get_number_with_country_code())
            .transpose()?
            .ok_or_else(missing_field_err("phone"))
    }

    fn get_optional_first_name(&self) -> Option<Secret<String>> {
        self.address
            .as_ref()
            .and_then(|billing_address| billing_address.get_optional_first_name())
    }

    fn get_optional_last_name(&self) -> Option<Secret<String>> {
        self.address
            .as_ref()
            .and_then(|billing_address| billing_address.get_optional_last_name())
    }
}
pub trait PaymentsPreProcessingRequestData {
    fn get_redirect_response_payload(&self) -> Result<pii::SecretSerdeValue, Error>;
    fn get_email(&self) -> Result<Email, Error>;
    fn get_payment_method_type(&self) -> Result<enums::PaymentMethodType, Error>;
    fn get_currency(&self) -> Result<enums::Currency, Error>;
    fn get_amount(&self) -> Result<i64, Error>;
    fn get_minor_amount(&self) -> Result<MinorUnit, Error>;
    fn is_auto_capture(&self) -> Result<bool, Error>;
    fn get_order_details(&self) -> Result<Vec<OrderDetailsWithAmount>, Error>;
    fn get_webhook_url(&self) -> Result<String, Error>;
    fn get_router_return_url(&self) -> Result<String, Error>;
    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
    fn get_complete_authorize_url(&self) -> Result<String, Error>;
    fn connector_mandate_id(&self) -> Option<String>;
    fn get_payment_method_data(&self) -> Result<PaymentMethodData, Error>;
}

impl PaymentsPreProcessingRequestData for PaymentsPreProcessingData {
    fn get_email(&self) -> Result<Email, Error> {
        self.email.clone().ok_or_else(missing_field_err("email"))
    }
    fn get_payment_method_type(&self) -> Result<enums::PaymentMethodType, Error> {
        self.payment_method_type
            .to_owned()
            .ok_or_else(missing_field_err("payment_method_type"))
    }
    fn get_payment_method_data(&self) -> Result<PaymentMethodData, Error> {
        self.payment_method_data
            .to_owned()
            .ok_or_else(missing_field_err("payment_method_data"))
    }
    fn get_currency(&self) -> Result<enums::Currency, Error> {
        self.currency.ok_or_else(missing_field_err("currency"))
    }
    fn get_amount(&self) -> Result<i64, Error> {
        self.amount.ok_or_else(missing_field_err("amount"))
    }

    // New minor amount function for amount framework
    fn get_minor_amount(&self) -> Result<MinorUnit, Error> {
        self.minor_amount.ok_or_else(missing_field_err("amount"))
    }
    fn is_auto_capture(&self) -> Result<bool, Error> {
        match self.capture_method {
            Some(enums::CaptureMethod::Automatic)
            | None
            | Some(enums::CaptureMethod::SequentialAutomatic) => Ok(true),
            Some(enums::CaptureMethod::Manual) => Ok(false),
            Some(enums::CaptureMethod::ManualMultiple) | Some(enums::CaptureMethod::Scheduled) => {
                Err(errors::ConnectorError::CaptureMethodNotSupported.into())
            }
        }
    }
    fn get_order_details(&self) -> Result<Vec<OrderDetailsWithAmount>, Error> {
        self.order_details
            .clone()
            .ok_or_else(missing_field_err("order_details"))
    }
    fn get_webhook_url(&self) -> Result<String, Error> {
        self.webhook_url
            .clone()
            .ok_or_else(missing_field_err("webhook_url"))
    }
    fn get_router_return_url(&self) -> Result<String, Error> {
        self.router_return_url
            .clone()
            .ok_or_else(missing_field_err("return_url"))
    }
    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
        self.browser_info
            .clone()
            .ok_or_else(missing_field_err("browser_info"))
    }
    fn get_complete_authorize_url(&self) -> Result<String, Error> {
        self.complete_authorize_url
            .clone()
            .ok_or_else(missing_field_err("complete_authorize_url"))
    }
    fn get_redirect_response_payload(&self) -> Result<pii::SecretSerdeValue, Error> {
        self.redirect_response
            .as_ref()
            .and_then(|res| res.payload.to_owned())
            .ok_or(
                errors::ConnectorError::MissingConnectorRedirectionPayload {
                    field_name: "request.redirect_response.payload",
                }
                .into(),
            )
    }
    fn connector_mandate_id(&self) -> Option<String> {
        self.mandate_id
            .as_ref()
            .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
                Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => {
                    connector_mandate_ids.get_connector_mandate_id()
                }
                Some(payments::MandateReferenceId::NetworkMandateId(_))
                | None
                | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None,
            })
    }
}

pub trait BrowserInformationData {
    fn get_accept_header(&self) -> Result<String, Error>;
    fn get_language(&self) -> Result<String, Error>;
    fn get_screen_height(&self) -> Result<u32, Error>;
    fn get_screen_width(&self) -> Result<u32, Error>;
    fn get_color_depth(&self) -> Result<u8, Error>;
    fn get_user_agent(&self) -> Result<String, Error>;
    fn get_time_zone(&self) -> Result<i32, Error>;
    fn get_java_enabled(&self) -> Result<bool, Error>;
    fn get_java_script_enabled(&self) -> Result<bool, Error>;
    fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error>;
    fn get_os_type(&self) -> Result<String, Error>;
    fn get_os_version(&self) -> Result<String, Error>;
    fn get_device_model(&self) -> Result<String, Error>;
}

impl BrowserInformationData for BrowserInformation {
    fn get_ip_address(&self) -> Result<Secret<String, IpAddress>, Error> {
        let ip_address = self
            .ip_address
            .ok_or_else(missing_field_err("browser_info.ip_address"))?;
        Ok(Secret::new(ip_address.to_string()))
    }
    fn get_accept_header(&self) -> Result<String, Error> {
        self.accept_header
            .clone()
            .ok_or_else(missing_field_err("browser_info.accept_header"))
    }
    fn get_language(&self) -> Result<String, Error> {
        self.language
            .clone()
            .ok_or_else(missing_field_err("browser_info.language"))
    }
    fn get_screen_height(&self) -> Result<u32, Error> {
        self.screen_height
            .ok_or_else(missing_field_err("browser_info.screen_height"))
    }
    fn get_screen_width(&self) -> Result<u32, Error> {
        self.screen_width
            .ok_or_else(missing_field_err("browser_info.screen_width"))
    }
    fn get_color_depth(&self) -> Result<u8, Error> {
        self.color_depth
            .ok_or_else(missing_field_err("browser_info.color_depth"))
    }
    fn get_user_agent(&self) -> Result<String, Error> {
        self.user_agent
            .clone()
            .ok_or_else(missing_field_err("browser_info.user_agent"))
    }
    fn get_time_zone(&self) -> Result<i32, Error> {
        self.time_zone
            .ok_or_else(missing_field_err("browser_info.time_zone"))
    }
    fn get_java_enabled(&self) -> Result<bool, Error> {
        self.java_enabled
            .ok_or_else(missing_field_err("browser_info.java_enabled"))
    }
    fn get_java_script_enabled(&self) -> Result<bool, Error> {
        self.java_script_enabled
            .ok_or_else(missing_field_err("browser_info.java_script_enabled"))
    }
    fn get_os_type(&self) -> Result<String, Error> {
        self.os_type
            .clone()
            .ok_or_else(missing_field_err("browser_info.os_type"))
    }
    fn get_os_version(&self) -> Result<String, Error> {
        self.os_version
            .clone()
            .ok_or_else(missing_field_err("browser_info.os_version"))
    }
    fn get_device_model(&self) -> Result<String, Error> {
        self.device_model
            .clone()
            .ok_or_else(missing_field_err("browser_info.device_model"))
    }
}

pub fn get_header_key_value<'a>(
    key: &str,
    headers: &'a actix_web::http::header::HeaderMap,
) -> CustomResult<&'a str, errors::ConnectorError> {
    get_header_field(headers.get(key))
}

pub fn get_http_header<'a>(
    key: &str,
    headers: &'a http::HeaderMap,
) -> CustomResult<&'a str, errors::ConnectorError> {
    get_header_field(headers.get(key))
}

fn get_header_field(
    field: Option<&http::HeaderValue>,
) -> CustomResult<&str, errors::ConnectorError> {
    field
        .map(|header_value| {
            header_value
                .to_str()
                .change_context(errors::ConnectorError::WebhookSignatureNotFound)
        })
        .ok_or(report!(
            errors::ConnectorError::WebhookSourceVerificationFailed
        ))?
}

pub trait CryptoData {
    fn get_pay_currency(&self) -> Result<String, Error>;
}

impl CryptoData for payment_method_data::CryptoData {
    fn get_pay_currency(&self) -> Result<String, Error> {
        self.pay_currency
            .clone()
            .ok_or_else(missing_field_err("crypto_data.pay_currency"))
    }
}

#[macro_export]
macro_rules! capture_method_not_supported {
    ($connector:expr, $capture_method:expr) => {
        Err(errors::ConnectorError::NotSupported {
            message: format!("{} for selected payment method", $capture_method),
            connector: $connector,
        }
        .into())
    };
    ($connector:expr, $capture_method:expr, $payment_method_type:expr) => {
        Err(errors::ConnectorError::NotSupported {
            message: format!("{} for {}", $capture_method, $payment_method_type),
            connector: $connector,
        }
        .into())
    };
}
#[macro_export]
macro_rules! get_formatted_date_time {
    ($date_format:tt) => {{
        let format = time::macros::format_description!($date_format);
        time::OffsetDateTime::now_utc()
            .format(&format)
            .change_context(ConnectorError::InvalidDateFormat)
    }};
}

#[macro_export]
macro_rules! unimplemented_payment_method {
    ($payment_method:expr, $connector:expr) => {
        hyperswitch_interfaces::errors::ConnectorError::NotImplemented(format!(
            "{} through {}",
            $payment_method, $connector
        ))
    };
    ($payment_method:expr, $flow:expr, $connector:expr) => {
        hyperswitch_interfaces::errors::ConnectorError::NotImplemented(format!(
            "{} {} through {}",
            $payment_method, $flow, $connector
        ))
    };
}

impl ForeignTryFrom<String> for UsStatesAbbreviation {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn foreign_try_from(value: String) -> Result<Self, Self::Error> {
        let state_abbreviation_check =
            StringExt::<Self>::parse_enum(value.to_uppercase().clone(), "UsStatesAbbreviation");

        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => {
                let binding = value.as_str().to_lowercase();
                let state = binding.as_str();
                match state {
                    "alabama" => Ok(Self::AL),
                    "alaska" => Ok(Self::AK),
                    "american samoa" => Ok(Self::AS),
                    "arizona" => Ok(Self::AZ),
                    "arkansas" => Ok(Self::AR),
                    "california" => Ok(Self::CA),
                    "colorado" => Ok(Self::CO),
                    "connecticut" => Ok(Self::CT),
                    "delaware" => Ok(Self::DE),
                    "district of columbia" | "columbia" => Ok(Self::DC),
                    "federated states of micronesia" | "micronesia" => Ok(Self::FM),
                    "florida" => Ok(Self::FL),
                    "georgia" => Ok(Self::GA),
                    "guam" => Ok(Self::GU),
                    "hawaii" => Ok(Self::HI),
                    "idaho" => Ok(Self::ID),
                    "illinois" => Ok(Self::IL),
                    "indiana" => Ok(Self::IN),
                    "iowa" => Ok(Self::IA),
                    "kansas" => Ok(Self::KS),
                    "kentucky" => Ok(Self::KY),
                    "louisiana" => Ok(Self::LA),
                    "maine" => Ok(Self::ME),
                    "marshall islands" => Ok(Self::MH),
                    "maryland" => Ok(Self::MD),
                    "massachusetts" => Ok(Self::MA),
                    "michigan" => Ok(Self::MI),
                    "minnesota" => Ok(Self::MN),
                    "mississippi" => Ok(Self::MS),
                    "missouri" => Ok(Self::MO),
                    "montana" => Ok(Self::MT),
                    "nebraska" => Ok(Self::NE),
                    "nevada" => Ok(Self::NV),
                    "new hampshire" => Ok(Self::NH),
                    "new jersey" => Ok(Self::NJ),
                    "new mexico" => Ok(Self::NM),
                    "new york" => Ok(Self::NY),


pub async fn toggle_success_based_routing(
    state: web::Data<AppState>,
    req: HttpRequest,
    query: web::Query<api_models::routing::ToggleDynamicRoutingQuery>,
    path: web::Path<routing_types::ToggleDynamicRoutingPath>,
) -> impl Responder {
    let flow = Flow::ToggleDynamicRouting;
    let wrapper = routing_types::ToggleDynamicRoutingWrapper {
        feature_to_enable: query.into_inner().enable,
        profile_id: path.into_inner().profile_id,
    };
    Box::pin(oss_api::server_wrap(
        flow,
        state,
        &req,
        wrapper.clone(),
        |state,
         auth: auth::AuthenticationData,
         wrapper: routing_types::ToggleDynamicRoutingWrapper,
         _| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            routing::toggle_specific_dynamic_routing(
                state,
                merchant_context,
                wrapper.feature_to_enable,
                wrapper.profile_id,
                api_models::routing::DynamicRoutingType::SuccessRateBasedRouting,
            )
        },
        auth::auth_type(
            &auth::HeaderAuth(auth::ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            }),
            &auth::JWTAuthProfileFromRoute {
                profile_id: wrapper.profile_id,
                required_permission: Permission::ProfileRoutingWrite,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub struct EventRetrieveResponse {
    #[serde(flatten)]
    pub event_information: EventListItemResponse,

    /// The request information (headers and body) sent in the webhook.
    pub request: OutgoingWebhookRequestContent,

    /// The response information (headers, body and status code) received for the webhook sent.
    pub response: OutgoingWebhookResponseContent,

    /// Indicates the type of delivery attempt.
    pub delivery_attempt: Option<WebhookDeliveryAttempt>,
}


pub fn get_decoupled_authentication_type(&self) -> common_enums::DecoupledAuthenticationType {
        match self {
            Self::Challenge(_) => common_enums::DecoupledAuthenticationType::Challenge,
            Self::Frictionless => common_enums::DecoupledAuthenticationType::Frictionless,
        }
    }


pub struct PaymentsRequest {
    ds_merchant_emv3ds: Option<EmvThreedsData>,
    ds_merchant_transactiontype: RedsysTransactionType,
    ds_merchant_currency: String,
    ds_merchant_pan: cards::CardNumber,
    ds_merchant_merchantcode: Secret<String>,
    ds_merchant_terminal: Secret<String>,
    ds_merchant_order: String,
    ds_merchant_amount: StringMinorUnit,
    ds_merchant_expirydate: Secret<String>,
    ds_merchant_cvv2: Secret<String>,
}


pub struct MerchantKeyStoreUpdateInternal {
    pub merchant_id: common_utils::id_type::MerchantId,
    pub key: Encryption,
}


pub struct DisputeSyncResponse {
    pub object_reference_id: api_models::webhooks::ObjectReferenceId,
    pub amount: common_utils::types::StringMinorUnit,
    pub currency: common_enums::enums::Currency,
    pub dispute_stage: common_enums::enums::DisputeStage,
    pub dispute_status: api_models::enums::DisputeStatus,
    pub connector_status: String,
    pub connector_dispute_id: String,
    pub connector_reason: Option<String>,
    pub connector_reason_code: Option<String>,
    pub challenge_required_by: Option<time::PrimitiveDateTime>,
    pub created_at: Option<time::PrimitiveDateTime>,
    pub updated_at: Option<time::PrimitiveDateTime>,
}


impl Responder {
        let flow = AnalyticsFlow::GetRefundFilters;
        Box::pin(api::server_wrap(
            flow,
            state,
            &req,
            json_payload.into_inner(),
            |state, auth: AuthenticationData, req: GetRefundFilterRequest, _| async move {
                let org_id = auth.merchant_account.get_org_id();
                let merchant_id = auth.merchant_account.get_id();
                let auth: AuthInfo = AuthInfo::MerchantLevel {
                    org_id: org_id.clone(),
                    merchant_ids: vec![merchant_id.clone()],
                };
                analytics::refunds::get_filters(&state.pool, req, &auth)
                    .await
                    .map(ApplicationResponse::Json)
            },
            &auth::JWTAuth {
                permission: Permission::MerchantAnalyticsRead,
            },
            api_locking::LockAction::NotApplicable,
        ))
        .await
    }


pub fn from_storage(authentication: &'a Authentication) -> Self {
        Self {
            created_at: authentication.created_at.assume_utc(),
            modified_at: authentication.modified_at.assume_utc(),
            authentication_id: &authentication.authentication_id,
            merchant_id: &authentication.merchant_id,
            authentication_status: authentication.authentication_status,
            authentication_connector: authentication.authentication_connector.as_ref(),
            connector_authentication_id: authentication.connector_authentication_id.as_ref(),
            authentication_data: authentication.authentication_data.clone(),
            payment_method_id: &authentication.payment_method_id,
            authentication_type: authentication.authentication_type,
            authentication_lifecycle_status: authentication.authentication_lifecycle_status,
            error_code: authentication.error_code.as_ref(),
            error_message: authentication.error_message.as_ref(),
            connector_metadata: authentication.connector_metadata.clone(),
            maximum_supported_version: authentication.maximum_supported_version.clone(),
            threeds_server_transaction_id: authentication.threeds_server_transaction_id.as_ref(),
            cavv: authentication.cavv.as_ref(),
            authentication_flow_type: authentication.authentication_flow_type.as_ref(),
            message_version: authentication.message_version.clone(),
            eci: authentication.eci.as_ref(),
            trans_status: authentication.trans_status.clone(),
            acquirer_bin: authentication.acquirer_bin.as_ref(),
            acquirer_merchant_id: authentication.acquirer_merchant_id.as_ref(),
            three_ds_method_data: authentication.three_ds_method_data.as_ref(),
            three_ds_method_url: authentication.three_ds_method_url.as_ref(),
            acs_url: authentication.acs_url.as_ref(),
            challenge_request: authentication.challenge_request.as_ref(),
            acs_reference_number: authentication.acs_reference_number.as_ref(),
            acs_trans_id: authentication.acs_trans_id.as_ref(),
            acs_signed_content: authentication.acs_signed_content.as_ref(),
            profile_id: &authentication.profile_id,
            payment_id: authentication.payment_id.as_ref(),
            merchant_connector_id: authentication.merchant_connector_id.as_ref(),
            ds_trans_id: authentication.ds_trans_id.as_ref(),
            directory_server_id: authentication.directory_server_id.as_ref(),
            acquirer_country_code: authentication.acquirer_country_code.as_ref(),
            organization_id: &authentication.organization_id,
        }
    }


impl api::PaymentSession for Bluecode {}

impl api::PaymentSession for for Bluecode


OpenAPI Block Path: components.schemas.CardType
{
  "type": "string",
  "enum": [
    "credit",
    "debit"
  ]
}


File: crates/router/tests/connectors/noon.rs

use std::str::FromStr;

use masking::Secret;
use router::types::{self, storage::enums};

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

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

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

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

static CONNECTOR: NoonTest = NoonTest {};

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

fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    Some(types::PaymentsAuthorizeData {
        currency: enums::Currency::AED,
        ..utils::PaymentAuthorizeType::default().0
    })
}

// 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 card number.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_card_number() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: types::domain::PaymentMethodData::Card(types::domain::Card {
                    card_number: cards::CardNumber::from_str("1234567891011").unwrap(),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card number is incorrect.".to_string(),
    );
}

// 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: types::domain::PaymentMethodData::Card(types::domain::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: types::domain::PaymentMethodData::Card(types::domain::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: types::domain::PaymentMethodData::Card(types::domain::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


pub async fn mk_tokenization_req(
    state: &routes::SessionState,
    payload_bytes: &[u8],
    customer_id: id_type::CustomerId,
    tokenization_service: &settings::NetworkTokenizationService,
) -> CustomResult<
    (pm_types::CardNetworkTokenResponsePayload, Option<String>),
    errors::NetworkTokenizationError,
> {
    let enc_key = tokenization_service.public_key.peek().clone();

    let key_id = tokenization_service.key_id.clone();

    let jwt = encryption::encrypt_jwe(
        payload_bytes,
        enc_key,
        services::EncryptionAlgorithm::A128GCM,
        Some(key_id.as_str()),
    )
    .await
    .change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
    .attach_printable("Error on jwe encrypt")?;

    let order_data = pm_types::OrderData {
        consent_id: uuid::Uuid::new_v4().to_string(),
        customer_id,
    };

    let api_payload = pm_types::ApiPayload {
        service: NETWORK_TOKEN_SERVICE.to_string(),
        card_data: Secret::new(jwt),
        order_data,
        key_id,
        should_send_token: true,
    };

    let mut request = services::Request::new(
        services::Method::Post,
        tokenization_service.generate_token_url.as_str(),
    );
    request.add_header(headers::CONTENT_TYPE, "application/json".into());
    request.add_header(
        headers::AUTHORIZATION,
        tokenization_service
            .token_service_api_key
            .peek()
            .clone()
            .into_masked(),
    );
    request.add_default_headers();

    request.set_body(RequestContent::Json(Box::new(api_payload)));

    logger::info!("Request to generate token: {:?}", request);

    let response = services::call_connector_api(state, request, "generate_token")
        .await
        .change_context(errors::NetworkTokenizationError::ApiError);

    let res = response
        .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)
        .attach_printable("Error while receiving response")
        .and_then(|inner| match inner {
            Err(err_res) => {
                let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
                    .response
                    .parse_struct("Card Network Tokenization Response")
                    .change_context(
                        errors::NetworkTokenizationError::ResponseDeserializationFailed,
                    )?;
                logger::error!(
                    error_code = %parsed_error.error_info.code,
                    developer_message = %parsed_error.error_info.developer_message,
                    "Network tokenization error: {}",
                    parsed_error.error_message
                );
                Err(errors::NetworkTokenizationError::ResponseDeserializationFailed)
                    .attach_printable(format!("Response Deserialization Failed: {err_res:?}"))
            }
            Ok(res) => Ok(res),
        })
        .inspect_err(|err| {
            logger::error!("Error while deserializing response: {:?}", err);
        })?;

    let network_response: pm_types::CardNetworkTokenResponse = res
        .response
        .parse_struct("Card Network Tokenization Response")
        .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;

    let dec_key = tokenization_service.private_key.peek().clone();

    let card_network_token_response = services::decrypt_jwe(
        network_response.payload.peek(),
        services::KeyIdCheck::SkipKeyIdCheck,
        dec_key,
        jwe::RSA_OAEP_256,
    )
    .await
    .change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
    .attach_printable(
        "Failed to decrypt the tokenization response from the tokenization service",
    )?;

    let cn_response: pm_types::CardNetworkTokenResponsePayload =
        serde_json::from_str(&card_network_token_response)
            .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
    Ok((cn_response.clone(), Some(cn_response.card_reference)))
}


OpenAPI Block Path: components.schemas.RoutingEvaluateResponse
{
  "type": "object",
  "required": [
    "status",
    "output",
    "evaluated_output",
    "eligible_connectors"
  ],
  "properties": {
    "status": {
      "type": "string"
    },
    "output": {},
    "evaluated_output": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/RoutableConnectorChoice"
      }
    },
    "eligible_connectors": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/RoutableConnectorChoice"
      }
    }
  }
}


pub struct RecipientCreateResponse {
    pub recipient_id: String,
}


File: crates/analytics/src/payment_intents/metrics/sessionized_metrics/payment_intent_count.rs

use std::collections::HashSet;

use api_models::analytics::{
    payment_intents::{
        PaymentIntentDimensions, PaymentIntentFilters, PaymentIntentMetricsBucketIdentifier,
    },
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::PaymentIntentMetricRow;
use crate::{
    enums::AuthInfo,
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, SeriesBucket, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
};

#[derive(Default)]
pub(crate) struct PaymentIntentCount;

#[async_trait::async_trait]
impl<T> super::PaymentIntentMetric<T> for PaymentIntentCount
where
    T: AnalyticsDataSource + super::PaymentIntentMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        dimensions: &[PaymentIntentDimensions],
        auth: &AuthInfo,
        filters: &PaymentIntentFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(PaymentIntentMetricsBucketIdentifier, PaymentIntentMetricRow)>>
    {
        let mut query_builder: QueryBuilder<T> =
            QueryBuilder::new(AnalyticsCollection::PaymentIntentSessionized);

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

        query_builder
            .add_select_column(Aggregate::Count {
                field: None,
                alias: Some("count"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Min {
                field: "created_at",
                alias: Some("start_bucket"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Max {
                field: "created_at",
                alias: Some("end_bucket"),
            })
            .switch()?;

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

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

        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;

        for dim in dimensions.iter() {
            query_builder
                .add_group_by_clause(dim)
                .attach_printable("Error grouping by dimensions")
                .switch()?;
        }

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

        query_builder
            .execute_query::<PaymentIntentMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    PaymentIntentMetricsBucketIdentifier::new(
                        i.status.as_ref().map(|i| i.0),
                        i.currency.as_ref().map(|i| i.0),
                        i.profile_id.clone(),
                        i.connector.clone(),
                        i.authentication_type.as_ref().map(|i| i.0),
                        i.payment_method.clone(),
                        i.payment_method_type.clone(),
                        i.card_network.clone(),
                        i.merchant_id.clone(),
                        i.card_last_4.clone(),
                        i.card_issuer.clone(),
                        i.error_reason.clone(),
                        TimeRange {
                            start_time: match (granularity, i.start_bucket) {
                                (Some(g), Some(st)) => g.clip_to_start(st)?,
                                _ => time_range.start_time,
                            },
                            end_time: granularity.as_ref().map_or_else(
                                || Ok(time_range.end_time),
                                |g| i.end_bucket.map(|et| g.clip_to_end(et)).transpose(),
                            )?,
                        },
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(PaymentIntentMetricsBucketIdentifier, PaymentIntentMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


impl ConnectorValidation for Taxjar {}


OpenAPI Block Path: components.schemas.ThreeDsData
{
  "type": "object",
  "required": [
    "three_ds_server_transaction_id",
    "maximum_supported_3ds_version",
    "connector_authentication_id",
    "three_ds_method_data",
    "three_ds_method_url",
    "message_version",
    "directory_server_id"
  ],
  "properties": {
    "three_ds_server_transaction_id": {
      "type": "string",
      "description": "The unique identifier for this authentication from the 3DS server."
    },
    "maximum_supported_3ds_version": {
      "type": "string",
      "description": "The maximum supported 3DS version."
    },
    "connector_authentication_id": {
      "type": "string",
      "description": "The unique identifier for this authentication from the connector."
    },
    "three_ds_method_data": {
      "type": "string",
      "description": "The data required to perform the 3DS method."
    },
    "three_ds_method_url": {
      "type": "string",
      "description": "The URL to which the user should be redirected after authentication.",
      "example": "https://example.com/redirect"
    },
    "message_version": {
      "type": "string",
      "description": "The version of the message."
    },
    "directory_server_id": {
      "type": "string",
      "description": "The unique identifier for this authentication."
    }
  }
}


impl AdminApiAuthWithApiKeyFallbackAndMerchantIdFromRoute {
    async fn fetch_merchant_key_store_and_account<A: SessionStateInfo + Sync>(
        merchant_id: &id_type::MerchantId,
        state: &A,
    ) -> RouterResult<(domain::MerchantKeyStore, domain::MerchantAccount)> {
        let key_manager_state = &(&state.session_state()).into();
        let key_store = state
            .store()
            .get_merchant_key_store_by_merchant_id(
                key_manager_state,
                merchant_id,
                &state.store().get_master_key().to_vec().into(),
            )
            .await
            .to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;

        let merchant = state
            .store()
            .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
            .await
            .to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;

        Ok((key_store, merchant))
    }
}


OpenAPI Block Path: components.schemas.ComparisonType
{
  "type": "string",
  "description": "Conditional comparison type",
  "enum": [
    "equal",
    "not_equal",
    "less_than",
    "less_than_equal",
    "greater_than",
    "greater_than_equal"
  ]
}


pub trait Feature<F, T> {
    async fn decide_flows<'a>(
        self,
        state: &SessionState,
        connector: &api::ConnectorData,
        call_connector_action: payments::CallConnectorAction,
        connector_request: Option<services::Request>,
        business_profile: &domain::Profile,
        header_payload: hyperswitch_domain_models::payments::HeaderPayload,
        return_raw_connector_response: Option<bool>,
    ) -> RouterResult<Self>
    where
        Self: Sized,
        F: Clone,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>;

    async fn add_access_token<'a>(
        &self,
        state: &SessionState,
        connector: &api::ConnectorData,
        merchant_context: &domain::MerchantContext,
        creds_identifier: Option<&str>,
    ) -> RouterResult<types::AddAccessTokenResult>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>;

    async fn add_session_token<'a>(
        self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
    ) -> RouterResult<Self>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(self)
    }

    async fn add_payment_method_token<'a>(
        &mut self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
        _tokenization_action: &payments::TokenizationAction,
        _should_continue_payment: bool,
    ) -> RouterResult<types::PaymentMethodTokenResult>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(types::PaymentMethodTokenResult {
            payment_method_token_result: Ok(None),
            is_payment_method_tokenization_performed: false,
            connector_response: None,
        })
    }

    async fn preprocessing_steps<'a>(
        self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
    ) -> RouterResult<Self>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(self)
    }

    async fn postprocessing_steps<'a>(
        self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
    ) -> RouterResult<Self>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(self)
    }

    async fn create_connector_customer<'a>(
        &self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
    ) -> RouterResult<Option<String>>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(None)
    }

    /// Returns the connector request and a bool which specifies whether to proceed with further
    async fn build_flow_specific_connector_request(
        &mut self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
        _call_connector_action: payments::CallConnectorAction,
    ) -> RouterResult<(Option<services::Request>, bool)> {
        Ok((None, true))
    }

    async fn create_order_at_connector(
        &mut self,
        _state: &SessionState,
        _connector: &api::ConnectorData,
        _should_continue_payment: bool,
    ) -> RouterResult<Option<types::CreateOrderResult>>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(None)
    }

    fn update_router_data_with_create_order_response(
        &mut self,
        _create_order_result: types::CreateOrderResult,
    ) {
    }

    async fn call_unified_connector_service<'a>(
        &mut self,
        _state: &SessionState,
        #[cfg(feature = "v1")] _merchant_connector_account: helpers::MerchantConnectorAccountType,
        #[cfg(feature = "v2")]
        _merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
        _merchant_context: &domain::MerchantContext,
    ) -> RouterResult<()>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(())
    }

    #[cfg(feature = "v2")]
    async fn call_unified_connector_service_with_external_vault_proxy<'a>(
        &mut self,
        _state: &SessionState,
        _merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
        _external_vault_merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
        _merchant_context: &domain::MerchantContext,
    ) -> RouterResult<()>
    where
        F: Clone,
        Self: Sized,
        dyn api::Connector: services::ConnectorIntegration<F, T, types::PaymentsResponseData>,
    {
        Ok(())
    }
}


pub struct SdkEventMetricsBucketValue {
    pub payment_attempts: Option<u64>,
    pub payment_methods_call_count: Option<u64>,
    pub average_payment_time: Option<u64>,
    pub load_time: Option<u64>,
    pub sdk_rendered_count: Option<u64>,
    pub sdk_initiated_count: Option<u64>,
    pub payment_method_selected_count: Option<u64>,
    pub payment_data_filled_count: Option<u64>,
}


pub struct DynamicAlgorithmWithTimestamp<T> {
    pub algorithm_id: Option<T>,
    pub timestamp: i64,
}


/// A helper struct to extract headers from the request
pub(crate) struct HeaderMapStruct<'a> {
    headers: &'a HeaderMap,
}


impl Default for PaymentMethodsPTMapping {
    fn default() -> Self {
        Self {
            custom_pm_mapping: HashMap::new(),
            default_mapping: RetryMapping {
                start_after: 900,
                frequencies: vec![(300, 5)],
            },
            max_retries_count: 5,
        }
    }
}

impl Default for for PaymentMethodsPTMapping


OpenAPI Block Path: components.schemas.RefundListResponse
{
  "type": "object",
  "required": [
    "count",
    "total_count",
    "data"
  ],
  "properties": {
    "count": {
      "type": "integer",
      "description": "The number of refunds included in the list",
      "minimum": 0
    },
    "total_count": {
      "type": "integer",
      "format": "int64",
      "description": "The total number of refunds in the list"
    },
    "data": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/RefundResponse"
      },
      "description": "The List of refund response object"
    }
  }
}


pub struct FiservemeaPaymentsRequest {
    request_type: FiservemeaRequestType,
    merchant_transaction_id: String,
    transaction_amount: FiservemeaTransactionAmount,
    order: FiservemeaOrder,
    payment_method: FiservemeaPaymentMethods,
}


pub struct Address {
    pub address: Option<AddressDetails>,
    pub phone: Option<PhoneDetails>,
    pub email: Option<common_utils::pii::Email>,
}


impl api::PaymentSync for Cashtocode {}

impl api::PaymentSync for for Cashtocode


pub struct Card {
    number: cards::CardNumber,
    expiration_month: Secret<String>,
    expiration_year: Secret<String>,
    security_code: Secret<String>,
    #[serde(rename = "type")]
    card_type: Option<String>,
}


pub struct ListUserRolesByUserIdPayload<'a> {
    pub user_id: &'a str,
    pub tenant_id: &'a id_type::TenantId,
    pub org_id: Option<&'a id_type::OrganizationId>,
    pub merchant_id: Option<&'a id_type::MerchantId>,
    pub profile_id: Option<&'a id_type::ProfileId>,
    pub entity_id: Option<&'a String>,
    pub version: Option<enums::UserRoleVersion>,
    pub status: Option<UserStatus>,
    pub limit: Option<u32>,
}


impl EmailSettings {
    /// Validation for the Email client specific configurations
    pub fn validate(&self) -> Result<(), &'static str> {
        match &self.client_config {
            EmailClientConfigs::Ses { ref aws_ses } => aws_ses.validate(),
            EmailClientConfigs::Smtp { ref smtp } => smtp.validate(),
            EmailClientConfigs::NoEmailClient => Ok(()),
        }
    }
}


pub async fn spawn(&self) -> errors::DrainerResult<()> {
        let mut stream_index: u8 = 0;
        let jobs_picked = Arc::new(atomic::AtomicU8::new(0));

        while self.running.load(atomic::Ordering::SeqCst) {
            metrics::DRAINER_HEALTH.add(1, &[]);
            for store in self.stores.values() {
                if store.is_stream_available(stream_index).await {
                    let _task_handle = tokio::spawn(
                        drainer_handler(
                            store.clone(),
                            stream_index,
                            self.conf.max_read_count,
                            self.active_tasks.clone(),
                            jobs_picked.clone(),
                        )
                        .in_current_span(),
                    );
                }
            }
            stream_index = utils::increment_stream_index(
                (stream_index, jobs_picked.clone()),
                self.conf.num_partitions,
            )
            .await;
            time::sleep(self.loop_interval).await;
        }

        Ok(())
    }


pub struct VgsInsertResponse {
    data: Vec<VgsTokenResponseItem>,
}


pub struct AuthorizedotnetWebhookObjectId {
    pub webhook_id: String,
    pub event_type: AuthorizedotnetWebhookEvent,
    pub payload: AuthorizedotnetWebhookPayload,
}


pub fn is_for_internal_use_only(self) -> bool {
        match self {
            Self::Dashboard | Self::Sdk | Self::MerchantServer | Self::Postman => false,
            Self::Webhook | Self::ExternalAuthenticator => true,
        }
    }


pub fn get_default_customer_billing_address(&self) -> Option<payments::AddressDetails> {
        self.default_billing_address.clone()
    }


pub struct IssuerInformation {
    country: Option<enums::CountryAlpha2>,
    discretionary_data: Option<String>,
    country_specific_discretionary_data: Option<String>,
    response_code: Option<String>,
    pin_request_indicator: Option<String>,
}


impl api::Refund for Checkout {}


pub struct SdkEventsRequest {
    pub payment_id: common_utils::id_type::PaymentId,
    pub time_range: TimeRange,
}


impl api::Payouts for Wise {}


pub struct PaymentsSyncData {
    //TODO : add fields based on the connector requirements
    pub connector_transaction_id: ResponseId,
    pub encoded_data: Option<String>,
    pub capture_method: Option<storage_enums::CaptureMethod>,
    pub connector_meta: Option<serde_json::Value>,
    pub sync_type: SyncRequestType,
    pub mandate_id: Option<api_models::payments::MandateIds>,
    pub payment_method_type: Option<storage_enums::PaymentMethodType>,
    pub currency: storage_enums::Currency,
    pub payment_experience: Option<common_enums::PaymentExperience>,
    pub split_payments: Option<common_types::payments::SplitPaymentsRequest>,
    pub amount: MinorUnit,
    pub integrity_object: Option<SyncIntegrityObject>,
    pub connector_reference_id: Option<String>,
}


pub struct Paypal {
    #[serde(rename = "payerID")]
    payer_id: Option<Secret<String>>,
}