File: crates/hyperswitch_connectors/src/connectors/unified_authentication_service/transformers.rs
 Public functions: 1
 Public structs: 36

use common_enums::{enums, MerchantCategoryCode};
use common_types::payments::MerchantCountryCode;
use common_utils::{ext_traits::OptionExt as _, types::FloatMajorUnit};
use hyperswitch_domain_models::{
    router_data::{ConnectorAuthType, RouterData},
    router_request_types::{
        authentication::{AuthNFlowType, ChallengeParams},
        unified_authentication_service::{
            AuthenticationInfo, DynamicData, PostAuthenticationDetails, PreAuthenticationDetails,
            TokenDetails, UasAuthenticationResponseData,
        },
    },
    types::{
        UasAuthenticationConfirmationRouterData, UasAuthenticationRouterData,
        UasPostAuthenticationRouterData, UasPreAuthenticationRouterData,
    },
};
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

use crate::types::ResponseRouterData;
//TODO: Fill the struct with respective fields
pub struct UnifiedAuthenticationServiceRouterData<T> {
    pub amount: FloatMajorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
    pub router_data: T,
}

impl<T> From<(FloatMajorUnit, T)> for UnifiedAuthenticationServiceRouterData<T> {
    fn from((amount, item): (FloatMajorUnit, T)) -> Self {
        //Todo :  use utils to convert the amount to the type of amount that a connector accepts
        Self {
            amount,
            router_data: item,
        }
    }
}

use error_stack::ResultExt;

#[derive(Debug, Serialize)]
pub struct UnifiedAuthenticationServicePreAuthenticateRequest {
    pub authenticate_by: String,
    pub session_id: common_utils::id_type::AuthenticationId,
    pub source_authentication_id: common_utils::id_type::AuthenticationId,
    pub authentication_info: Option<AuthenticationInfo>,
    pub service_details: Option<CtpServiceDetails>,
    pub customer_details: Option<CustomerDetails>,
    pub pmt_details: Option<PaymentDetails>,
    pub auth_creds: UnifiedAuthenticationServiceAuthType,
    pub transaction_details: Option<TransactionDetails>,
    pub acquirer_details: Option<Acquirer>,
    pub billing_address: Option<Address>,
}

#[derive(Debug, Serialize)]
pub struct UnifiedAuthenticationServiceAuthenticateConfirmationRequest {
    pub authenticate_by: String,
    pub source_authentication_id: common_utils::id_type::AuthenticationId,
    pub auth_creds: UnifiedAuthenticationServiceAuthType,
    pub x_src_flow_id: Option<String>,
    pub transaction_amount: Option<FloatMajorUnit>,
    pub transaction_currency: Option<enums::Currency>,
    pub checkout_event_type: Option<String>,
    pub checkout_event_status: Option<String>,
    pub confirmation_status: Option<String>,
    pub confirmation_reason: Option<String>,
    pub confirmation_timestamp: Option<String>,
    pub network_authorization_code: Option<String>,
    pub network_transaction_identifier: Option<String>,
    pub correlation_id: Option<String>,
    pub merchant_transaction_id: Option<String>,
}

#[derive(Debug, Serialize, PartialEq, Deserialize)]
pub struct UnifiedAuthenticationServiceAuthenticateConfirmationResponse {
    status: String,
}

impl<F, T>
    TryFrom<
        ResponseRouterData<
            F,
            UnifiedAuthenticationServiceAuthenticateConfirmationResponse,
            T,
            UasAuthenticationResponseData,
        >,
    > for RouterData<F, T, UasAuthenticationResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            UnifiedAuthenticationServiceAuthenticateConfirmationResponse,
            T,
            UasAuthenticationResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(UasAuthenticationResponseData::Confirmation {}),
            ..item.data
        })
    }
}

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

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct TransactionDetails {
    pub amount: FloatMajorUnit,
    pub currency: enums::Currency,
    pub date: Option<PrimitiveDateTime>,
    pub pan_source: Option<String>,
    pub protection_type: Option<String>,
    pub entry_mode: Option<String>,
    pub transaction_type: Option<String>,
    pub otp_value: Option<String>,
    pub three_ds_data: Option<ThreeDSData>,
    pub message_category: Option<MessageCategory>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MessageCategory {
    Payment,
    NonPayment,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThreeDSData {
    pub preferred_protocol_version: common_utils::types::SemanticVersion,
    pub threeds_method_comp_ind: api_models::payments::ThreeDsCompletionIndicator,
}

#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Acquirer {
    pub acquirer_merchant_id: Option<String>,
    pub acquirer_bin: Option<String>,
    pub acquirer_country_code: Option<String>,
}

#[derive(Default, Debug, Serialize, PartialEq, Clone, Deserialize)]
pub struct BrowserInfo {
    pub color_depth: Option<u8>,
    pub java_enabled: Option<bool>,
    pub java_script_enabled: Option<bool>,
    pub language: Option<String>,
    pub screen_height: Option<u32>,
    pub screen_width: Option<u32>,
    pub time_zone: Option<i32>,
    pub ip_address: Option<std::net::IpAddr>,
    pub accept_header: Option<String>,
    pub user_agent: Option<String>,
    pub os_type: Option<String>,
    pub os_version: Option<String>,
    pub device_model: Option<String>,
    pub accept_language: Option<String>,
}

#[derive(Default, Debug, Serialize, PartialEq)]
pub struct CtpServiceDetails {
    pub service_session_ids: Option<ServiceSessionIds>,
    pub merchant_details: Option<MerchantDetails>,
}

#[derive(Default, Debug, Serialize, PartialEq)]
pub struct ServiceSessionIds {
    pub client_id: Option<String>,
    pub service_id: Option<String>,
    pub correlation_id: Option<String>,
    pub client_reference_id: Option<String>,
    pub merchant_transaction_id: Option<String>,
    pub x_src_flow_id: Option<String>,
}

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

#[derive(Default, Clone, Debug, Serialize, PartialEq, Deserialize)]
pub struct Address {
    pub city: Option<String>,
    pub country: Option<common_enums::CountryAlpha2>,
    pub line1: Option<Secret<String>>,
    pub line2: Option<Secret<String>>,
    pub line3: Option<Secret<String>>,
    pub post_code: Option<Secret<String>>,
    pub state: Option<Secret<String>>,
}

#[derive(Default, Clone, Debug, Serialize, PartialEq, Deserialize)]
pub struct CustomerDetails {
    pub name: Secret<String>,
    pub email: Option<Secret<String>>,
    pub phone_number: Option<Secret<String>>,
    pub customer_id: String,
    #[serde(rename = "type")]
    pub customer_type: Option<String>,
    pub billing_address: Address,
    pub shipping_address: Address,
    pub wallet_account_id: Secret<String>,
    pub email_hash: Secret<String>,
    pub country_code: String,
    pub national_identifier: String,
}

#[derive(Default, Debug, Serialize, Eq, PartialEq)]
pub struct UnifiedAuthenticationServiceCard {
    number: cards::CardNumber,
    expiry_month: Secret<String>,
    expiry_year: Secret<String>,
    cvc: Secret<String>,
    complete: bool,
}

impl TryFrom<&UnifiedAuthenticationServiceRouterData<&UasPreAuthenticationRouterData>>
    for UnifiedAuthenticationServicePreAuthenticateRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &UnifiedAuthenticationServiceRouterData<&UasPreAuthenticationRouterData>,
    ) -> Result<Self, Self::Error> {
        let authentication_id = item.router_data.authentication_id.clone().ok_or(
            errors::ConnectorError::MissingRequiredField {
                field_name: "authentication_id",
            },
        )?;
        let authentication_info = item.router_data.request.authentication_info.clone();
        let auth_type =
            UnifiedAuthenticationServiceAuthType::try_from(&item.router_data.connector_auth_type)?;
        Ok(Self {
            authenticate_by: item.router_data.connector.clone(),
            session_id: authentication_id.clone(),
            source_authentication_id: authentication_id,
            authentication_info,
            service_details: Some(CtpServiceDetails {
                service_session_ids: item.router_data.request.service_details.clone().map(
                    |service_details| ServiceSessionIds {
                        client_id: None,
                        service_id: None,
                        correlation_id: service_details
                            .service_session_ids
                            .clone()
                            .and_then(|service_session_ids| service_session_ids.correlation_id),
                        client_reference_id: None,
                        merchant_transaction_id: service_details
                            .service_session_ids
                            .clone()
                            .and_then(|service_session_ids| {
                                service_session_ids.merchant_transaction_id
                            }),
                        x_src_flow_id: service_details
                            .service_session_ids
                            .clone()
                            .and_then(|service_session_ids| service_session_ids.x_src_flow_id),
                    },
                ),
                merchant_details: None,
            }),
            customer_details: None,
            pmt_details: None,
            auth_creds: auth_type,
            acquirer_details: None,
            billing_address: None,
            transaction_details: Some(TransactionDetails {
                amount: item.amount,
                currency: item
                    .router_data
                    .request
                    .transaction_details
                    .clone()
                    .ok_or(errors::ConnectorError::MissingRequiredField {
                        field_name: "transaction_details",
                    })?
                    .currency
                    .ok_or(errors::ConnectorError::MissingRequiredField {
                        field_name: "currency",
                    })?,
                date: None,
                pan_source: None,
                protection_type: None,
                entry_mode: None,
                transaction_type: None,
                otp_value: None,
                three_ds_data: None,
                message_category: None,
            }),
        })
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum UnifiedAuthenticationServicePreAuthenticateStatus {
    ACKSUCCESS,
    ACKFAILURE,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UnifiedAuthenticationServicePreAuthenticateResponse {
    status: UnifiedAuthenticationServicePreAuthenticateStatus,
    pub eligibility: Option<Eligibility>,
}

impl<F, T>
    TryFrom<
        ResponseRouterData<
            F,
            UnifiedAuthenticationServicePreAuthenticateResponse,
            T,
            UasAuthenticationResponseData,
        >,
    > for RouterData<F, T, UasAuthenticationResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            UnifiedAuthenticationServicePreAuthenticateResponse,
            T,
            UasAuthenticationResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        let three_ds_eligibility_response = if let Some(Eligibility::ThreeDsEligibilityResponse {
            three_ds_eligibility_response,
        }) = item.response.eligibility
        {
            Some(three_ds_eligibility_response)
        } else {
            None
        };
        let max_acs_protocol_version = three_ds_eligibility_response
            .as_ref()
            .and_then(|response| response.get_max_acs_protocol_version_if_available());
        let maximum_supported_3ds_version = max_acs_protocol_version
            .as_ref()
            .map(|acs_protocol_version| acs_protocol_version.version.clone());
        let three_ds_method_data =
            three_ds_eligibility_response
                .as_ref()
                .and_then(|three_ds_eligibility_response| {
                    three_ds_eligibility_response
                        .three_ds_method_data_form
                        .as_ref()
                        .and_then(|form| form.three_ds_method_data.clone())
                });
        let three_ds_method_url = max_acs_protocol_version
            .and_then(|acs_protocol_version| acs_protocol_version.three_ds_method_url);
        Ok(Self {
            response: Ok(UasAuthenticationResponseData::PreAuthentication {
                authentication_details: PreAuthenticationDetails {
                    threeds_server_transaction_id: three_ds_eligibility_response
                        .as_ref()
                        .map(|response| response.three_ds_server_trans_id.clone()),
                    maximum_supported_3ds_version: maximum_supported_3ds_version.clone(),
                    connector_authentication_id: three_ds_eligibility_response
                        .as_ref()
                        .map(|response| response.three_ds_server_trans_id.clone()),
                    three_ds_method_data,
                    three_ds_method_url,
                    message_version: maximum_supported_3ds_version,
                    connector_metadata: None,
                    directory_server_id: three_ds_eligibility_response
                        .and_then(|response| response.directory_server_id),
                },
            }),
            ..item.data
        })
    }
}

