File: crates/hyperswitch_connectors/src/connectors/paystack/transformers.rs
 Public functions: 1
 Public structs: 15

use common_enums::{enums, Currency};
use common_utils::{pii::Email, request::Method, types::MinorUnit};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
    payment_method_data::{BankRedirectData, PaymentMethodData},
    router_data::{ConnectorAuthType, ErrorResponse, RouterData},
    router_flow_types::refunds::{Execute, RSync},
    router_request_types::ResponseId,
    router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData},
    types::{PaymentsAuthorizeRouterData, RefundsRouterData},
};
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};
use url::Url;

use crate::{
    types::{RefundsResponseRouterData, ResponseRouterData},
    utils::PaymentsAuthorizeRequestData,
};

pub struct PaystackRouterData<T> {
    pub amount: MinorUnit,
    pub router_data: T,
}

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

#[derive(Default, Debug, Serialize, PartialEq)]
pub struct PaystackEftProvider {
    provider: String,
}

#[derive(Default, Debug, Serialize, PartialEq)]
pub struct PaystackPaymentsRequest {
    amount: MinorUnit,
    currency: Currency,
    email: Email,
    eft: PaystackEftProvider,
}

impl TryFrom<&PaystackRouterData<&PaymentsAuthorizeRouterData>> for PaystackPaymentsRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &PaystackRouterData<&PaymentsAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        match item.router_data.request.payment_method_data.clone() {
            PaymentMethodData::BankRedirect(BankRedirectData::Eft { provider }) => {
                let email = item.router_data.request.get_email()?;
                let eft = PaystackEftProvider { provider };
                Ok(Self {
                    amount: item.amount,
                    currency: item.router_data.request.currency,
                    email,
                    eft,
                })
            }
            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
        }
    }
}

pub struct PaystackAuthType {
    pub(super) api_key: Secret<String>,
}

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

