// File: crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs
// Module: hyperswitch_connectors
// Public functions: 1
// Public structs: 55

use std::collections::BTreeMap;

use api_models::{payments::AdditionalPaymentData, webhooks::IncomingWebhookEvent};
use common_enums::enums;
use common_utils::{
    errors::CustomResult,
    ext_traits::{Encode, OptionExt, ValueExt},
    id_type::CustomerId,
    pii::Email,
    request::Method,
    types::FloatMajorUnit,
};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
    payment_method_data::{Card, PaymentMethodData, WalletData},
    router_data::{
        AdditionalPaymentMethodConnectorResponse, ConnectorAuthType, ConnectorResponseData,
        ErrorResponse, RouterData,
    },
    router_flow_types::RSync,
    router_request_types::ResponseId,
    router_response_types::{
        ConnectorCustomerResponseData, MandateReference, PaymentsResponseData, RedirectForm,
        RefundsResponseData,
    },
    types::{
        ConnectorCustomerRouterData, PaymentsAuthorizeRouterData, PaymentsCancelRouterData,
        PaymentsCaptureRouterData, PaymentsCompleteAuthorizeRouterData, PaymentsSyncRouterData,
        RefundsRouterData, SetupMandateRouterData,
    },
};
use hyperswitch_interfaces::errors;
use masking::{ExposeInterface, PeekInterface, Secret, StrongSecret};
use rand::distributions::{Alphanumeric, DistString};
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::{
    types::{RefundsResponseRouterData, ResponseRouterData},
    utils::{
        self, CardData, ForeignTryFrom, PaymentsAuthorizeRequestData, PaymentsSyncRequestData,
        RefundsRequestData, RouterData as OtherRouterData, WalletData as OtherWalletData,
    },
};

const MAX_ID_LENGTH: usize = 20;

fn get_random_string() -> String {
    Alphanumeric.sample_string(&mut rand::thread_rng(), MAX_ID_LENGTH)
}

#[derive(Debug, Serialize)]
pub enum TransactionType {
    #[serde(rename = "authCaptureTransaction")]
    Payment,
    #[serde(rename = "authOnlyTransaction")]
    Authorization,
    #[serde(rename = "priorAuthCaptureTransaction")]
    Capture,
    #[serde(rename = "refundTransaction")]
    Refund,
    #[serde(rename = "voidTransaction")]
    Void,
    #[serde(rename = "authOnlyContinueTransaction")]
    ContinueAuthorization,
    #[serde(rename = "authCaptureContinueTransaction")]
    ContinueCapture,
}

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

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

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedotnetAuthType {
    name: Secret<String>,
    transaction_key: Secret<String>,
}