#[derive(Debug, Serialize)]
pub struct UnifiedAuthenticationServicePostAuthenticateRequest {
    pub authenticate_by: String,
    pub source_authentication_id: common_utils::id_type::AuthenticationId,
    pub auth_creds: ConnectorAuthType,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UnifiedAuthenticationServicePostAuthenticateResponse {
    pub authentication_details: AuthenticationDetails,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AuthenticationDetails {
    pub eci: Option<String>,
    pub token_details: Option<UasTokenDetails>,
    pub dynamic_data_details: Option<UasDynamicData>,
    pub trans_status: Option<common_enums::TransactionStatus>,
}

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

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

impl TryFrom<&UasPostAuthenticationRouterData>
    for UnifiedAuthenticationServicePostAuthenticateRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &UasPostAuthenticationRouterData) -> Result<Self, Self::Error> {
        Ok(Self {
            authenticate_by: item.connector.clone(),
            source_authentication_id: item.authentication_id.clone().ok_or(
                errors::ConnectorError::MissingRequiredField {
                    field_name: "authentication_id",
                },
            )?,
            auth_creds: item.connector_auth_type.clone(),
        })
    }
}

impl<F, T>
    TryFrom<
        ResponseRouterData<
            F,
            UnifiedAuthenticationServicePostAuthenticateResponse,
            T,
            UasAuthenticationResponseData,
        >,
    > for RouterData<F, T, UasAuthenticationResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            UnifiedAuthenticationServicePostAuthenticateResponse,
            T,
            UasAuthenticationResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(UasAuthenticationResponseData::PostAuthentication {
                authentication_details: PostAuthenticationDetails {
                    eci: item.response.authentication_details.eci,
                    token_details: item.response.authentication_details.token_details.map(
                        |token_details| TokenDetails {
                            payment_token: token_details.payment_token,
                            payment_account_reference: token_details.payment_account_reference,
                            token_expiration_month: token_details.token_expiration_month,
                            token_expiration_year: token_details.token_expiration_year,
                        },
                    ),
                    dynamic_data_details: item
                        .response
                        .authentication_details
                        .dynamic_data_details
                        .map(|dynamic_data| DynamicData {
                            dynamic_data_value: dynamic_data.dynamic_data_value,
                            dynamic_data_type: dynamic_data.dynamic_data_type,
                            ds_trans_id: dynamic_data.ds_trans_id,
                        }),
                    trans_status: item.response.authentication_details.trans_status,
                    challenge_cancel: None,
                    challenge_code_reason: None,
                },
            }),
            ..item.data
        })
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct UnifiedAuthenticationServiceErrorResponse {
    pub error: String,
}

impl TryFrom<&UnifiedAuthenticationServiceRouterData<&UasAuthenticationConfirmationRouterData>>
    for UnifiedAuthenticationServiceAuthenticateConfirmationRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &UnifiedAuthenticationServiceRouterData<&UasAuthenticationConfirmationRouterData>,
    ) -> Result<Self, Self::Error> {
        let authentication_id = item.router_data.authentication_id.clone().ok_or(
            errors::ConnectorError::MissingRequiredField {
                field_name: "authentication_id",
            },
        )?;
        let auth_type =
            UnifiedAuthenticationServiceAuthType::try_from(&item.router_data.connector_auth_type)?;

        Ok(Self {
            authenticate_by: item.router_data.connector.clone(),
            auth_creds: auth_type,
            source_authentication_id: authentication_id,
            x_src_flow_id: item.router_data.request.x_src_flow_id.clone(),
            transaction_amount: Some(item.amount),
            transaction_currency: Some(item.router_data.request.transaction_currency),
            checkout_event_type: item.router_data.request.checkout_event_type.clone(),
            checkout_event_status: item.router_data.request.checkout_event_status.clone(),
            confirmation_status: item.router_data.request.confirmation_status.clone(),
            confirmation_reason: item.router_data.request.confirmation_reason.clone(),
            confirmation_timestamp: item.router_data.request.confirmation_timestamp.clone(),
            network_authorization_code: item.router_data.request.network_authorization_code.clone(),
            network_transaction_identifier: item
                .router_data
                .request
                .network_transaction_identifier
                .clone(),
            correlation_id: item.router_data.request.correlation_id.clone(),
            merchant_transaction_id: item.router_data.request.merchant_transaction_id.clone(),
        })
    }
}

// ThreeDs request
impl TryFrom<&UasPreAuthenticationRouterData>
    for UnifiedAuthenticationServicePreAuthenticateRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &UasPreAuthenticationRouterData) -> Result<Self, Self::Error> {
        let auth_type = UnifiedAuthenticationServiceAuthType::try_from(&item.connector_auth_type)?;
        let authentication_id =
            item.authentication_id
                .clone()
                .ok_or(errors::ConnectorError::MissingRequiredField {
                    field_name: "authentication_id",
                })?;

        let merchant_data = item.request.merchant_details.clone().ok_or(
            errors::ConnectorError::MissingRequiredField {
                field_name: "merchant_details",
            },
        )?;

        let merchant_details = MerchantDetails {
            merchant_id: merchant_data.merchant_id,
            merchant_name: merchant_data.merchant_name,
            merchant_category_code: merchant_data.merchant_category_code,
            merchant_country_code: merchant_data.merchant_country_code.clone(),
            endpoint_prefix: merchant_data.endpoint_prefix,
            three_ds_requestor_url: merchant_data.three_ds_requestor_url,
            three_ds_requestor_id: merchant_data.three_ds_requestor_id,
            three_ds_requestor_name: merchant_data.three_ds_requestor_name,
            configuration_id: None,
            notification_url: merchant_data.notification_url,
        };

        let acquirer = Acquirer {
            acquirer_bin: item.request.acquirer_bin.clone(),
            acquirer_merchant_id: item.request.acquirer_merchant_id.clone(),
            acquirer_country_code: merchant_data
                .merchant_country_code
                .map(|code| code.get_country_code()),
        };

        let service_details = Some(CtpServiceDetails {
            service_session_ids: None,
            merchant_details: Some(merchant_details),
        });

        let billing_address = item
            .request
            .billing_address
            .clone()
            .map(|address_wrap| Address {
                city: address_wrap
                    .address
                    .clone()
                    .and_then(|address| address.city),
                country: address_wrap
                    .address
                    .clone()
                    .and_then(|address| address.country),
                line1: address_wrap
                    .address
                    .clone()
                    .and_then(|address| address.line1),
                line2: address_wrap
                    .address
                    .clone()
                    .and_then(|address| address.line2),
                line3: address_wrap
                    .address
                    .clone()
                    .and_then(|address| address.line3),
                post_code: address_wrap.address.clone().and_then(|address| address.zip),
                state: address_wrap.address.and_then(|address| address.state),
            });

        Ok(Self {
            authenticate_by: item.connector.clone(),
            session_id: authentication_id.clone(),
            source_authentication_id: authentication_id,
            authentication_info: None,
            service_details,
            customer_details: None,
            pmt_details: item
                .request
                .payment_details
                .clone()
                .map(|details| PaymentDetails {
                    pan: details.pan,
                    digital_card_id: details.digital_card_id,
                    payment_data_type: details.payment_data_type,
                    encrypted_src_card_details: details.encrypted_src_card_details,
                    cardholder_name: details.cardholder_name,
                    card_token_number: details.card_token_number,
                    account_type: details.account_type,
                    card_expiry_month: details.card_expiry_month,
                    card_expiry_year: details.card_expiry_year,
                    card_cvc: details.card_cvc,
                }),
            auth_creds: auth_type,
            transaction_details: None,
            acquirer_details: Some(acquirer),
            billing_address,
        })
    }
}

#[derive(Debug, Serialize, PartialEq)]
#[serde(tag = "auth_type")]
pub enum UnifiedAuthenticationServiceAuthType {
    HeaderKey {
        api_key: Secret<String>,
    },
    CertificateAuth {
        certificate: Secret<String>,
        private_key: Secret<String>,
    },
    NoKey,
}

