// File: crates/hyperswitch_interfaces/src/unified_connector_service/transformers.rs

use common_enums::AttemptStatus;
use common_types::primitive_wrappers::{ExtendedAuthorizationAppliedBool, OvercaptureEnabledBool};
use hyperswitch_domain_models::{
    router_data::{
        AdditionalPaymentMethodConnectorResponse, ConnectorResponseData, ErrorResponse,
        ExtendedAuthorizationResponseData,
    },
    router_response_types::PaymentsResponseData,
};

use crate::{helpers::ForeignTryFrom, unified_connector_service::payments_grpc};

/// Unified Connector Service error variants
#[derive(Debug, Clone, thiserror::Error)]
pub enum UnifiedConnectorServiceError {
    /// Error occurred while communicating with the gRPC server.
    #[error("Error from gRPC Server : {0}")]
    ConnectionError(String),

    /// Failed to encode the request to the unified connector service.
    #[error("Failed to encode unified connector service request")]
    RequestEncodingFailed,

    /// Failed to process webhook from unified connector service.
    #[error("Failed to process webhook from unified connector service")]
    WebhookProcessingFailure,

    /// Request encoding failed due to a specific reason.
    #[error("Request encoding failed : {0}")]
    RequestEncodingFailedWithReason(String),

    /// Failed to deserialize the response from the connector.
    #[error("Failed to deserialize connector response")]
    ResponseDeserializationFailed,

    /// The connector name provided is invalid or unrecognized.
    #[error("An invalid connector name was provided")]
    InvalidConnectorName,

    /// Connector name is missing
    #[error("Connector name is missing")]
    MissingConnectorName,

    /// A required field was missing in the request.
    #[error("Missing required field: {field_name}")]
    MissingRequiredField {
        /// Missing Field
        field_name: &'static str,
    },

    /// Multiple required fields were missing in the request.
    #[error("Missing required fields: {field_names:?}")]
    MissingRequiredFields {
        /// Missing Fields
        field_names: Vec<&'static str>,
    },

    /// The requested step or feature is not yet implemented.
    #[error("This step has not been implemented for: {0}")]
    NotImplemented(String),

    /// Parsing of some value or input failed.
    #[error("Parsing failed")]
    ParsingFailed,

    /// Data format provided is invalid
    #[error("Invalid Data format")]
    InvalidDataFormat {
        /// Field Name for which data is invalid
        field_name: &'static str,
    },

    /// Failed to obtain authentication type
    #[error("Failed to obtain authentication type")]
    FailedToObtainAuthType,

    /// Failed to inject metadata into request headers
    #[error("Failed to inject metadata into request headers: {0}")]
    HeaderInjectionFailed(String),

    /// Failed to perform Create Order from gRPC Server
    #[error("Failed to perform Create Order from gRPC Server")]
    PaymentCreateOrderFailure,

    /// Failed to perform Payment Authorize from gRPC Server
    #[error("Failed to perform. Granular Payment Authorize from gRPC Server")]
    PaymentAuthorizeGranularFailure,

    /// Failed to perform Payment Authorize from gRPC Server
    #[error("Failed to perform Payment Session Token Create from gRPC Server")]
    PaymentCreateSessionTokenFailure,

    /// Failed to perform Payment Authorize from gRPC Server
    #[error("Failed to perform Payment Access Token Create from gRPC Server")]
    PaymentCreateAccessTokenFailure,

    /// Failed to perform Payment Authorize from gRPC Server
    #[error("Failed to perform Payment Method Token Create from gRPC Server")]
    PaymentMethodTokenCreateFailure,

    /// Failed to perform Payment Authorize from gRPC Server
    #[error("Failed to perform Connector Customer Create from gRPC Server")]
    PaymentConnectorCustomerCreateFailure,

    /// Failed to perform Payment Authorize from gRPC Server
    #[error("Failed to perform Payment Authorize from gRPC Server")]
    PaymentAuthorizeFailure,

    /// Failed to perform Payment Authenticate from gRPC Server
    #[error("Failed to perform Payment Pre Authenticate from gRPC Server")]
    PaymentPreAuthenticateFailure,

    /// Failed to perform Payment Authenticate from gRPC Server
    #[error("Failed to perform Payment Authenticate from gRPC Server")]
    PaymentAuthenticateFailure,

    /// Failed to perform Payment Authenticate from gRPC Server
    #[error("Failed to perform Payment Post Authenticate from gRPC Server")]
    PaymentPostAuthenticateFailure,

    /// Failed to perform Payment Get from gRPC Server
    #[error("Failed to perform Payment Get from gRPC Server")]
    PaymentGetFailure,

    /// Failed to perform Payment Capture from gRPC Server
    #[error("Failed to perform Payment Capture from gRPC Server")]
    PaymentCaptureFailure,

    /// Failed to perform Payment Setup Mandate from gRPC Server
    #[error("Failed to perform Setup Mandate from gRPC Server")]
    PaymentRegisterFailure,

    /// Failed to perform Payment Repeat Payment from gRPC Server
    #[error("Failed to perform Repeat Payment from gRPC Server")]
    PaymentRepeatEverythingFailure,

    /// Failed to perform Payment Refund from gRPC Server
    #[error("Failed to perform Payment Refund from gRPC Server")]
    PaymentRefundFailure,

    /// Failed to perform Refund Sync from gRPC Server
    #[error("Failed to perform Refund Sync from gRPC Server")]
    RefundSyncFailure,

    /// Failed to transform incoming webhook from gRPC Server
    #[error("Failed to transform incoming webhook from gRPC Server")]
    WebhookTransformFailure,

    /// Failed to perform Payment Cancel from gRPC Server
    #[error("Failed to perform Cancel from gRPC Server")]
    PaymentCancelFailure,
}

/// UCS Webhook transformation status
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum WebhookTransformationStatus {
    /// Transformation completed successfully, no further action needed
    Complete,
    /// Transformation incomplete, requires second call for final status
    Incomplete,
}

#[allow(missing_docs)]
/// Webhook transform data structure containing UCS response information
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct WebhookTransformData {
    pub event_type: api_models::webhooks::IncomingWebhookEvent,
    pub source_verified: bool,
    pub webhook_content: Option<payments_grpc::WebhookResponseContent>,
    pub response_ref_id: Option<String>,
    pub webhook_transformation_status: WebhookTransformationStatus,
}

impl ForeignTryFrom<payments_grpc::PaymentServiceGetResponse>
    for Result<(PaymentsResponseData, AttemptStatus), ErrorResponse>
{
    type Error = error_stack::Report<UnifiedConnectorServiceError>;

    fn foreign_try_from(
        response: payments_grpc::PaymentServiceGetResponse,
    ) -> Result<Self, Self::Error> {
        let connector_response_reference_id =
            response.response_ref_id.as_ref().and_then(|identifier| {
                identifier
                    .id_type
                    .clone()
                    .and_then(|id_type| match id_type {
                        payments_grpc::identifier::IdType::Id(id) => Some(id),
                        payments_grpc::identifier::IdType::EncodedData(encoded_data) => {
                            Some(encoded_data)
                        }
                        payments_grpc::identifier::IdType::NoResponseIdMarker(_) => None,
                    })
            });

        let status_code = convert_connector_service_status_code(response.status_code)?;

        let resource_id: hyperswitch_domain_models::router_request_types::ResponseId = match response.transaction_id.as_ref().and_then(|id| id.id_type.clone()) {
            Some(payments_grpc::identifier::IdType::Id(id)) => hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(id),
            Some(payments_grpc::identifier::IdType::EncodedData(encoded_data)) => hyperswitch_domain_models::router_request_types::ResponseId::EncodedData(encoded_data),
            Some(payments_grpc::identifier::IdType::NoResponseIdMarker(_)) | None => hyperswitch_domain_models::router_request_types::ResponseId::NoResponseId,
        };

        let response = if response.error_code.is_some() {
            let attempt_status = match response.status() {
                payments_grpc::PaymentStatus::AttemptStatusUnspecified => None,
                _ => Some(AttemptStatus::foreign_try_from(response.status())?),
            };

            Err(ErrorResponse {
                code: response.error_code().to_owned(),
                message: response.error_message().to_owned(),
                reason: Some(response.error_message().to_owned()),
                status_code,
                attempt_status,
                connector_transaction_id: connector_response_reference_id,
                network_decline_code: None,
                network_advice_code: None,
                network_error_message: None,
                connector_metadata: None,
            })
        } else {
            let status = AttemptStatus::foreign_try_from(response.status())?;

            Ok((
                PaymentsResponseData::TransactionResponse {
                    resource_id,
                    redirection_data: Box::new(None),
                    mandate_reference: Box::new(response.mandate_reference.map(|grpc_mandate| {
                        hyperswitch_domain_models::router_response_types::MandateReference {
                            connector_mandate_id: grpc_mandate.mandate_id,
                            payment_method_id: grpc_mandate.payment_method_id,
                            mandate_metadata: None,
                            connector_mandate_request_reference_id: None,
                        }
                    })),
                    connector_metadata: None,
                    network_txn_id: response.network_txn_id.clone(),
                    connector_response_reference_id,
                    incremental_authorization_allowed: None,
                    charges: None,
                },
                status,
            ))
        };

        Ok(response)
    }
}

impl ForeignTryFrom<payments_grpc::PaymentStatus> for AttemptStatus {
    type Error = error_stack::Report<UnifiedConnectorServiceError>;

    fn foreign_try_from(grpc_status: payments_grpc::PaymentStatus) -> Result<Self, Self::Error> {
        match grpc_status {
            payments_grpc::PaymentStatus::Started => Ok(Self::Started),
            payments_grpc::PaymentStatus::AuthenticationFailed => Ok(Self::AuthenticationFailed),
            payments_grpc::PaymentStatus::RouterDeclined => Ok(Self::RouterDeclined),
            payments_grpc::PaymentStatus::AuthenticationPending => Ok(Self::AuthenticationPending),
            payments_grpc::PaymentStatus::AuthenticationSuccessful => {
                Ok(Self::AuthenticationSuccessful)
            }
            payments_grpc::PaymentStatus::Authorized => Ok(Self::Authorized),
            payments_grpc::PaymentStatus::AuthorizationFailed => Ok(Self::AuthorizationFailed),
            payments_grpc::PaymentStatus::Charged => Ok(Self::Charged),
            payments_grpc::PaymentStatus::Authorizing => Ok(Self::Authorizing),
            payments_grpc::PaymentStatus::CodInitiated => Ok(Self::CodInitiated),
            payments_grpc::PaymentStatus::Voided => Ok(Self::Voided),
            payments_grpc::PaymentStatus::VoidInitiated => Ok(Self::VoidInitiated),
            payments_grpc::PaymentStatus::CaptureInitiated => Ok(Self::CaptureInitiated),
            payments_grpc::PaymentStatus::CaptureFailed => Ok(Self::CaptureFailed),
            payments_grpc::PaymentStatus::VoidFailed => Ok(Self::VoidFailed),
            payments_grpc::PaymentStatus::AutoRefunded => Ok(Self::AutoRefunded),
            payments_grpc::PaymentStatus::PartialCharged => Ok(Self::PartialCharged),
            payments_grpc::PaymentStatus::PartialChargedAndChargeable => {
                Ok(Self::PartialChargedAndChargeable)
            }
            payments_grpc::PaymentStatus::Unresolved => Ok(Self::Unresolved),
            payments_grpc::PaymentStatus::Pending => Ok(Self::Pending),
            payments_grpc::PaymentStatus::Failure => Ok(Self::Failure),
            payments_grpc::PaymentStatus::PaymentMethodAwaited => Ok(Self::PaymentMethodAwaited),
            payments_grpc::PaymentStatus::ConfirmationAwaited => Ok(Self::ConfirmationAwaited),
            payments_grpc::PaymentStatus::DeviceDataCollectionPending => {
                Ok(Self::DeviceDataCollectionPending)
            }
            payments_grpc::PaymentStatus::VoidedPostCapture => Ok(Self::Voided),
            payments_grpc::PaymentStatus::AttemptStatusUnspecified => Ok(Self::Unresolved),
            payments_grpc::PaymentStatus::PartiallyAuthorized => Ok(Self::PartiallyAuthorized),
            payments_grpc::PaymentStatus::Expired => Ok(Self::Expired),
        }
    }
}

// Transformer for ConnectorResponseData from UCS proto to Hyperswitch domain type
impl ForeignTryFrom<payments_grpc::ConnectorResponseData> for ConnectorResponseData {
    type Error = error_stack::Report<UnifiedConnectorServiceError>;

