Bug: [REFACTOR] Define the Mapping between `ConnectorError` and `ApiErrorResponse` using the `ErrorSwitch` trait



### Feature Description

Currently, we are mapping errors from `ConnectorError` to `ApiErrorResponse` using custom logic (can be found [here](https://github.com/juspay/hyperswitch/blob/cd0cf40fe29358700f92c1520475934752bb4b30/crates/router/src/core/webhooks/utils.rs#L52)).

We want to refactor this implementation to make use of the existing `ErrorSwitch` trait which satisfies the same usecase.


### Possible Implementation

We have a custom trait for conversion of error from `ConnectorError` to `ApiErrorResponse` as can be found using the link in the description above. The mapping has to be defined using the `ErrorSwitch` trait instead, and the custom trait can hence be deleted.

### Have you spent some time to check if this feature request has been raised before?

- [X] I checked and didn't find similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

No, but I'm happy to collaborate on a PR with someone else
diff --git a/crates/router/src/core/errors.rs b/crates/router/src/core/errors.rs
index d79e120c5c0..2ab8aff3a0a 100644
--- a/crates/router/src/core/errors.rs
+++ b/crates/router/src/core/errors.rs
@@ -1,5 +1,6 @@
 pub mod api_error_response;
 pub mod error_handlers;
+pub mod transformers;
 pub mod utils;
 
 use std::fmt::Display;
diff --git a/crates/router/src/core/errors/api_error_response.rs b/crates/router/src/core/errors/api_error_response.rs
index 6b0142f4bc0..7cdf2ab6c03 100644
--- a/crates/router/src/core/errors/api_error_response.rs
+++ b/crates/router/src/core/errors/api_error_response.rs
@@ -1,6 +1,5 @@
 #![allow(dead_code, unused_variables)]
 
-use api_models::errors::types::Extra;
 use http::StatusCode;
 
 #[derive(Clone, Debug, serde::Serialize)]
@@ -261,244 +260,3 @@ impl actix_web::ResponseError for ApiErrorResponse {
 }
 
 impl crate::services::EmbedError for error_stack::Report<ApiErrorResponse> {}
-
-impl common_utils::errors::ErrorSwitch<api_models::errors::types::ApiErrorResponse>
-    for ApiErrorResponse
-{
-    fn switch(&self) -> api_models::errors::types::ApiErrorResponse {
-        use api_models::errors::types::{ApiError, ApiErrorResponse as AER};
-
-        let error_message = self.error_message();
-        let error_codes = self.error_code();
-        let error_type = self.error_type();
-
-        match self {
-            Self::NotImplemented { message } => {
-                AER::NotImplemented(ApiError::new("IR", 0, format!("{message:?}"), None))
-            }
-            Self::Unauthorized => AER::Unauthorized(ApiError::new(
-                "IR",
-                1,
-                "API key not provided or invalid API key used", None
-            )),
-            Self::InvalidRequestUrl => {
-                AER::NotFound(ApiError::new("IR", 2, "Unrecognized request URL", None))
-            }
-            Self::InvalidHttpMethod => AER::MethodNotAllowed(ApiError::new(
-                "IR",
-                3,
-                "The HTTP method is not applicable for this API", None
-            )),
-            Self::MissingRequiredField { field_name } => AER::BadRequest(
-                ApiError::new("IR", 4, format!("Missing required param: {field_name}"), None),
-            ),
-            Self::InvalidDataFormat {
-                field_name,
-                expected_format,
-            } => AER::Unprocessable(ApiError::new(
-                "IR",
-                5,
-                format!(
-                    "{field_name} contains invalid data. Expected format is {expected_format}"
-                ), None
-            )),
-            Self::InvalidRequestData { message } => {
-                AER::Unprocessable(ApiError::new("IR", 6, message.to_string(), None))
-            }
-            Self::InvalidDataValue { field_name } => AER::BadRequest(ApiError::new(
-                "IR",
-                7,
-                format!("Invalid value provided: {field_name}"), None
-            )),
-            Self::ClientSecretNotGiven => AER::BadRequest(ApiError::new(
-                "IR",
-                8,
-                "client_secret was not provided", None
-            )),
-            Self::ClientSecretInvalid => {
-                AER::BadRequest(ApiError::new("IR", 9, "The client_secret provided does not match the client_secret associated with the Payment", None))
-            }
-            Self::MandateActive => {
-                AER::BadRequest(ApiError::new("IR", 10, "Customer has active mandate/subsciption", None))
-            }
-            Self::CustomerRedacted => {
-                AER::BadRequest(ApiError::new("IR", 11, "Customer has already been redacted", None))
-            }
-            Self::MaximumRefundCount => AER::BadRequest(ApiError::new("IR", 12, "Reached maximum refund attempts", None)),
-            Self::RefundAmountExceedsPaymentAmount => {
-                AER::BadRequest(ApiError::new("IR", 13, "Refund amount exceeds the payment amount", None))
-            }
-            Self::PaymentUnexpectedState {
-                current_flow,
-                field_name,
-                current_value,
-                states,
-            } => AER::BadRequest(ApiError::new("IR", 14, format!("This Payment could not be {current_flow} because it has a {field_name} of {current_value}. The expected state is {states}"), None)),
-            Self::InvalidEphemeralKey => AER::Unauthorized(ApiError::new("IR", 15, "Invalid Ephemeral Key for the customer", None)),
-            Self::PreconditionFailed { message } => {
-                AER::BadRequest(ApiError::new("IR", 16, message.to_string(), None))
-            }
-            Self::InvalidJwtToken => AER::Unauthorized(ApiError::new("IR", 17, "Access forbidden, invalid JWT token was used", None)),
-            Self::GenericUnauthorized { message } => {
-                AER::Unauthorized(ApiError::new("IR", 18, message.to_string(), None))
-            },
-            Self::ClientSecretExpired => AER::BadRequest(ApiError::new(
-                "IR",
-                19,
-                "The provided client_secret has expired", None
-            )),
-            Self::MissingRequiredFields { field_names } => AER::BadRequest(
-                ApiError::new("IR", 21, "Missing required params".to_string(), Some(Extra {data: Some(serde_json::json!(field_names)), ..Default::default() })),
-            ),
-            Self::AccessForbidden => AER::ForbiddenCommonResource(ApiError::new("IR", 22, "Access forbidden. Not authorized to access this resource", None)),
-            Self::FileProviderNotSupported { message } => {
-                AER::BadRequest(ApiError::new("IR", 23, message.to_string(), None))
-            },
-            Self::UnprocessableEntity {entity} => AER::Unprocessable(ApiError::new("IR", 23, format!("{entity} expired or invalid"), None)),
-            Self::ExternalConnectorError {
-                code,
-                message,
-                connector,
-                reason,
-                status_code,
-            } => AER::ConnectorError(ApiError::new("CE", 0, format!("{code}: {message}"), Some(Extra {connector: Some(connector.clone()), reason: reason.clone(), ..Default::default()})), StatusCode::from_u16(*status_code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)),
-            Self::PaymentAuthorizationFailed { data } => {
-                AER::BadRequest(ApiError::new("CE", 1, "Payment failed during authorization with connector. Retry payment", Some(Extra { data: data.clone(), ..Default::default()})))
-            }
-            Self::PaymentAuthenticationFailed { data } => {
-                AER::BadRequest(ApiError::new("CE", 2, "Payment failed during authentication with connector. Retry payment", Some(Extra { data: data.clone(), ..Default::default()})))
-            }
-            Self::PaymentCaptureFailed { data } => {
-                AER::BadRequest(ApiError::new("CE", 3, "Capture attempt failed while processing with connector", Some(Extra { data: data.clone(), ..Default::default()})))
-            }
-            Self::DisputeFailed { data } => {
-                AER::BadRequest(ApiError::new("CE", 1, "Dispute operation failed while processing with connector. Retry operation", Some(Extra { data: data.clone(), ..Default::default()})))
-            }
-            Self::InvalidCardData { data } => AER::BadRequest(ApiError::new("CE", 4, "The card data is invalid", Some(Extra { data: data.clone(), ..Default::default()}))),
-            Self::CardExpired { data } => AER::BadRequest(ApiError::new("CE", 5, "The card has expired", Some(Extra { data: data.clone(), ..Default::default()}))),
-            Self::RefundFailed { data } => AER::BadRequest(ApiError::new("CE", 6, "Refund failed while processing with connector. Retry refund", Some(Extra { data: data.clone(), ..Default::default()}))),
-            Self::VerificationFailed { data } => {
-                AER::BadRequest(ApiError::new("CE", 7, "Verification failed while processing with connector. Retry operation", Some(Extra { data: data.clone(), ..Default::default()})))
-            },
-            Self::MandateUpdateFailed | Self::MandateSerializationFailed | Self::MandateDeserializationFailed | Self::InternalServerError => {
-                AER::InternalServerError(ApiError::new("HE", 0, "Something went wrong", None))
-            }
-            Self::DuplicateRefundRequest => AER::BadRequest(ApiError::new("HE", 1, "Duplicate refund request. Refund already attempted with the refund ID", None)),
-            Self::DuplicateMandate => AER::BadRequest(ApiError::new("HE", 1, "Duplicate mandate request. Mandate already attempted with the Mandate ID", None)),
-            Self::DuplicateMerchantAccount => AER::BadRequest(ApiError::new("HE", 1, "The merchant account with the specified details already exists in our records", None)),
-            Self::DuplicateMerchantConnectorAccount { connector_label } => {
-                AER::BadRequest(ApiError::new("HE", 1, format!("The merchant connector account with the specified connector_label '{connector_label}' already exists in our records"), None))
-            }
-            Self::DuplicatePaymentMethod => AER::BadRequest(ApiError::new("HE", 1, "The payment method with the specified details already exists in our records", None)),
-            Self::DuplicatePayment { payment_id } => {
-                AER::BadRequest(ApiError::new("HE", 1, format!("The payment with the specified payment_id '{payment_id}' already exists in our records"), None))
-            }
-            Self::RefundNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Refund does not exist in our records.", None))
-            }
-            Self::CustomerNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Customer does not exist in our records", None))
-            }
-            Self::ConfigNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Config key does not exist in our records.", None))
-            }
-            Self::PaymentNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Payment does not exist in our records", None))
-            }
-            Self::PaymentMethodNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Payment method does not exist in our records", None))
-            }
-            Self::MerchantAccountNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Merchant account does not exist in our records", None))
-            }
-            Self::MerchantConnectorAccountNotFound { id } => {
-                AER::NotFound(ApiError::new("HE", 2, format!("Merchant connector account with id '{id}' does not exist in our records"), None))
-            }
-            Self::MerchantConnectorAccountDisabled => {
-                AER::BadRequest(ApiError::new("HE", 3, "The selected merchant connector account is disabled", None))
-            }
-            Self::ResourceIdNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Resource ID does not exist in our records", None))
-            }
-            Self::MandateNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "Mandate does not exist in our records", None))
-            }
-            Self::ReturnUrlUnavailable => AER::NotFound(ApiError::new("HE", 3, "Return URL is not configured and not passed in payments request", None)),
-            Self::RefundNotPossible { connector } => {
-                AER::BadRequest(ApiError::new("HE", 3, format!("This refund is not possible through Hyperswitch. Please raise the refund through {connector} dashboard"), None))
-            }
-            Self::MandateValidationFailed { reason } => {
-                AER::BadRequest(ApiError::new("HE", 3, "Mandate Validation Failed", Some(Extra { reason: Some(reason.clone()), ..Default::default() })))
-            }
-            Self::PaymentNotSucceeded => AER::BadRequest(ApiError::new("HE", 3, "The payment has not succeeded yet. Please pass a successful payment to initiate refund", None)),
-            Self::SuccessfulPaymentNotFound => {
-                AER::NotFound(ApiError::new("HE", 4, "Successful payment not found for the given payment id", None))
-            }
-            Self::IncorrectConnectorNameGiven => {
-                AER::NotFound(ApiError::new("HE", 4, "The connector provided in the request is incorrect or not available", None))
-            }
-            Self::AddressNotFound => {
-                AER::NotFound(ApiError::new("HE", 4, "Address does not exist in our records", None))
-            },
-            Self::GenericNotFoundError { message } => {
-                AER::NotFound(ApiError::new("HE", 5, message, None))
-            },
-            Self::ApiKeyNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "API Key does not exist in our records", None))
-            }
-            Self::NotSupported { message } => {
-                AER::BadRequest(ApiError::new("HE", 3, "Payment method type not supported", Some(Extra {reason: Some(message.to_owned()), ..Default::default()})))
-            },
-            Self::InvalidCardIin => AER::BadRequest(ApiError::new("HE", 3, "The provided card IIN does not exist", None)),
-            Self::InvalidCardIinLength  => AER::BadRequest(ApiError::new("HE", 3, "The provided card IIN length is invalid, please provide an IIN with 6 digits", None)),
-            Self::FlowNotSupported { flow, connector } => {
-                AER::BadRequest(ApiError::new("IR", 20, format!("{flow} flow not supported"), Some(Extra {connector: Some(connector.to_owned()), ..Default::default()}))) //FIXME: error message
-            }
-            Self::DisputeNotFound { .. } => {
-                AER::NotFound(ApiError::new("HE", 2, "Dispute does not exist in our records", None))
-            }
-            Self::FileNotFound => {
-                AER::NotFound(ApiError::new("HE", 2, "File does not exist in our records", None))
-            }
-            Self::FileNotAvailable => {
-                AER::NotFound(ApiError::new("HE", 2, "File not available", None))
-            }
-            Self::DisputeStatusValidationFailed { .. } => {
-                AER::BadRequest(ApiError::new("HE", 2, "Dispute status validation failed", None))
-            }
-            Self::FileValidationFailed { reason } => {
-                AER::BadRequest(ApiError::new("HE", 2, format!("File validation failed {reason}"), None))
-            }
-            Self::MissingFile => {
-                AER::BadRequest(ApiError::new("HE", 2, "File not found in the request", None))
-            }
-            Self::MissingFilePurpose => {
-                AER::BadRequest(ApiError::new("HE", 2, "File purpose not found in the request or is invalid", None))
-            }
-            Self::MissingFileContentType => {
-                AER::BadRequest(ApiError::new("HE", 2, "File content type not found", None))
-            }
-            Self::MissingDisputeId => {
-                AER::BadRequest(ApiError::new("HE", 2, "Dispute id not found in the request", None))
-            }
-            Self::WebhookAuthenticationFailed => {
-                AER::Unauthorized(ApiError::new("WE", 1, "Webhook authentication failed", None))
-            }
-            Self::WebhookResourceNotFound => {
-                AER::NotFound(ApiError::new("WE", 4, "Webhook resource was not found", None))
-            }
-            Self::WebhookBadRequest => {
-                AER::BadRequest(ApiError::new("WE", 2, "Bad request body received", None))
-            }
-            Self::WebhookProcessingFailure => {
-                AER::InternalServerError(ApiError::new("WE", 3, "There was an issue processing the webhook", None))
-            },
-            Self::IncorrectPaymentMethodConfiguration => {
-                AER::BadRequest(ApiError::new("HE", 4, "No eligible connector was found for the current payment method configuration", None))
-            }
-            Self::WebhookUnprocessableEntity => {
-                AER::Unprocessable(ApiError::new("WE", 5, "There was an issue processing the webhook body", None))
-            }
-        }
-    }
-}
diff --git a/crates/router/src/core/errors/transformers.rs b/crates/router/src/core/errors/transformers.rs
new file mode 100644
index 00000000000..facc453c587
--- /dev/null
+++ b/crates/router/src/core/errors/transformers.rs
@@ -0,0 +1,255 @@
+use api_models::errors::types::Extra;
+use common_utils::errors::ErrorSwitch;
+use http::StatusCode;
+
+use super::{ApiErrorResponse, ConnectorError};
+
+impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ApiErrorResponse {
+    fn switch(&self) -> api_models::errors::types::ApiErrorResponse {
+        use api_models::errors::types::{ApiError, ApiErrorResponse as AER};
+
+        match self {
+            Self::NotImplemented { message } => {
+                AER::NotImplemented(ApiError::new("IR", 0, format!("{message:?}"), None))
+            }
+            Self::Unauthorized => AER::Unauthorized(ApiError::new(
+                "IR",
+                1,
+                "API key not provided or invalid API key used", None
+            )),
+            Self::InvalidRequestUrl => {
+                AER::NotFound(ApiError::new("IR", 2, "Unrecognized request URL", None))
+            }
+            Self::InvalidHttpMethod => AER::MethodNotAllowed(ApiError::new(
+                "IR",
+                3,
+                "The HTTP method is not applicable for this API", None
+            )),
+            Self::MissingRequiredField { field_name } => AER::BadRequest(
+                ApiError::new("IR", 4, format!("Missing required param: {field_name}"), None),
+            ),
+            Self::InvalidDataFormat {
+                field_name,
+                expected_format,
+            } => AER::Unprocessable(ApiError::new(
+                "IR",
+                5,
+                format!(
+                    "{field_name} contains invalid data. Expected format is {expected_format}"
+                ), None
+            )),
+            Self::InvalidRequestData { message } => {
+                AER::Unprocessable(ApiError::new("IR", 6, message.to_string(), None))
+            }
+            Self::InvalidDataValue { field_name } => AER::BadRequest(ApiError::new(
+                "IR",
+                7,
+                format!("Invalid value provided: {field_name}"), None
+            )),
+            Self::ClientSecretNotGiven => AER::BadRequest(ApiError::new(
+                "IR",
+                8,
+                "client_secret was not provided", None
+            )),
+            Self::ClientSecretInvalid => {
+                AER::BadRequest(ApiError::new("IR", 9, "The client_secret provided does not match the client_secret associated with the Payment", None))
+            }
+            Self::MandateActive => {
+                AER::BadRequest(ApiError::new("IR", 10, "Customer has active mandate/subsciption", None))
+            }
+            Self::CustomerRedacted => {
+                AER::BadRequest(ApiError::new("IR", 11, "Customer has already been redacted", None))
+            }
+            Self::MaximumRefundCount => AER::BadRequest(ApiError::new("IR", 12, "Reached maximum refund attempts", None)),
+            Self::RefundAmountExceedsPaymentAmount => {
+                AER::BadRequest(ApiError::new("IR", 13, "Refund amount exceeds the payment amount", None))
+            }
+            Self::PaymentUnexpectedState {
+                current_flow,
+                field_name,
+                current_value,
+                states,
+            } => AER::BadRequest(ApiError::new("IR", 14, format!("This Payment could not be {current_flow} because it has a {field_name} of {current_value}. The expected state is {states}"), None)),
+            Self::InvalidEphemeralKey => AER::Unauthorized(ApiError::new("IR", 15, "Invalid Ephemeral Key for the customer", None)),
+            Self::PreconditionFailed { message } => {
+                AER::BadRequest(ApiError::new("IR", 16, message.to_string(), None))
+            }
+            Self::InvalidJwtToken => AER::Unauthorized(ApiError::new("IR", 17, "Access forbidden, invalid JWT token was used", None)),
+            Self::GenericUnauthorized { message } => {
+                AER::Unauthorized(ApiError::new("IR", 18, message.to_string(), None))
+            },
+            Self::ClientSecretExpired => AER::BadRequest(ApiError::new(
+                "IR",
+                19,
+                "The provided client_secret has expired", None
+            )),
+            Self::MissingRequiredFields { field_names } => AER::BadRequest(
+                ApiError::new("IR", 21, "Missing required params".to_string(), Some(Extra {data: Some(serde_json::json!(field_names)), ..Default::default() })),
+            ),
+            Self::AccessForbidden => AER::ForbiddenCommonResource(ApiError::new("IR", 22, "Access forbidden. Not authorized to access this resource", None)),
+            Self::FileProviderNotSupported { message } => {
+                AER::BadRequest(ApiError::new("IR", 23, message.to_string(), None))
+            },
+            Self::UnprocessableEntity {entity} => AER::Unprocessable(ApiError::new("IR", 23, format!("{entity} expired or invalid"), None)),
+            Self::ExternalConnectorError {
+                code,
+                message,
+                connector,
+                reason,
+                status_code,
+            } => AER::ConnectorError(ApiError::new("CE", 0, format!("{code}: {message}"), Some(Extra {connector: Some(connector.clone()), reason: reason.clone(), ..Default::default()})), StatusCode::from_u16(*status_code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)),
+            Self::PaymentAuthorizationFailed { data } => {
+                AER::BadRequest(ApiError::new("CE", 1, "Payment failed during authorization with connector. Retry payment", Some(Extra { data: data.clone(), ..Default::default()})))
+            }
+            Self::PaymentAuthenticationFailed { data } => {
+                AER::BadRequest(ApiError::new("CE", 2, "Payment failed during authentication with connector. Retry payment", Some(Extra { data: data.clone(), ..Default::default()})))
+            }
+            Self::PaymentCaptureFailed { data } => {
+                AER::BadRequest(ApiError::new("CE", 3, "Capture attempt failed while processing with connector", Some(Extra { data: data.clone(), ..Default::default()})))
+            }
+            Self::DisputeFailed { data } => {
+                AER::BadRequest(ApiError::new("CE", 1, "Dispute operation failed while processing with connector. Retry operation", Some(Extra { data: data.clone(), ..Default::default()})))
+            }
+            Self::InvalidCardData { data } => AER::BadRequest(ApiError::new("CE", 4, "The card data is invalid", Some(Extra { data: data.clone(), ..Default::default()}))),
+            Self::CardExpired { data } => AER::BadRequest(ApiError::new("CE", 5, "The card has expired", Some(Extra { data: data.clone(), ..Default::default()}))),
+            Self::RefundFailed { data } => AER::BadRequest(ApiError::new("CE", 6, "Refund failed while processing with connector. Retry refund", Some(Extra { data: data.clone(), ..Default::default()}))),
+            Self::VerificationFailed { data } => {
+                AER::BadRequest(ApiError::new("CE", 7, "Verification failed while processing with connector. Retry operation", Some(Extra { data: data.clone(), ..Default::default()})))
+            },
+            Self::MandateUpdateFailed | Self::MandateSerializationFailed | Self::MandateDeserializationFailed | Self::InternalServerError => {
+                AER::InternalServerError(ApiError::new("HE", 0, "Something went wrong", None))
+            }
+            Self::DuplicateRefundRequest => AER::BadRequest(ApiError::new("HE", 1, "Duplicate refund request. Refund already attempted with the refund ID", None)),
+            Self::DuplicateMandate => AER::BadRequest(ApiError::new("HE", 1, "Duplicate mandate request. Mandate already attempted with the Mandate ID", None)),
+            Self::DuplicateMerchantAccount => AER::BadRequest(ApiError::new("HE", 1, "The merchant account with the specified details already exists in our records", None)),
+            Self::DuplicateMerchantConnectorAccount { connector_label } => {
+                AER::BadRequest(ApiError::new("HE", 1, format!("The merchant connector account with the specified connector_label '{connector_label}' already exists in our records"), None))
+            }
+            Self::DuplicatePaymentMethod => AER::BadRequest(ApiError::new("HE", 1, "The payment method with the specified details already exists in our records", None)),
+            Self::DuplicatePayment { payment_id } => {
+                AER::BadRequest(ApiError::new("HE", 1, format!("The payment with the specified payment_id '{payment_id}' already exists in our records"), None))
+            }
+            Self::RefundNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Refund does not exist in our records.", None))
+            }
+            Self::CustomerNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Customer does not exist in our records", None))
+            }
+            Self::ConfigNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Config key does not exist in our records.", None))
+            }
+            Self::PaymentNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Payment does not exist in our records", None))
+            }
+            Self::PaymentMethodNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Payment method does not exist in our records", None))
+            }
+            Self::MerchantAccountNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Merchant account does not exist in our records", None))
+            }
+            Self::MerchantConnectorAccountNotFound { id } => {
+                AER::NotFound(ApiError::new("HE", 2, format!("Merchant connector account with id '{id}' does not exist in our records"), None))
+            }
+            Self::MerchantConnectorAccountDisabled => {
+                AER::BadRequest(ApiError::new("HE", 3, "The selected merchant connector account is disabled", None))
+            }
+            Self::ResourceIdNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Resource ID does not exist in our records", None))
+            }
+            Self::MandateNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "Mandate does not exist in our records", None))
+            }
+            Self::ReturnUrlUnavailable => AER::NotFound(ApiError::new("HE", 3, "Return URL is not configured and not passed in payments request", None)),
+            Self::RefundNotPossible { connector } => {
+                AER::BadRequest(ApiError::new("HE", 3, format!("This refund is not possible through Hyperswitch. Please raise the refund through {connector} dashboard"), None))
+            }
+            Self::MandateValidationFailed { reason } => {
+                AER::BadRequest(ApiError::new("HE", 3, "Mandate Validation Failed", Some(Extra { reason: Some(reason.clone()), ..Default::default() })))
+            }
+            Self::PaymentNotSucceeded => AER::BadRequest(ApiError::new("HE", 3, "The payment has not succeeded yet. Please pass a successful payment to initiate refund", None)),
+            Self::SuccessfulPaymentNotFound => {
+                AER::NotFound(ApiError::new("HE", 4, "Successful payment not found for the given payment id", None))
+            }
+            Self::IncorrectConnectorNameGiven => {
+                AER::NotFound(ApiError::new("HE", 4, "The connector provided in the request is incorrect or not available", None))
+            }
+            Self::AddressNotFound => {
+                AER::NotFound(ApiError::new("HE", 4, "Address does not exist in our records", None))
+            },
+            Self::GenericNotFoundError { message } => {
+                AER::NotFound(ApiError::new("HE", 5, message, None))
+            },
+            Self::ApiKeyNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "API Key does not exist in our records", None))
+            }
+            Self::NotSupported { message } => {
+                AER::BadRequest(ApiError::new("HE", 3, "Payment method type not supported", Some(Extra {reason: Some(message.to_owned()), ..Default::default()})))
+            },
+            Self::InvalidCardIin => AER::BadRequest(ApiError::new("HE", 3, "The provided card IIN does not exist", None)),
+            Self::InvalidCardIinLength  => AER::BadRequest(ApiError::new("HE", 3, "The provided card IIN length is invalid, please provide an IIN with 6 digits", None)),
+            Self::FlowNotSupported { flow, connector } => {
+                AER::BadRequest(ApiError::new("IR", 20, format!("{flow} flow not supported"), Some(Extra {connector: Some(connector.to_owned()), ..Default::default()}))) //FIXME: error message
+            }
+            Self::DisputeNotFound { .. } => {
+                AER::NotFound(ApiError::new("HE", 2, "Dispute does not exist in our records", None))
+            }
+            Self::FileNotFound => {
+                AER::NotFound(ApiError::new("HE", 2, "File does not exist in our records", None))
+            }
+            Self::FileNotAvailable => {
+                AER::NotFound(ApiError::new("HE", 2, "File not available", None))
+            }
+            Self::DisputeStatusValidationFailed { .. } => {
+                AER::BadRequest(ApiError::new("HE", 2, "Dispute status validation failed", None))
+            }
+            Self::FileValidationFailed { reason } => {
+                AER::BadRequest(ApiError::new("HE", 2, format!("File validation failed {reason}"), None))
+            }
+            Self::MissingFile => {
+                AER::BadRequest(ApiError::new("HE", 2, "File not found in the request", None))
+            }
+            Self::MissingFilePurpose => {
+                AER::BadRequest(ApiError::new("HE", 2, "File purpose not found in the request or is invalid", None))
+            }
+            Self::MissingFileContentType => {
+                AER::BadRequest(ApiError::new("HE", 2, "File content type not found", None))
+            }
+            Self::MissingDisputeId => {
+                AER::BadRequest(ApiError::new("HE", 2, "Dispute id not found in the request", None))
+            }
+            Self::WebhookAuthenticationFailed => {
+                AER::Unauthorized(ApiError::new("WE", 1, "Webhook authentication failed", None))
+            }
+            Self::WebhookResourceNotFound => {
+                AER::NotFound(ApiError::new("WE", 4, "Webhook resource was not found", None))
+            }
+            Self::WebhookBadRequest => {
+                AER::BadRequest(ApiError::new("WE", 2, "Bad request body received", None))
+            }
+            Self::WebhookProcessingFailure => {
+                AER::InternalServerError(ApiError::new("WE", 3, "There was an issue processing the webhook", None))
+            },
+            Self::IncorrectPaymentMethodConfiguration => {
+                AER::BadRequest(ApiError::new("HE", 4, "No eligible connector was found for the current payment method configuration", None))
+            }
+            Self::WebhookUnprocessableEntity => {
+                AER::Unprocessable(ApiError::new("WE", 5, "There was an issue processing the webhook body", None))
+            }
+        }
+    }
+}
+
+impl ErrorSwitch<ApiErrorResponse> for ConnectorError {
+    fn switch(&self) -> ApiErrorResponse {
+        match self {
+            Self::WebhookSourceVerificationFailed => ApiErrorResponse::WebhookAuthenticationFailed,
+            Self::WebhookSignatureNotFound
+            | Self::WebhookReferenceIdNotFound
+            | Self::WebhookResourceObjectNotFound
+            | Self::WebhookBodyDecodingFailed
+            | Self::WebhooksNotImplemented => ApiErrorResponse::WebhookBadRequest,
+            Self::WebhookEventTypeNotFound => ApiErrorResponse::WebhookUnprocessableEntity,
+            _ => ApiErrorResponse::InternalServerError,
+        }
+    }
+}
diff --git a/crates/router/src/core/webhooks.rs b/crates/router/src/core/webhooks.rs
index 7cf8dc9c3f0..6ab62632e0f 100644
--- a/crates/router/src/core/webhooks.rs
+++ b/crates/router/src/core/webhooks.rs
@@ -1,10 +1,10 @@
 pub mod types;
 pub mod utils;
 