impl TryFrom<&ConnectorAuthType> for UnifiedAuthenticationServiceAuthType {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        match auth_type {
            ConnectorAuthType::HeaderKey { api_key } => Ok(Self::HeaderKey {
                api_key: api_key.clone(),
            }),
            ConnectorAuthType::CertificateAuth {
                certificate,
                private_key,
            } => Ok(Self::CertificateAuth {
                certificate: certificate.clone(),
                private_key: private_key.clone(),
            }),
            ConnectorAuthType::NoKey => Ok(Self::NoKey),
            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
        }
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "eligibility")]
pub enum Eligibility {
    None,
    TokenEligibilityResponse {
        token_eligibility_response: Box<TokenEligibilityResponse>,
    },
    ThreeDsEligibilityResponse {
        three_ds_eligibility_response: Box<ThreeDsEligibilityResponse>,
    },
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TokenEligibilityResponse {
    pub network_request_id: Option<String>,
    pub network_client_id: Option<String>,
    pub nonce: Option<String>,
    pub payment_method_details: Option<PaymentMethodDetails>,
    pub network_pan_enrollment_id: Option<String>,
    pub ignore_00_field: Option<String>,
    pub token_details: Option<TokenDetails>,
    pub network_provisioned_token_id: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PaymentMethodDetails {
    pub ignore_01_field: String,
    pub cvv2_printed_ind: String,
    pub last4: String,
    pub exp_date_printed_ind: String,
    pub payment_account_reference: String,
    pub exp_year: String,
    pub exp_month: String,
    pub verification_results: VerificationResults,
    pub enabled_services: EnabledServices,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VerificationResults {
    pub address_verification_code: String,
    pub cvv2_verification_code: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EnabledServices {
    pub merchant_presented_qr: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ThreeDsEligibilityResponse {
    pub three_ds_server_trans_id: String,
    pub scheme_id: Option<String>,
    pub acs_protocol_versions: Option<Vec<AcsProtocolVersion>>,
    pub ds_protocol_versions: Option<Vec<String>>,
    pub three_ds_method_data_form: Option<ThreeDsMethodDataForm>,
    pub three_ds_method_data: Option<ThreeDsMethodData>,
    pub error_details: Option<String>,
    pub is_card_found_in_2x_ranges: bool,
    pub directory_server_id: Option<String>,
}

impl ThreeDsEligibilityResponse {
    pub fn get_max_acs_protocol_version_if_available(&self) -> Option<AcsProtocolVersion> {
        let max_acs_version =
            self.acs_protocol_versions
                .as_ref()
                .and_then(|acs_protocol_versions| {
                    acs_protocol_versions
                        .iter()
                        .max_by_key(|acs_protocol_versions| acs_protocol_versions.version.clone())
                });
        max_acs_version.cloned()
    }
}

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct AcsProtocolVersion {
    pub version: common_utils::types::SemanticVersion,
    pub acs_info_ind: Vec<String>,
    pub three_ds_method_url: Option<String>,
    pub supported_msg_ext: Option<Vec<SupportedMsgExt>>,
}

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct SupportedMsgExt {
    pub id: String,
    pub version: String,
}

#[derive(Clone, Serialize, Deserialize, Debug, Default)]
pub struct ThreeDsMethodDataForm {
    pub three_ds_method_data: Option<String>,
}

#[derive(Default, Clone, Serialize, Deserialize, Debug)]
pub struct ThreeDsMethodData {
    pub three_ds_method_notification_url: String,
    pub server_transaction_id: String,
}

#[derive(Serialize, Debug)]
pub struct UnifiedAuthenticationServiceAuthenticateRequest {
    pub authenticate_by: String,
    pub source_authentication_id: common_utils::id_type::AuthenticationId,
    pub transaction_details: TransactionDetails,
    pub device_details: DeviceDetails,
    pub customer_details: Option<CustomerDetails>,
    pub auth_creds: UnifiedAuthenticationServiceAuthType,
}

#[derive(Default, Debug, Serialize, PartialEq)]
pub struct ServiceDetails {
    pub service_session_ids: Option<ServiceSessionIds>,
    pub merchant_details: Option<MerchantDetails>,
}

#[derive(Serialize, Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum UnifiedAuthenticationServiceAuthenticateResponse {
    Success(Box<ThreeDsResponseData>),
    Failure(UnifiedAuthenticationServiceErrorResponse),
}

#[derive(Serialize, Debug, Clone, Deserialize)]
pub struct ThreeDsResponseData {
    pub three_ds_auth_response: ThreeDsAuthDetails,
}

#[derive(Serialize, Debug, Clone, Deserialize)]
pub struct ThreeDsAuthDetails {
    pub three_ds_server_trans_id: String,
    pub acs_trans_id: String,
    pub acs_reference_number: String,
    pub acs_operator_id: Option<String>,
    pub ds_reference_number: String,
    pub ds_trans_id: String,
    pub sdk_trans_id: Option<String>,
    pub trans_status: common_enums::TransactionStatus,
    pub acs_challenge_mandated: Option<ACSChallengeMandatedEnum>,
    pub message_type: String,
    pub message_version: String,
    pub acs_url: Option<url::Url>,
    pub challenge_request: Option<String>,
    pub acs_signed_content: Option<String>,
    pub authentication_value: Option<Secret<String>>,
    pub eci: Option<String>,
    pub challenge_code: Option<String>,
    pub challenge_cancel: Option<String>,
    pub challenge_code_reason: Option<String>,
    pub message_extension: Option<common_utils::pii::SecretSerdeValue>,
}

#[derive(Debug, Serialize, Clone, Copy, Deserialize)]
pub enum ACSChallengeMandatedEnum {
    /// Challenge is mandated
    Y,
    /// Challenge is not mandated
    N,
}

#[derive(Clone, Serialize, Debug)]
pub struct DeviceDetails {
    pub device_channel: api_models::payments::DeviceChannel,
    pub browser_info: Option<BrowserInfo>,
    pub sdk_info: Option<api_models::payments::SdkInformation>,
}

impl TryFrom<&UnifiedAuthenticationServiceRouterData<&UasAuthenticationRouterData>>
    for UnifiedAuthenticationServiceAuthenticateRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &UnifiedAuthenticationServiceRouterData<&UasAuthenticationRouterData>,
    ) -> Result<Self, Self::Error> {
        let authentication_id = item.router_data.authentication_id.clone().ok_or(
            errors::ConnectorError::MissingRequiredField {
                field_name: "authentication_id",
            },
        )?;

        let browser_info =
            if let Some(browser_details) = item.router_data.request.browser_details.clone() {
                BrowserInfo {
                    color_depth: browser_details.color_depth,
                    java_enabled: browser_details.java_enabled,
                    java_script_enabled: browser_details.java_script_enabled,
                    language: browser_details.language,
                    screen_height: browser_details.screen_height,
                    screen_width: browser_details.screen_width,
                    time_zone: browser_details.time_zone,
                    ip_address: browser_details.ip_address,
                    accept_header: browser_details.accept_header,
                    user_agent: browser_details.user_agent,
                    os_type: browser_details.os_type,
                    os_version: browser_details.os_version,
                    device_model: browser_details.device_model,
                    accept_language: browser_details.accept_language,
                }
            } else {
                BrowserInfo::default()
            };

        let three_ds_data = ThreeDSData {
            preferred_protocol_version: item
                .router_data
                .request
                .pre_authentication_data
                .message_version
                .clone(),
            threeds_method_comp_ind: item.router_data.request.threeds_method_comp_ind.clone(),
        };

        let device_details = DeviceDetails {
            device_channel: item
                .router_data
                .request
                .transaction_details
                .device_channel
                .clone()
                .ok_or(errors::ConnectorError::MissingRequiredField {
                    field_name: "device_channel",
                })?,
            browser_info: Some(browser_info),
            sdk_info: item.router_data.request.sdk_information.clone(),
        };

        let message_category = item.router_data.request.transaction_details.message_category.clone().map(|category| match category {
            hyperswitch_domain_models::router_request_types::authentication::MessageCategory::Payment => MessageCategory::Payment ,
            hyperswitch_domain_models::router_request_types::authentication::MessageCategory::NonPayment => MessageCategory::NonPayment,
        });

        let transaction_details = TransactionDetails {
            amount: item.amount,
            currency: item
                .router_data
                .request
                .transaction_details
                .currency
                .get_required_value("currency")
                .change_context(errors::ConnectorError::InSufficientBalanceInPaymentMethod)?,
            date: None,
            pan_source: None,
            protection_type: None,
            entry_mode: None,
            transaction_type: None,
            otp_value: None,
            three_ds_data: Some(three_ds_data),
            message_category,
        };
        let auth_type =
            UnifiedAuthenticationServiceAuthType::try_from(&item.router_data.connector_auth_type)?;

        Ok(Self {
            authenticate_by: item.router_data.connector.clone(),
            source_authentication_id: authentication_id,
            transaction_details,
            auth_creds: auth_type,
            device_details,
            customer_details: None,
        })
    }
}

impl<F, T>
    TryFrom<
        ResponseRouterData<
            F,
            UnifiedAuthenticationServiceAuthenticateResponse,
            T,
            UasAuthenticationResponseData,
        >,
    > for RouterData<F, T, UasAuthenticationResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            UnifiedAuthenticationServiceAuthenticateResponse,
            T,
            UasAuthenticationResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        let response = match item.response {
            UnifiedAuthenticationServiceAuthenticateResponse::Success(auth_response) => {
                let authn_flow_type = match auth_response
                    .three_ds_auth_response
                    .acs_challenge_mandated
                {
                    Some(ACSChallengeMandatedEnum::Y) => {
                        AuthNFlowType::Challenge(Box::new(ChallengeParams {
                            acs_url: auth_response.three_ds_auth_response.acs_url.clone(),
                            challenge_request: auth_response
                                .three_ds_auth_response
                                .challenge_request,
                            acs_reference_number: Some(
                                auth_response.three_ds_auth_response.acs_reference_number,
                            ),
                            acs_trans_id: Some(auth_response.three_ds_auth_response.acs_trans_id),
                            three_dsserver_trans_id: Some(
                                auth_response
                                    .three_ds_auth_response
                                    .three_ds_server_trans_id,
                            ),
                            acs_signed_content: auth_response
                                .three_ds_auth_response
                                .acs_signed_content,
                        }))
                    }
                    Some(ACSChallengeMandatedEnum::N) | None => AuthNFlowType::Frictionless,
                };
                Ok(UasAuthenticationResponseData::Authentication {
                    authentication_details: hyperswitch_domain_models::router_request_types::unified_authentication_service::AuthenticationDetails {
                        authn_flow_type,
                        authentication_value: auth_response.three_ds_auth_response.authentication_value,
                        trans_status: auth_response.three_ds_auth_response.trans_status,
                        connector_metadata: None,
                        ds_trans_id: Some(auth_response.three_ds_auth_response.ds_trans_id),
                        eci: auth_response.three_ds_auth_response.eci,
                        challenge_code: auth_response.three_ds_auth_response.challenge_code,
                        challenge_cancel: auth_response.three_ds_auth_response.challenge_cancel,
                        challenge_code_reason: auth_response.three_ds_auth_response.challenge_code_reason,
                        message_extension:  auth_response.three_ds_auth_response.message_extension,
                    },
                })
            }
            UnifiedAuthenticationServiceAuthenticateResponse::Failure(error_response) => {
                Err(hyperswitch_domain_models::router_data::ErrorResponse {
                    code: hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string(),
                    message: error_response.error.clone(),
                    reason: None,
                    status_code: item.http_code,
                    attempt_status: None,
                    connector_transaction_id: None,
                    network_advice_code: None,
                    network_decline_code: None,
                    network_error_message: None,
                    connector_metadata: None,
                })
            }
        };

        Ok(Self {
            response,
            ..item.data
        })
    }
}