#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PaystackEftRedirect {
    reference: String,
    status: String,
    url: String,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PaystackPaymentsResponseData {
    status: bool,
    message: String,
    data: PaystackEftRedirect,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum PaystackPaymentsResponse {
    PaystackPaymentsData(PaystackPaymentsResponseData),
    PaystackPaymentsError(PaystackErrorResponse),
}

impl<F, T> TryFrom<ResponseRouterData<F, PaystackPaymentsResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, PaystackPaymentsResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        let (status, response) = match item.response {
            PaystackPaymentsResponse::PaystackPaymentsData(resp) => {
                let redirection_url = Url::parse(resp.data.url.as_str())
                    .change_context(errors::ConnectorError::ParsingFailed)?;
                let redirection_data = RedirectForm::from((redirection_url, Method::Get));
                (
                    common_enums::AttemptStatus::AuthenticationPending,
                    Ok(PaymentsResponseData::TransactionResponse {
                        resource_id: ResponseId::ConnectorTransactionId(
                            resp.data.reference.clone(),
                        ),
                        redirection_data: Box::new(Some(redirection_data)),
                        mandate_reference: Box::new(None),
                        connector_metadata: None,
                        network_txn_id: None,
                        connector_response_reference_id: None,
                        incremental_authorization_allowed: None,
                        charges: None,
                    }),
                )
            }
            PaystackPaymentsResponse::PaystackPaymentsError(err) => {
                let err_msg = get_error_message(err.clone());
                (
                    common_enums::AttemptStatus::Failure,
                    Err(ErrorResponse {
                        code: err.code,
                        message: err_msg.clone(),
                        reason: Some(err_msg.clone()),
                        attempt_status: None,
                        connector_transaction_id: None,
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    }),
                )
            }
        };
        Ok(Self {
            status,
            response,
            ..item.data
        })
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum PaystackPSyncStatus {
    Abandoned,
    Failed,
    Ongoing,
    Pending,
    Processing,
    Queued,
    Reversed,
    Success,
}

impl From<PaystackPSyncStatus> for common_enums::AttemptStatus {
    fn from(item: PaystackPSyncStatus) -> Self {
        match item {
            PaystackPSyncStatus::Success => Self::Charged,
            PaystackPSyncStatus::Abandoned => Self::AuthenticationPending,
            PaystackPSyncStatus::Ongoing
            | PaystackPSyncStatus::Pending
            | PaystackPSyncStatus::Processing
            | PaystackPSyncStatus::Queued => Self::Pending,
            PaystackPSyncStatus::Failed => Self::Failure,
            PaystackPSyncStatus::Reversed => Self::Voided,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PaystackPSyncData {
    status: PaystackPSyncStatus,
    reference: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PaystackPSyncResponseData {
    status: bool,
    message: String,
    data: PaystackPSyncData,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum PaystackPSyncResponse {
    PaystackPSyncData(PaystackPSyncResponseData),
    PaystackPSyncWebhook(PaystackPaymentWebhookData),
    PaystackPSyncError(PaystackErrorResponse),
}

impl<F, T> TryFrom<ResponseRouterData<F, PaystackPSyncResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, PaystackPSyncResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            PaystackPSyncResponse::PaystackPSyncData(resp) => Ok(Self {
                status: common_enums::AttemptStatus::from(resp.data.status),
                response: Ok(PaymentsResponseData::TransactionResponse {
                    resource_id: ResponseId::ConnectorTransactionId(resp.data.reference.clone()),
                    redirection_data: Box::new(None),
                    mandate_reference: Box::new(None),
                    connector_metadata: None,
                    network_txn_id: None,
                    connector_response_reference_id: None,
                    incremental_authorization_allowed: None,
                    charges: None,
                }),
                ..item.data
            }),
            PaystackPSyncResponse::PaystackPSyncWebhook(resp) => Ok(Self {
                status: common_enums::AttemptStatus::from(resp.status),
                response: Ok(PaymentsResponseData::TransactionResponse {
                    resource_id: ResponseId::ConnectorTransactionId(resp.reference.clone()),
                    redirection_data: Box::new(None),
                    mandate_reference: Box::new(None),
                    connector_metadata: None,
                    network_txn_id: None,
                    connector_response_reference_id: None,
                    incremental_authorization_allowed: None,
                    charges: None,
                }),
                ..item.data
            }),
            PaystackPSyncResponse::PaystackPSyncError(err) => {
                let err_msg = get_error_message(err.clone());
                Ok(Self {
                    response: Err(ErrorResponse {
                        code: err.code,
                        message: err_msg.clone(),
                        reason: Some(err_msg.clone()),
                        attempt_status: None,
                        connector_transaction_id: None,
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    }),
                    ..item.data
                })
            }
        }
    }
}

#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
pub struct PaystackRefundRequest {
    pub transaction: String,
    pub amount: MinorUnit,
}

impl<F> TryFrom<&PaystackRouterData<&RefundsRouterData<F>>> for PaystackRefundRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &PaystackRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
        Ok(Self {
            transaction: item.router_data.request.connector_transaction_id.clone(),
            amount: item.amount.to_owned(),
        })
    }
}

#[derive(Debug, Serialize, Default, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum PaystackRefundStatus {
    Processed,
    Failed,
    #[default]
    Processing,
    Pending,
}

impl From<PaystackRefundStatus> for enums::RefundStatus {
    fn from(item: PaystackRefundStatus) -> Self {
        match item {
            PaystackRefundStatus::Processed => Self::Success,
            PaystackRefundStatus::Failed => Self::Failure,
            PaystackRefundStatus::Processing | PaystackRefundStatus::Pending => Self::Pending,
        }
    }
}