    fn foreign_try_from(value: payments_grpc::ConnectorResponseData) -> Result<Self, Self::Error> {
        // Extract additional_payment_method_data
        let additional_payment_method_data = value
            .additional_payment_method_data
            .map(AdditionalPaymentMethodConnectorResponse::foreign_try_from)
            .transpose()?;

        let extended_authorization_response_data =
            value.extended_authorization_response_data.map(|data| {
                ExtendedAuthorizationResponseData {
                    capture_before: data
                        .capture_before
                        .and_then(|ts| time::OffsetDateTime::from_unix_timestamp(ts).ok())
                        .map(|offset_dt| {
                            time::PrimitiveDateTime::new(offset_dt.date(), offset_dt.time())
                        }),
                    extended_authentication_applied: data
                        .extended_authentication_applied
                        .map(ExtendedAuthorizationAppliedBool::from),
                    extended_authorization_last_applied_at: None, // This field has to be added to UCS
                }
            });

        let is_overcapture_enabled = value
            .is_overcapture_enabled
            .map(OvercaptureEnabledBool::new);

        Ok(Self::new(
            additional_payment_method_data,
            is_overcapture_enabled,
            extended_authorization_response_data,
            None,
        ))
    }
}

// Transformer for AdditionalPaymentMethodConnectorResponse
impl ForeignTryFrom<payments_grpc::AdditionalPaymentMethodConnectorResponse>
    for AdditionalPaymentMethodConnectorResponse
{
    type Error = error_stack::Report<UnifiedConnectorServiceError>;

    fn foreign_try_from(
        value: payments_grpc::AdditionalPaymentMethodConnectorResponse,
    ) -> Result<Self, Self::Error> {
        let card_data = value.card.unwrap_or_default();

        Ok(Self::Card {
            authentication_data: card_data.authentication_data.and_then(|data| {
                serde_json::from_slice(&data)
                    .inspect_err(|e| {
                        router_env::logger::warn!(
                            deserialization_error=?e,
                            "Failed to deserialize authentication_data from UCS connector response"
                        );
                    })
                    .ok()
            }),
            payment_checks: card_data.payment_checks.and_then(|data| {
                serde_json::from_slice(&data)
                    .inspect_err(|e| {
                        router_env::logger::warn!(
                            deserialization_error=?e,
                            "Failed to deserialize payment_checks from UCS connector response"
                        );
                    })
                    .ok()
            }),
            card_network: card_data.card_network,
            domestic_network: card_data.domestic_network,
        })
    }
}

#[allow(missing_docs)]
pub fn convert_connector_service_status_code(
    status_code: u32,
) -> Result<u16, error_stack::Report<UnifiedConnectorServiceError>> {
    u16::try_from(status_code).map_err(|err| {
        UnifiedConnectorServiceError::RequestEncodingFailedWithReason(format!(
            "Failed to convert connector service status code to u16: {err}"
        ))
        .into()
    })
}


// File: crates/hyperswitch_interfaces/src/api/fraud_check_v2.rs

//! FRM V2 interface
use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::FrmFlowData,
    router_flow_types::{Checkout, Fulfillment, RecordReturn, Sale, Transaction},
    router_request_types::fraud_check::{
        FraudCheckCheckoutData, FraudCheckFulfillmentData, FraudCheckRecordReturnData,
        FraudCheckSaleData, FraudCheckTransactionData,
    },
    router_response_types::fraud_check::FraudCheckResponseData,
};

use crate::api::ConnectorIntegrationV2;

/// trait FraudCheckSaleV2
pub trait FraudCheckSaleV2:
    ConnectorIntegrationV2<Sale, FrmFlowData, FraudCheckSaleData, FraudCheckResponseData>
{
}

/// trait FraudCheckCheckoutV2
pub trait FraudCheckCheckoutV2:
    ConnectorIntegrationV2<Checkout, FrmFlowData, FraudCheckCheckoutData, FraudCheckResponseData>
{
}

/// trait FraudCheckTransactionV2
pub trait FraudCheckTransactionV2:
    ConnectorIntegrationV2<Transaction, FrmFlowData, FraudCheckTransactionData, FraudCheckResponseData>
{
}

/// trait FraudCheckFulfillmentV2
pub trait FraudCheckFulfillmentV2:
    ConnectorIntegrationV2<Fulfillment, FrmFlowData, FraudCheckFulfillmentData, FraudCheckResponseData>
{
}

/// trait FraudCheckRecordReturnV2
pub trait FraudCheckRecordReturnV2:
    ConnectorIntegrationV2<
    RecordReturn,
    FrmFlowData,
    FraudCheckRecordReturnData,
    FraudCheckResponseData,
>
{
}

/// trait FraudCheckV2
pub trait FraudCheckV2:
    super::ConnectorCommon
    + FraudCheckSaleV2
    + FraudCheckTransactionV2
    + FraudCheckCheckoutV2
    + FraudCheckFulfillmentV2
    + FraudCheckRecordReturnV2
{
}


// File: crates/hyperswitch_interfaces/src/api/payouts_v2.rs

//! Payouts V2 interface
use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::PayoutFlowData,
    router_flow_types::payouts::{
        PoCancel, PoCreate, PoEligibility, PoFulfill, PoQuote, PoRecipient, PoRecipientAccount,
        PoSync,
    },
    router_request_types::PayoutsData,
    router_response_types::PayoutsResponseData,
};

use super::ConnectorCommon;
use crate::api::ConnectorIntegrationV2;

/// trait PayoutCancelV2
pub trait PayoutCancelV2:
    ConnectorIntegrationV2<PoCancel, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutCreateV2
pub trait PayoutCreateV2:
    ConnectorIntegrationV2<PoCreate, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutEligibilityV2
pub trait PayoutEligibilityV2:
    ConnectorIntegrationV2<PoEligibility, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutFulfillV2
pub trait PayoutFulfillV2:
    ConnectorIntegrationV2<PoFulfill, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutQuoteV2
pub trait PayoutQuoteV2:
    ConnectorIntegrationV2<PoQuote, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutRecipientV2
pub trait PayoutRecipientV2:
    ConnectorIntegrationV2<PoRecipient, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutRecipientAccountV2
pub trait PayoutRecipientAccountV2:
    ConnectorIntegrationV2<PoRecipientAccount, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutSyncV2
pub trait PayoutSyncV2:
    ConnectorIntegrationV2<PoSync, PayoutFlowData, PayoutsData, PayoutsResponseData>
{
}

#[cfg(feature = "payouts")]
/// trait Payouts
pub trait PayoutsV2:
    ConnectorCommon
    + PayoutCancelV2
    + PayoutCreateV2
    + PayoutEligibilityV2
    + PayoutFulfillV2
    + PayoutQuoteV2
    + PayoutRecipientV2
    + PayoutRecipientAccountV2
    + PayoutSyncV2
{
}

/// Empty trait for when payouts feature is disabled
#[cfg(not(feature = "payouts"))]
pub trait PayoutsV2 {}


// File: crates/hyperswitch_interfaces/src/api/refunds.rs

//! Refunds interface

use hyperswitch_domain_models::{
    router_flow_types::{Execute, RSync},
    router_request_types::RefundsData,
    router_response_types::RefundsResponseData,
};

use crate::api::{self, ConnectorCommon};

/// trait RefundExecute
pub trait RefundExecute:
    api::ConnectorIntegration<Execute, RefundsData, RefundsResponseData>
{
}

/// trait RefundSync
pub trait RefundSync: api::ConnectorIntegration<RSync, RefundsData, RefundsResponseData> {}

/// trait Refund
pub trait Refund: ConnectorCommon + RefundExecute + RefundSync {}


// File: crates/hyperswitch_interfaces/src/api/subscriptions.rs

//! Subscriptions Interface for V1

use hyperswitch_domain_models::{
    router_flow_types::{
        subscriptions::{
            GetSubscriptionEstimate, GetSubscriptionPlanPrices, GetSubscriptionPlans,
            SubscriptionCreate as SubscriptionCreateFlow,
        },
        InvoiceRecordBack,
    },
    router_request_types::{
        revenue_recovery::InvoiceRecordBackRequest,
        subscriptions::{
            GetSubscriptionEstimateRequest, GetSubscriptionPlanPricesRequest,
            GetSubscriptionPlansRequest, SubscriptionCreateRequest,
        },
    },
    router_response_types::{
        revenue_recovery::InvoiceRecordBackResponse,
        subscriptions::{
            GetSubscriptionEstimateResponse, GetSubscriptionPlanPricesResponse,
            GetSubscriptionPlansResponse, SubscriptionCreateResponse,
        },
    },
};

use super::{
    payments::ConnectorCustomer as PaymentsConnectorCustomer, ConnectorCommon, ConnectorIntegration,
};

/// trait GetSubscriptionPlans for V1
pub trait GetSubscriptionPlansFlow:
    ConnectorIntegration<
    GetSubscriptionPlans,
    GetSubscriptionPlansRequest,
    GetSubscriptionPlansResponse,
>
{
}

/// trait SubscriptionRecordBack for V1
pub trait SubscriptionRecordBackFlow:
    ConnectorIntegration<InvoiceRecordBack, InvoiceRecordBackRequest, InvoiceRecordBackResponse>
{
}

/// trait SubscriptionPause for V1
pub trait SubscriptionPauseFlow:
    ConnectorIntegration<
    hyperswitch_domain_models::router_flow_types::subscriptions::SubscriptionPause,
    hyperswitch_domain_models::router_request_types::subscriptions::SubscriptionPauseRequest,
    hyperswitch_domain_models::router_response_types::subscriptions::SubscriptionPauseResponse,
>
{
}

/// trait SubscriptionResume for V1
pub trait SubscriptionResumeFlow:
    ConnectorIntegration<
    hyperswitch_domain_models::router_flow_types::subscriptions::SubscriptionResume,
    hyperswitch_domain_models::router_request_types::subscriptions::SubscriptionResumeRequest,
    hyperswitch_domain_models::router_response_types::subscriptions::SubscriptionResumeResponse,
>
{
}

/// trait SubscriptionCancel for V1
pub trait SubscriptionCancelFlow:
    ConnectorIntegration<
    hyperswitch_domain_models::router_flow_types::subscriptions::SubscriptionCancel,
    hyperswitch_domain_models::router_request_types::subscriptions::SubscriptionCancelRequest,
    hyperswitch_domain_models::router_response_types::subscriptions::SubscriptionCancelResponse,
>
{
}

/// trait GetSubscriptionPlanPrices for V1
pub trait GetSubscriptionPlanPricesFlow:
    ConnectorIntegration<
    GetSubscriptionPlanPrices,
    GetSubscriptionPlanPricesRequest,
    GetSubscriptionPlanPricesResponse,
>
{
}

/// trait SubscriptionCreate
pub trait SubscriptionCreate:
    ConnectorIntegration<SubscriptionCreateFlow, SubscriptionCreateRequest, SubscriptionCreateResponse>
{
}

/// trait GetSubscriptionEstimate for V1
pub trait GetSubscriptionEstimateFlow:
    ConnectorIntegration<
    GetSubscriptionEstimate,
    GetSubscriptionEstimateRequest,
    GetSubscriptionEstimateResponse,
>
{
}
/// trait Subscriptions
pub trait Subscriptions:
    ConnectorCommon
    + GetSubscriptionPlansFlow
    + GetSubscriptionPlanPricesFlow
    + SubscriptionCreate
    + PaymentsConnectorCustomer
    + SubscriptionRecordBackFlow
    + GetSubscriptionEstimateFlow
    + SubscriptionPauseFlow
    + SubscriptionResumeFlow
    + SubscriptionCancelFlow
{
}


// File: crates/hyperswitch_interfaces/src/api/payouts.rs

//! Payouts interface

use hyperswitch_domain_models::{
    router_flow_types::payouts::{
        PoCancel, PoCreate, PoEligibility, PoFulfill, PoQuote, PoRecipient, PoRecipientAccount,
        PoSync,
    },
    router_request_types::PayoutsData,
    router_response_types::PayoutsResponseData,
};

use super::ConnectorCommon;
use crate::api::ConnectorIntegration;

/// trait PayoutCancel
pub trait PayoutCancel: ConnectorIntegration<PoCancel, PayoutsData, PayoutsResponseData> {}

/// trait PayoutCreate
pub trait PayoutCreate: ConnectorIntegration<PoCreate, PayoutsData, PayoutsResponseData> {}

/// trait PayoutEligibility
pub trait PayoutEligibility:
    ConnectorIntegration<PoEligibility, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutFulfill
pub trait PayoutFulfill: ConnectorIntegration<PoFulfill, PayoutsData, PayoutsResponseData> {}

/// trait PayoutQuote
pub trait PayoutQuote: ConnectorIntegration<PoQuote, PayoutsData, PayoutsResponseData> {}

/// trait PayoutRecipient
pub trait PayoutRecipient:
    ConnectorIntegration<PoRecipient, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutRecipientAccount
pub trait PayoutRecipientAccount:
    ConnectorIntegration<PoRecipientAccount, PayoutsData, PayoutsResponseData>
{
}

/// trait PayoutSync
pub trait PayoutSync: ConnectorIntegration<PoSync, PayoutsData, PayoutsResponseData> {}