impl api::ConnectorAccessToken for Checkbook {}

impl api::ConnectorAccessToken for for Checkbook


File: crates/router/build.rs

fn main() {
    // Set thread stack size to 10 MiB for debug builds
    // Reference: https://doc.rust-lang.org/std/thread/#stack-size
    #[cfg(debug_assertions)]
    println!("cargo:rustc-env=RUST_MIN_STACK=10485760"); // 10 * 1024 * 1024 = 10 MiB

    #[cfg(feature = "vergen")]
    router_env::vergen::generate_cargo_instructions();
}


pub struct FluidData {
    value: Secret<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    descriptor: Option<String>,
}


impl PaymentCapture for Riskified {}


impl SingleUsePaymentMethodToken {
    pub fn get_single_use_token_from_payment_method_token(
        token: Secret<String>,
        mca_id: id_type::MerchantConnectorAccountId,
    ) -> Self {
        Self {
            token,
            merchant_connector_id: mca_id,
        }
    }
}


pub struct StripebillingInvoiceBody {
    #[serde(rename = "type")]
    pub event_type: StripebillingEventType,
    pub data: StripebillingInvoiceData,
}


pub struct SupportedPaymentMethodTypesForMandate(
    pub HashMap<enums::PaymentMethodType, SupportedConnectorsForMandate>,
);


impl api::PaymentAuthorize for UnifiedAuthenticationService {}

impl api::PaymentAuthorize for for UnifiedAuthenticationService


pub struct MultiAuthKey {
    pub api_key: Secret<String>,
    pub key1: Secret<String>,
    pub api_secret: Secret<String>,
    pub key2: Secret<String>,
}


impl<T> EncryptedJsonType<T> {
    pub fn inner(&self) -> &T {
        &self.0
    }

    pub fn into_inner(self) -> T {
        self.0
    }
}


impl api::PaymentCapture for Taxjar {}


pub async fn check_totp_in_redis(state: &SessionState, user_id: &str) -> UserResult<bool> {
    let redis_conn = super::get_redis_connection_for_global_tenant(state)?;
    let key = format!("{}{}", consts::user::REDIS_TOTP_PREFIX, user_id);
    redis_conn
        .exists::<()>(&key.into())
        .await
        .change_context(UserErrors::InternalServerError)
}


File: crates/diesel_models/src/query.rs

pub mod address;
pub mod api_keys;
pub mod blocklist_lookup;
pub mod business_profile;
mod capture;
pub mod cards_info;
pub mod configs;

pub mod authentication;
pub mod authorization;
pub mod blocklist;
pub mod blocklist_fingerprint;
pub mod callback_mapper;
pub mod customers;
pub mod dashboard_metadata;
pub mod dispute;
pub mod dynamic_routing_stats;
pub mod events;
pub mod file;
pub mod fraud_check;
pub mod generic_link;
pub mod generics;
pub mod gsm;
pub mod locker_mock_up;
pub mod mandate;
pub mod merchant_account;
pub mod merchant_connector_account;
pub mod merchant_key_store;
pub mod organization;
pub mod payment_attempt;
pub mod payment_intent;
pub mod payment_link;
pub mod payment_method;
pub mod payout_attempt;
pub mod payouts;
pub mod process_tracker;
pub mod refund;
pub mod relay;
pub mod reverse_lookup;
pub mod role;
pub mod routing_algorithm;
pub mod subscription;
#[cfg(feature = "tokenization_v2")]
pub mod tokenization;
pub mod unified_translations;
pub mod user;
pub mod user_authentication_method;
pub mod user_key_store;
pub mod user_role;
mod utils;


pub struct AuthenticationCreateRequest {
    /// The unique identifier for this authentication.
    #[schema(value_type = Option<String>, example = "auth_mbabizu24mvu3mela5njyhpit4")]
    pub authentication_id: Option<id_type::AuthenticationId>,

    /// The business profile that is associated with this authentication
    #[schema(value_type = Option<String>)]
    pub profile_id: Option<id_type::ProfileId>,

    /// Customer details.
    #[schema(value_type = Option<CustomerDetails>)]
    pub customer: Option<CustomerDetails>,

    /// The amount for the transaction, required.
    #[schema(value_type = MinorUnit, example = 1000)]
    pub amount: common_utils::types::MinorUnit,

    /// The connector to be used for authentication, if known.
    #[schema(value_type = Option<AuthenticationConnectors>, example = "netcetera")]
    pub authentication_connector: Option<AuthenticationConnectors>,

    /// The currency for the transaction, required.
    #[schema(value_type = Currency)]
    pub currency: common_enums::Currency,

    /// The URL to which the user should be redirected after authentication.
    #[schema(value_type = Option<String>, example = "https://example.com/redirect")]
    pub return_url: Option<String>,

    /// Force 3DS challenge.
    #[serde(default)]
    pub force_3ds_challenge: Option<bool>,

    /// Choose what kind of sca exemption is required for this payment
    #[schema(value_type = Option<ScaExemptionType>)]
    pub psd2_sca_exemption_type: Option<common_enums::ScaExemptionType>,

    /// Profile Acquirer ID get from profile acquirer configuration
    #[schema(value_type = Option<String>)]
    pub profile_acquirer_id: Option<id_type::ProfileAcquirerId>,

    /// Acquirer details information
    #[schema(value_type = Option<AcquirerDetails>)]
    pub acquirer_details: Option<AcquirerDetails>,
}