#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PaystackRefundsData {
    status: PaystackRefundStatus,
    id: i64,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PaystackRefundsResponseData {
    status: bool,
    message: String,
    data: PaystackRefundsData,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum PaystackRefundsResponse {
    PaystackRefundsData(PaystackRefundsResponseData),
    PaystackRSyncWebhook(PaystackRefundWebhookData),
    PaystackRefundsError(PaystackErrorResponse),
}

impl TryFrom<RefundsResponseRouterData<Execute, PaystackRefundsResponse>>
    for RefundsRouterData<Execute>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<Execute, PaystackRefundsResponse>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            PaystackRefundsResponse::PaystackRefundsData(resp) => Ok(Self {
                response: Ok(RefundsResponseData {
                    connector_refund_id: resp.data.id.to_string(),
                    refund_status: enums::RefundStatus::from(resp.data.status),
                }),
                ..item.data
            }),
            PaystackRefundsResponse::PaystackRSyncWebhook(resp) => Ok(Self {
                response: Ok(RefundsResponseData {
                    connector_refund_id: resp.id,
                    refund_status: enums::RefundStatus::from(resp.status),
                }),
                ..item.data
            }),
            PaystackRefundsResponse::PaystackRefundsError(err) => {
                let err_msg = get_error_message(err.clone());
                Ok(Self {
                    response: Err(ErrorResponse {
                        code: err.code,
                        message: err_msg.clone(),
                        reason: Some(err_msg.clone()),
                        attempt_status: None,
                        connector_transaction_id: None,
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    }),
                    ..item.data
                })
            }
        }
    }
}

impl TryFrom<RefundsResponseRouterData<RSync, PaystackRefundsResponse>>
    for RefundsRouterData<RSync>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<RSync, PaystackRefundsResponse>,
    ) -> Result<Self, Self::Error> {
        match item.response {
            PaystackRefundsResponse::PaystackRefundsData(resp) => Ok(Self {
                response: Ok(RefundsResponseData {
                    connector_refund_id: resp.data.id.to_string(),
                    refund_status: enums::RefundStatus::from(resp.data.status),
                }),
                ..item.data
            }),
            PaystackRefundsResponse::PaystackRSyncWebhook(resp) => Ok(Self {
                response: Ok(RefundsResponseData {
                    connector_refund_id: resp.id,
                    refund_status: enums::RefundStatus::from(resp.status),
                }),
                ..item.data
            }),
            PaystackRefundsResponse::PaystackRefundsError(err) => {
                let err_msg = get_error_message(err.clone());
                Ok(Self {
                    response: Err(ErrorResponse {
                        code: err.code,
                        message: err_msg.clone(),
                        reason: Some(err_msg.clone()),
                        attempt_status: None,
                        connector_transaction_id: None,
                        status_code: item.http_code,
                        network_advice_code: None,
                        network_decline_code: None,
                        network_error_message: None,
                        connector_metadata: None,
                    }),
                    ..item.data
                })
            }
        }
    }
}

#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PaystackErrorResponse {
    pub status: bool,
    pub message: String,
    pub data: Option<serde_json::Value>,
    pub meta: serde_json::Value,
    pub code: String,
}