#[cfg(feature = "payouts")]
/// trait Payouts
pub trait Payouts:
    ConnectorCommon
    + PayoutCancel
    + PayoutCreate
    + PayoutEligibility
    + PayoutFulfill
    + PayoutQuote
    + PayoutRecipient
    + PayoutRecipientAccount
    + PayoutSync
{
}

/// Empty trait for when payouts feature is disabled
#[cfg(not(feature = "payouts"))]
pub trait Payouts {}


// File: crates/hyperswitch_interfaces/src/api/refunds_v2.rs

//! Refunds V2 interface

use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::RefundFlowData,
    router_flow_types::refunds::{Execute, RSync},
    router_request_types::RefundsData,
    router_response_types::RefundsResponseData,
};

use crate::api::{ConnectorCommon, ConnectorIntegrationV2};

/// trait RefundExecuteV2
pub trait RefundExecuteV2:
    ConnectorIntegrationV2<Execute, RefundFlowData, RefundsData, RefundsResponseData>
{
}

/// trait RefundSyncV2
pub trait RefundSyncV2:
    ConnectorIntegrationV2<RSync, RefundFlowData, RefundsData, RefundsResponseData>
{
}

/// trait RefundV2
pub trait RefundV2: ConnectorCommon + RefundExecuteV2 + RefundSyncV2 {}


// File: crates/hyperswitch_interfaces/src/api/fraud_check.rs

//! FRM interface
use hyperswitch_domain_models::{
    router_flow_types::{Checkout, Fulfillment, RecordReturn, Sale, Transaction},
    router_request_types::fraud_check::{
        FraudCheckCheckoutData, FraudCheckFulfillmentData, FraudCheckRecordReturnData,
        FraudCheckSaleData, FraudCheckTransactionData,
    },
    router_response_types::fraud_check::FraudCheckResponseData,
};

use crate::api::ConnectorIntegration;

/// trait FraudCheckSale
pub trait FraudCheckSale:
    ConnectorIntegration<Sale, FraudCheckSaleData, FraudCheckResponseData>
{
}

/// trait FraudCheckCheckout
pub trait FraudCheckCheckout:
    ConnectorIntegration<Checkout, FraudCheckCheckoutData, FraudCheckResponseData>
{
}

/// trait FraudCheckTransaction
pub trait FraudCheckTransaction:
    ConnectorIntegration<Transaction, FraudCheckTransactionData, FraudCheckResponseData>
{
}

/// trait FraudCheckFulfillment
pub trait FraudCheckFulfillment:
    ConnectorIntegration<Fulfillment, FraudCheckFulfillmentData, FraudCheckResponseData>
{
}

/// trait FraudCheckRecordReturn
pub trait FraudCheckRecordReturn:
    ConnectorIntegration<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>
{
}

/// trait FraudCheck
pub trait FraudCheck:
    super::ConnectorCommon
    + FraudCheckSale
    + FraudCheckTransaction
    + FraudCheckCheckout
    + FraudCheckFulfillment
    + FraudCheckRecordReturn
{
}


// File: crates/hyperswitch_interfaces/src/api/subscriptions_v2.rs

//! SubscriptionsV2
use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::{
        GetSubscriptionEstimateData, GetSubscriptionPlanPricesData, GetSubscriptionPlansData,
        InvoiceRecordBackData, SubscriptionCancelData, SubscriptionCreateData,
        SubscriptionCustomerData, SubscriptionPauseData, SubscriptionResumeData,
    },
    router_flow_types::{
        revenue_recovery::InvoiceRecordBack,
        subscriptions::{
            GetSubscriptionEstimate, GetSubscriptionPlanPrices, GetSubscriptionPlans,
            SubscriptionCancel, SubscriptionCreate, SubscriptionPause, SubscriptionResume,
        },
        CreateConnectorCustomer,
    },
    router_request_types::{
        revenue_recovery::InvoiceRecordBackRequest,
        subscriptions::{
            GetSubscriptionEstimateRequest, GetSubscriptionPlanPricesRequest,
            GetSubscriptionPlansRequest, SubscriptionCancelRequest, SubscriptionCreateRequest,
            SubscriptionPauseRequest, SubscriptionResumeRequest,
        },
        ConnectorCustomerData,
    },
    router_response_types::{
        revenue_recovery::InvoiceRecordBackResponse,
        subscriptions::{
            GetSubscriptionEstimateResponse, GetSubscriptionPlanPricesResponse,
            GetSubscriptionPlansResponse, SubscriptionCancelResponse, SubscriptionCreateResponse,
            SubscriptionPauseResponse, SubscriptionResumeResponse,
        },
        PaymentsResponseData,
    },
};

use crate::connector_integration_v2::ConnectorIntegrationV2;

/// trait SubscriptionsV2
pub trait SubscriptionsV2:
    GetSubscriptionPlansV2
    + SubscriptionsCreateV2
    + SubscriptionConnectorCustomerV2
    + GetSubscriptionPlanPricesV2
    + SubscriptionRecordBackV2
    + GetSubscriptionEstimateV2
    + SubscriptionCancelV2
    + SubscriptionPauseV2
    + SubscriptionResumeV2
{
}

/// trait GetSubscriptionPlans for V2
pub trait GetSubscriptionPlansV2:
    ConnectorIntegrationV2<
    GetSubscriptionPlans,
    GetSubscriptionPlansData,
    GetSubscriptionPlansRequest,
    GetSubscriptionPlansResponse,
>
{
}

/// trait SubscriptionRecordBack for V2
pub trait SubscriptionRecordBackV2:
    ConnectorIntegrationV2<
    InvoiceRecordBack,
    InvoiceRecordBackData,
    InvoiceRecordBackRequest,
    InvoiceRecordBackResponse,
>
{
}
/// trait GetSubscriptionPlanPricesV2 for V2
pub trait GetSubscriptionPlanPricesV2:
    ConnectorIntegrationV2<
    GetSubscriptionPlanPrices,
    GetSubscriptionPlanPricesData,
    GetSubscriptionPlanPricesRequest,
    GetSubscriptionPlanPricesResponse,
>
{
}

/// trait SubscriptionsCreateV2
pub trait SubscriptionsCreateV2:
    ConnectorIntegrationV2<
    SubscriptionCreate,
    SubscriptionCreateData,
    SubscriptionCreateRequest,
    SubscriptionCreateResponse,
>
{
}

/// trait SubscriptionConnectorCustomerV2
pub trait SubscriptionConnectorCustomerV2:
    ConnectorIntegrationV2<
    CreateConnectorCustomer,
    SubscriptionCustomerData,
    ConnectorCustomerData,
    PaymentsResponseData,
>
{
}
/// trait GetSubscriptionEstimate for V2
pub trait GetSubscriptionEstimateV2:
    ConnectorIntegrationV2<
    GetSubscriptionEstimate,
    GetSubscriptionEstimateData,
    GetSubscriptionEstimateRequest,
    GetSubscriptionEstimateResponse,
>
{
}

/// trait SubscriptionCancel for V2
pub trait SubscriptionCancelV2:
    ConnectorIntegrationV2<
    SubscriptionCancel,
    SubscriptionCancelData,
    SubscriptionCancelRequest,
    SubscriptionCancelResponse,
>
{
}

/// trait SubscriptionPause for V2
pub trait SubscriptionPauseV2:
    ConnectorIntegrationV2<
    SubscriptionPause,
    SubscriptionPauseData,
    SubscriptionPauseRequest,
    SubscriptionPauseResponse,
>
{
}
/// trait SubscriptionResume for V2
pub trait SubscriptionResumeV2:
    ConnectorIntegrationV2<
    SubscriptionResume,
    SubscriptionResumeData,
    SubscriptionResumeRequest,
    SubscriptionResumeResponse,
>
{
}


// File: crates/hyperswitch_interfaces/src/api/payments.rs

//! Payments interface

use hyperswitch_domain_models::{
    router_flow_types::{
        payments::{
            Approve, Authorize, AuthorizeSessionToken, CalculateTax, Capture, CompleteAuthorize,
            CreateConnectorCustomer, ExtendAuthorization, IncrementalAuthorization, PSync,
            PaymentMethodToken, PostCaptureVoid, PostProcessing, PostSessionTokens, PreProcessing,
            Reject, SdkSessionUpdate, Session, SetupMandate, UpdateMetadata, Void,
        },
        Authenticate, CreateOrder, ExternalVaultProxy, GiftCardBalanceCheck, PostAuthenticate,
        PreAuthenticate,
    },
    router_request_types::{
        AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
        CreateOrderRequestData, ExternalVaultProxyPaymentsData, GiftCardBalanceCheckRequestData,
        PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthenticateData,
        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
        PaymentsCaptureData, PaymentsExtendAuthorizationData, PaymentsIncrementalAuthorizationData,
        PaymentsPostAuthenticateData, PaymentsPostProcessingData, PaymentsPostSessionTokensData,
        PaymentsPreAuthenticateData, PaymentsPreProcessingData, PaymentsRejectData,
        PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
        PaymentsUpdateMetadataData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
    },
    router_response_types::{
        GiftCardBalanceCheckResponseData, PaymentsResponseData, TaxCalculationResponseData,
    },
};

use crate::api;

/// trait Payment
pub trait Payment:
    api::ConnectorCommon
    + api::ConnectorSpecifications
    + api::ConnectorValidation
    + PaymentAuthorize
    + PaymentsPreAuthenticate
    + PaymentsAuthenticate
    + PaymentsPostAuthenticate
    + PaymentAuthorizeSessionToken
    + PaymentsCompleteAuthorize
    + PaymentSync
    + PaymentCapture
    + PaymentVoid
    + PaymentPostCaptureVoid
    + PaymentApprove
    + PaymentReject
    + MandateSetup
    + PaymentSession
    + PaymentToken
    + PaymentsPreProcessing
    + PaymentsPostProcessing
    + ConnectorCustomer
    + PaymentIncrementalAuthorization
    + PaymentExtendAuthorization
    + PaymentSessionUpdate
    + PaymentPostSessionTokens
    + PaymentUpdateMetadata
    + PaymentsCreateOrder
    + ExternalVaultProxyPaymentsCreateV1
    + PaymentsGiftCardBalanceCheck
{
}

/// trait PaymentSession
pub trait PaymentSession:
    api::ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData>
{
}

/// trait MandateSetup
pub trait MandateSetup:
    api::ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
{
}

/// trait PaymentAuthorize
pub trait PaymentAuthorize:
    api::ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData>
{
}

/// trait PaymentCapture
pub trait PaymentCapture:
    api::ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData>
{
}

/// trait PaymentSync
pub trait PaymentSync:
    api::ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData>
{
}

/// trait PaymentVoid
pub trait PaymentVoid:
    api::ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData>
{
}

/// trait PaymentPostCaptureVoid
pub trait PaymentPostCaptureVoid:
    api::ConnectorIntegration<PostCaptureVoid, PaymentsCancelPostCaptureData, PaymentsResponseData>
{
}

/// trait PaymentExtendAuthorization
pub trait PaymentExtendAuthorization:
    api::ConnectorIntegration<
    ExtendAuthorization,
    PaymentsExtendAuthorizationData,
    PaymentsResponseData,
>
{
}

/// trait PaymentApprove
pub trait PaymentApprove:
    api::ConnectorIntegration<Approve, PaymentsApproveData, PaymentsResponseData>
{
}

/// trait PaymentReject
pub trait PaymentReject:
    api::ConnectorIntegration<Reject, PaymentsRejectData, PaymentsResponseData>
{
}

/// trait PaymentToken
pub trait PaymentToken:
    api::ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
{
}

/// trait PaymentAuthorizeSessionToken
pub trait PaymentAuthorizeSessionToken:
    api::ConnectorIntegration<AuthorizeSessionToken, AuthorizeSessionTokenData, PaymentsResponseData>
{
}

/// trait PaymentIncrementalAuthorization
pub trait PaymentIncrementalAuthorization:
    api::ConnectorIntegration<
    IncrementalAuthorization,
    PaymentsIncrementalAuthorizationData,
    PaymentsResponseData,
>
{
}

/// trait TaxCalculation
pub trait TaxCalculation:
    api::ConnectorIntegration<CalculateTax, PaymentsTaxCalculationData, TaxCalculationResponseData>
{
}

/// trait SessionUpdate
pub trait PaymentSessionUpdate:
    api::ConnectorIntegration<SdkSessionUpdate, SdkPaymentsSessionUpdateData, PaymentsResponseData>
{
}

/// trait PostSessionTokens
pub trait PaymentPostSessionTokens:
    api::ConnectorIntegration<PostSessionTokens, PaymentsPostSessionTokensData, PaymentsResponseData>
{
}

/// trait UpdateMetadata
pub trait PaymentUpdateMetadata:
    api::ConnectorIntegration<UpdateMetadata, PaymentsUpdateMetadataData, PaymentsResponseData>
{
}