pub async fn payments_complete_authorize_redirect_with_creds_identifier(
    state: web::Data<app::AppState>,
    req: actix_web::HttpRequest,
    json_payload: Option<web::Form<serde_json::Value>>,
    path: web::Path<(
        common_utils::id_type::PaymentId,
        common_utils::id_type::MerchantId,
        String,
        String,
    )


pub struct PlaidPaymentsResponse {
    status: PlaidPaymentStatus,
    payment_id: String,
}


pub struct AciWebhookAuthenticationDetails {
    #[serde(rename = "entityId")]
    pub entity_id: Secret<String>,
}


OpenAPI Block Path: components.schemas.PaymentData
{
  "type": "object",
  "description": "Represents the payment data used in the 3DS decision rule.",
  "required": [
    "amount",
    "currency"
  ],
  "properties": {
    "amount": {
      "type": "integer",
      "format": "int64",
      "description": "The amount of the payment in minor units (e.g., cents for USD)."
    },
    "currency": {
      "$ref": "#/components/schemas/Currency"
    }
  }
}


pub trait Metadata: erased_serde::Serialize + Any + Send + Sync + fmt::Debug {}


pub struct FlexitiAccessTokenResponse {
    access_token: Secret<String>,
    expires_in: i64,
}


pub struct AciRedirectionData {
    method: Option<Method>,
    parameters: Vec<Parameters>,
    url: Url,
}


                "Kyustendil Province" => Ok(Self::KyustendilProvince),
                "Lovech Province" => Ok(Self::LovechProvince),
                "Montana Province" => Ok(Self::MontanaProvince),
                "Pazardzhik Province" => Ok(Self::PazardzhikProvince),
                "Pernik Province" => Ok(Self::PernikProvince),
                "Pleven Province" => Ok(Self::PlevenProvince),
                "Plovdiv Province" => Ok(Self::PlovdivProvince),
                "Razgrad Province" => Ok(Self::RazgradProvince),
                "Ruse Province" => Ok(Self::RuseProvince),
                "Shumen" => Ok(Self::Shumen),
                "Silistra Province" => Ok(Self::SilistraProvince),
                "Sliven Province" => Ok(Self::SlivenProvince),
                "Smolyan Province" => Ok(Self::SmolyanProvince),
                "Sofia City Province" => Ok(Self::SofiaCityProvince),
                "Sofia Province" => Ok(Self::SofiaProvince),
                "Stara Zagora Province" => Ok(Self::StaraZagoraProvince),
                "Targovishte Provinc" => Ok(Self::TargovishteProvince),
                "Varna Province" => Ok(Self::VarnaProvince),
                "Veliko Tarnovo Province" => Ok(Self::VelikoTarnovoProvince),
                "Vidin Province" => Ok(Self::VidinProvince),
                "Vratsa Province" => Ok(Self::VratsaProvince),
                "Yambol Province" => Ok(Self::YambolProvince),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for BosniaAndHerzegovinaStatesAbbreviation {
    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.clone(), "BosniaAndHerzegovinaStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Bosnian Podrinje Canton" => Ok(Self::BosnianPodrinjeCanton),
                "Brčko District" => Ok(Self::BrckoDistrict),
                "Canton 10" => Ok(Self::Canton10),
                "Central Bosnia Canton" => Ok(Self::CentralBosniaCanton),
                "Federation of Bosnia and Herzegovina" => {
                    Ok(Self::FederationOfBosniaAndHerzegovina)
                }
                "Herzegovina-Neretva Canton" => Ok(Self::HerzegovinaNeretvaCanton),
                "Posavina Canton" => Ok(Self::PosavinaCanton),
                "Republika Srpska" => Ok(Self::RepublikaSrpska),
                "Sarajevo Canton" => Ok(Self::SarajevoCanton),
                "Tuzla Canton" => Ok(Self::TuzlaCanton),
                "Una-Sana Canton" => Ok(Self::UnaSanaCanton),
                "West Herzegovina Canton" => Ok(Self::WestHerzegovinaCanton),
                "Zenica-Doboj Canton" => Ok(Self::ZenicaDobojCanton),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for UnitedKingdomStatesAbbreviation {
    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.clone(), "UnitedKingdomStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Aberdeen" => Ok(Self::Aberdeen),
                "Aberdeenshire" => Ok(Self::Aberdeenshire),
                "Angus" => Ok(Self::Angus),
                "Antrim" => Ok(Self::Antrim),
                "Antrim and Newtownabbey" => Ok(Self::AntrimAndNewtownabbey),
                "Ards" => Ok(Self::Ards),
                "Ards and North Down" => Ok(Self::ArdsAndNorthDown),
                "Argyll and Bute" => Ok(Self::ArgyllAndBute),
                "Armagh City and District Council" => Ok(Self::ArmaghCityAndDistrictCouncil),
                "Armagh, Banbridge and Craigavon" => Ok(Self::ArmaghBanbridgeAndCraigavon),
                "Ascension Island" => Ok(Self::AscensionIsland),
                "Ballymena Borough" => Ok(Self::BallymenaBorough),
                "Ballymoney" => Ok(Self::Ballymoney),
                "Banbridge" => Ok(Self::Banbridge),
                "Barnsley" => Ok(Self::Barnsley),
                "Bath and North East Somerset" => Ok(Self::BathAndNorthEastSomerset),
                "Bedford" => Ok(Self::Bedford),
                "Belfast district" => Ok(Self::BelfastDistrict),
                "Birmingham" => Ok(Self::Birmingham),
                "Blackburn with Darwen" => Ok(Self::BlackburnWithDarwen),
                "Blackpool" => Ok(Self::Blackpool),
                "Blaenau Gwent County Borough" => Ok(Self::BlaenauGwentCountyBorough),
                "Bolton" => Ok(Self::Bolton),
                "Bournemouth" => Ok(Self::Bournemouth),
                "Bracknell Forest" => Ok(Self::BracknellForest),
                "Bradford" => Ok(Self::Bradford),
                "Bridgend County Borough" => Ok(Self::BridgendCountyBorough),
                "Brighton and Hove" => Ok(Self::BrightonAndHove),
                "Buckinghamshire" => Ok(Self::Buckinghamshire),
                "Bury" => Ok(Self::Bury),
                "Caerphilly County Borough" => Ok(Self::CaerphillyCountyBorough),
                "Calderdale" => Ok(Self::Calderdale),
                "Cambridgeshire" => Ok(Self::Cambridgeshire),
                "Carmarthenshire" => Ok(Self::Carmarthenshire),
                "Carrickfergus Borough Council" => Ok(Self::CarrickfergusBoroughCouncil),
                "Castlereagh" => Ok(Self::Castlereagh),
                "Causeway Coast and Glens" => Ok(Self::CausewayCoastAndGlens),
                "Central Bedfordshire" => Ok(Self::CentralBedfordshire),
                "Ceredigion" => Ok(Self::Ceredigion),
                "Cheshire East" => Ok(Self::CheshireEast),
                "Cheshire West and Chester" => Ok(Self::CheshireWestAndChester),
                "City and County of Cardiff" => Ok(Self::CityAndCountyOfCardiff),
                "City and County of Swansea" => Ok(Self::CityAndCountyOfSwansea),
                "City of Bristol" => Ok(Self::CityOfBristol),
                "City of Derby" => Ok(Self::CityOfDerby),
                "City of Kingston upon Hull" => Ok(Self::CityOfKingstonUponHull),
                "City of Leicester" => Ok(Self::CityOfLeicester),
                "City of London" => Ok(Self::CityOfLondon),
                "City of Nottingham" => Ok(Self::CityOfNottingham),
                "City of Peterborough" => Ok(Self::CityOfPeterborough),
                "City of Plymouth" => Ok(Self::CityOfPlymouth),
                "City of Portsmouth" => Ok(Self::CityOfPortsmouth),
                "City of Southampton" => Ok(Self::CityOfSouthampton),
                "City of Stoke-on-Trent" => Ok(Self::CityOfStokeOnTrent),
                "City of Sunderland" => Ok(Self::CityOfSunderland),
                "City of Westminster" => Ok(Self::CityOfWestminster),
                "City of Wolverhampton" => Ok(Self::CityOfWolverhampton),
                "City of York" => Ok(Self::CityOfYork),
                "Clackmannanshire" => Ok(Self::Clackmannanshire),
                "Coleraine Borough Council" => Ok(Self::ColeraineBoroughCouncil),
                "Conwy County Borough" => Ok(Self::ConwyCountyBorough),
                "Cookstown District Council" => Ok(Self::CookstownDistrictCouncil),
                "Cornwall" => Ok(Self::Cornwall),
                "County Durham" => Ok(Self::CountyDurham),
                "Coventry" => Ok(Self::Coventry),
                "Craigavon Borough Council" => Ok(Self::CraigavonBoroughCouncil),
                "Cumbria" => Ok(Self::Cumbria),
                "Darlington" => Ok(Self::Darlington),
                "Denbighshire" => Ok(Self::Denbighshire),
                "Derbyshire" => Ok(Self::Derbyshire),
                "Derry City and Strabane" => Ok(Self::DerryCityAndStrabane),
                "Derry City Council" => Ok(Self::DerryCityCouncil),
                "Devon" => Ok(Self::Devon),
                "Doncaster" => Ok(Self::Doncaster),
                "Dorset" => Ok(Self::Dorset),
                "Down District Council" => Ok(Self::DownDistrictCouncil),
                "Dudley" => Ok(Self::Dudley),
                "Dumfries and Galloway" => Ok(Self::DumfriesAndGalloway),
                "Dundee" => Ok(Self::Dundee),
                "Dungannon and South Tyrone Borough Council" => {
                    Ok(Self::DungannonAndSouthTyroneBoroughCouncil)
                }
                "East Ayrshire" => Ok(Self::EastAyrshire),
                "East Dunbartonshire" => Ok(Self::EastDunbartonshire),
                "East Lothian" => Ok(Self::EastLothian),
                "East Renfrewshire" => Ok(Self::EastRenfrewshire),
                "East Riding of Yorkshire" => Ok(Self::EastRidingOfYorkshire),
                "East Sussex" => Ok(Self::EastSussex),
                "Edinburgh" => Ok(Self::Edinburgh),
                "England" => Ok(Self::England),
                "Essex" => Ok(Self::Essex),
                "Falkirk" => Ok(Self::Falkirk),
                "Fermanagh and Omagh" => Ok(Self::FermanaghAndOmagh),
                "Fermanagh District Council" => Ok(Self::FermanaghDistrictCouncil),
                "Fife" => Ok(Self::Fife),
                "Flintshire" => Ok(Self::Flintshire),
                "Gateshead" => Ok(Self::Gateshead),
                "Glasgow" => Ok(Self::Glasgow),
                "Gloucestershire" => Ok(Self::Gloucestershire),
                "Gwynedd" => Ok(Self::Gwynedd),
                "Halton" => Ok(Self::Halton),
                "Hampshire" => Ok(Self::Hampshire),
                "Hartlepool" => Ok(Self::Hartlepool),
                "Herefordshire" => Ok(Self::Herefordshire),
                "Hertfordshire" => Ok(Self::Hertfordshire),
                "Highland" => Ok(Self::Highland),
                "Inverclyde" => Ok(Self::Inverclyde),
                "Isle of Wight" => Ok(Self::IsleOfWight),
                "Isles of Scilly" => Ok(Self::IslesOfScilly),
                "Kent" => Ok(Self::Kent),
                "Kirklees" => Ok(Self::Kirklees),
                "Knowsley" => Ok(Self::Knowsley),
                "Lancashire" => Ok(Self::Lancashire),
                "Larne Borough Council" => Ok(Self::LarneBoroughCouncil),
                "Leeds" => Ok(Self::Leeds),
                "Leicestershire" => Ok(Self::Leicestershire),
                "Limavady Borough Council" => Ok(Self::LimavadyBoroughCouncil),
                "Lincolnshire" => Ok(Self::Lincolnshire),
                "Lisburn and Castlereagh" => Ok(Self::LisburnAndCastlereagh),
                "Lisburn City Council" => Ok(Self::LisburnCityCouncil),
                "Liverpool" => Ok(Self::Liverpool),
                "London Borough of Barking and Dagenham" => {
                    Ok(Self::LondonBoroughOfBarkingAndDagenham)
                }
                "London Borough of Barnet" => Ok(Self::LondonBoroughOfBarnet),
                "London Borough of Bexley" => Ok(Self::LondonBoroughOfBexley),
                "London Borough of Brent" => Ok(Self::LondonBoroughOfBrent),
                "London Borough of Bromley" => Ok(Self::LondonBoroughOfBromley),
                "London Borough of Camden" => Ok(Self::LondonBoroughOfCamden),
                "London Borough of Croydon" => Ok(Self::LondonBoroughOfCroydon),
                "London Borough of Ealing" => Ok(Self::LondonBoroughOfEaling),
                "London Borough of Enfield" => Ok(Self::LondonBoroughOfEnfield),
                "London Borough of Hackney" => Ok(Self::LondonBoroughOfHackney),
                "London Borough of Hammersmith and Fulham" => {
                    Ok(Self::LondonBoroughOfHammersmithAndFulham)
                }
                "London Borough of Haringey" => Ok(Self::LondonBoroughOfHaringey),
                "London Borough of Harrow" => Ok(Self::LondonBoroughOfHarrow),
                "London Borough of Havering" => Ok(Self::LondonBoroughOfHavering),
                "London Borough of Hillingdon" => Ok(Self::LondonBoroughOfHillingdon),
                "London Borough of Hounslow" => Ok(Self::LondonBoroughOfHounslow),
                "London Borough of Islington" => Ok(Self::LondonBoroughOfIslington),
                "London Borough of Lambeth" => Ok(Self::LondonBoroughOfLambeth),
                "London Borough of Lewisham" => Ok(Self::LondonBoroughOfLewisham),
                "London Borough of Merton" => Ok(Self::LondonBoroughOfMerton),
                "London Borough of Newham" => Ok(Self::LondonBoroughOfNewham),
                "London Borough of Redbridge" => Ok(Self::LondonBoroughOfRedbridge),
                "London Borough of Richmond upon Thames" => {
                    Ok(Self::LondonBoroughOfRichmondUponThames)
                }
                "London Borough of Southwark" => Ok(Self::LondonBoroughOfSouthwark),
                "London Borough of Sutton" => Ok(Self::LondonBoroughOfSutton),
                "London Borough of Tower Hamlets" => Ok(Self::LondonBoroughOfTowerHamlets),
                "London Borough of Waltham Forest" => Ok(Self::LondonBoroughOfWalthamForest),
                "London Borough of Wandsworth" => Ok(Self::LondonBoroughOfWandsworth),
                "Magherafelt District Council" => Ok(Self::MagherafeltDistrictCouncil),
                "Manchester" => Ok(Self::Manchester),
                "Medway" => Ok(Self::Medway),
                "Merthyr Tydfil County Borough" => Ok(Self::MerthyrTydfilCountyBorough),
                "Metropolitan Borough of Wigan" => Ok(Self::MetropolitanBoroughOfWigan),
                "Mid and East Antrim" => Ok(Self::MidAndEastAntrim),
                "Mid Ulster" => Ok(Self::MidUlster),
                "Middlesbrough" => Ok(Self::Middlesbrough),
                "Midlothian" => Ok(Self::Midlothian),
                "Milton Keynes" => Ok(Self::MiltonKeynes),
                "Monmouthshire" => Ok(Self::Monmouthshire),
                "Moray" => Ok(Self::Moray),
                "Moyle District Council" => Ok(Self::MoyleDistrictCouncil),
                "Neath Port Talbot County Borough" => Ok(Self::NeathPortTalbotCountyBorough),
                "Newcastle upon Tyne" => Ok(Self::NewcastleUponTyne),
                "Newport" => Ok(Self::Newport),
                "Newry and Mourne District Council" => Ok(Self::NewryAndMourneDistrictCouncil),
                "Newry, Mourne and Down" => Ok(Self::NewryMourneAndDown),
                "Newtownabbey Borough Council" => Ok(Self::NewtownabbeyBoroughCouncil),
                "Norfolk" => Ok(Self::Norfolk),
                "North Ayrshire" => Ok(Self::NorthAyrshire),
                "North Down Borough Council" => Ok(Self::NorthDownBoroughCouncil),
                "North East Lincolnshire" => Ok(Self::NorthEastLincolnshire),
                "North Lanarkshire" => Ok(Self::NorthLanarkshire),
                "North Lincolnshire" => Ok(Self::NorthLincolnshire),
                "North Somerset" => Ok(Self::NorthSomerset),
                "North Tyneside" => Ok(Self::NorthTyneside),
                "North Yorkshire" => Ok(Self::NorthYorkshire),
                "Northamptonshire" => Ok(Self::Northamptonshire),
                "Northern Ireland" => Ok(Self::NorthernIreland),
                "Northumberland" => Ok(Self::Northumberland),
                "Nottinghamshire" => Ok(Self::Nottinghamshire),
                "Oldham" => Ok(Self::Oldham),
                "Omagh District Council" => Ok(Self::OmaghDistrictCouncil),
                "Orkney Islands" => Ok(Self::OrkneyIslands),
                "Outer Hebrides" => Ok(Self::OuterHebrides),
                "Oxfordshire" => Ok(Self::Oxfordshire),
                "Pembrokeshire" => Ok(Self::Pembrokeshire),
                "Perth and Kinross" => Ok(Self::PerthAndKinross),
                "Poole" => Ok(Self::Poole),
                "Powys" => Ok(Self::Powys),
                "Reading" => Ok(Self::Reading),
                "Redcar and Cleveland" => Ok(Self::RedcarAndCleveland),
                "Renfrewshire" => Ok(Self::Renfrewshire),
                "Rhondda Cynon Taf" => Ok(Self::RhonddaCynonTaf),
                "Rochdale" => Ok(Self::Rochdale),
                "Rotherham" => Ok(Self::Rotherham),
                "Royal Borough of Greenwich" => Ok(Self::RoyalBoroughOfGreenwich),
                "Royal Borough of Kensington and Chelsea" => {
                    Ok(Self::RoyalBoroughOfKensingtonAndChelsea)
                }
                "Royal Borough of Kingston upon Thames" => {
                    Ok(Self::RoyalBoroughOfKingstonUponThames)
                }
                "Rutland" => Ok(Self::Rutland),
                "Saint Helena" => Ok(Self::SaintHelena),
                "Salford" => Ok(Self::Salford),
                "Sandwell" => Ok(Self::Sandwell),
                "Scotland" => Ok(Self::Scotland),
                "Scottish Borders" => Ok(Self::ScottishBorders),
                "Sefton" => Ok(Self::Sefton),
                "Sheffield" => Ok(Self::Sheffield),
                "Shetland Islands" => Ok(Self::ShetlandIslands),
                "Shropshire" => Ok(Self::Shropshire),
                "Slough" => Ok(Self::Slough),
                "Solihull" => Ok(Self::Solihull),
                "Somerset" => Ok(Self::Somerset),
                "South Ayrshire" => Ok(Self::SouthAyrshire),
                "South Gloucestershire" => Ok(Self::SouthGloucestershire),
                "South Lanarkshire" => Ok(Self::SouthLanarkshire),
                "South Tyneside" => Ok(Self::SouthTyneside),
                "Southend-on-Sea" => Ok(Self::SouthendOnSea),
                "St Helens" => Ok(Self::StHelens),
                "Staffordshire" => Ok(Self::Staffordshire),
                "Stirling" => Ok(Self::Stirling),
                "Stockport" => Ok(Self::Stockport),
                "Stockton-on-Tees" => Ok(Self::StocktonOnTees),
                "Strabane District Council" => Ok(Self::StrabaneDistrictCouncil),
                "Suffolk" => Ok(Self::Suffolk),
                "Surrey" => Ok(Self::Surrey),
                "Swindon" => Ok(Self::Swindon),
                "Tameside" => Ok(Self::Tameside),
                "Telford and Wrekin" => Ok(Self::TelfordAndWrekin),
                "Thurrock" => Ok(Self::Thurrock),
                "Torbay" => Ok(Self::Torbay),
                "Torfaen" => Ok(Self::Torfaen),
                "Trafford" => Ok(Self::Trafford),
                "United Kingdom" => Ok(Self::UnitedKingdom),
                "Vale of Glamorgan" => Ok(Self::ValeOfGlamorgan),
                "Wakefield" => Ok(Self::Wakefield),
                "Wales" => Ok(Self::Wales),
                "Walsall" => Ok(Self::Walsall),
                "Warrington" => Ok(Self::Warrington),
                "Warwickshire" => Ok(Self::Warwickshire),
                "West Berkshire" => Ok(Self::WestBerkshire),
                "West Dunbartonshire" => Ok(Self::WestDunbartonshire),
                "West Lothian" => Ok(Self::WestLothian),
                "West Sussex" => Ok(Self::WestSussex),
                "Wiltshire" => Ok(Self::Wiltshire),
                "Windsor and Maidenhead" => Ok(Self::WindsorAndMaidenhead),
                "Wirral" => Ok(Self::Wirral),
                "Wokingham" => Ok(Self::Wokingham),
                "Worcestershire" => Ok(Self::Worcestershire),
                "Wrexham County Borough" => Ok(Self::WrexhamCountyBorough),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for BelgiumStatesAbbreviation {
    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.clone(), "BelgiumStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Antwerp" => Ok(Self::Antwerp),
                "Brussels-Capital Region" => Ok(Self::BrusselsCapitalRegion),
                "East Flanders" => Ok(Self::EastFlanders),
                "Flanders" => Ok(Self::Flanders),
                "Flemish Brabant" => Ok(Self::FlemishBrabant),
                "Hainaut" => Ok(Self::Hainaut),
                "Limburg" => Ok(Self::Limburg),
                "Liège" => Ok(Self::Liege),
                "Luxembourg" => Ok(Self::Luxembourg),
                "Namur" => Ok(Self::Namur),
                "Wallonia" => Ok(Self::Wallonia),
                "Walloon Brabant" => Ok(Self::WalloonBrabant),
                "West Flanders" => Ok(Self::WestFlanders),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for LuxembourgStatesAbbreviation {
    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.clone(), "LuxembourgStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Canton of Capellen" => Ok(Self::CantonOfCapellen),
                "Canton of Clervaux" => Ok(Self::CantonOfClervaux),
                "Canton of Diekirch" => Ok(Self::CantonOfDiekirch),
                "Canton of Echternach" => Ok(Self::CantonOfEchternach),
                "Canton of Esch-sur-Alzette" => Ok(Self::CantonOfEschSurAlzette),
                "Canton of Grevenmacher" => Ok(Self::CantonOfGrevenmacher),
                "Canton of Luxembourg" => Ok(Self::CantonOfLuxembourg),
                "Canton of Mersch" => Ok(Self::CantonOfMersch),
                "Canton of Redange" => Ok(Self::CantonOfRedange),
                "Canton of Remich" => Ok(Self::CantonOfRemich),
                "Canton of Vianden" => Ok(Self::CantonOfVianden),
                "Canton of Wiltz" => Ok(Self::CantonOfWiltz),
                "Diekirch District" => Ok(Self::DiekirchDistrict),
                "Grevenmacher District" => Ok(Self::GrevenmacherDistrict),
                "Luxembourg District" => Ok(Self::LuxembourgDistrict),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for RussiaStatesAbbreviation {
    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.clone(), "RussiaStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Altai Krai" => Ok(Self::AltaiKrai),
                "Altai Republic" => Ok(Self::AltaiRepublic),
                "Amur Oblast" => Ok(Self::AmurOblast),
                "Arkhangelsk" => Ok(Self::Arkhangelsk),
                "Astrakhan Oblast" => Ok(Self::AstrakhanOblast),
                "Belgorod Oblast" => Ok(Self::BelgorodOblast),
                "Bryansk Oblast" => Ok(Self::BryanskOblast),
                "Chechen Republic" => Ok(Self::ChechenRepublic),
                "Chelyabinsk Oblast" => Ok(Self::ChelyabinskOblast),
                "Chukotka Autonomous Okrug" => Ok(Self::ChukotkaAutonomousOkrug),
                "Chuvash Republic" => Ok(Self::ChuvashRepublic),
                "Irkutsk" => Ok(Self::Irkutsk),
                "Ivanovo Oblast" => Ok(Self::IvanovoOblast),
                "Jewish Autonomous Oblast" => Ok(Self::JewishAutonomousOblast),
                "Kabardino-Balkar Republic" => Ok(Self::KabardinoBalkarRepublic),
                "Kaliningrad" => Ok(Self::Kaliningrad),
                "Kaluga Oblast" => Ok(Self::KalugaOblast),
                "Kamchatka Krai" => Ok(Self::KamchatkaKrai),
                "Karachay-Cherkess Republic" => Ok(Self::KarachayCherkessRepublic),
                "Kemerovo Oblast" => Ok(Self::KemerovoOblast),
                "Khabarovsk Krai" => Ok(Self::KhabarovskKrai),
                "Khanty-Mansi Autonomous Okrug" => Ok(Self::KhantyMansiAutonomousOkrug),
                "Kirov Oblast" => Ok(Self::KirovOblast),
                "Komi Republic" => Ok(Self::KomiRepublic),
                "Kostroma Oblast" => Ok(Self::KostromaOblast),
                "Krasnodar Krai" => Ok(Self::KrasnodarKrai),
                "Krasnoyarsk Krai" => Ok(Self::KrasnoyarskKrai),
                "Kurgan Oblast" => Ok(Self::KurganOblast),
                "Kursk Oblast" => Ok(Self::KurskOblast),
                "Leningrad Oblast" => Ok(Self::LeningradOblast),
                "Lipetsk Oblast" => Ok(Self::LipetskOblast),
                "Magadan Oblast" => Ok(Self::MagadanOblast),
                "Mari El Republic" => Ok(Self::MariElRepublic),
                "Moscow" => Ok(Self::Moscow),
                "Moscow Oblast" => Ok(Self::MoscowOblast),
                "Murmansk Oblast" => Ok(Self::MurmanskOblast),
                "Nenets Autonomous Okrug" => Ok(Self::NenetsAutonomousOkrug),
                "Nizhny Novgorod Oblast" => Ok(Self::NizhnyNovgorodOblast),
                "Novgorod Oblast" => Ok(Self::NovgorodOblast),
                "Novosibirsk" => Ok(Self::Novosibirsk),
                "Omsk Oblast" => Ok(Self::OmskOblast),
                "Orenburg Oblast" => Ok(Self::OrenburgOblast),
                "Oryol Oblast" => Ok(Self::OryolOblast),
                "Penza Oblast" => Ok(Self::PenzaOblast),
                "Perm Krai" => Ok(Self::PermKrai),
                "Primorsky Krai" => Ok(Self::PrimorskyKrai),
                "Pskov Oblast" => Ok(Self::PskovOblast),
                "Republic of Adygea" => Ok(Self::RepublicOfAdygea),
                "Republic of Bashkortostan" => Ok(Self::RepublicOfBashkortostan),
                "Republic of Buryatia" => Ok(Self::RepublicOfBuryatia),
                "Republic of Dagestan" => Ok(Self::RepublicOfDagestan),
                "Republic of Ingushetia" => Ok(Self::RepublicOfIngushetia),
                "Republic of Kalmykia" => Ok(Self::RepublicOfKalmykia),
                "Republic of Karelia" => Ok(Self::RepublicOfKarelia),
                "Republic of Khakassia" => Ok(Self::RepublicOfKhakassia),
                "Republic of Mordovia" => Ok(Self::RepublicOfMordovia),
                "Republic of North Ossetia-Alania" => Ok(Self::RepublicOfNorthOssetiaAlania),
                "Republic of Tatarstan" => Ok(Self::RepublicOfTatarstan),
                "Rostov Oblast" => Ok(Self::RostovOblast),
                "Ryazan Oblast" => Ok(Self::RyazanOblast),
                "Saint Petersburg" => Ok(Self::SaintPetersburg),
                "Sakha Republic" => Ok(Self::SakhaRepublic),
                "Sakhalin" => Ok(Self::Sakhalin),
                "Samara Oblast" => Ok(Self::SamaraOblast),
                "Saratov Oblast" => Ok(Self::SaratovOblast),
                "Sevastopol" => Ok(Self::Sevastopol),
                "Smolensk Oblast" => Ok(Self::SmolenskOblast),
                "Stavropol Krai" => Ok(Self::StavropolKrai),
                "Sverdlovsk" => Ok(Self::Sverdlovsk),
                "Tambov Oblast" => Ok(Self::TambovOblast),
                "Tomsk Oblast" => Ok(Self::TomskOblast),
                "Tula Oblast" => Ok(Self::TulaOblast),
                "Tuva Republic" => Ok(Self::TuvaRepublic),
                "Tver Oblast" => Ok(Self::TverOblast),
                "Tyumen Oblast" => Ok(Self::TyumenOblast),
                "Udmurt Republic" => Ok(Self::UdmurtRepublic),
                "Ulyanovsk Oblast" => Ok(Self::UlyanovskOblast),
                "Vladimir Oblast" => Ok(Self::VladimirOblast),
                "Vologda Oblast" => Ok(Self::VologdaOblast),
                "Voronezh Oblast" => Ok(Self::VoronezhOblast),
                "Yamalo-Nenets Autonomous Okrug" => Ok(Self::YamaloNenetsAutonomousOkrug),
                "Yaroslavl Oblast" => Ok(Self::YaroslavlOblast),
                "Zabaykalsky Krai" => Ok(Self::ZabaykalskyKrai),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for SanMarinoStatesAbbreviation {
    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.clone(), "SanMarinoStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Acquaviva" => Ok(Self::Acquaviva),
                "Borgo Maggiore" => Ok(Self::BorgoMaggiore),
                "Chiesanuova" => Ok(Self::Chiesanuova),
                "Domagnano" => Ok(Self::Domagnano),
                "Faetano" => Ok(Self::Faetano),
                "Fiorentino" => Ok(Self::Fiorentino),
                "Montegiardino" => Ok(Self::Montegiardino),
                "San Marino" => Ok(Self::SanMarino),
                "Serravalle" => Ok(Self::Serravalle),
                _ => Err(errors::ConnectorError::InvalidDataFormat {
                    field_name: "address.state",
                }
                .into()),
            },
        }
    }
}

impl ForeignTryFrom<String> for SerbiaStatesAbbreviation {
    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.clone(), "SerbiaStatesAbbreviation");
        match state_abbreviation_check {
            Ok(state_abbreviation) => Ok(state_abbreviation),
            Err(_) => match value.as_str() {
                "Belgrade" => Ok(Self::Belgrade),
                "Bor District" => Ok(Self::BorDistrict),
                "Braničevo District" => Ok(Self::BraničevoDistrict),
                "Central Banat District" => Ok(Self::CentralBanatDistrict),
                "Jablanica District" => Ok(Self::JablanicaDistrict),
                "Kolubara District" => Ok(Self::KolubaraDistrict),
                "Mačva District" => Ok(Self::MačvaDistrict),
                "Moravica District" => Ok(Self::MoravicaDistrict),
                "Nišava District" => Ok(Self::NišavaDistrict),
                "North Banat District" => Ok(Self::NorthBanatDistrict),
                "North Bačka District" => Ok(Self::NorthBačkaDistrict),
                "Pirot District" => Ok(Self::PirotDistrict),
                "Podunavlje District" => Ok(Self::PodunavljeDistrict),
                "Pomoravlje District" => Ok(Self::PomoravljeDistrict),
                "Pčinja District" => Ok(Self::PčinjaDistrict),
                "Rasina District" => Ok(Self::RasinaDistrict),
                "Raška District" => Ok(Self::RaškaDistrict),
                "South Banat District" => Ok(Self::SouthBanatDistrict),
                "South Bačka District" => Ok(Self::SouthBačkaDistrict),
                "Srem District" => Ok(Self::SremDistrict),
                "Toplica District" => Ok(Self::ToplicaDistrict),
                "Vojvodina" => Ok(Self::Vojvodina),
                "West Bačka District" => Ok(Self::WestBačkaDistrict),
                "Zaječar District" => Ok(Self::ZaječarDistrict),
                "Zlatibor District" => Ok(Self::ZlatiborDistrict),
                "Šumadija District" => Ok(Self::ŠumadijaDistrict),
                _ => Err(errors::ConnectorError::InvalidDataFormat {


pub struct PayloadWebhookEvent {
    pub object: String, // Added to match actual webhook structure
    pub trigger: PayloadWebhooksTrigger,
    pub webhook_id: String,
    pub triggered_at: String, // Added to match actual webhook structure
    // Webhooks Payload
    pub triggered_on: PayloadEventDetails,
    pub url: String,
}


File: crates/openapi/src/lib.rs

pub mod routes;


impl ConnectorCommon for Cybersource {
    fn id(&self) -> &'static str {
        "cybersource"
    }

    fn common_get_content_type(&self) -> &'static str {
        "application/json;charset=utf-8"
    }

    fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str {
        connectors.cybersource.base_url.as_ref()
    }

    fn get_currency_unit(&self) -> api::CurrencyUnit {
        api::CurrencyUnit::Base
    }

    fn build_error_response(
        &self,
        res: Response,
        event_builder: Option<&mut ConnectorEvent>,
    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
        let response: Result<
            cybersource::CybersourceErrorResponse,
            Report<common_utils::errors::ParsingError>,
        > = res.response.parse_struct("Cybersource ErrorResponse");

        let error_message = if res.status_code == 401 {
            constants::CONNECTOR_UNAUTHORIZED_ERROR
        } else {
            hyperswitch_interfaces::consts::NO_ERROR_MESSAGE
        };
        match response {
            Ok(transformers::CybersourceErrorResponse::StandardError(response)) => {
                event_builder.map(|i| i.set_error_response_body(&response));
                router_env::logger::info!(connector_response=?response);

                let (code, message, reason) = match response.error_information {
                    Some(ref error_info) => {
                        let detailed_error_info = error_info.details.as_ref().map(|details| {
                            details
                                .iter()
                                .map(|det| format!("{} : {}", det.field, det.reason))
                                .collect::<Vec<_>>()
                                .join(", ")
                        });
                        (
                            error_info.reason.clone(),
                            error_info.reason.clone(),
                            transformers::get_error_reason(
                                Some(error_info.message.clone()),
                                detailed_error_info,
                                None,
                            ),
                        )
                    }
                    None => {
                        let detailed_error_info = response.details.map(|details| {
                            details
                                .iter()
                                .map(|det| format!("{} : {}", det.field, det.reason))
                                .collect::<Vec<_>>()
                                .join(", ")
                        });
                        (
                            response.reason.clone().map_or(
                                hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string(),
                                |reason| reason.to_string(),
                            ),
                            response
                                .reason
                                .map_or(error_message.to_string(), |reason| reason.to_string()),
                            transformers::get_error_reason(
                                response.message,
                                detailed_error_info,
                                None,
                            ),
                        )
                    }
                };

                Ok(ErrorResponse {
                    status_code: res.status_code,
                    code,
                    message,
                    reason,
                    attempt_status: None,
                    connector_transaction_id: None,
                    network_advice_code: None,
                    network_decline_code: None,
                    network_error_message: None,
                    connector_metadata: None,
                })
            }
            Ok(transformers::CybersourceErrorResponse::AuthenticationError(response)) => {
                event_builder.map(|i| i.set_error_response_body(&response));
                router_env::logger::info!(connector_response=?response);
                Ok(ErrorResponse {
                    status_code: res.status_code,
                    code: hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string(),
                    message: response.response.rmsg.clone(),
                    reason: Some(response.response.rmsg),
                    attempt_status: None,
                    connector_transaction_id: None,
                    network_advice_code: None,
                    network_decline_code: None,
                    network_error_message: None,
                    connector_metadata: None,
                })
            }
            Ok(transformers::CybersourceErrorResponse::NotAvailableError(response)) => {
                event_builder.map(|i| i.set_error_response_body(&response));
                router_env::logger::info!(connector_response=?response);
                let error_response = response
                    .errors
                    .iter()
                    .map(|error_info| {
                        format!(
                            "{}: {}",
                            error_info.error_type.clone().unwrap_or("".to_string()),
                            error_info.message.clone().unwrap_or("".to_string())
                        )
                    })
                    .collect::<Vec<String>>()
                    .join(" & ");
                Ok(ErrorResponse {
                    status_code: res.status_code,
                    code: hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string(),
                    message: error_response.clone(),
                    reason: Some(error_response),
                    attempt_status: None,
                    connector_transaction_id: None,
                    network_advice_code: None,
                    network_decline_code: None,
                    network_error_message: None,
                    connector_metadata: None,
                })
            }
            Err(error_msg) => {
                event_builder.map(|event| event.set_error(serde_json::json!({"error": res.response.escape_ascii().to_string(), "status_code": res.status_code})));
                router_env::logger::error!(deserialization_error =? error_msg);
                utils::handle_json_response_deserialization_failure(res, "cybersource")
            }
        }
    }
}

impl ConnectorCommon for for Cybersource


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


pub struct VaultRetrieveResponse {
    pub data: domain::PaymentMethodVaultingData,
}


pub struct FrmConfigsObject {
    pub frm_enabled_pm: Option<PaymentMethod>,
    pub frm_enabled_gateway: Option<api_models::enums::Connector>,
    pub frm_preferred_flow_type: api_enums::FrmPreferredFlowTypes,
}


pub struct BamboraPaymentsCaptureRequest {
    amount: FloatMajorUnit,
    payment_method: PaymentMethod,
}


pub struct PaypalRedirection {
    /// paypal's email address
    pub email: Option<Email>,
}


OpenAPI Block Path: components.schemas.IntentStatus
{
  "type": "string",
  "description": "Represents the overall status of a payment intent.\nThe status transitions through various states depending on the payment method, confirmation, capture method, and any subsequent actions (like customer authentication or manual capture).",
  "enum": [
    "succeeded",
    "failed",
    "cancelled",
    "cancelled_post_capture",
    "processing",
    "requires_customer_action",
    "requires_merchant_action",
    "requires_payment_method",
    "requires_confirmation",
    "requires_capture",
    "partially_captured",
    "partially_captured_and_capturable",
    "partially_authorized_and_requires_capture",
    "conflicted",
    "expired"
  ]
}


pub struct CreateThemeRequest {
    pub lineage: ThemeLineage,
    pub theme_name: String,
    pub theme_data: ThemeData,
    pub email_config: Option<EmailThemeConfig>,
}


pub struct RoutingLinkWrapper {
    pub profile_id: common_utils::id_type::ProfileId,
    pub algorithm_id: RoutingAlgorithmId,
}


pub fn get_co_badged_card_data(&self) -> Option<payment_methods::CoBadgedCardData> {
        if let Self::Card(card) = self {
            card.co_badged_card_data.clone()
        } else {
            None
        }
    }


impl CardInfoBuilder<CardInfoAdd> {
    fn set_added_card_info(
        self,
        card_info: card_info_models::CardInfo,
    ) -> CardInfoBuilder<CardInfoResponse> {
        CardInfoBuilder {
            state: std::marker::PhantomData,
            card_info: Some(card_info),
        }
    }
}


pub async fn customers_list(
    state: web::Data<AppState>,
    req: HttpRequest,
    query: web::Query<customers::CustomerListRequest>,
) -> HttpResponse {
    let flow = Flow::CustomersList;
    let payload = query.into_inner();

    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload,
        |state, auth: auth::AuthenticationData, request, _| {
            list_customers(
                state,
                auth.merchant_account.get_id().to_owned(),
                None,
                auth.key_store,
                request,
            )
        },
        auth::auth_type(
            &auth::V2ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            },
            &auth::JWTAuth {
                permission: Permission::MerchantCustomerRead,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub struct Cache;


pub async fn decide_gateway_open_router(
    state: SessionState,
    req_body: OpenRouterDecideGatewayRequest,
) -> RouterResponse<DecideGatewayResponse> {
    let response = if state.conf.open_router.dynamic_routing_enabled {
        SRApiClient::send_decision_engine_request(
            &state,
            Method::Post,
            "decide-gateway",
            Some(req_body),
            None,
            None,
        )
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)?
        .response
        .ok_or(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Failed to perform decide gateway call with open router")?
    } else {
        Err(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Dynamic routing is not enabled")?
    };

    Ok(hyperswitch_domain_models::api::ApplicationResponse::Json(
        response,
    ))
}


pub struct NmiVaultRequest {
    security_key: Secret<String>,
    ccnumber: CardNumber,
    ccexp: Secret<String>,
    cvv: Secret<String>,
    first_name: Secret<String>,
    last_name: Secret<String>,
    address1: Option<Secret<String>>,
    address2: Option<Secret<String>>,
    city: Option<String>,
    state: Option<Secret<String>>,
    zip: Option<Secret<String>>,
    country: Option<CountryAlpha2>,
    customer_vault: CustomerAction,
}


pub struct Data {
    #[serde(rename = "type")]
    pub payment_type: Option<String>,
    pub order_id: String,
    pub currency: Option<String>,
    pub amount: Option<MinorUnit>,
    pub description: Option<String>,
    pub capture: Option<String>,
    pub payment_url: Option<Url>,
    pub status: Option<MultisafepayPaymentStatus>,
    pub reason: Option<String>,
    pub reason_code: Option<String>,
    pub payment_details: Option<MultisafepayPaymentDetails>,
}


pub struct StripebillingRecordBackResponse {
    pub id: String,
}


Documentation: api-reference/v2/organization/organization--update.mdx
# Type: Doc File

---
openapi: put /v2/organizations/{id}
---


impl CommonMandateReference {
    pub fn get_mandate_details_value(&self) -> CustomResult<serde_json::Value, ParsingError> {
        let mut payments = self
            .payments
            .as_ref()
            .map_or_else(|| Ok(serde_json::json!({})), serde_json::to_value)
            .change_context(ParsingError::StructParseFailure("payment mandate details"))?;

        self.payouts
            .as_ref()
            .map(|payouts_mandate| {
                serde_json::to_value(payouts_mandate).map(|payouts_mandate_value| {
                    payments.as_object_mut().map(|payments_object| {
                        payments_object.insert("payouts".to_string(), payouts_mandate_value);
                    })
                })
            })
            .transpose()
            .change_context(ParsingError::StructParseFailure("payout mandate details"))?;

        Ok(payments)
    }

    #[cfg(feature = "v2")]
    /// Insert a new payment token reference for the given connector_id
    pub fn insert_payment_token_reference_record(
        &mut self,
        connector_id: &common_utils::id_type::MerchantConnectorAccountId,
        record: ConnectorTokenReferenceRecord,
    ) {
        match self.payments {
            Some(ref mut payments_reference) => {
                payments_reference.insert(connector_id.clone(), record);
            }
            None => {
                let mut payments_reference = HashMap::new();
                payments_reference.insert(connector_id.clone(), record);
                self.payments = Some(PaymentsTokenReference(payments_reference));
            }
        }
    }
}


OpenAPI Block Path: components.schemas.RecurringDetails
{
  "oneOf": [
    {
      "type": "object",
      "required": [
        "type",
        "data"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "mandate_id"
          ]
        },
        "data": {
          "type": "string"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "type",
        "data"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "payment_method_id"
          ]
        },
        "data": {
          "type": "string"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "type",
        "data"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "processor_payment_token"
          ]
        },
        "data": {
          "$ref": "#/components/schemas/ProcessorPaymentToken"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "type",
        "data"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "network_transaction_id_and_card_details"
          ]
        },
        "data": {
          "$ref": "#/components/schemas/NetworkTransactionIdAndCardDetails"
        }
      }
    }
  ],
  "description": "Details required for recurring payment",
  "discriminator": {
    "propertyName": "type"
  }
}


impl PlatformOrgAdminAuthWithMerchantIdFromRoute {
    async fn fetch_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))
    }
}


pub fn get_payment_intent_dimensions() -> Vec<NameDescription> {
    vec![
        PaymentIntentDimensions::PaymentIntentStatus,
        PaymentIntentDimensions::Currency,
        PaymentIntentDimensions::ProfileId,
        PaymentIntentDimensions::Connector,
        PaymentIntentDimensions::AuthType,
        PaymentIntentDimensions::PaymentMethod,
        PaymentIntentDimensions::PaymentMethodType,
        PaymentIntentDimensions::CardNetwork,
        PaymentIntentDimensions::MerchantId,
    ]
    .into_iter()
    .map(Into::into)
    .collect()
}


pub struct PaypalRelatedIds {
    pub order_id: String,
}


pub struct DirectDebitMethodData {
    consumer_name: Option<Secret<String>>,
    consumer_account: Secret<String>,
}


pub struct FrictionlessSuccessCount;