+use common_utils::errors::ReportSwitchExt;
 use error_stack::{report, IntoReport, ResultExt};
 use masking::ExposeInterface;
 use router_env::{instrument, tracing};
-use utils::WebhookApiErrorSwitch;
 
 use super::{errors::StorageErrorExt, metrics};
 use crate::{
diff --git a/crates/router/src/core/webhooks/utils.rs b/crates/router/src/core/webhooks/utils.rs
index 35bca6c30c0..5826216b16b 100644
--- a/crates/router/src/core/webhooks/utils.rs
+++ b/crates/router/src/core/webhooks/utils.rs
@@ -1,7 +1,4 @@
-use error_stack::ResultExt;
-
 use crate::{
-    core::errors,
     db::{get_and_deserialize_key, StorageInterface},
     types::api,
 };
@@ -48,34 +45,3 @@ pub async fn lookup_webhook_event(
         }
     }
 }
-
-pub trait WebhookApiErrorSwitch<T> {
-    fn switch(self) -> errors::RouterResult<T>;
-}
-
-impl<T> WebhookApiErrorSwitch<T> for errors::CustomResult<T, errors::ConnectorError> {
-    fn switch(self) -> errors::RouterResult<T> {
-        match self {
-            Ok(res) => Ok(res),
-            Err(e) => match e.current_context() {
-                errors::ConnectorError::WebhookSourceVerificationFailed => {
-                    Err(e).change_context(errors::ApiErrorResponse::WebhookAuthenticationFailed)
-                }
-
-                errors::ConnectorError::WebhookSignatureNotFound
-                | errors::ConnectorError::WebhookReferenceIdNotFound
-                | errors::ConnectorError::WebhookResourceObjectNotFound
-                | errors::ConnectorError::WebhookBodyDecodingFailed
-                | errors::ConnectorError::WebhooksNotImplemented => {
-                    Err(e).change_context(errors::ApiErrorResponse::WebhookBadRequest)
-                }
-
-                errors::ConnectorError::WebhookEventTypeNotFound => {
-                    Err(e).change_context(errors::ApiErrorResponse::WebhookUnprocessableEntity)
-                }
-
-                _ => Err(e).change_context(errors::ApiErrorResponse::InternalServerError),
-            },
-        }
-    }
-}

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->


### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless its an obvious bug or documentation fix
that will have little conversation).
-->
Refactor error mapping with WebhookApiErrorSwitch to make use of the existing `ErrorSwitch` trait which satisfies the same usecase.
Closes #1326


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [ ] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