/// trait PaymentsCompleteAuthorize
pub trait PaymentsCompleteAuthorize:
    api::ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResponseData>
{
}

/// trait ConnectorCustomer
pub trait ConnectorCustomer:
    api::ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>
{
}

/// trait PaymentsPreProcessing
pub trait PaymentsPreProcessing:
    api::ConnectorIntegration<PreProcessing, PaymentsPreProcessingData, PaymentsResponseData>
{
}

/// trait PaymentsPreAuthenticate
pub trait PaymentsPreAuthenticate:
    api::ConnectorIntegration<PreAuthenticate, PaymentsPreAuthenticateData, PaymentsResponseData>
{
}

/// trait PaymentsAuthenticate
pub trait PaymentsAuthenticate:
    api::ConnectorIntegration<Authenticate, PaymentsAuthenticateData, PaymentsResponseData>
{
}

/// trait PaymentsPostAuthenticate
pub trait PaymentsPostAuthenticate:
    api::ConnectorIntegration<PostAuthenticate, PaymentsPostAuthenticateData, PaymentsResponseData>
{
}

/// trait PaymentsPostProcessing
pub trait PaymentsPostProcessing:
    api::ConnectorIntegration<PostProcessing, PaymentsPostProcessingData, PaymentsResponseData>
{
}

/// trait PaymentsCreateOrder
pub trait PaymentsCreateOrder:
    api::ConnectorIntegration<CreateOrder, CreateOrderRequestData, PaymentsResponseData>
{
}

/// trait ExternalVaultProxyPaymentsCreate
pub trait ExternalVaultProxyPaymentsCreateV1:
    api::ConnectorIntegration<ExternalVaultProxy, ExternalVaultProxyPaymentsData, PaymentsResponseData>
{
}

/// trait PaymentsGiftCardBalanceCheck
pub trait PaymentsGiftCardBalanceCheck:
    api::ConnectorIntegration<
    GiftCardBalanceCheck,
    GiftCardBalanceCheckRequestData,
    GiftCardBalanceCheckResponseData,
>
{
}


// File: crates/hyperswitch_interfaces/src/api/disputes.rs

//! Disputes interface

use hyperswitch_domain_models::{
    router_flow_types::dispute::{Accept, Defend, Dsync, Evidence, Fetch},
    router_request_types::{
        AcceptDisputeRequestData, DefendDisputeRequestData, DisputeSyncData,
        FetchDisputesRequestData, SubmitEvidenceRequestData,
    },
    router_response_types::{
        AcceptDisputeResponse, DefendDisputeResponse, DisputeSyncResponse, FetchDisputesResponse,
        SubmitEvidenceResponse,
    },
};

use crate::api::ConnectorIntegration;

/// trait AcceptDispute
pub trait AcceptDispute:
    ConnectorIntegration<Accept, AcceptDisputeRequestData, AcceptDisputeResponse>
{
}

/// trait SubmitEvidence
pub trait SubmitEvidence:
    ConnectorIntegration<Evidence, SubmitEvidenceRequestData, SubmitEvidenceResponse>
{
}

/// trait DefendDispute
pub trait DefendDispute:
    ConnectorIntegration<Defend, DefendDisputeRequestData, DefendDisputeResponse>
{
}

/// trait Dispute
pub trait Dispute:
    super::ConnectorCommon
    + AcceptDispute
    + SubmitEvidence
    + DefendDispute
    + FetchDisputes
    + DisputeSync
{
}

/// trait FetchDisputes
pub trait FetchDisputes:
    ConnectorIntegration<Fetch, FetchDisputesRequestData, FetchDisputesResponse>
{
}

/// trait SyncDisputes
pub trait DisputeSync: ConnectorIntegration<Dsync, DisputeSyncData, DisputeSyncResponse> {}


// File: crates/hyperswitch_interfaces/src/api/disputes_v2.rs

//! Disputes V2 interface
use hyperswitch_domain_models::{
    router_data_v2::DisputesFlowData,
    router_flow_types::dispute::{Accept, Defend, Dsync, Evidence, Fetch},
    router_request_types::{
        AcceptDisputeRequestData, DefendDisputeRequestData, DisputeSyncData,
        FetchDisputesRequestData, SubmitEvidenceRequestData,
    },
    router_response_types::{
        AcceptDisputeResponse, DefendDisputeResponse, DisputeSyncResponse, FetchDisputesResponse,
        SubmitEvidenceResponse,
    },
};

use crate::api::ConnectorIntegrationV2;

/// trait AcceptDisputeV2
pub trait AcceptDisputeV2:
    ConnectorIntegrationV2<Accept, DisputesFlowData, AcceptDisputeRequestData, AcceptDisputeResponse>
{
}

/// trait SubmitEvidenceV2
pub trait SubmitEvidenceV2:
    ConnectorIntegrationV2<
    Evidence,
    DisputesFlowData,
    SubmitEvidenceRequestData,
    SubmitEvidenceResponse,
>
{
}

/// trait DefendDisputeV2
pub trait DefendDisputeV2:
    ConnectorIntegrationV2<Defend, DisputesFlowData, DefendDisputeRequestData, DefendDisputeResponse>
{
}

/// trait DisputeV2
pub trait DisputeV2:
    super::ConnectorCommon
    + AcceptDisputeV2
    + SubmitEvidenceV2
    + DefendDisputeV2
    + FetchDisputesV2
    + DisputeSyncV2
{
}

/// trait FetchDisputeV2
pub trait FetchDisputesV2:
    ConnectorIntegrationV2<Fetch, DisputesFlowData, FetchDisputesRequestData, FetchDisputesResponse>
{
}

/// trait DisputeSyncV2
pub trait DisputeSyncV2:
    ConnectorIntegrationV2<Dsync, DisputesFlowData, DisputeSyncData, DisputeSyncResponse>
{
}


// File: crates/hyperswitch_interfaces/src/api/revenue_recovery_v2.rs

//! Revenue Recovery Interface V2

use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::{
        BillingConnectorInvoiceSyncFlowData, BillingConnectorPaymentsSyncFlowData,
        InvoiceRecordBackData,
    },
    router_flow_types::{
        BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, InvoiceRecordBack,
    },
    router_request_types::revenue_recovery::{
        BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
        InvoiceRecordBackRequest,
    },
    router_response_types::revenue_recovery::{
        BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
        InvoiceRecordBackResponse,
    },
};

use crate::connector_integration_v2::ConnectorIntegrationV2;

#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
/// trait RevenueRecoveryV2
pub trait RevenueRecoveryV2:
    BillingConnectorPaymentsSyncIntegrationV2
    + RevenueRecoveryRecordBackV2
    + BillingConnectorInvoiceSyncIntegrationV2
{
}

#[cfg(not(all(feature = "v2", feature = "revenue_recovery")))]
/// trait RevenueRecoveryV2
pub trait RevenueRecoveryV2 {}

/// trait BillingConnectorPaymentsSyncIntegrationV2
pub trait BillingConnectorPaymentsSyncIntegrationV2:
    ConnectorIntegrationV2<
    BillingConnectorPaymentsSync,
    BillingConnectorPaymentsSyncFlowData,
    BillingConnectorPaymentsSyncRequest,
    BillingConnectorPaymentsSyncResponse,
>
{
}

/// trait RevenueRecoveryRecordBackV2
pub trait RevenueRecoveryRecordBackV2:
    ConnectorIntegrationV2<
    InvoiceRecordBack,
    InvoiceRecordBackData,
    InvoiceRecordBackRequest,
    InvoiceRecordBackResponse,
>
{
}

/// trait BillingConnectorInvoiceSyncIntegrationV2
pub trait BillingConnectorInvoiceSyncIntegrationV2:
    ConnectorIntegrationV2<
    BillingConnectorInvoiceSync,
    BillingConnectorInvoiceSyncFlowData,
    BillingConnectorInvoiceSyncRequest,
    BillingConnectorInvoiceSyncResponse,
>
{
}


// File: crates/hyperswitch_interfaces/src/api/gateway.rs

//! Gateway abstraction layer for unified connector execution
//!
//! This module provides a unified interface for executing payment operations through either:
//! - Direct connector integration (traditional HTTP-based)
//! - Unified Connector Service (UCS) via gRPC
//!
//! The gateway abstraction allows seamless switching between execution paths without
//! requiring changes to individual flow implementations.

use async_trait::async_trait;
use common_enums::{CallConnectorAction, ExecutionMode, ExecutionPath};
use common_utils::{errors::CustomResult, request::Request};
use error_stack::ResultExt;
use hyperswitch_domain_models::router_data::RouterData;
use router_env::logger;

use crate::{
    api_client::{self, ApiClientWrapper},
    connector_integration_interface::{BoxedConnectorIntegrationInterface, RouterDataConversion},
    errors::ConnectorError,
    helpers,
};

/// Minimal trait that gateway context must implement
///
/// This allows the framework to extract execution metadata without knowing
/// the concrete context structure. Implementation crates define their own
/// context types with whatever fields they need.
pub trait GatewayContext: Clone + Send + Sync {
    /// Get the execution path (Direct, UCS, or Shadow)
    fn execution_path(&self) -> ExecutionPath;

    /// Get the execution mode (Primary, Shadow, etc.)
    fn execution_mode(&self) -> ExecutionMode;
}

/// Payment gateway trait
///
/// Defines the interface for executing payment operations through different gateway types.
/// Implementations include DirectGateway and flow-specific UCS gateways.
///
/// # Type Parameters
/// * `State` - Application state (e.g., SessionState)
/// * `ConnectorData` - Connector-specific data type
/// * `F` - Flow type (e.g., domain::Authorize, domain::PSync)
/// * `Req` - Request data type
/// * `Resp` - Response data type
/// * `Context` - Gateway context type (must implement GatewayContext trait)
#[async_trait]
#[allow(clippy::too_many_arguments)]
pub trait PaymentGateway<State, ConnectorData, F, Req, Resp, Context>: Send + Sync
where
    State: Clone + Send + Sync + 'static + ApiClientWrapper,
    ConnectorData: Clone + RouterDataConversion<F, Req, Resp> + Send + Sync + 'static,
    F: Clone + std::fmt::Debug + Send + Sync + 'static,
    Req: std::fmt::Debug + Clone + Send + Sync + 'static,
    Resp: std::fmt::Debug + Clone + Send + Sync + 'static,
    Context: GatewayContext,
{
    /// Execute payment gateway operation
    async fn execute(
        self: Box<Self>,
        state: &State,
        connector_integration: BoxedConnectorIntegrationInterface<F, ConnectorData, Req, Resp>,
        router_data: &RouterData<F, Req, Resp>,
        call_connector_action: CallConnectorAction,
        connector_request: Option<Request>,
        return_raw_connector_response: Option<bool>,
        context: Context,
    ) -> CustomResult<RouterData<F, Req, Resp>, ConnectorError>;
}

/// Direct gateway implementation
///
/// Executes payment operations through traditional HTTP connector integration.
/// This is the default execution path and maintains backward compatibility.
#[derive(Debug, Clone, Copy)]
pub struct DirectGateway;

#[async_trait]
impl<State, ConnectorData, F, Req, Resp, Context>
    PaymentGateway<State, ConnectorData, F, Req, Resp, Context> for DirectGateway
where
    State: Clone + Send + Sync + 'static + ApiClientWrapper,
    ConnectorData: Clone + RouterDataConversion<F, Req, Resp> + Send + Sync + 'static,
    F: Clone + std::fmt::Debug + Send + Sync + 'static,
    Req: std::fmt::Debug + Clone + Send + Sync + 'static,
    Resp: std::fmt::Debug + Clone + Send + Sync + 'static,
    Context: GatewayContext + 'static,
{
    async fn execute(
        self: Box<Self>,
        state: &State,
        connector_integration: BoxedConnectorIntegrationInterface<F, ConnectorData, Req, Resp>,
        router_data: &RouterData<F, Req, Resp>,
        call_connector_action: CallConnectorAction,
        connector_request: Option<Request>,
        return_raw_connector_response: Option<bool>,
        _context: Context,
    ) -> CustomResult<RouterData<F, Req, Resp>, ConnectorError> {
        // Direct gateway delegates to the existing execute_connector_processing_step
        // This maintains backward compatibility with the traditional HTTP-based flow
        api_client::execute_connector_processing_step(
            state,
            connector_integration,
            router_data,
            call_connector_action,
            connector_request,
            return_raw_connector_response,
        )
        .await
    }
}

/// Flow gateway trait for determining execution path
///
/// This trait allows flows to specify which gateway implementation should be used
/// based on the execution path. Each flow implements this trait to provide
/// flow-specific gateway selection logic.
pub trait FlowGateway<State, ConnectorData, Req, Resp, Context>:
    Clone + std::fmt::Debug + Send + Sync + 'static