pub fn get_error_message(response: PaystackErrorResponse) -> String {
    if let Some(serde_json::Value::Object(err_map)) = response.data {
        err_map.get("message").map(|msg| msg.clone().to_string())
    } else {
        None
    }
    .unwrap_or(response.message)
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct PaystackPaymentWebhookData {
    pub status: PaystackPSyncStatus,
    pub reference: String,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct PaystackRefundWebhookData {
    pub status: PaystackRefundStatus,
    pub id: String,
    pub transaction_reference: String,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum PaystackWebhookEventData {
    Payment(PaystackPaymentWebhookData),
    Refund(PaystackRefundWebhookData),
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct PaystackWebhookData {
    pub event: String,
    pub data: PaystackWebhookEventData,
}

impl From<PaystackWebhookEventData> for api_models::webhooks::IncomingWebhookEvent {
    fn from(item: PaystackWebhookEventData) -> Self {
        match item {
            PaystackWebhookEventData::Payment(payment_data) => match payment_data.status {
                PaystackPSyncStatus::Success => Self::PaymentIntentSuccess,
                PaystackPSyncStatus::Failed => Self::PaymentIntentFailure,
                PaystackPSyncStatus::Abandoned
                | PaystackPSyncStatus::Ongoing
                | PaystackPSyncStatus::Pending
                | PaystackPSyncStatus::Processing
                | PaystackPSyncStatus::Queued => Self::PaymentIntentProcessing,
                PaystackPSyncStatus::Reversed => Self::EventNotSupported,
            },
            PaystackWebhookEventData::Refund(refund_data) => match refund_data.status {
                PaystackRefundStatus::Processed => Self::RefundSuccess,
                PaystackRefundStatus::Failed => Self::RefundFailure,
                PaystackRefundStatus::Processing | PaystackRefundStatus::Pending => {
                    Self::EventNotSupported
                }
            },
        }
    }
}


pub struct PlaidErrorResponse {
    pub display_message: Option<String>,
    pub error_code: Option<String>,
    pub error_message: String,
    pub error_type: Option<String>,
}


OpenAPI Block Path: components.schemas.PayoutListFilterConstraints
{
  "allOf": [
    {
      "allOf": [
        {
          "$ref": "#/components/schemas/TimeRange"
        }
      ],
      "nullable": true
    },
    {
      "type": "object",
      "required": [
        "currency",
        "entity_type"
      ],
      "properties": {
        "payout_id": {
          "type": "string",
          "description": "The identifier for payout",
          "example": "187282ab-40ef-47a9-9206-5099ba31e432",
          "nullable": true,
          "maxLength": 30,
          "minLength": 30
        },
        "merchant_order_reference_id": {
          "type": "string",
          "description": "The merchant order reference ID for payout",
          "example": "merchant_order_ref_123",
          "nullable": true,
          "maxLength": 255
        },
        "profile_id": {
          "type": "string",
          "description": "The identifier for business profile",
          "nullable": true
        },
        "customer_id": {
          "type": "string",
          "description": "The identifier for customer",
          "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44",
          "nullable": true
        },
        "limit": {
          "type": "integer",
          "format": "int32",
          "description": "The limit on the number of objects. The default limit is 10 and max limit is 20",
          "minimum": 0
        },
        "offset": {
          "type": "integer",
          "format": "int32",
          "description": "The starting point within a list of objects",
          "nullable": true,
          "minimum": 0
        },
        "connector": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/PayoutConnectors"
          },
          "description": "The list of connectors to filter payouts list",
          "example": [
            "wise",
            "adyen"
          ],
          "nullable": true
        },
        "currency": {
          "$ref": "#/components/schemas/Currency"
        },
        "status": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/PayoutStatus"
          },
          "description": "The list of payout status to filter payouts list",
          "example": [
            "pending",
            "failed"
          ],
          "nullable": true
        },
        "payout_method": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/PayoutType"
          },
          "description": "The list of payout methods to filter payouts list",
          "example": [
            "bank",
            "card"
          ],
          "nullable": true
        },
        "entity_type": {
          "$ref": "#/components/schemas/PayoutEntityType"
        }
      }
    }
  ]
}


impl api::Refund for Payload {}


pub fn get_frm_routing_algorithm(
        &self,
    ) -> CustomResult<
        Option<api_models::routing::RoutingAlgorithmRef>,
        api_error_response::ApiErrorResponse,
    > {
        self.frm_routing_algorithm
            .clone()
            .map(|val| {
                val.parse_value::<api_models::routing::RoutingAlgorithmRef>("RoutingAlgorithmRef")
            })
            .transpose()
            .change_context(api_error_response::ApiErrorResponse::InternalServerError)
            .attach_printable(
                "unable to deserialize frm routing algorithm ref from merchant account",
            )
    }


impl Globepay {
    pub fn new() -> &'static Self {
        &Self {
            amount_converter: &MinorUnitForConnector,
        }
    }
}