impl TryFrom<&ConnectorAuthType> for AuthorizedotnetAuthType {
    type Error = error_stack::Report<errors::ConnectorError>;

    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        if let ConnectorAuthType::BodyKey { api_key, key1 } = auth_type {
            Ok(Self {
                name: api_key.to_owned(),
                transaction_key: key1.to_owned(),
            })
        } else {
            Err(errors::ConnectorError::FailedToObtainAuthType)?
        }
    }
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct CreditCardDetails {
    card_number: StrongSecret<String, cards::CardNumberStrategy>,
    expiration_date: Secret<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    card_code: Option<Secret<String>>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
enum PaymentDetails {
    CreditCard(CreditCardDetails),
    OpaqueData(WalletDetails),
    PayPal(PayPalDetails),
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PayPalDetails {
    pub success_url: Option<String>,
    pub cancel_url: Option<String>,
}

#[derive(Serialize, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WalletDetails {
    pub data_descriptor: WalletMethod,
    pub data_value: Secret<String>,
}

#[derive(Serialize, Debug, Deserialize)]
pub enum WalletMethod {
    #[serde(rename = "COMMON.GOOGLE.INAPP.PAYMENT")]
    Googlepay,
    #[serde(rename = "COMMON.APPLE.INAPP.PAYMENT")]
    Applepay,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct TransactionRequest {
    transaction_type: TransactionType,
    amount: FloatMajorUnit,
    currency_code: common_enums::Currency,
    #[serde(skip_serializing_if = "Option::is_none")]
    payment: Option<PaymentDetails>,
    #[serde(skip_serializing_if = "Option::is_none")]
    profile: Option<ProfileDetails>,
    order: Order,
    #[serde(skip_serializing_if = "Option::is_none")]
    customer: Option<CustomerDetails>,
    #[serde(skip_serializing_if = "Option::is_none")]
    bill_to: Option<BillTo>,
    #[serde(skip_serializing_if = "Option::is_none")]
    user_fields: Option<UserFields>,
    #[serde(skip_serializing_if = "Option::is_none")]
    processing_options: Option<ProcessingOptions>,
    #[serde(skip_serializing_if = "Option::is_none")]
    subsequent_auth_information: Option<SubsequentAuthInformation>,
    authorization_indicator_type: Option<AuthorizationIndicator>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UserFields {
    user_field: Vec<UserField>,
}

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

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum ProfileDetails {
    CreateProfileDetails(CreateProfileDetails),
    CustomerProfileDetails(CustomerProfileDetails),
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CreateProfileDetails {
    create_profile: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    customer_profile_id: Option<Secret<String>>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct CustomerProfileDetails {
    customer_profile_id: Secret<String>,
    payment_profile: PaymentProfileDetails,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct PaymentProfileDetails {
    payment_profile_id: Secret<String>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CustomerDetails {
    id: String,
    email: Option<Email>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ProcessingOptions {
    is_subsequent_auth: bool,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BillTo {
    first_name: Option<Secret<String>>,
    last_name: Option<Secret<String>>,
    address: Option<Secret<String>>,
    city: Option<String>,
    state: Option<Secret<String>>,
    zip: Option<Secret<String>>,
    country: Option<enums::CountryAlpha2>,
}

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

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SubsequentAuthInformation {
    original_network_trans_id: Secret<String>,
    // original_auth_amount: String, Required for Discover, Diners Club, JCB, and China Union Pay transactions.
    reason: Reason,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Reason {
    Resubmission,
    #[serde(rename = "delayedCharge")]
    DelayedCharge,
    Reauthorization,
    #[serde(rename = "noShow")]
    NoShow,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct AuthorizationIndicator {
    authorization_indicator: AuthorizationType,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct TransactionVoidOrCaptureRequest {
    transaction_type: TransactionType,
    #[serde(skip_serializing_if = "Option::is_none")]
    amount: Option<FloatMajorUnit>,
    ref_trans_id: String,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedotnetPaymentsRequest {
    merchant_authentication: AuthorizedotnetAuthType,
    ref_id: Option<String>,
    transaction_request: TransactionRequest,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedotnetPaymentCancelOrCaptureRequest {
    merchant_authentication: AuthorizedotnetAuthType,
    transaction_request: TransactionVoidOrCaptureRequest,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
// The connector enforces field ordering, it expects fields to be in the same order as in their API documentation
pub struct CustomerRequest {
    create_customer_profile_request: CreateCustomerRequest,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateCustomerRequest {
    merchant_authentication: AuthorizedotnetAuthType,
    profile: Profile,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateCustomerPaymentProfileRequest {
    create_customer_payment_profile_request: AuthorizedotnetPaymentProfileRequest,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedotnetPaymentProfileRequest {
    merchant_authentication: AuthorizedotnetAuthType,
    customer_profile_id: Secret<String>,
    payment_profile: PaymentProfile,
    validation_mode: ValidationMode,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ShipToList {
    #[serde(skip_serializing_if = "Option::is_none")]
    first_name: Option<Secret<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    last_name: Option<Secret<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    address: Option<Secret<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    city: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    state: Option<Secret<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    zip: Option<Secret<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    country: Option<enums::CountryAlpha2>,
    #[serde(skip_serializing_if = "Option::is_none")]
    phone_number: Option<Secret<String>>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct Profile {
    #[serde(skip_serializing_if = "Option::is_none")]
    merchant_customer_id: Option<CustomerId>,
    #[serde(skip_serializing_if = "Option::is_none")]
    description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    email: Option<Email>,
    #[serde(skip_serializing_if = "Option::is_none")]
    payment_profiles: Option<PaymentProfiles>,
    #[serde(skip_serializing_if = "Option::is_none")]
    ship_to_list: Option<Vec<ShipToList>>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct PaymentProfiles {
    customer_type: CustomerType,
    #[serde(skip_serializing_if = "Option::is_none")]
    bill_to: Option<BillTo>,
    payment: PaymentDetails,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct PaymentProfile {
    #[serde(skip_serializing_if = "Option::is_none")]
    bill_to: Option<BillTo>,
    payment: PaymentDetails,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum CustomerType {
    Individual,
    Business,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ValidationMode {
    // testMode performs a Luhn mod-10 check on the card number, without further validation at connector.
    TestMode,
    // liveMode submits a zero-dollar or one-cent transaction (depending on card type and processor support) to confirm that the card number belongs to an active credit or debit account.
    LiveMode,
}

impl ForeignTryFrom<Value> for Vec<UserField> {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn foreign_try_from(metadata: Value) -> Result<Self, Self::Error> {
        let hashmap: BTreeMap<String, Value> = serde_json::from_str(&metadata.to_string())
            .change_context(errors::ConnectorError::RequestEncodingFailedWithReason(
                "Failed to serialize request metadata".to_owned(),
            ))
            .attach_printable("")?;
        let mut vector: Self = Self::new();
        for (key, value) in hashmap {
            vector.push(UserField {
                name: key,
                value: value.to_string(),
            });
        }
        Ok(vector)
    }
}

impl TryFrom<&ConnectorCustomerRouterData> for CustomerRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &ConnectorCustomerRouterData) -> Result<Self, Self::Error> {
        let merchant_authentication = AuthorizedotnetAuthType::try_from(&item.connector_auth_type)?;
        let ship_to_list = item.get_optional_shipping().and_then(|shipping| {
            shipping.address.as_ref().map(|address| {
                vec![ShipToList {
                    first_name: address.first_name.clone(),
                    last_name: address.last_name.clone(),
                    address: address.line1.clone(),
                    city: address.city.clone(),
                    state: address.state.clone(),
                    zip: address.zip.clone(),
                    country: address.country,
                    phone_number: shipping
                        .phone
                        .as_ref()
                        .and_then(|phone| phone.number.as_ref().map(|number| number.to_owned())),
                }]
            })
        });

        let merchant_customer_id = match item.customer_id.as_ref() {
            Some(cid) if cid.get_string_repr().len() <= MAX_ID_LENGTH => Some(cid.clone()),
            _ => None,
        };

        Ok(Self {
            create_customer_profile_request: CreateCustomerRequest {
                merchant_authentication,
                profile: Profile {
                    merchant_customer_id,
                    description: None,
                    email: item.request.email.clone(),
                    payment_profiles: None,
                    ship_to_list,
                },
            },
        })
    }
}

impl TryFrom<&SetupMandateRouterData> for CreateCustomerPaymentProfileRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &SetupMandateRouterData) -> Result<Self, Self::Error> {
        let merchant_authentication = AuthorizedotnetAuthType::try_from(&item.connector_auth_type)?;
        let validation_mode = match item.test_mode {
            Some(true) | None => ValidationMode::TestMode,
            Some(false) => ValidationMode::LiveMode,
        };
        let customer_profile_id = item.get_connector_customer_id()?.into();

        let bill_to = item
            .get_optional_billing()
            .and_then(|billing_address| billing_address.address.as_ref())
            .map(|address| BillTo {
                first_name: address.first_name.clone(),
                last_name: address.last_name.clone(),
                address: address.line1.clone(),
                city: address.city.clone(),
                state: address.state.clone(),
                zip: address.zip.clone(),
                country: address.country,
            });
        let payment_profile = match item.request.payment_method_data.clone() {
            PaymentMethodData::Card(ccard) => Ok(PaymentProfile {
                bill_to,
                payment: PaymentDetails::CreditCard(CreditCardDetails {
                    card_number: (*ccard.card_number).clone(),
                    expiration_date: ccard.get_expiry_date_as_yyyymm("-"),
                    card_code: Some(ccard.card_cvc.clone()),
                }),
            }),
            PaymentMethodData::Wallet(wallet_data) => match wallet_data {
                WalletData::GooglePay(_) => Ok(PaymentProfile {
                    bill_to,
                    payment: PaymentDetails::OpaqueData(WalletDetails {
                        data_descriptor: WalletMethod::Googlepay,
                        data_value: Secret::new(wallet_data.get_encoded_wallet_token()?),
                    }),
                }),
                WalletData::ApplePay(applepay_token) => {
                    let apple_pay_encrypted_data = applepay_token
                        .payment_data
                        .get_encrypted_apple_pay_payment_data_mandatory()
                        .change_context(errors::ConnectorError::MissingRequiredField {
                            field_name: "Apple pay encrypted data",
                        })?;

                    Ok(PaymentProfile {
                        bill_to,
                        payment: PaymentDetails::OpaqueData(WalletDetails {
                            data_descriptor: WalletMethod::Applepay,
                            data_value: Secret::new(apple_pay_encrypted_data.clone()),
                        }),
                    })
                }

                WalletData::AliPayQr(_)
                | WalletData::AliPayRedirect(_)
                | WalletData::AliPayHkRedirect(_)
                | WalletData::AmazonPayRedirect(_)
                | WalletData::Paysera(_)
                | WalletData::BluecodeRedirect {}
                | WalletData::Skrill(_)
                | WalletData::MomoRedirect(_)
                | WalletData::KakaoPayRedirect(_)
                | WalletData::GoPayRedirect(_)
                | WalletData::GcashRedirect(_)
                | WalletData::ApplePayRedirect(_)
                | WalletData::ApplePayThirdPartySdk(_)
                | WalletData::DanaRedirect {}
                | WalletData::GooglePayRedirect(_)
                | WalletData::GooglePayThirdPartySdk(_)
                | WalletData::MbWayRedirect(_)
                | WalletData::MobilePayRedirect(_)
                | WalletData::PaypalRedirect(_)
                | WalletData::AmazonPay(_)
                | WalletData::PaypalSdk(_)
                | WalletData::Paze(_)
                | WalletData::SamsungPay(_)
                | WalletData::TwintRedirect {}
                | WalletData::VippsRedirect {}
                | WalletData::TouchNGoRedirect(_)
                | WalletData::WeChatPayRedirect(_)
                | WalletData::WeChatPayQr(_)
                | WalletData::CashappQr(_)
                | WalletData::SwishQr(_)
                | WalletData::Mifinity(_)
                | WalletData::RevolutPay(_) => Err(errors::ConnectorError::NotImplemented(
                    utils::get_unimplemented_payment_method_error_message("authorizedotnet"),
                )),
            },
            PaymentMethodData::CardRedirect(_)
            | PaymentMethodData::PayLater(_)
            | PaymentMethodData::BankRedirect(_)
            | PaymentMethodData::BankDebit(_)
            | PaymentMethodData::BankTransfer(_)
            | PaymentMethodData::Crypto(_)
            | PaymentMethodData::MandatePayment
            | PaymentMethodData::Reward
            | PaymentMethodData::RealTimePayment(_)
            | PaymentMethodData::MobilePayment(_)
            | PaymentMethodData::Upi(_)
            | PaymentMethodData::Voucher(_)
            | PaymentMethodData::GiftCard(_)
            | PaymentMethodData::OpenBanking(_)
            | PaymentMethodData::CardToken(_)
            | PaymentMethodData::NetworkToken(_)
            | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                Err(errors::ConnectorError::NotImplemented(
                    utils::get_unimplemented_payment_method_error_message("authorizedotnet"),
                ))
            }
        }?;
        Ok(Self {
            create_customer_payment_profile_request: AuthorizedotnetPaymentProfileRequest {
                merchant_authentication,
                customer_profile_id,
                payment_profile,
                validation_mode,
            },
        })
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedotnetSetupMandateResponse {
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    customer_payment_profile_id_list: Vec<String>,
    customer_profile_id: Option<String>,
    #[serde(rename = "customerPaymentProfileId")]
    customer_payment_profile_id: Option<String>,
    validation_direct_response_list: Option<Vec<Secret<String>>>,
    pub messages: ResponseMessages,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedotnetCustomerResponse {
    customer_profile_id: Option<String>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    customer_payment_profile_id_list: Vec<String>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    customer_shipping_address_id_list: Vec<String>,
    pub messages: ResponseMessages,
}

fn extract_customer_id(text: &str) -> Option<String> {
    let re = Regex::new(r"ID (\d+)").ok()?;
    re.captures(text)
        .and_then(|captures| captures.get(1))
        .map(|capture_match| capture_match.as_str().to_string())
}

impl<F, T> TryFrom<ResponseRouterData<F, AuthorizedotnetCustomerResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, AuthorizedotnetCustomerResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        match item.response.messages.result_code {
            ResultCode::Ok => match item.response.customer_profile_id.clone() {
                Some(connector_customer_id) => Ok(Self {
                    response: Ok(PaymentsResponseData::ConnectorCustomerResponse(
                        ConnectorCustomerResponseData::new_with_customer_id(connector_customer_id),
                    )),
                    ..item.data
                }),
                None => Err(
                    errors::ConnectorError::UnexpectedResponseError(bytes::Bytes::from(
                        "Missing customer profile id from Authorizedotnet".to_string(),
                    ))
                    .into(),
                ),
            },
            ResultCode::Error => {
                let error_message = item.response.messages.message.first();
                if let Some(connector_customer_id) =
                    error_message.and_then(|error| extract_customer_id(&error.text))
                {
                    Ok(Self {
                        response: Ok(PaymentsResponseData::ConnectorCustomerResponse(
                            ConnectorCustomerResponseData::new_with_customer_id(
                                connector_customer_id,
                            ),
                        )),
                        ..item.data
                    })
                } else {
                    let error_code = error_message.map(|error| error.code.clone());
                    let error_code = error_code.unwrap_or_else(|| {
                        hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string()
                    });
                    let error_reason = item
                        .response
                        .messages
                        .message
                        .iter()
                        .map(|error: &ResponseMessage| error.text.clone())
                        .collect::<Vec<String>>()
                        .join(" ");
                    let response = Err(ErrorResponse {
                        code: error_code,
                        message: item.response.messages.result_code.to_string(),
                        reason: Some(error_reason),
                        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,
                        status: enums::AttemptStatus::Failure,
                        ..item.data
                    })
                }
            }
        }
    }
}

// zero dollar response
impl<F, T>
    TryFrom<ResponseRouterData<F, AuthorizedotnetSetupMandateResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, AuthorizedotnetSetupMandateResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        let connector_customer_id = item.data.get_connector_customer_id()?;
        if item.response.customer_profile_id.is_some() {
            Ok(Self {
                status: enums::AttemptStatus::Charged,
                response: Ok(PaymentsResponseData::TransactionResponse {
                    resource_id: ResponseId::NoResponseId,
                    redirection_data: Box::new(None),
                    mandate_reference: Box::new(Some(MandateReference {
                        connector_mandate_id: item
                            .response
                            .customer_payment_profile_id_list
                            .first()
                            .or(item.response.customer_payment_profile_id.as_ref())
                            .map(|payment_profile_id| {
                                format!("{connector_customer_id}-{payment_profile_id}")
                            }),
                        payment_method_id: None,
                        mandate_metadata: None,
                        connector_mandate_request_reference_id: None,
                    })),
                    connector_metadata: None,
                    network_txn_id: None,
                    connector_response_reference_id: None,
                    incremental_authorization_allowed: None,
                    charges: None,
                }),
                ..item.data
            })
        } else {
            let error_message = item.response.messages.message.first();
            let error_code = error_message.map(|error| error.code.clone());
            let error_code = error_code
                .unwrap_or_else(|| hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string());
            let error_reason = item
                .response
                .messages
                .message
                .iter()
                .map(|error: &ResponseMessage| error.text.clone())
                .collect::<Vec<String>>()
                .join(" ");
            let response = Err(ErrorResponse {
                code: error_code,
                message: item.response.messages.result_code.to_string(),
                reason: Some(error_reason),
                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,
                status: enums::AttemptStatus::Failure,
                ..item.data
            })
        }
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
// The connector enforces field ordering, it expects fields to be in the same order as in their API documentation
pub struct CreateTransactionRequest {
    create_transaction_request: AuthorizedotnetPaymentsRequest,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CancelOrCaptureTransactionRequest {
    create_transaction_request: AuthorizedotnetPaymentCancelOrCaptureRequest,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum AuthorizationType {
    Final,
    Pre,
}

impl TryFrom<enums::CaptureMethod> for AuthorizationType {
    type Error = error_stack::Report<errors::ConnectorError>;

    fn try_from(capture_method: enums::CaptureMethod) -> Result<Self, Self::Error> {
        match capture_method {
            enums::CaptureMethod::Manual => Ok(Self::Pre),
            enums::CaptureMethod::SequentialAutomatic | enums::CaptureMethod::Automatic => {
                Ok(Self::Final)
            }
            enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(
                utils::construct_not_supported_error_report(capture_method, "authorizedotnet"),
            )?,
        }
    }
}

impl TryFrom<&AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>>
    for CreateTransactionRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        let merchant_authentication =
            AuthorizedotnetAuthType::try_from(&item.router_data.connector_auth_type)?;

        let ref_id = if item.router_data.connector_request_reference_id.len() <= MAX_ID_LENGTH {
            Some(item.router_data.connector_request_reference_id.clone())
        } else {
            None
        };

        let transaction_request = match item
            .router_data
            .request
            .mandate_id
            .clone()
            .and_then(|mandate_ids| mandate_ids.mandate_reference_id)
        {
            Some(api_models::payments::MandateReferenceId::NetworkMandateId(network_trans_id)) => {
                TransactionRequest::try_from((item, network_trans_id))?
            }
            Some(api_models::payments::MandateReferenceId::ConnectorMandateId(
                connector_mandate_id,
            )) => TransactionRequest::try_from((item, connector_mandate_id))?,
            Some(api_models::payments::MandateReferenceId::NetworkTokenWithNTI(_)) => {
                Err(errors::ConnectorError::NotImplemented(
                    utils::get_unimplemented_payment_method_error_message("authorizedotnet"),
                ))?
            }
            None => {
                match &item.router_data.request.payment_method_data {
                    PaymentMethodData::Card(ccard) => TransactionRequest::try_from((item, ccard)),
                    PaymentMethodData::Wallet(wallet_data) => {
                        TransactionRequest::try_from((item, wallet_data))
                    }
                    PaymentMethodData::CardRedirect(_)
                    | PaymentMethodData::PayLater(_)
                    | PaymentMethodData::BankRedirect(_)
                    | PaymentMethodData::BankDebit(_)
                    | PaymentMethodData::BankTransfer(_)
                    | PaymentMethodData::Crypto(_)
                    | PaymentMethodData::MandatePayment
                    | PaymentMethodData::Reward
                    | PaymentMethodData::RealTimePayment(_)
                    | PaymentMethodData::MobilePayment(_)
                    | PaymentMethodData::Upi(_)
                    | PaymentMethodData::Voucher(_)
                    | PaymentMethodData::GiftCard(_)
                    | PaymentMethodData::OpenBanking(_)
                    | PaymentMethodData::CardToken(_)
                    | PaymentMethodData::NetworkToken(_)
                    | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                        Err(errors::ConnectorError::NotImplemented(
                            utils::get_unimplemented_payment_method_error_message(
                                "authorizedotnet",
                            ),
                        ))?
                    }
                }
            }?,
        };
        Ok(Self {
            create_transaction_request: AuthorizedotnetPaymentsRequest {
                merchant_authentication,
                ref_id,
                transaction_request,
            },
        })
    }
}

impl
    TryFrom<(
        &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
        String,
    )> for TransactionRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, network_trans_id): (
            &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
            String,
        ),
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            transaction_type: TransactionType::try_from(item.router_data.request.capture_method)?,
            amount: item.amount,
            currency_code: item.router_data.request.currency,
            payment: Some(match item.router_data.request.payment_method_data {
                PaymentMethodData::Card(ref ccard) => {
                    PaymentDetails::CreditCard(CreditCardDetails {
                        card_number: (*ccard.card_number).clone(),
                        expiration_date: ccard.get_expiry_date_as_yyyymm("-"),
                        card_code: None,
                    })
                }
                PaymentMethodData::CardRedirect(_)
                | PaymentMethodData::Wallet(_)
                | PaymentMethodData::PayLater(_)
                | PaymentMethodData::BankRedirect(_)
                | PaymentMethodData::BankDebit(_)
                | PaymentMethodData::BankTransfer(_)
                | PaymentMethodData::Crypto(_)
                | PaymentMethodData::MandatePayment
                | PaymentMethodData::Reward
                | PaymentMethodData::RealTimePayment(_)
                | PaymentMethodData::MobilePayment(_)
                | PaymentMethodData::Upi(_)
                | PaymentMethodData::Voucher(_)
                | PaymentMethodData::GiftCard(_)
                | PaymentMethodData::OpenBanking(_)
                | PaymentMethodData::CardToken(_)
                | PaymentMethodData::NetworkToken(_)
                | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                    Err(errors::ConnectorError::NotImplemented(
                        utils::get_unimplemented_payment_method_error_message("authorizedotnet"),
                    ))?
                }
            }),
            profile: None,
            order: Order {
                invoice_number: match &item.router_data.request.merchant_order_reference_id {
                    Some(merchant_order_reference_id) => {
                        if merchant_order_reference_id.len() <= MAX_ID_LENGTH {
                            merchant_order_reference_id.to_string()
                        } else {
                            get_random_string()
                        }
                    }
                    None => get_random_string(),
                },

                description: item.router_data.connector_request_reference_id.clone(),
            },
            customer: Some(CustomerDetails {
                id: if item.router_data.payment_id.len() <= MAX_ID_LENGTH {
                    item.router_data.payment_id.clone()
                } else {
                    get_random_string()
                },
                email: item.router_data.request.get_optional_email(),
            }),
            bill_to: item
                .router_data
                .get_optional_billing()
                .and_then(|billing_address| billing_address.address.as_ref())
                .map(|address| BillTo {
                    first_name: address.first_name.clone(),
                    last_name: address.last_name.clone(),
                    address: address.line1.clone(),
                    city: address.city.clone(),
                    state: address.state.clone(),
                    zip: address.zip.clone(),
                    country: address.country,
                }),
            user_fields: match item.router_data.request.metadata.clone() {
                Some(metadata) => Some(UserFields {
                    user_field: Vec::<UserField>::foreign_try_from(metadata)?,
                }),
                None => None,
            },
            processing_options: Some(ProcessingOptions {
                is_subsequent_auth: true,
            }),
            subsequent_auth_information: Some(SubsequentAuthInformation {
                original_network_trans_id: Secret::new(network_trans_id),
                reason: Reason::Resubmission,
            }),
            authorization_indicator_type: match item.router_data.request.capture_method {
                Some(capture_method) => Some(AuthorizationIndicator {
                    authorization_indicator: capture_method.try_into()?,
                }),
                None => None,
            },
        })
    }
}

impl
    TryFrom<(
        &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
        api_models::payments::ConnectorMandateReferenceId,
    )> for TransactionRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, connector_mandate_id): (
            &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
            api_models::payments::ConnectorMandateReferenceId,
        ),
    ) -> Result<Self, Self::Error> {
        let mandate_id = connector_mandate_id
            .get_connector_mandate_id()
            .ok_or(errors::ConnectorError::MissingConnectorMandateID)?;
        Ok(Self {
            transaction_type: TransactionType::try_from(item.router_data.request.capture_method)?,
            amount: item.amount,
            currency_code: item.router_data.request.currency,
            payment: None,
            profile: mandate_id
                .split_once('-')
                .map(|(customer_profile_id, payment_profile_id)| {
                    ProfileDetails::CustomerProfileDetails(CustomerProfileDetails {
                        customer_profile_id: Secret::from(customer_profile_id.to_string()),
                        payment_profile: PaymentProfileDetails {
                            payment_profile_id: Secret::from(payment_profile_id.to_string()),
                        },
                    })
                }),
            order: Order {
                invoice_number: match &item.router_data.request.merchant_order_reference_id {
                    Some(merchant_order_reference_id) => {
                        if merchant_order_reference_id.len() <= MAX_ID_LENGTH {
                            merchant_order_reference_id.to_string()
                        } else {
                            get_random_string()
                        }
                    }
                    None => get_random_string(),
                },

                description: item.router_data.connector_request_reference_id.clone(),
            },
            customer: None,
            bill_to: None,
            user_fields: match item.router_data.request.metadata.clone() {
                Some(metadata) => Some(UserFields {
                    user_field: Vec::<UserField>::foreign_try_from(metadata)?,
                }),
                None => None,
            },
            processing_options: Some(ProcessingOptions {
                is_subsequent_auth: true,
            }),
            subsequent_auth_information: None,
            authorization_indicator_type: match item.router_data.request.capture_method {
                Some(capture_method) => Some(AuthorizationIndicator {
                    authorization_indicator: capture_method.try_into()?,
                }),
                None => None,
            },
        })
    }
}

impl
    TryFrom<(
        &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
        &Card,
    )> for TransactionRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, ccard): (
            &AuthorizedotnetRouterData<&PaymentsAuthorizeRouterData>,
            &Card,
        ),
    ) -> Result<Self, Self::Error> {
        let profile = if item
            .router_data
            .request
            .is_customer_initiated_mandate_payment()
        {
            let connector_customer_id =
                Secret::new(item.router_data.connector_customer.clone().ok_or(
                    errors::ConnectorError::MissingConnectorRelatedTransactionID {
                        id: "connector_customer_id".to_string(),
                    },
                )?);
            Some(ProfileDetails::CreateProfileDetails(CreateProfileDetails {
                create_profile: true,
                customer_profile_id: Some(connector_customer_id),
            }))
        } else {
            None
        };

        let customer = if !item
            .router_data
            .request
            .is_customer_initiated_mandate_payment()
        {
            item.router_data.customer_id.as_ref().and_then(|customer| {
                let customer_id = customer.get_string_repr();
                (customer_id.len() <= MAX_ID_LENGTH).then_some(CustomerDetails {
                    id: customer_id.to_string(),
                    email: item.router_data.request.get_optional_email(),
                })
            })
        } else {
            None
        };

        Ok(Self {
            transaction_type: TransactionType::try_from(item.router_data.request.capture_method)?,
            amount: item.amount,
            currency_code: item.router_data.request.currency,
            payment: Some(PaymentDetails::CreditCard(CreditCardDetails {
                card_number: (*ccard.card_number).clone(),
                expiration_date: ccard.get_expiry_date_as_yyyymm("-"),


// Struct: PaymentsResPaymentInstrument
// File: crates/hyperswitch_connectors/src/connectors/worldpay/response.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaymentsResPaymentInstrument


                    domain::payments::BankRedirectData::OnlineBankingSlovakia { .. } => {
                        Self::OnlineBankingSlovakia
                    }
                    domain::payments::BankRedirectData::OpenBankingUk { .. } => Self::OpenBankingUk,
                    domain::payments::BankRedirectData::Przelewy24 { .. } => Self::Przelewy24,
                    domain::payments::BankRedirectData::Sofort { .. } => Self::Sofort,
                    domain::payments::BankRedirectData::Trustly { .. } => Self::Trustly,
                    domain::payments::BankRedirectData::OnlineBankingFpx { .. } => {
                        Self::OnlineBankingFpx
                    }
                    domain::payments::BankRedirectData::OnlineBankingThailand { .. } => {
                        Self::OnlineBankingThailand
                    }
                    domain::payments::BankRedirectData::LocalBankRedirect { } => {
                        Self::LocalBankRedirect
                    }
                }
            }
            domain::payments::PaymentMethodData::BankDebit(bank_debit_data) => {
                match bank_debit_data {
                    domain::payments::BankDebitData::AchBankDebit { .. } => Self::AchBankDebit,
                    domain::payments::BankDebitData::SepaBankDebit { .. } => Self::SepaBankDebit,
                    domain::payments::BankDebitData::BecsBankDebit { .. } => Self::BecsBankDebit,
                    domain::payments::BankDebitData::BacsBankDebit { .. } => Self::BacsBankDebit,
                }
            }
            domain::payments::PaymentMethodData::BankTransfer(bank_transfer_data) => {
                match *bank_transfer_data {
                    domain::payments::BankTransferData::AchBankTransfer { .. } => {
                        Self::AchBankTransfer
                    }
                    domain::payments::BankTransferData::SepaBankTransfer { .. } => {
                        Self::SepaBankTransfer
                    }
                    domain::payments::BankTransferData::BacsBankTransfer { .. } => {
                        Self::BacsBankTransfer
                    }
                    domain::payments::BankTransferData::MultibancoBankTransfer { .. } => {
                        Self::MultibancoBankTransfer
                    }
                    domain::payments::BankTransferData::PermataBankTransfer { .. } => {
                        Self::PermataBankTransfer
                    }
                    domain::payments::BankTransferData::BcaBankTransfer { .. } => {
                        Self::BcaBankTransfer
                    }
                    domain::payments::BankTransferData::BniVaBankTransfer { .. } => {
                        Self::BniVaBankTransfer
                    }
                    domain::payments::BankTransferData::BriVaBankTransfer { .. } => {
                        Self::BriVaBankTransfer
                    }
                    domain::payments::BankTransferData::CimbVaBankTransfer { .. } => {
                        Self::CimbVaBankTransfer
                    }
                    domain::payments::BankTransferData::DanamonVaBankTransfer { .. } => {
                        Self::DanamonVaBankTransfer
                    }
                    domain::payments::BankTransferData::MandiriVaBankTransfer { .. } => {
                        Self::MandiriVaBankTransfer
                    }
                    domain::payments::BankTransferData::Pix { .. } => Self::Pix,
                    domain::payments::BankTransferData::Pse {} => Self::Pse,
                    domain::payments::BankTransferData::LocalBankTransfer { .. } => {
                        Self::LocalBankTransfer
                    }
                    domain::payments::BankTransferData::InstantBankTransfer {} => {
                        Self::InstantBankTransfer
                    }
                    domain::payments::BankTransferData::InstantBankTransferFinland {} => {
                        Self::InstantBankTransferFinland
                    }
                    domain::payments::BankTransferData::InstantBankTransferPoland {} => {
                        Self::InstantBankTransferPoland
                    }
                    domain::payments::BankTransferData::IndonesianBankTransfer { .. } => {
                        Self::IndonesianBankTransfer
                    }
                }
            }
            domain::payments::PaymentMethodData::Crypto(_) => Self::Crypto,
            domain::payments::PaymentMethodData::MandatePayment => Self::MandatePayment,
            domain::payments::PaymentMethodData::Reward => Self::Reward,
            domain::payments::PaymentMethodData::Upi(_) => Self::Upi,
            domain::payments::PaymentMethodData::Voucher(voucher_data) => match voucher_data {
                domain::payments::VoucherData::Boleto(_) => Self::Boleto,
                domain::payments::VoucherData::Efecty => Self::Efecty,
                domain::payments::VoucherData::PagoEfectivo => Self::PagoEfectivo,
                domain::payments::VoucherData::RedCompra => Self::RedCompra,
                domain::payments::VoucherData::RedPagos => Self::RedPagos,
                domain::payments::VoucherData::Alfamart(_) => Self::Alfamart,
                domain::payments::VoucherData::Indomaret(_) => Self::Indomaret,
                domain::payments::VoucherData::Oxxo => Self::Oxxo,
                domain::payments::VoucherData::SevenEleven(_) => Self::SevenEleven,
                domain::payments::VoucherData::Lawson(_) => Self::Lawson,
                domain::payments::VoucherData::MiniStop(_) => Self::MiniStop,
                domain::payments::VoucherData::FamilyMart(_) => Self::FamilyMart,
                domain::payments::VoucherData::Seicomart(_) => Self::Seicomart,
                domain::payments::VoucherData::PayEasy(_) => Self::PayEasy,
            },
            domain::PaymentMethodData::RealTimePayment(real_time_payment_data) => match *real_time_payment_data{
                hyperswitch_domain_models::payment_method_data::RealTimePaymentData::DuitNow {  } =>  Self::DuitNow,
                hyperswitch_domain_models::payment_method_data::RealTimePaymentData::Fps {  } => Self::Fps,
                hyperswitch_domain_models::payment_method_data::RealTimePaymentData::PromptPay {  } => Self::PromptPay,
                hyperswitch_domain_models::payment_method_data::RealTimePaymentData::VietQr {  } => Self::VietQr,
            },
            domain::payments::PaymentMethodData::GiftCard(gift_card_data) => {
                match *gift_card_data {
                    domain::payments::GiftCardData::Givex(_) => Self::Givex,
                    domain::payments::GiftCardData::BhnCardNetwork(_)=>Self::BhnCardNetwork,
                    domain::payments::GiftCardData::PaySafeCard {} => Self::PaySafeCar,
                }
            }
            domain::payments::PaymentMethodData::CardToken(_) => Self::CardToken,
            domain::payments::PaymentMethodData::OpenBanking(data) => match data {
                hyperswitch_domain_models::payment_method_data::OpenBankingData::OpenBankingPIS {  } => Self::OpenBanking
            },
            domain::payments::PaymentMethodData::MobilePayment(mobile_payment_data) => match mobile_payment_data {
                hyperswitch_domain_models::payment_method_data::MobilePaymentData::DirectCarrierBilling { .. } => Self::DirectCarrierBilling,
            },
        }
    }
}

pub fn convert_amount<T>(
    amount_convertor: &dyn AmountConvertor<Output = T>,
    amount: MinorUnit,
    currency: enums::Currency,
) -> Result<T, error_stack::Report<errors::ConnectorError>> {
    amount_convertor
        .convert(amount, currency)
        .change_context(errors::ConnectorError::AmountConversionFailed)
}

pub fn convert_back_amount_to_minor_units<T>(
    amount_convertor: &dyn AmountConvertor<Output = T>,
    amount: T,
    currency: enums::Currency,
) -> Result<MinorUnit, error_stack::Report<errors::ConnectorError>> {
    amount_convertor
        .convert_back(amount, currency)
        .change_context(errors::ConnectorError::AmountConversionFailed)
}
pub trait NetworkTokenData {
    fn get_card_issuer(&self) -> Result<CardIssuer, Error>;
    fn get_expiry_year_4_digit(&self) -> Secret<String>;
    fn get_network_token(&self) -> NetworkTokenNumber;
    fn get_network_token_expiry_month(&self) -> Secret<String>;
    fn get_network_token_expiry_year(&self) -> Secret<String>;
    fn get_cryptogram(&self) -> Option<Secret<String>>;
}

impl NetworkTokenData for domain::NetworkTokenData {
    #[cfg(feature = "v1")]
    fn get_card_issuer(&self) -> Result<CardIssuer, Error> {
        get_card_issuer(self.token_number.peek())
    }

    #[cfg(feature = "v2")]
    fn get_card_issuer(&self) -> Result<CardIssuer, Error> {
        get_card_issuer(self.network_token.peek())
    }

    #[cfg(feature = "v1")]
    fn get_expiry_year_4_digit(&self) -> Secret<String> {
        let mut year = self.token_exp_year.peek().clone();
        if year.len() == 2 {
            year = format!("20{year}");
        }
        Secret::new(year)
    }

    #[cfg(feature = "v2")]
    fn get_expiry_year_4_digit(&self) -> Secret<String> {
        let mut year = self.network_token_exp_year.peek().clone();
        if year.len() == 2 {
            year = format!("20{year}");
        }
        Secret::new(year)
    }

    #[cfg(feature = "v1")]
    fn get_network_token(&self) -> NetworkTokenNumber {
        self.token_number.clone()
    }

    #[cfg(feature = "v2")]
    fn get_network_token(&self) -> NetworkTokenNumber {
        self.network_token.clone()
    }

    #[cfg(feature = "v1")]
    fn get_network_token_expiry_month(&self) -> Secret<String> {
        self.token_exp_month.clone()
    }

    #[cfg(feature = "v2")]
    fn get_network_token_expiry_month(&self) -> Secret<String> {
        self.network_token_exp_month.clone()
    }

    #[cfg(feature = "v1")]
    fn get_network_token_expiry_year(&self) -> Secret<String> {
        self.token_exp_year.clone()
    }

    #[cfg(feature = "v2")]
    fn get_network_token_expiry_year(&self) -> Secret<String> {
        self.network_token_exp_year.clone()
    }

    #[cfg(feature = "v1")]
    fn get_cryptogram(&self) -> Option<Secret<String>> {
        self.token_cryptogram.clone()
    }

    #[cfg(feature = "v2")]
    fn get_cryptogram(&self) -> Option<Secret<String>> {
        self.cryptogram.clone()
    }
}

pub fn convert_uppercase<'de, D, T>(v: D) -> Result<T, D::Error>
where
    D: serde::Deserializer<'de>,
    T: FromStr,
    <T as FromStr>::Err: std::fmt::Debug + std::fmt::Display + std::error::Error,
{
    use serde::de::Error;
    let output = <&str>::deserialize(v)?;
    output.to_uppercase().parse::<T>().map_err(D::Error::custom)
}


                UploadFileRequestData,
                UploadFileResponse,
            > for $path::$connector
            {}
            impl RetrieveFile for $path::$connector {}
            impl
                ConnectorIntegration<
                Retrieve,
                RetrieveFileRequestData,
                RetrieveFileResponse,
            > for $path::$connector
            {}
    )*
    };
}

default_imp_for_file_upload!(
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Ebanx,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Nomupay,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Payone,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Wise,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

macro_rules! default_imp_for_payouts {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl api::Payouts for $path::$connector {}
    )*
    };
}

default_imp_for_payouts!(
    connectors::Paysafe,
    connectors::Affirm,
    connectors::Vgs,
    connectors::Aci,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Cryptopay,
    connectors::Datatrans,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Custombilling,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Nordea,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Paybox,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Novalnet,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Square,
    connectors::Stax,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Volt,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_create {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutCreate for $path::$connector {}
            impl
            ConnectorIntegration<
            PoCreate,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_create!(
    connectors::Paysafe,
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Nordea,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Payone,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_retrieve {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutSync for $path::$connector {}
            impl
            ConnectorIntegration<
            PoSync,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_retrieve!(
    connectors::Paysafe,
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyen,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Ebanx,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Payone,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_eligibility {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutEligibility for $path::$connector {}
            impl
            ConnectorIntegration<
            PoEligibility,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_eligibility!(
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payone,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_fulfill {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutFulfill for $path::$connector {}
            impl
            ConnectorIntegration<
            PoFulfill,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_fulfill!(
    connectors::Paysafe,
    connectors::Affirm,
    connectors::Vgs,
    connectors::Aci,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nmi,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_cancel {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutCancel for $path::$connector {}
            impl
            ConnectorIntegration<
            PoCancel,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_cancel!(
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payone,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_quote {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutQuote for $path::$connector {}
            impl
            ConnectorIntegration<
            PoQuote,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_quote!(
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyen,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payone,
    connectors::Payme,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Peachpayments,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Tesouro,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenex,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "payouts")]
macro_rules! default_imp_for_payouts_recipient {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl PayoutRecipient for $path::$connector {}
            impl
            ConnectorIntegration<
            PoRecipient,
            PayoutsData,
            PayoutsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

#[cfg(feature = "payouts")]
default_imp_for_payouts_recipient!(
    connectors::Vgs,
    connectors::Aci,
    connectors::Adyen,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Finix,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Gigadat,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Loonio,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,


// Struct: Volt
// File: crates/hyperswitch_connectors/src/connectors/volt.rs
// Module: hyperswitch_connectors
// Implementations: 17
// Traits: api::Payment, api::PaymentSession, api::ConnectorAccessToken, api::MandateSetup, api::PaymentAuthorize, api::PaymentSync, api::PaymentCapture, api::PaymentVoid, api::Refund, api::RefundExecute, api::RefundSync, api::PaymentToken, ConnectorCommon, ConnectorValidation, webhooks::IncomingWebhook, ConnectorSpecifications

pub struct Volt

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


// Implementation: impl api::Payment for for Authorizedotnet
// File: crates/hyperswitch_connectors/src/connectors/authorizedotnet.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Payment for for Authorizedotnet