where
    State: Clone + Send + Sync + 'static + ApiClientWrapper,
    ConnectorData: Clone + RouterDataConversion<Self, Req, Resp> + Send + Sync + 'static,
    Req: std::fmt::Debug + Clone + Send + Sync + 'static,
    Resp: std::fmt::Debug + Clone + Send + Sync + 'static,
    Context: GatewayContext,
{
    /// Get the appropriate gateway for this flow based on execution path
    ///
    /// Returns a boxed gateway implementation that can be either:
    /// - DirectGateway for traditional HTTP connector integration
    /// - Flow-specific UCS gateway for gRPC integration
    fn get_gateway(
        execution_path: ExecutionPath,
    ) -> Box<dyn PaymentGateway<State, ConnectorData, Self, Req, Resp, Context>>;
}

/// Execute payment gateway operation (backward compatible version)
///
/// This version maintains backward compatibility by using direct execution when no context is provided.
/// Use `execute_payment_gateway_with_context` for UCS support.
pub async fn execute_payment_gateway<State, ConnectorData, F, Req, Resp, Context>(
    state: &State,
    connector_integration: BoxedConnectorIntegrationInterface<F, ConnectorData, Req, Resp>,
    router_data: &RouterData<F, Req, Resp>,
    call_connector_action: CallConnectorAction,
    connector_request: Option<Request>,
    return_raw_connector_response: Option<bool>,
    context: Context,
) -> CustomResult<RouterData<F, Req, Resp>, ConnectorError>
where
    State: Clone + Send + Sync + 'static + ApiClientWrapper + helpers::GetComparisonServiceConfig,
    ConnectorData: Clone + RouterDataConversion<F, Req, Resp> + Send + Sync + 'static,
    F: Clone
        + std::fmt::Debug
        + Send
        + Sync
        + 'static
        + FlowGateway<State, ConnectorData, Req, Resp, Context>,
    Req: std::fmt::Debug + Clone + Send + Sync + serde::Serialize + 'static,
    Resp: std::fmt::Debug + Clone + Send + Sync + serde::Serialize + 'static,
    Context: GatewayContext + 'static,
{
    let execution_path = context.execution_path();

    match execution_path {
        ExecutionPath::Direct => {
            // Use direct execution for backward compatibility
            api_client::execute_connector_processing_step(
                state,
                connector_integration,
                router_data,
                call_connector_action,
                connector_request,
                return_raw_connector_response,
            )
            .await
        }
        ExecutionPath::UnifiedConnectorService => {
            let gateway: Box<dyn PaymentGateway<State, ConnectorData, F, Req, Resp, Context>> =
                F::get_gateway(execution_path);

            // Execute through selected gateway
            gateway
                .execute(
                    state,
                    connector_integration,
                    router_data,
                    call_connector_action,
                    connector_request,
                    return_raw_connector_response,
                    context,
                )
                .await
                .attach_printable("Gateway execution failed")
        }
        ExecutionPath::ShadowUnifiedConnectorService => {
            let direct_router_data = api_client::execute_connector_processing_step(
                state,
                connector_integration.clone_box(),
                router_data,
                call_connector_action.clone(),
                connector_request,
                return_raw_connector_response,
            )
            .await?;
            let state_clone = state.clone();
            let router_data_clone = router_data.clone();
            let direct_router_data_clone = direct_router_data.clone();
            let return_raw_connector_response_clone = return_raw_connector_response;
            let context_clone = context.clone();
            tokio::spawn(async move {
                let gateway: Box<dyn PaymentGateway<State, ConnectorData, F, Req, Resp, Context>> =
                    F::get_gateway(execution_path);
                let ucs_shadow_result = gateway
                    .execute(
                        &state_clone,
                        connector_integration,
                        &router_data_clone,
                        call_connector_action,
                        None,
                        return_raw_connector_response_clone,
                        context_clone,
                    )
                    .await
                    .attach_printable("Gateway execution failed");
                // Send comparison data asynchronously
                match ucs_shadow_result {
                    Ok(ucs_router_data) => {
                        // Send comparison data asynchronously
                        if let Some(comparison_service_config) =
                            state_clone.get_comparison_service_config()
                        {
                            let request_id = state_clone.get_request_id_str();
                            let _ = helpers::serialize_router_data_and_send_to_comparison_service(
                                &state_clone,
                                direct_router_data_clone,
                                ucs_router_data,
                                comparison_service_config,
                                request_id,
                            )
                            .await;
                        };
                    }
                    Err(e) => {
                        logger::error!("UCS shadow execution failed: {:?}", e);
                    }
                }
            });
            Ok(direct_router_data)
        }
    }
}


// File: crates/hyperswitch_interfaces/src/api/files.rs

//! Files interface

use hyperswitch_domain_models::{
    router_flow_types::files::{Retrieve, Upload},
    router_request_types::{RetrieveFileRequestData, UploadFileRequestData},
    router_response_types::{RetrieveFileResponse, UploadFileResponse},
};

use crate::{
    api::{ConnectorCommon, ConnectorIntegration},
    errors,
};

/// enum FilePurpose
#[derive(Debug, serde::Deserialize, strum::Display, Clone, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum FilePurpose {
    /// DisputeEvidence
    DisputeEvidence,
}

/// trait UploadFile
pub trait UploadFile:
    ConnectorIntegration<Upload, UploadFileRequestData, UploadFileResponse>
{
}

/// trait RetrieveFile
pub trait RetrieveFile:
    ConnectorIntegration<Retrieve, RetrieveFileRequestData, RetrieveFileResponse>
{
}

/// trait FileUpload
pub trait FileUpload: ConnectorCommon + Sync + UploadFile + RetrieveFile {
    /// fn validate_file_upload
    fn validate_file_upload(
        &self,
        _purpose: FilePurpose,
        _file_size: i32,
        _file_type: mime::Mime,
    ) -> common_utils::errors::CustomResult<(), errors::ConnectorError> {
        Err(errors::ConnectorError::FileValidationFailed {
            reason: "".to_owned(),
        }
        .into())
    }
}


// File: crates/hyperswitch_interfaces/src/api/authentication_v2.rs

use hyperswitch_domain_models::{
    router_data_v2::ExternalAuthenticationFlowData,
    router_flow_types::authentication::{
        Authentication, PostAuthentication, PreAuthentication, PreAuthenticationVersionCall,
    },
    router_request_types::authentication::{
        ConnectorAuthenticationRequestData, ConnectorPostAuthenticationRequestData,
        PreAuthNRequestData,
    },
    router_response_types::AuthenticationResponseData,
};

use crate::api::ConnectorIntegrationV2;

/// trait ConnectorAuthenticationV2
pub trait ConnectorAuthenticationV2:
    ConnectorIntegrationV2<
    Authentication,
    ExternalAuthenticationFlowData,
    ConnectorAuthenticationRequestData,
    AuthenticationResponseData,
>
{
}

/// trait ConnectorPreAuthenticationV2
pub trait ConnectorPreAuthenticationV2:
    ConnectorIntegrationV2<
    PreAuthentication,
    ExternalAuthenticationFlowData,
    PreAuthNRequestData,
    AuthenticationResponseData,
>
{
}

/// trait ConnectorPreAuthenticationVersionCallV2
pub trait ConnectorPreAuthenticationVersionCallV2:
    ConnectorIntegrationV2<
    PreAuthenticationVersionCall,
    ExternalAuthenticationFlowData,
    PreAuthNRequestData,
    AuthenticationResponseData,
>
{
}

/// trait ConnectorPostAuthenticationV2
pub trait ConnectorPostAuthenticationV2:
    ConnectorIntegrationV2<
    PostAuthentication,
    ExternalAuthenticationFlowData,
    ConnectorPostAuthenticationRequestData,
    AuthenticationResponseData,
>
{
}

/// trait ExternalAuthenticationV2
pub trait ExternalAuthenticationV2:
    super::ConnectorCommon
    + ConnectorAuthenticationV2
    + ConnectorPreAuthenticationV2
    + ConnectorPreAuthenticationVersionCallV2
    + ConnectorPostAuthenticationV2
{
}


// File: crates/hyperswitch_interfaces/src/api/payments_v2.rs

//! Payments V2 interface

use hyperswitch_domain_models::{
    router_data_v2::{flow_common_types::GiftCardBalanceCheckFlowData, PaymentFlowData},
    router_flow_types::{
        payments::{
            Approve, Authorize, AuthorizeSessionToken, CalculateTax, Capture, CompleteAuthorize,
            CreateConnectorCustomer, CreateOrder, ExtendAuthorization, ExternalVaultProxy,
            IncrementalAuthorization, PSync, PaymentMethodToken, PostCaptureVoid, PostProcessing,
            PostSessionTokens, PreProcessing, Reject, SdkSessionUpdate, Session, SetupMandate,
            UpdateMetadata, Void,
        },
        Authenticate, GiftCardBalanceCheck, PostAuthenticate, PreAuthenticate,
    },
    router_request_types::{
        AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
        CreateOrderRequestData, ExternalVaultProxyPaymentsData, GiftCardBalanceCheckRequestData,
        PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthenticateData,
        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
        PaymentsCaptureData, PaymentsExtendAuthorizationData, PaymentsIncrementalAuthorizationData,
        PaymentsPostAuthenticateData, PaymentsPostProcessingData, PaymentsPostSessionTokensData,
        PaymentsPreAuthenticateData, PaymentsPreProcessingData, PaymentsRejectData,
        PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
        PaymentsUpdateMetadataData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
    },
    router_response_types::{
        GiftCardBalanceCheckResponseData, PaymentsResponseData, TaxCalculationResponseData,
    },
};

use crate::api::{
    ConnectorCommon, ConnectorIntegrationV2, ConnectorSpecifications, ConnectorValidation,
};

/// trait PaymentAuthorizeV2
pub trait PaymentAuthorizeV2:
    ConnectorIntegrationV2<Authorize, PaymentFlowData, PaymentsAuthorizeData, PaymentsResponseData>
{
}

/// trait PaymentAuthorizeSessionTokenV2
pub trait PaymentAuthorizeSessionTokenV2:
    ConnectorIntegrationV2<
    AuthorizeSessionToken,
    PaymentFlowData,
    AuthorizeSessionTokenData,
    PaymentsResponseData,
>
{
}

/// trait PaymentSyncV2
pub trait PaymentSyncV2:
    ConnectorIntegrationV2<PSync, PaymentFlowData, PaymentsSyncData, PaymentsResponseData>
{
}

/// trait PaymentVoidV2
pub trait PaymentVoidV2:
    ConnectorIntegrationV2<Void, PaymentFlowData, PaymentsCancelData, PaymentsResponseData>
{
}

/// trait PaymentPostCaptureVoidV2
pub trait PaymentPostCaptureVoidV2:
    ConnectorIntegrationV2<
    PostCaptureVoid,
    PaymentFlowData,
    PaymentsCancelPostCaptureData,
    PaymentsResponseData,
>
{
}

/// trait PaymentApproveV2
pub trait PaymentApproveV2:
    ConnectorIntegrationV2<Approve, PaymentFlowData, PaymentsApproveData, PaymentsResponseData>
{
}

/// trait PaymentRejectV2
pub trait PaymentRejectV2:
    ConnectorIntegrationV2<Reject, PaymentFlowData, PaymentsRejectData, PaymentsResponseData>
{
}

/// trait PaymentCaptureV2
pub trait PaymentCaptureV2:
    ConnectorIntegrationV2<Capture, PaymentFlowData, PaymentsCaptureData, PaymentsResponseData>
{
}

/// trait PaymentSessionV2
pub trait PaymentSessionV2:
    ConnectorIntegrationV2<Session, PaymentFlowData, PaymentsSessionData, PaymentsResponseData>
{
}

/// trait MandateSetupV2
pub trait MandateSetupV2:
    ConnectorIntegrationV2<SetupMandate, PaymentFlowData, SetupMandateRequestData, PaymentsResponseData>
{
}

/// trait PaymentIncrementalAuthorizationV2
pub trait PaymentIncrementalAuthorizationV2:
    ConnectorIntegrationV2<
    IncrementalAuthorization,
    PaymentFlowData,
    PaymentsIncrementalAuthorizationData,
    PaymentsResponseData,
>
{
}

/// trait PaymentExtendAuthorizationV2
pub trait PaymentExtendAuthorizationV2:
    ConnectorIntegrationV2<
    ExtendAuthorization,
    PaymentFlowData,
    PaymentsExtendAuthorizationData,
    PaymentsResponseData,
>
{
}

///trait TaxCalculationV2
pub trait TaxCalculationV2:
    ConnectorIntegrationV2<
    CalculateTax,
    PaymentFlowData,
    PaymentsTaxCalculationData,
    TaxCalculationResponseData,
>
{
}

///trait PaymentSessionUpdateV2
pub trait PaymentSessionUpdateV2:
    ConnectorIntegrationV2<
    SdkSessionUpdate,
    PaymentFlowData,
    SdkPaymentsSessionUpdateData,
    PaymentsResponseData,
>
{
}