OpenAPI Block Path: components.schemas.MandateCardDetails
{
  "type": "object",
  "properties": {
    "last4_digits": {
      "type": "string",
      "description": "The last 4 digits of card",
      "nullable": true
    },
    "card_exp_month": {
      "type": "string",
      "description": "The expiry month of card",
      "nullable": true
    },
    "card_exp_year": {
      "type": "string",
      "description": "The expiry year of card",
      "nullable": true
    },
    "card_holder_name": {
      "type": "string",
      "description": "The card holder name",
      "nullable": true
    },
    "card_token": {
      "type": "string",
      "description": "The token from card locker",
      "nullable": true
    },
    "scheme": {
      "type": "string",
      "description": "The card scheme network for the particular card",
      "nullable": true
    },
    "issuer_country": {
      "type": "string",
      "description": "The country code in in which the card was issued",
      "nullable": true
    },
    "card_fingerprint": {
      "type": "string",
      "description": "A unique identifier alias to identify a particular card",
      "nullable": true
    },
    "card_isin": {
      "type": "string",
      "description": "The first 6 digits of card",
      "nullable": true
    },
    "card_issuer": {
      "type": "string",
      "description": "The bank that issued the card",
      "nullable": true
    },
    "card_network": {
      "allOf": [
        {
          "$ref": "#/components/schemas/CardNetwork"
        }
      ],
      "nullable": true
    },
    "card_type": {
      "type": "string",
      "description": "The type of the payment card",
      "nullable": true
    },
    "nick_name": {
      "type": "string",
      "description": "The nick_name of the card holder",
      "nullable": true
    }
  }
}


File: crates/router/src/types/connector_transformers.rs

use api_models::enums as api_enums;

use super::ForeignTryFrom;

impl ForeignTryFrom<api_enums::Connector> for common_enums::RoutableConnectors {
    type Error = error_stack::Report<common_utils::errors::ValidationError>;