///trait PaymentPostSessionTokensV2
pub trait PaymentPostSessionTokensV2:
    ConnectorIntegrationV2<
    PostSessionTokens,
    PaymentFlowData,
    PaymentsPostSessionTokensData,
    PaymentsResponseData,
>
{
}

/// trait ConnectorCreateOrderV2
pub trait PaymentCreateOrderV2:
    ConnectorIntegrationV2<CreateOrder, PaymentFlowData, CreateOrderRequestData, PaymentsResponseData>
{
}

/// trait PaymentUpdateMetadataV2
pub trait PaymentUpdateMetadataV2:
    ConnectorIntegrationV2<
    UpdateMetadata,
    PaymentFlowData,
    PaymentsUpdateMetadataData,
    PaymentsResponseData,
>
{
}

/// trait PaymentsCompleteAuthorizeV2
pub trait PaymentsCompleteAuthorizeV2:
    ConnectorIntegrationV2<
    CompleteAuthorize,
    PaymentFlowData,
    CompleteAuthorizeData,
    PaymentsResponseData,
>
{
}

/// trait PaymentTokenV2
pub trait PaymentTokenV2:
    ConnectorIntegrationV2<
    PaymentMethodToken,
    PaymentFlowData,
    PaymentMethodTokenizationData,
    PaymentsResponseData,
>
{
}

/// trait ConnectorCustomerV2
pub trait ConnectorCustomerV2:
    ConnectorIntegrationV2<
    CreateConnectorCustomer,
    PaymentFlowData,
    ConnectorCustomerData,
    PaymentsResponseData,
>
{
}

/// trait PaymentsPreProcessingV2
pub trait PaymentsPreProcessingV2:
    ConnectorIntegrationV2<
    PreProcessing,
    PaymentFlowData,
    PaymentsPreProcessingData,
    PaymentsResponseData,
>
{
}

/// trait PaymentsGiftCardBalanceCheckV2
pub trait PaymentsGiftCardBalanceCheckV2:
    ConnectorIntegrationV2<
    GiftCardBalanceCheck,
    GiftCardBalanceCheckFlowData,
    GiftCardBalanceCheckRequestData,
    GiftCardBalanceCheckResponseData,
>
{
}

/// trait PaymentsPreAuthenticateV2
pub trait PaymentsPreAuthenticateV2:
    ConnectorIntegrationV2<
    PreAuthenticate,
    PaymentFlowData,
    PaymentsPreAuthenticateData,
    PaymentsResponseData,
>
{
}

/// trait PaymentsAuthenticateV2
pub trait PaymentsAuthenticateV2:
    ConnectorIntegrationV2<
    Authenticate,
    PaymentFlowData,
    PaymentsAuthenticateData,
    PaymentsResponseData,
>
{
}

/// trait PaymentsPostAuthenticateV2
pub trait PaymentsPostAuthenticateV2:
    ConnectorIntegrationV2<
    PostAuthenticate,
    PaymentFlowData,
    PaymentsPostAuthenticateData,
    PaymentsResponseData,
>
{
}
/// trait PaymentsPostProcessingV2
pub trait PaymentsPostProcessingV2:
    ConnectorIntegrationV2<
    PostProcessing,
    PaymentFlowData,
    PaymentsPostProcessingData,
    PaymentsResponseData,
>
{
}

/// trait ExternalVaultProxyPaymentsCreate
pub trait ExternalVaultProxyPaymentsCreate:
    ConnectorIntegrationV2<
    ExternalVaultProxy,
    PaymentFlowData,
    ExternalVaultProxyPaymentsData,
    PaymentsResponseData,
>
{
}

/// trait PaymentV2
pub trait PaymentV2:
    ConnectorCommon
    + ConnectorSpecifications
    + ConnectorValidation
    + PaymentAuthorizeV2
    + PaymentsPreAuthenticateV2
    + PaymentsAuthenticateV2
    + PaymentsPostAuthenticateV2
    + PaymentAuthorizeSessionTokenV2
    + PaymentsCompleteAuthorizeV2
    + PaymentSyncV2
    + PaymentCaptureV2
    + PaymentVoidV2
    + PaymentPostCaptureVoidV2
    + PaymentApproveV2
    + PaymentRejectV2
    + MandateSetupV2
    + PaymentSessionV2
    + PaymentTokenV2
    + PaymentsPreProcessingV2
    + PaymentsPostProcessingV2
    + ConnectorCustomerV2
    + PaymentIncrementalAuthorizationV2
    + PaymentExtendAuthorizationV2
    + TaxCalculationV2
    + PaymentSessionUpdateV2
    + PaymentPostSessionTokensV2
    + PaymentUpdateMetadataV2
    + PaymentCreateOrderV2
    + ExternalVaultProxyPaymentsCreate
    + PaymentsGiftCardBalanceCheckV2
{
}


// File: crates/hyperswitch_interfaces/src/api/revenue_recovery.rs

//! Revenue Recovery Interface

use hyperswitch_domain_models::{
    router_flow_types::{
        BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, InvoiceRecordBack,
    },
    router_request_types::revenue_recovery::{
        BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
        InvoiceRecordBackRequest,
    },
    router_response_types::revenue_recovery::{
        BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
        InvoiceRecordBackResponse,
    },
};

#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
use super::ConnectorCommon;
use super::ConnectorIntegration;

/// trait RevenueRecovery
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
pub trait RevenueRecovery:
    ConnectorCommon
    + BillingConnectorPaymentsSyncIntegration
    + RevenueRecoveryRecordBack
    + BillingConnectorInvoiceSyncIntegration
{
}

/// trait BillingConnectorPaymentsSyncIntegration
pub trait BillingConnectorPaymentsSyncIntegration:
    ConnectorIntegration<
    BillingConnectorPaymentsSync,
    BillingConnectorPaymentsSyncRequest,
    BillingConnectorPaymentsSyncResponse,
>
{
}

/// trait RevenueRecoveryRecordBack
pub trait RevenueRecoveryRecordBack:
    ConnectorIntegration<InvoiceRecordBack, InvoiceRecordBackRequest, InvoiceRecordBackResponse>
{
}

/// trait BillingConnectorInvoiceSyncIntegration
pub trait BillingConnectorInvoiceSyncIntegration:
    ConnectorIntegration<
    BillingConnectorInvoiceSync,
    BillingConnectorInvoiceSyncRequest,
    BillingConnectorInvoiceSyncResponse,
>
{
}

#[cfg(not(all(feature = "v2", feature = "revenue_recovery")))]
/// trait RevenueRecovery
pub trait RevenueRecovery {}


// File: crates/hyperswitch_interfaces/src/api/authentication.rs

use hyperswitch_domain_models::{
    router_flow_types::authentication::{
        Authentication, PostAuthentication, PreAuthentication, PreAuthenticationVersionCall,
    },
    router_request_types::authentication::{
        ConnectorAuthenticationRequestData, ConnectorPostAuthenticationRequestData,
        PreAuthNRequestData,
    },
    router_response_types::AuthenticationResponseData,
};

use crate::api::ConnectorIntegration;

/// trait ConnectorAuthentication
pub trait ConnectorAuthentication:
    ConnectorIntegration<Authentication, ConnectorAuthenticationRequestData, AuthenticationResponseData>
{
}

/// trait ConnectorPreAuthentication
pub trait ConnectorPreAuthentication:
    ConnectorIntegration<PreAuthentication, PreAuthNRequestData, AuthenticationResponseData>
{
}

/// trait ConnectorPreAuthenticationVersionCall
pub trait ConnectorPreAuthenticationVersionCall:
    ConnectorIntegration<PreAuthenticationVersionCall, PreAuthNRequestData, AuthenticationResponseData>
{
}

/// trait ConnectorPostAuthentication
pub trait ConnectorPostAuthentication:
    ConnectorIntegration<
    PostAuthentication,
    ConnectorPostAuthenticationRequestData,
    AuthenticationResponseData,
>
{
}

/// trait ExternalAuthentication
pub trait ExternalAuthentication:
    super::ConnectorCommon
    + ConnectorAuthentication
    + ConnectorPreAuthentication
    + ConnectorPreAuthenticationVersionCall
    + ConnectorPostAuthentication
{
}


// File: crates/hyperswitch_interfaces/src/api/files_v2.rs

//! Files V2 interface

use hyperswitch_domain_models::{
    router_data_v2::FilesFlowData,
    router_flow_types::{Retrieve, Upload},
    router_request_types::{RetrieveFileRequestData, UploadFileRequestData},
    router_response_types::{RetrieveFileResponse, UploadFileResponse},
};

use crate::api::{errors, files::FilePurpose, ConnectorCommon, ConnectorIntegrationV2};

/// trait UploadFileV2
pub trait UploadFileV2:
    ConnectorIntegrationV2<Upload, FilesFlowData, UploadFileRequestData, UploadFileResponse>
{
}

/// trait RetrieveFileV2
pub trait RetrieveFileV2:
    ConnectorIntegrationV2<Retrieve, FilesFlowData, RetrieveFileRequestData, RetrieveFileResponse>
{
}

/// trait FileUploadV2
pub trait FileUploadV2: ConnectorCommon + Sync + UploadFileV2 + RetrieveFileV2 {
    /// fn validate_file_upload_v2
    fn validate_file_upload_v2(
        &self,
        _purpose: FilePurpose,
        _file_size: i32,
        _file_type: mime::Mime,
    ) -> common_utils::errors::CustomResult<(), errors::ConnectorError> {
        Err(errors::ConnectorError::FileValidationFailed {
            reason: "".to_owned(),
        }
        .into())
    }
}


// File: crates/hyperswitch_interfaces/src/api/vault.rs

//! Vault interface

use hyperswitch_domain_models::{
    router_flow_types::vault::{
        ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow,
        ExternalVaultRetrieveFlow,
    },
    router_request_types::VaultRequestData,
    router_response_types::VaultResponseData,
};

use super::ConnectorCommon;
use crate::api::ConnectorIntegration;

/// trait ExternalVaultInsert
pub trait ExternalVaultInsert:
    ConnectorIntegration<ExternalVaultInsertFlow, VaultRequestData, VaultResponseData>
{
}

/// trait ExternalVaultRetrieve
pub trait ExternalVaultRetrieve:
    ConnectorIntegration<ExternalVaultRetrieveFlow, VaultRequestData, VaultResponseData>
{
}

/// trait ExternalVaultDelete
pub trait ExternalVaultDelete:
    ConnectorIntegration<ExternalVaultDeleteFlow, VaultRequestData, VaultResponseData>
{
}

/// trait ExternalVaultDelete
pub trait ExternalVaultCreate:
    ConnectorIntegration<ExternalVaultCreateFlow, VaultRequestData, VaultResponseData>
{
}

/// trait ExternalVault
pub trait ExternalVault:
    ConnectorCommon
    + ExternalVaultInsert
    + ExternalVaultRetrieve
    + ExternalVaultDelete
    + ExternalVaultCreate
{
}


// File: crates/hyperswitch_interfaces/src/api/vault_v2.rs

//! Vault V2 interface
use hyperswitch_domain_models::{
    router_data_v2::flow_common_types::VaultConnectorFlowData,
    router_flow_types::vault::{
        ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow,
        ExternalVaultRetrieveFlow,
    },
    router_request_types::VaultRequestData,
    router_response_types::VaultResponseData,
};

use super::ConnectorCommon;
use crate::api::ConnectorIntegrationV2;

/// trait ExternalVaultInsertV2
pub trait ExternalVaultInsertV2:
    ConnectorIntegrationV2<
    ExternalVaultInsertFlow,
    VaultConnectorFlowData,
    VaultRequestData,
    VaultResponseData,
>
{
}
/// trait ExternalVaultRetrieveV2
pub trait ExternalVaultRetrieveV2:
    ConnectorIntegrationV2<
    ExternalVaultRetrieveFlow,
    VaultConnectorFlowData,
    VaultRequestData,
    VaultResponseData,
>
{
}

/// trait ExternalVaultDeleteV2
pub trait ExternalVaultDeleteV2:
    ConnectorIntegrationV2<
    ExternalVaultDeleteFlow,
    VaultConnectorFlowData,
    VaultRequestData,
    VaultResponseData,
>
{
}

/// trait ExternalVaultDeleteV2
pub trait ExternalVaultCreateV2:
    ConnectorIntegrationV2<
    ExternalVaultCreateFlow,
    VaultConnectorFlowData,
    VaultRequestData,
    VaultResponseData,
>
{
}

/// trait ExternalVaultV2
pub trait ExternalVaultV2:
    ConnectorCommon
    + ExternalVaultInsertV2
    + ExternalVaultRetrieveV2
    + ExternalVaultDeleteV2
    + ExternalVaultCreateV2
{
}


// File: crates/hyperswitch_interfaces/src/events/routing_api_logs.rs

//! Routing API logs interface

use std::fmt;