    fn foreign_try_from(from: api_enums::Connector) -> Result<Self, Self::Error> {
        Ok(match from {
            api_enums::Connector::Aci => Self::Aci,
            api_enums::Connector::Adyen => Self::Adyen,
            api_enums::Connector::Affirm => Self::Affirm,
            api_enums::Connector::Adyenplatform => Self::Adyenplatform,
            api_enums::Connector::Airwallex => Self::Airwallex,
            api_enums::Connector::Amazonpay => Self::Amazonpay,
            api_enums::Connector::Archipel => Self::Archipel,
            api_enums::Connector::Authipay => Self::Authipay,
            api_enums::Connector::Authorizedotnet => Self::Authorizedotnet,
            api_enums::Connector::Bambora => Self::Bambora,
            api_enums::Connector::Bamboraapac => Self::Bamboraapac,
            api_enums::Connector::Bankofamerica => Self::Bankofamerica,
            api_enums::Connector::Barclaycard => Self::Barclaycard,
            api_enums::Connector::Billwerk => Self::Billwerk,
            api_enums::Connector::Bitpay => Self::Bitpay,
            api_enums::Connector::Bluesnap => Self::Bluesnap,
            api_enums::Connector::Blackhawknetwork => Self::Blackhawknetwork,
            api_enums::Connector::Bluecode => Self::Bluecode,
            api_enums::Connector::Boku => Self::Boku,
            api_enums::Connector::Braintree => Self::Braintree,
            api_enums::Connector::Breadpay => Self::Breadpay,
            api_enums::Connector::Cashtocode => Self::Cashtocode,
            api_enums::Connector::Celero => Self::Celero,
            api_enums::Connector::Chargebee => Self::Chargebee,
            api_enums::Connector::Checkbook => Self::Checkbook,
            api_enums::Connector::Checkout => Self::Checkout,
            api_enums::Connector::Coinbase => Self::Coinbase,
            api_enums::Connector::Coingate => Self::Coingate,
            api_enums::Connector::Cryptopay => Self::Cryptopay,
            api_enums::Connector::Custombilling => Self::Custombilling,
            api_enums::Connector::CtpVisa => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "ctp visa is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::CtpMastercard => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "ctp mastercard is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Cybersource => Self::Cybersource,
            api_enums::Connector::Datatrans => Self::Datatrans,
            api_enums::Connector::Deutschebank => Self::Deutschebank,
            api_enums::Connector::Digitalvirgo => Self::Digitalvirgo,
            api_enums::Connector::Dlocal => Self::Dlocal,
            api_enums::Connector::Dwolla => Self::Dwolla,
            api_enums::Connector::Ebanx => Self::Ebanx,
            api_enums::Connector::Elavon => Self::Elavon,
            api_enums::Connector::Facilitapay => Self::Facilitapay,
            api_enums::Connector::Fiserv => Self::Fiserv,
            api_enums::Connector::Fiservemea => Self::Fiservemea,
            api_enums::Connector::Fiuu => Self::Fiuu,
            api_enums::Connector::Flexiti => Self::Flexiti,
            api_enums::Connector::Forte => Self::Forte,
            api_enums::Connector::Getnet => Self::Getnet,
            api_enums::Connector::Globalpay => Self::Globalpay,
            api_enums::Connector::Globepay => Self::Globepay,
            api_enums::Connector::Gocardless => Self::Gocardless,
            api_enums::Connector::Gpayments => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "gpayments is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Hipay => Self::Hipay,
            api_enums::Connector::Helcim => Self::Helcim,
            api_enums::Connector::HyperswitchVault => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "Hyperswitch Vault is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Iatapay => Self::Iatapay,
            api_enums::Connector::Inespay => Self::Inespay,
            api_enums::Connector::Itaubank => Self::Itaubank,
            api_enums::Connector::Jpmorgan => Self::Jpmorgan,
            api_enums::Connector::Juspaythreedsserver => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "juspaythreedsserver is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Klarna => Self::Klarna,
            api_enums::Connector::Mifinity => Self::Mifinity,
            api_enums::Connector::Mollie => Self::Mollie,
            api_enums::Connector::Moneris => Self::Moneris,
            api_enums::Connector::Multisafepay => Self::Multisafepay,
            api_enums::Connector::Netcetera => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "netcetera is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Nexinets => Self::Nexinets,
            api_enums::Connector::Nexixpay => Self::Nexixpay,
            api_enums::Connector::Nmi => Self::Nmi,
            api_enums::Connector::Nomupay => Self::Nomupay,
            api_enums::Connector::Noon => Self::Noon,
            api_enums::Connector::Nordea => Self::Nordea,
            api_enums::Connector::Novalnet => Self::Novalnet,
            api_enums::Connector::Nuvei => Self::Nuvei,
            api_enums::Connector::Opennode => Self::Opennode,
            api_enums::Connector::Paybox => Self::Paybox,
            api_enums::Connector::Payload => Self::Payload,
            api_enums::Connector::Payme => Self::Payme,
            api_enums::Connector::Payone => Self::Payone,
            api_enums::Connector::Paypal => Self::Paypal,
            api_enums::Connector::Paysafe => Self::Paysafe,
            api_enums::Connector::Paystack => Self::Paystack,
            api_enums::Connector::Payu => Self::Payu,
            api_models::enums::Connector::Placetopay => Self::Placetopay,
            api_enums::Connector::Plaid => Self::Plaid,
            api_enums::Connector::Powertranz => Self::Powertranz,
            api_enums::Connector::Prophetpay => Self::Prophetpay,
            api_enums::Connector::Rapyd => Self::Rapyd,
            api_enums::Connector::Razorpay => Self::Razorpay,
            api_enums::Connector::Recurly => Self::Recurly,
            api_enums::Connector::Redsys => Self::Redsys,
            api_enums::Connector::Santander => Self::Santander,
            api_enums::Connector::Shift4 => Self::Shift4,
            api_enums::Connector::Silverflow => Self::Silverflow,
            api_enums::Connector::Signifyd => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "signifyd is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Riskified => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "riskified is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Square => Self::Square,
            api_enums::Connector::Stax => Self::Stax,
            api_enums::Connector::Stripe => Self::Stripe,
            api_enums::Connector::Stripebilling => Self::Stripebilling,
            // api_enums::Connector::Thunes => Self::Thunes,
            api_enums::Connector::Tokenio => Self::Tokenio,
            api_enums::Connector::Trustpay => Self::Trustpay,
            api_enums::Connector::Tsys => Self::Tsys,
            // api_enums::Connector::UnifiedAuthenticationService => {
            //     Self::UnifiedAuthenticationService
            // }
            api_enums::Connector::Vgs => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "Vgs is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Volt => Self::Volt,
            api_enums::Connector::Wellsfargo => Self::Wellsfargo,
            // api_enums::Connector::Wellsfargopayout => Self::Wellsfargopayout,
            api_enums::Connector::Wise => Self::Wise,
            api_enums::Connector::Worldline => Self::Worldline,
            api_enums::Connector::Worldpay => Self::Worldpay,
            api_enums::Connector::Worldpayvantiv => Self::Worldpayvantiv,
            api_enums::Connector::Worldpayxml => Self::Worldpayxml,
            api_enums::Connector::Xendit => Self::Xendit,
            api_enums::Connector::Zen => Self::Zen,
            api_enums::Connector::Zsl => Self::Zsl,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyBillingConnector => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "stripe_billing_test is not a routable connector".to_string(),
                })?
            }
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector1 => Self::DummyConnector1,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector2 => Self::DummyConnector2,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector3 => Self::DummyConnector3,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector4 => Self::DummyConnector4,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector5 => Self::DummyConnector5,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector6 => Self::DummyConnector6,
            #[cfg(feature = "dummy_connector")]
            api_enums::Connector::DummyConnector7 => Self::DummyConnector7,
            api_enums::Connector::Threedsecureio => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "threedsecureio is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Taxjar => {
                Err(common_utils::errors::ValidationError::InvalidValue {
                    message: "Taxjar is not a routable connector".to_string(),
                })?
            }
            api_enums::Connector::Phonepe => Self::Phonepe,
            api_enums::Connector::Paytm => Self::Paytm,
        })
    }
}


impl PaymentCapture for Netcetera {}


impl Responder {
    let flow = Flow::IncomingWebhookReceive;
    let (merchant_id, profile_id, connector_id) = path.into_inner();
    let is_relay_webhook = true;

    Box::pin(api::server_wrap(
        flow.clone(),
        state,
        &req,
        (),
        |state, auth, _, req_state| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            webhooks::incoming_webhooks_wrapper::<W>(
                &flow,
                state.to_owned(),
                req_state,
                &req,
                merchant_context,
                auth.profile,
                &connector_id,
                body.clone(),
                is_relay_webhook,
            )
        },
        &auth::MerchantIdAndProfileIdAuth {
            merchant_id,
            profile_id,
        },
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


                DisputeSyncData,
                DisputeSyncResponse,
            > for $path::$connector
            {}
    )*
    };
}

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

macro_rules! default_imp_for_new_connector_integration_defend_dispute {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl DefendDisputeV2 for $path::$connector {}
            impl
                ConnectorIntegrationV2<
                Defend,
                DisputesFlowData,
                DefendDisputeRequestData,
                DefendDisputeResponse,
            > for $path::$connector
            {}
        )*
    };
}

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

macro_rules! default_imp_for_new_connector_integration_submit_evidence {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl SubmitEvidenceV2 for $path::$connector {}
            impl
                ConnectorIntegrationV2<
                Evidence,
                DisputesFlowData,
                SubmitEvidenceRequestData,
                SubmitEvidenceResponse,
            > for $path::$connector
            {}
    )*
    };
}

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