use api_models::routing::RoutableConnectorChoice;
use common_utils::request::Method;
use router_env::RequestId;
use serde::Serialize;
use serde_json::json;
use time::OffsetDateTime;

/// RoutingEngine enum
#[derive(Debug, Clone, Copy, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RoutingEngine {
    /// Dynamo for routing
    IntelligentRouter,
    /// Decision engine for routing
    DecisionEngine,
}

/// Method type enum
#[derive(Debug, Clone, Copy, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum ApiMethod {
    /// grpc call
    Grpc,
    /// Rest call
    Rest(Method),
}

impl fmt::Display for ApiMethod {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Grpc => write!(f, "Grpc"),
            Self::Rest(method) => write!(f, "Rest ({method})"),
        }
    }
}

#[derive(Debug, Serialize)]
/// RoutingEvent type
pub struct RoutingEvent {
    tenant_id: common_utils::id_type::TenantId,
    routable_connectors: String,
    payment_connector: Option<String>,
    flow: String,
    request: String,
    response: Option<String>,
    error: Option<String>,
    url: String,
    method: String,
    payment_id: String,
    profile_id: common_utils::id_type::ProfileId,
    merchant_id: common_utils::id_type::MerchantId,
    created_at: i128,
    status_code: Option<u16>,
    request_id: String,
    routing_engine: RoutingEngine,
    routing_approach: Option<String>,
}

impl RoutingEvent {
    /// fn new RoutingEvent
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        tenant_id: common_utils::id_type::TenantId,
        routable_connectors: String,
        flow: &str,
        request: serde_json::Value,
        url: String,
        method: ApiMethod,
        payment_id: String,
        profile_id: common_utils::id_type::ProfileId,
        merchant_id: common_utils::id_type::MerchantId,
        request_id: Option<RequestId>,
        routing_engine: RoutingEngine,
    ) -> Self {
        Self {
            tenant_id,
            routable_connectors,
            flow: flow.to_string(),
            request: request.to_string(),
            response: None,
            error: None,
            url,
            method: method.to_string(),
            payment_id,
            profile_id,
            merchant_id,
            created_at: OffsetDateTime::now_utc().unix_timestamp_nanos(),
            status_code: None,
            request_id: request_id
                .map(|i| i.to_string())
                .unwrap_or("NO_REQUEST_ID".to_string()),
            routing_engine,
            payment_connector: None,
            routing_approach: None,
        }
    }

    /// fn set_response_body
    pub fn set_response_body<T: Serialize>(&mut self, response: &T) {
        match masking::masked_serialize(response) {
            Ok(masked) => {
                self.response = Some(masked.to_string());
            }
            Err(er) => self.set_error(json!({"error": er.to_string()})),
        }
    }

    /// fn set_error_response_body
    pub fn set_error_response_body<T: Serialize>(&mut self, response: &T) {
        match masking::masked_serialize(response) {
            Ok(masked) => {
                self.error = Some(masked.to_string());
            }
            Err(er) => self.set_error(json!({"error": er.to_string()})),
        }
    }

    /// fn set_error
    pub fn set_error(&mut self, error: serde_json::Value) {
        self.error = Some(error.to_string());
    }

    /// set response status code
    pub fn set_status_code(&mut self, code: u16) {
        self.status_code = Some(code);
    }

    /// set response status code
    pub fn set_routable_connectors(&mut self, connectors: Vec<RoutableConnectorChoice>) {
        let connectors = connectors
            .into_iter()
            .map(|c| {
                format!(
                    "{:?}:{:?}",
                    c.connector,
                    c.merchant_connector_id
                        .map(|id| id.get_string_repr().to_string())
                        .unwrap_or(String::from(""))
                )
            })
            .collect::<Vec<_>>()
            .join(",");
        self.routable_connectors = connectors;
    }

    /// set payment connector
    pub fn set_payment_connector(&mut self, connector: RoutableConnectorChoice) {
        self.payment_connector = Some(format!(
            "{:?}:{:?}",
            connector.connector,
            connector
                .merchant_connector_id
                .map(|id| id.get_string_repr().to_string())
                .unwrap_or(String::from(""))
        ));
    }

    /// set routing approach
    pub fn set_routing_approach(&mut self, approach: String) {
        self.routing_approach = Some(approach);
    }

    /// Returns the request ID of the event.
    pub fn get_request_id(&self) -> &str {
        &self.request_id
    }

    /// Returns the merchant ID of the event.
    pub fn get_merchant_id(&self) -> &str {
        self.merchant_id.get_string_repr()
    }

    /// Returns the payment ID of the event.
    pub fn get_payment_id(&self) -> &str {
        &self.payment_id
    }

    /// Returns the profile ID of the event.
    pub fn get_profile_id(&self) -> &str {
        self.profile_id.get_string_repr()
    }
}


// File: crates/hyperswitch_interfaces/src/events/connector_api_logs.rs

//! Connector API logs interface

use common_utils::request::Method;
use router_env::RequestId;
use serde::Serialize;
use serde_json::json;
use time::OffsetDateTime;

/// struct ConnectorEvent
#[derive(Debug, Serialize)]
pub struct ConnectorEvent {
    tenant_id: common_utils::id_type::TenantId,
    connector_name: String,
    flow: String,
    request: String,
    masked_response: Option<String>,
    error: Option<String>,
    url: String,
    method: String,
    payment_id: String,
    merchant_id: common_utils::id_type::MerchantId,
    created_at: i128,
    /// Connector Event Request ID
    pub request_id: String,
    latency: u128,
    refund_id: Option<String>,
    dispute_id: Option<String>,
    status_code: u16,
}

impl ConnectorEvent {
    /// fn new ConnectorEvent
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        tenant_id: common_utils::id_type::TenantId,
        connector_name: String,
        flow: &str,
        request: serde_json::Value,
        url: String,
        method: Method,
        payment_id: String,
        merchant_id: common_utils::id_type::MerchantId,
        request_id: Option<&RequestId>,
        latency: u128,
        refund_id: Option<String>,
        dispute_id: Option<String>,
        status_code: u16,
    ) -> Self {
        Self {
            tenant_id,
            connector_name,
            flow: flow
                .rsplit_once("::")
                .map(|(_, s)| s)
                .unwrap_or(flow)
                .to_string(),
            request: request.to_string(),
            masked_response: None,
            error: None,
            url,
            method: method.to_string(),
            payment_id,
            merchant_id,
            created_at: OffsetDateTime::now_utc().unix_timestamp_nanos() / 1_000_000,
            request_id: request_id
                .map(|i| i.to_string())
                .unwrap_or("NO_REQUEST_ID".to_string()),
            latency,
            refund_id,
            dispute_id,
            status_code,
        }
    }

    /// fn set_response_body
    pub fn set_response_body<T: Serialize>(&mut self, response: &T) {
        match masking::masked_serialize(response) {
            Ok(masked) => {
                self.masked_response = Some(masked.to_string());
            }
            Err(er) => self.set_error(json!({"error": er.to_string()})),
        }
    }

    /// fn set_error_response_body
    pub fn set_error_response_body<T: Serialize>(&mut self, response: &T) {
        match masking::masked_serialize(response) {
            Ok(masked) => {
                self.error = Some(masked.to_string());
            }
            Err(er) => self.set_error(json!({"error": er.to_string()})),
        }
    }

    /// fn set_error
    pub fn set_error(&mut self, error: serde_json::Value) {
        self.error = Some(error.to_string());
    }
}


// File: crates/router/Cargo.toml

[package]
name = "router"
description = "Modern, fast and open payment router"
version = "0.2.0"
edition.workspace = true
default-run = "router"
rust-version.workspace = true
readme = "README.md"
license.workspace = true

[features]
default = ["common_default", "v1"]
common_default = ["kv_store", "stripe", "oltp", "olap", "accounts_cache", "dummy_connector", "payouts", "payout_retry", "retry", "frm", "tls", "partial-auth", "km_forward_x_request_id", "external_services/superposition"]
olap = ["hyperswitch_domain_models/olap", "storage_impl/olap", "scheduler/olap", "api_models/olap", "dep:analytics"]
tls = ["actix-web/rustls-0_22"]
email = ["external_services/email", "scheduler/email", "olap"]
# keymanager_create, keymanager_mtls, encryption_service should not be removed or added to default feature. Once this features were enabled it can't be disabled as these are breaking changes.
keymanager_create = []
keymanager_mtls = ["reqwest/rustls-tls", "common_utils/keymanager_mtls"]
encryption_service = ["keymanager_create", "hyperswitch_domain_models/encryption_service", "common_utils/encryption_service"]
km_forward_x_request_id = ["common_utils/km_forward_x_request_id"]
frm = ["api_models/frm", "hyperswitch_domain_models/frm", "hyperswitch_connectors/frm", "hyperswitch_interfaces/frm"]
stripe = []
release = ["stripe", "email", "accounts_cache", "kv_store", "vergen", "recon", "external_services/aws_kms", "external_services/aws_s3", "keymanager_mtls", "keymanager_create", "encryption_service", "dynamic_routing", "payout_retry"]
oltp = ["storage_impl/oltp"]
kv_store = ["scheduler/kv_store"]
accounts_cache = ["storage_impl/accounts_cache"]
vergen = ["router_env/vergen"]
dummy_connector = ["api_models/dummy_connector", "euclid/dummy_connector", "hyperswitch_interfaces/dummy_connector", "kgraph_utils/dummy_connector", "payment_methods/dummy_connector", "hyperswitch_domain_models/dummy_connector","hyperswitch_connectors/dummy_connector"]
external_access_dc = ["dummy_connector"]
detailed_errors = ["api_models/detailed_errors", "error-stack/serde"]
payouts = ["api_models/payouts", "common_enums/payouts", "hyperswitch_connectors/payouts", "hyperswitch_domain_models/payouts", "storage_impl/payouts", "payment_methods/payouts"]
payout_retry = ["payouts"]
recon = ["email", "api_models/recon"]
retry = []
v2 = [ "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2", "hyperswitch_connectors/v2", "hyperswitch_interfaces/v2", "common_types/v2", "revenue_recovery", "scheduler/v2", "euclid/v2", "payment_methods/v2", "tokenization_v2", "subscriptions/v2"]
v1 = ["common_default", "api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1", "common_utils/v1", "hyperswitch_connectors/v1", "common_types/v1", "scheduler/v1", "payment_link/v1", "payment_methods/v1", "subscriptions/v1"]
dynamic_routing = ["external_services/dynamic_routing", "storage_impl/dynamic_routing", "api_models/dynamic_routing"]
revenue_recovery = ["api_models/revenue_recovery", "hyperswitch_interfaces/revenue_recovery", "hyperswitch_domain_models/revenue_recovery", "hyperswitch_connectors/revenue_recovery", "external_services/revenue_recovery", "dep:prost-types"]
tokenization_v2 = ["api_models/tokenization_v2", "diesel_models/tokenization_v2", "hyperswitch_domain_models/tokenization_v2", "storage_impl/tokenization_v2"]

# Partial Auth
# The feature reduces the overhead of the router authenticating the merchant for every request, and trusts on `x-merchant-id` header to be present in the request.
# This is named as partial-auth because the router will still try to authenticate if the `x-merchant-id` header is not present.
partial-auth = []

[dependencies]
actix-cors = "0.6.5"
actix-http = "3.11.0"
actix-multipart = "0.6.2"
actix-rt = "2.10.0"
actix-web = "4.11.0"
argon2 = { version = "0.5.3", features = ["std"] }
async-bb8-diesel = "0.2.1"
async-trait = "0.1.88"
base64 = "0.22.1"
bb8 = "0.8"
blake3 = "1.8.2"
bytes = "1.10.1"
clap = { version = "4.5.38", default-features = false, features = ["std", "derive", "help", "usage"] }
config = { version = "0.14.1", features = ["toml"] }
prost-types = { version = "0.13", optional = true }
cookie = "0.18.1"
csv = "1.3.1"
diesel = { version = "2.2.10", features = ["postgres"] }
dyn-clone = "1.0.19"
error-stack = "0.4.1"
futures = "0.3.31"
hex = "0.4.3"
hkdf = "0.12.4"
http = "0.2.12"
infer = "0.15.0"
josekit = "0.8.7"
jsonwebtoken = "9.3.1"
maud = { version = "0.26.0", features = ["actix-web"] }
mimalloc = { version = "0.1", optional = true }
mime = "0.3.17"
nanoid = "0.4.0"
num_cpus = "1.16.0"
num-traits = "0.2.19"
once_cell = "1.21.3"
openidconnect = "3.5.0" # TODO: remove reqwest
openssl = "0.10.72"
rand = "0.8.5"
rand_chacha = "0.3.1"
rdkafka = "0.36.2"
regex = "1.11.1"
reqwest = { version = "0.11.27", features = ["json", "rustls-tls", "gzip", "multipart"] }
ring = "0.17.14"
rust_decimal = { version = "1.37.1", features = ["serde-with-float", "serde-with-str"] }
rust-i18n = { git = "https://github.com/kashif-m/rust-i18n", rev = "f2d8096aaaff7a87a847c35a5394c269f75e077a" }
unified-connector-service-client = { git = "https://github.com/juspay/connector-service", rev = "b5a367c1c775c32503feb00cdc6cd063cc97ea3b", package = "rust-grpc-client" }
unified-connector-service-cards = { git = "https://github.com/juspay/connector-service", rev = "b5a367c1c775c32503feb00cdc6cd063cc97ea3b", package = "ucs_cards" }
unified-connector-service-masking = { git = "https://github.com/juspay/hyperswitch", tag = "2025.09.24.0", package = "masking" }
rustc-hash = "1.1.0"
rustls = "0.22"
rustls-pemfile = "2"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
serde_path_to_error = "0.1.17"
serde_qs = "0.12.0"
serde_with = "3.12.0"
sha2 = "0.10.9"
strum = { version = "0.26", features = ["derive"] }
tera = "1.20.0"
thiserror = "1.0.69"
time = { version = "0.3.41", features = ["serde", "serde-well-known", "std", "parsing", "serde-human-readable"] }
tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread"] }
totp-rs = { version = "5.7.0", features = ["gen_secret", "otpauth"] }
tracing-futures = { version = "0.2.5", features = ["tokio"] }
unicode-segmentation = "1.12.0"
url = { version = "2.5.4", features = ["serde"] }
urlencoding = "2.1.3"
utoipa = { version = "4.2.3", features = ["preserve_order", "preserve_path_order", "time"] }
uuid = { version = "1.17.0", features = ["v4"] }
validator = "0.17.0"
x509-parser = "0.16.0"