macro_rules! default_imp_for_new_connector_integration_file_upload {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl FileUploadV2 for $path::$connector {}
            impl UploadFileV2 for $path::$connector {}
            impl
                ConnectorIntegrationV2<
                Upload,
                FilesFlowData,
                UploadFileRequestData,
                UploadFileResponse,
            > for $path::$connector
            {}
            impl RetrieveFileV2 for $path::$connector {}
            impl
                ConnectorIntegrationV2<
                Retrieve,
                FilesFlowData,
                RetrieveFileRequestData,
                RetrieveFileResponse,
            > for $path::$connector
            {}
    )*
    };
}

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

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

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

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

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

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

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

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

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

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

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


pub fn custom_error_handlers<B: body::MessageBody + 'static>(
    res: ServiceResponse<B>,
) -> actix_web::Result<ErrorHandlerResponse<B>> {
    let error_response = match res.status() {
        StatusCode::NOT_FOUND => ApiErrorResponse::InvalidRequestUrl,
        StatusCode::METHOD_NOT_ALLOWED => ApiErrorResponse::InvalidHttpMethod,
        _ => ApiErrorResponse::InternalServerError,
    };

    let (req, res) = res.into_parts();
    logger::warn!(error_response=?res);
    let res = match res.error() {
        Some(_) => res.map_into_boxed_body(),
        None => error_response.error_response(),
    };
    let res = ServiceResponse::new(req, res)
        .map_into_boxed_body()
        .map_into_right_body();
    Ok(ErrorHandlerResponse::Response(res))
}


/// Version of the crate containing the following information:
///
/// - The latest git tag. If tags are not present in the repository, the short commit hash is used
///   instead.
/// - Short hash of the latest git commit.
/// - Timestamp of the latest git commit.
///
/// Example: `0.1.0-abcd012-2038-01-19T03:14:08Z`.
#[cfg(feature = "vergen")]
#[macro_export]
macro_rules! version {
    () => {
        concat!(
            env!("VERGEN_GIT_DESCRIBE"),
            "-",
            env!("VERGEN_GIT_SHA"),
            "-",
            env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
        )
    };
}


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

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

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

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

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

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

static CONNECTOR: FiservemeaTest = FiservemeaTest {};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Connector dependent test cases goes here

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


impl EphemeralKey {
    pub fn server(config: AppState) -> Scope {
        web::scope("/ephemeral_keys")
            .app_data(web::Data::new(config))
            .service(web::resource("").route(web::post().to(ephemeral_key_create)))
            .service(web::resource("/{id}").route(web::delete().to(ephemeral_key_delete)))
    }
}


pub struct MerchantAccount {
    merchant_id: common_utils::id_type::MerchantId,
    pub return_url: Option<String>,
    pub enable_payment_response_hash: bool,
    pub payment_response_hash_key: Option<String>,
    pub redirect_to_merchant_with_http_post: bool,
    pub merchant_name: OptionalEncryptableName,
    pub merchant_details: OptionalEncryptableValue,
    pub webhook_details: Option<diesel_models::business_profile::WebhookDetails>,
    pub sub_merchants_enabled: Option<bool>,
    pub parent_merchant_id: Option<common_utils::id_type::MerchantId>,
    pub publishable_key: String,
    pub storage_scheme: MerchantStorageScheme,
    pub locker_id: Option<String>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub routing_algorithm: Option<serde_json::Value>,
    pub primary_business_details: serde_json::Value,
    pub frm_routing_algorithm: Option<serde_json::Value>,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub intent_fulfillment_time: Option<i64>,
    pub payout_routing_algorithm: Option<serde_json::Value>,
    pub organization_id: common_utils::id_type::OrganizationId,
    pub is_recon_enabled: bool,
    pub default_profile: Option<common_utils::id_type::ProfileId>,
    pub recon_status: diesel_models::enums::ReconStatus,
    pub payment_link_config: Option<serde_json::Value>,
    pub pm_collect_link_config: Option<serde_json::Value>,
    pub version: common_enums::ApiVersion,
    pub is_platform_account: bool,
    pub product_type: Option<common_enums::MerchantProductType>,
    pub merchant_account_type: common_enums::MerchantAccountType,
}