# First party crates

analytics = { version = "0.1.0", path = "../analytics", optional = true, default-features = false }
api_models = { version = "0.1.0", path = "../api_models", features = ["errors", "control_center_theme"] }
cards = { version = "0.1.0", path = "../cards" }
common_enums = { version = "0.1.0", path = "../common_enums" }
common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager", "encryption_service"] }
common_types = { version = "0.1.0", path = "../common_types" }
currency_conversion = { version = "0.1.0", path = "../currency_conversion" }
diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_store", "tokenization_v2"], default-features = false }
euclid = { version = "0.1.0", path = "../euclid", features = ["valued_jit"] }
events = { version = "0.1.0", path = "../events" }
external_services = { version = "0.1.0", path = "../external_services" }
hyperswitch_connectors = { version = "0.1.0", path = "../hyperswitch_connectors", default-features = false }
hyperswitch_constraint_graph = { version = "0.1.0", path = "../hyperswitch_constraint_graph" }
hyperswitch_domain_models = { version = "0.1.0", path = "../hyperswitch_domain_models", default-features = false }
hyperswitch_interfaces = { version = "0.1.0", path = "../hyperswitch_interfaces", default-features = false }
injector = { version = "0.1.0", path = "../injector", optional = true }
kgraph_utils = { version = "0.1.0", path = "../kgraph_utils" }
masking = { version = "0.1.0", path = "../masking" }
pm_auth = { version = "0.1.0", path = "../pm_auth", package = "pm_auth" }
redis_interface = { version = "0.1.0", path = "../redis_interface" }
router_derive = { version = "0.1.0", path = "../router_derive" }
router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] }
scheduler = { version = "0.1.0", path = "../scheduler", default-features = false }
storage_impl = { version = "0.1.0", path = "../storage_impl", default-features = false }
payment_link = { version = "0.1.0", path = "../payment_link", default-features = false }
payment_methods = { version = "0.1.0", path = "../payment_methods", default-features = false }
subscriptions = { version = "0.1.0", path = "../subscriptions", default-features = false }

[build-dependencies]
router_env = { version = "0.1.0", path = "../router_env", default-features = false }

[dev-dependencies]
actix-http = "3.11.0"
awc = { version = "3.7.0", features = ["rustls"] }
derive_deref = "1.1.1"
rand = "0.8.5"
serial_test = "3.2.0"
time = { version = "0.3.41", features = ["macros"] }
tokio = "1.48.0"
wiremock = "0.6.3"

# First party dev-dependencies
test_utils = { version = "0.1.0", path = "../test_utils" }

[[bin]]
name = "router"
path = "src/bin/router.rs"

[[bin]]
name = "scheduler"
path = "src/bin/scheduler.rs"

[lints]
workspace = true


// File: crates/router/build.rs

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

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


// File: crates/router/README.md

# Router

Main crate of the project.

## Files Tree Layout

<!-- FIXME: this table should either be generated by a script or smoke test should be introduced checking it agrees with actual structure -->
<!-- FIXME: fill missing -->

```text

├── src                        : source code
│   ├── configs                : config loading
│   ├── connector              : various connector (gateway) specific transformations implementations.
│   │   ├── adyen              : adyen connector
│   │   └── stripe             : stripe connector
│   ├── core                   : the core router / orchestrator code. All common code/flow should exist here. only minimal code in connector implementations.
│   │   ├── customers          : ?
│   │   ├── payment_methods    : ?
│   │   ├── payments           : ?
│   │   └── refunds            : ?
│   ├── routes                 : the API endpoints exposed by router. currently uses actix_web.
│   ├── scheduler              : ?
│   │   └── types              : ?
│   ├── services               : ?
│   │   └── redis              : ?
│   ├── types                  : the objects/API type definitions
│   │   ├── api                : the router API
│   │   └── storage            : definitions for using DB/Storage. Currently uses Diesel.
│   └── utils                  : utilities
└── tests                      : unit and integration tests

```

<!--
command to generate the tree `tree -L 3 -d`
-->


// File: crates/router/locales/ca.yml

_version: 1

payout_link:
  initiate:
    not_allowed: "No tens permís per veure aquest contingut"
    title: "Enllaços de Pagament"
  status:
    title: "Estat del Pagament"
    info:
      ref_id: "ID de Referència"
      error_code: "Codi d'Error"
      error_message: "Missatge d'Error"
    message:
      failed: "No s'ha pogut processar el teu pagament. Si us plau, comprova-ho amb el teu proveïdor per obtenir més detalls."
      processing: "El teu pagament hauria de ser processat en 2-3 dies hàbils."
      success: "El teu pagament s'ha realitzat al mètode de pagament seleccionat."
    redirection_text:
      redirecting: "Redirigint..."
      redirecting_in: "Redirigint en"
      seconds: "segons..."
    text:
      failed: "Falla en el Pagament"
      processing: "Pagament en Procés"
      success: "Pagament Exitos"

time:
  am: "AM"
  pm: "PM"

months:
  january: "Gener"
  february: "Febrer"
  march: "Març"
  april: "Abril"
  may: "Maig"
  june: "Juny"
  july: "Juliol"
  august: "Agost"
  september: "Setembre"
  october: "Octubre"
  november: "Novembre"
  december: "Desembre"


// File: crates/router/locales/en_gb.yml

_version: 1

payout_link:
  initiate:
    not_allowed: "You are not allowed to view this content"
    title: "Payout Links"
  status:
    title: "Payout Status"
    info:
      ref_id: "Ref Id"
      error_code: "Error Code"
      error_message: "Error Message"
    message:
      failed: "Failed to process your payout. Please check with your provider for more details."
      processing: "Your payout should be processed within 2-3 business days."
      success: "Your payout was made to selected payment method."
    redirection_text:
      redirecting: "Redirecting..."
      redirecting_in: "Redirecting in"
      seconds: "seconds..."
    text:
      failed: "Payout Failed"
      processing: "Payout Processing"
      success: "Payout Successful"

time:
  am: "AM"
  pm: "PM"

months:
  january: "January"
  february: "February"
  march: "March"
  april: "April"
  may: "May"
  june: "June"
  july: "July"
  august: "August"
  september: "September"
  october: "October"
  november: "November"
  december: "December"


// File: crates/router/locales/es.yml

_version: 1

payout_link:
  initiate:
    not_allowed: "No tienes permiso para ver este contenido"
    title: "Enlaces de Pago"
  status:
    title: "Estado del Pago"
    info:
      ref_id: "ID de Referencia"
      error_code: "Código de Error"
      error_message: "Mensaje de Error"
    message:
      failed: "No se pudo procesar tu pago. Consulta con tu proveedor para más detalles."
      processing: "Tu pago debería ser procesado en 2-3 días hábiles."
      success: "Tu pago se realizó al método de pago seleccionado."
    redirection_text:
      redirecting: "Redirigiendo..."
      redirecting_in: "Redirigiendo en"
      seconds: "segundos..."
    text:
      failed: "Fallo en el Pago"
      processing: "Pago en Proceso"
      success: "Pago Exitoso"

time:
  am: "AM"
  pm: "PM"

months:
  january: "Enero"
  february: "Febrero"
  march: "Marzo"
  april: "Abril"
  may: "Mayo"
  june: "Junio"
  july: "Julio"
  august: "Agosto"
  september: "Septiembre"
  october: "Octubre"
  november: "Noviembre"
  december: "Diciembre"


// File: crates/router/locales/pt.yml

_version: 1

payout_link:
  initiate:
    not_allowed: "Você não tem permissão para visualizar este conteúdo"
    title: "Links de Pagamento"
  status:
    title: "Status do Pagamento"
    info:
      ref_id: "ID de Referência"
      error_code: "Código de Erro"
      error_message: "Mensagem de Erro"
    message:
      failed: "Falha ao processar seu pagamento. Verifique com seu provedor para mais detalhes."
      processing: "Seu pagamento deve ser processado em 2-3 dias úteis."
      success: "Seu pagamento foi realizado no método de pagamento selecionado."
    redirection_text:
      redirecting: "Redirecionando..."
      redirecting_in: "Redirecionando em"
      seconds: "segundos..."
    text:
      failed: "Falha no Pagamento"
      processing: "Pagamento em Processamento"
      success: "Pagamento Bem-Sucedido"

time:
  am: "AM"
  pm: "PM"

months:
  january: "Janeiro"
  february: "Fevereiro"
  march: "Março"
  april: "Abril"
  may: "Maio"
  june: "Junho"
  july: "Julho"
  august: "Agosto"
  september: "Setembro"
  october: "Outubro"
  november: "Novembro"
  december: "Dezembro"


// File: crates/router/locales/he.yml

_version: 1

payout_link:
  initiate:
    not_allowed: "אינך מורשה לצפות בתוכן זה"
    title: "קישורי תשלום"
  status:
    title: "סטטוס תשלום"
    info:
      ref_id: "מספר הפניה"
      error_code: "קוד שגיאה"
      error_message: "הודעת שגיאה"
    message:
      failed: "נכשל בעיבוד התשלום שלך. אנא בדוק עם הספק שלך למידע נוסף."
      processing: "התשלום שלך צריך להיות מעובד בתוך 2-3 ימי עסקים."
      success: "התשלום שלך בוצע לשיטת התשלום שנבחרה."
    redirection_text:
      redirecting: "מופנה..."
      redirecting_in: "מופנה בעוד"
      seconds: "שניות..."
    text:
      failed: "תשלום נכשל"
      processing: "תשלום בתהליך"
      success: "תשלום הצליח"

time:
  am: "בבוקר"
  pm: "בערב"

months:
  january: "ינואר"
  february: "פברואר"
  march: "מרץ"
  april: "אפריל"
  may: "מאי"
  june: "יוני"
  july: "יולי"
  august: "אוגוסט"
  september: "ספטמבר"
  october: "אוקטובר"
  november: "נובמבר"
  december: "דצמבר"


// File: crates/router/locales/de.yml

_version: 1

payout_link:
  initiate:
    not_allowed: "Sie dürfen diesen Inhalt nicht anzeigen"
    title: "Auszahlungslinks"
  status:
    title: "Auszahlungsstatus"
    info:
      ref_id: "Referenz-ID"
      error_code: "Fehlercode"
      error_message: "Fehlermeldung"
    message:
      failed: "Die Auszahlung konnte nicht verarbeitet werden. Bitte überprüfen Sie weitere Details bei Ihrem Anbieter."
      processing: "Ihre Auszahlung sollte innerhalb von 2-3 Werktagen verarbeitet werden."
      success: "Ihre Auszahlung wurde auf die ausgewählte Zahlungsmethode vorgenommen."
    redirection_text:
      redirecting: "Weiterleitung..."
      redirecting_in: "Weiterleitung in"
      seconds: "Sekunden..."
    text:
      failed: "Auszahlung fehlgeschlagen"
      processing: "Auszahlung wird bearbeitet"
      success: "Auszahlung erfolgreich"

time:
  am: "AM"
  pm: "PM"

months:
  january: "Januar"
  february: "Februar"
  march: "März"
  april: "April"
  may: "Mai"
  june: "Juni"
  july: "Juli"
  august: "August"
  september: "September"
  october: "Oktober"
  november: "November"
  december: "Dezember"