Bug: feat(Connector): [Noon] Add Cards payments, Refunds, Capture and Void



### Feature Description

AddSupport for payments with Non-3DS cards via Noon.
Includes: 

- [Authorize](https://docs.noonpayments.com/payment-api/reference/initiate)
- [Capture](https://docs.noonpayments.com/payment-api/reference/capture)
- [Void](https://docs.noonpayments.com/payment-api/reference/reverse)
- [Refund](https://docs.noonpayments.com/payment-api/reference/refund)

### Possible Implementation

Add all the flows in the connector files for Noon

### 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?

Yes I am willing to submit a PR!
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index 0b1726daaa7..f91732cfa73 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -616,7 +616,7 @@ pub enum Connector {
     Multisafepay,
     Nexinets,
     Nmi,
-    // Noon, added as template code for future usage
+    Noon,
     Nuvei,
     // Payeezy, As psync and rsync are not supported by this connector, it is added as template code for future usage
     Paypal,
@@ -698,7 +698,7 @@ pub enum RoutableConnectors {
     Multisafepay,
     Nexinets,
     Nmi,
-    // Noon, added as template code for future usage
+    Noon,
     Nuvei,
     Opennode,
     // Payeezy, As psync and rsync are not supported by this connector, it is added as template code for future usage
diff --git a/crates/router/src/connector/noon.rs b/crates/router/src/connector/noon.rs
index 2be0faddbc6..06dde9243bf 100644
--- a/crates/router/src/connector/noon.rs
+++ b/crates/router/src/connector/noon.rs
@@ -2,12 +2,18 @@ mod transformers;
 
 use std::fmt::Debug;
 
+use base64::Engine;
 use error_stack::{IntoReport, ResultExt};
 use transformers as noon;
 
+use super::utils::PaymentsSyncRequestData;
 use crate::{
     configs::settings,
-    core::errors::{self, CustomResult},
+    consts,
+    core::{
+        errors::{self, CustomResult},
+        payments,
+    },
     headers,
     services::{self, ConnectorIntegration},
     types::{
@@ -80,9 +86,16 @@ impl ConnectorCommon for Noon {
         &self,
         auth_type: &types::ConnectorAuthType,
     ) -> CustomResult<Vec<(String, String)>, errors::ConnectorError> {
-        let auth = noon::NoonAuthType::try_from(auth_type)
-            .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
-        Ok(vec![(headers::AUTHORIZATION.to_string(), auth.api_key)])
+        let auth = noon::NoonAuthType::try_from(auth_type)?;
+
+        let encoded_api_key = consts::BASE64_ENGINE.encode(format!(
+            "{}.{}:{}",
+            auth.business_identifier, auth.application_identifier, auth.api_key
+        ));
+        Ok(vec![(
+            headers::AUTHORIZATION.to_string(),
+            format!("Key_Test {encoded_api_key}"),
+        )])
     }
 
     fn build_error_response(
@@ -96,9 +109,9 @@ impl ConnectorCommon for Noon {
 
         Ok(ErrorResponse {
             status_code: res.status_code,
-            code: response.code,
+            code: response.result_code.to_string(),
             message: response.message,
-            reason: response.reason,
+            reason: Some(response.class_description),
         })
     }
 }
@@ -137,9 +150,9 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
     fn get_url(
         &self,
         _req: &types::PaymentsAuthorizeRouterData,
-        _connectors: &settings::Connectors,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!("{}payment/v1/order", self.base_url(connectors)))
     }
 
     fn get_request_body(
@@ -187,7 +200,6 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -215,10 +227,14 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
 
     fn get_url(
         &self,
-        _req: &types::PaymentsSyncRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::PaymentsSyncRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let connector_transaction_id = req.request.get_connector_transaction_id()?;
+        Ok(format!(
+            "{}payment/v1/order/{connector_transaction_id}",
+            self.base_url(connectors)
+        ))
     }
 
     fn build_request(
@@ -250,7 +266,6 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -279,16 +294,20 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
     fn get_url(
         &self,
         _req: &types::PaymentsCaptureRouterData,
-        _connectors: &settings::Connectors,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!("{}payment/v1/order", self.base_url(connectors)))
     }
 
     fn get_request_body(
         &self,
-        _req: &types::PaymentsCaptureRouterData,
+        req: &types::PaymentsCaptureRouterData,
     ) -> CustomResult<Option<String>, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into())
+        let req_obj = noon::NoonPaymentsActionRequest::try_from(req)?;
+        let noon_req =
+            utils::Encode::<noon::NoonPaymentsRequest>::encode_to_string_of_json(&req_obj)
+                .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        Ok(Some(noon_req))
     }
 
     fn build_request(
@@ -323,7 +342,6 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -337,6 +355,75 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
 impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsResponseData>
     for Noon
 {
+    fn get_headers(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Vec<(String, String)>, errors::ConnectorError> {
+        self.build_headers(req, connectors)
+    }
+
+    fn get_content_type(&self) -> &'static str {
+        self.common_get_content_type()
+    }
+
+    fn get_url(
+        &self,
+        _req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        Ok(format!("{}payment/v1/order", self.base_url(connectors)))
+    }
+    fn get_request_body(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+    ) -> CustomResult<Option<String>, errors::ConnectorError> {
+        let connector_req = noon::NoonPaymentsCancelRequest::try_from(req)?;
+        let noon_req = utils::Encode::<noon::NoonPaymentsCancelRequest>::encode_to_string_of_json(
+            &connector_req,
+        )
+        .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        Ok(Some(noon_req))
+    }
+
+    fn build_request(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
+        Ok(Some(
+            services::RequestBuilder::new()
+                .method(services::Method::Post)
+                .url(&types::PaymentsVoidType::get_url(self, req, connectors)?)
+                .attach_default_headers()
+                .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?)
+                .body(types::PaymentsVoidType::get_request_body(self, req)?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &types::PaymentsCancelRouterData,
+        res: Response,
+    ) -> CustomResult<types::PaymentsCancelRouterData, errors::ConnectorError> {
+        let response: noon::NoonPaymentsResponse = res
+            .response
+            .parse_struct("Noon PaymentsCancelResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+        types::RouterData::try_from(types::ResponseRouterData {
+            response,
+            data: data.clone(),
+            http_code: res.status_code,
+        })
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res)
+    }
 }
 
 impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData> for Noon {
@@ -355,18 +442,19 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
     fn get_url(
         &self,
         _req: &types::RefundsRouterData<api::Execute>,
-        _connectors: &settings::Connectors,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!("{}payment/v1/order", self.base_url(connectors)))
     }
 
     fn get_request_body(
         &self,
         req: &types::RefundsRouterData<api::Execute>,
     ) -> CustomResult<Option<String>, errors::ConnectorError> {
-        let req_obj = noon::NoonRefundRequest::try_from(req)?;
-        let noon_req = utils::Encode::<noon::NoonRefundRequest>::encode_to_string_of_json(&req_obj)
-            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        let req_obj = noon::NoonPaymentsActionRequest::try_from(req)?;
+        let noon_req =
+            utils::Encode::<noon::NoonPaymentsActionRequest>::encode_to_string_of_json(&req_obj)
+                .change_context(errors::ConnectorError::RequestEncodingFailed)?;
         Ok(Some(noon_req))
     }
 
@@ -401,7 +489,6 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -427,10 +514,14 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
 
     fn get_url(
         &self,
-        _req: &types::RefundSyncRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::RefundSyncRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!(
+            "{}payment/v1/order/{}",
+            self.base_url(connectors),
+            req.request.connector_transaction_id
+        ))
     }
 
     fn build_request(
@@ -454,10 +545,11 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
         data: &types::RefundSyncRouterData,
         res: Response,
     ) -> CustomResult<types::RefundSyncRouterData, errors::ConnectorError> {
-        let response: noon::RefundResponse =
-            res.response
-                .parse_struct("noon RefundSyncResponse")
-                .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+        let response: noon::RefundSyncResponse = res
+            .response
+            .parse_struct("noon RefundSyncResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+
         types::RouterData::try_from(types::ResponseRouterData {
             response,
             data: data.clone(),
@@ -474,6 +566,17 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
     }
 }
 
+impl services::ConnectorRedirectResponse for Noon {
+    fn get_flow_type(
+        &self,
+        _query_params: &str,
+        _json_payload: Option<serde_json::Value>,
+        _action: services::PaymentAction,
+    ) -> CustomResult<payments::CallConnectorAction, errors::ConnectorError> {
+        Ok(payments::CallConnectorAction::Trigger)
+    }
+}
+
 #[async_trait::async_trait]
 impl api::IncomingWebhook for Noon {
     fn get_webhook_object_reference_id(
diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs
index da00cfeee52..71a5ce81f2e 100644
--- a/crates/router/src/connector/noon/transformers.rs
+++ b/crates/router/src/connector/noon/transformers.rs
@@ -2,94 +2,192 @@ use masking::Secret;
 use serde::{Deserialize, Serialize};
 
 use crate::{
-    connector::utils::PaymentsAuthorizeRequestData,
+    connector::utils::{
+        self as conn_utils, PaymentsAuthorizeRequestData, RefundsRequestData, RouterData,
+    },
     core::errors,
+    services,
     types::{self, api, storage::enums},
 };
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
-pub struct NoonPaymentsRequest {
-    amount: i64,
-    card: NoonCard,
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum NoonChannels {
+    Web,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonOrder {
+    amount: String,
+    currency: storage_models::enums::Currency,
+    channel: NoonChannels,
+    category: String,
+    //Short description of the order.
+    name: String,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum NoonPaymentActions {
+    Authorize,
+    Sale,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonConfiguration {
+    payment_action: NoonPaymentActions,
+    return_url: Option<String>,
 }
 
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
 pub struct NoonCard {
-    name: Secret<String>,
-    number: cards::CardNumber,
+    name_on_card: Secret<String>,
+    number_plain: cards::CardNumber,
     expiry_month: Secret<String>,
     expiry_year: Secret<String>,
-    cvc: Secret<String>,
-    complete: bool,
+    cvv: Secret<String>,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(tag = "type", content = "data")]
+pub enum NoonPaymentData {
+    Card(NoonCard),
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum NoonApiOperations {
+    Initiate,
+    Capture,
+    Reverse,
+    Refund,
+}
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonPaymentsRequest {
+    api_operation: NoonApiOperations,
+    order: NoonOrder,
+    configuration: NoonConfiguration,
+    payment_data: NoonPaymentData,
 }
 
 impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
-        match item.request.payment_method_data.clone() {
-            api::PaymentMethodData::Card(req_card) => {
-                let card = NoonCard {
-                    name: req_card.card_holder_name,
-                    number: req_card.card_number,
-                    expiry_month: req_card.card_exp_month,
-                    expiry_year: req_card.card_exp_year,
-                    cvc: req_card.card_cvc,
-                    complete: item.request.is_auto_capture()?,
-                };
-                Ok(Self {
-                    amount: item.request.amount,
-                    card,
-                })
-            }
-            _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
-        }
+        let payment_data = match item.request.payment_method_data.clone() {
+            api::PaymentMethodData::Card(req_card) => Ok(NoonPaymentData::Card(NoonCard {
+                name_on_card: req_card.card_holder_name,
+                number_plain: req_card.card_number,
+                expiry_month: req_card.card_exp_month,
+                expiry_year: req_card.card_exp_year,
+                cvv: req_card.card_cvc,
+            })),
+            _ => Err(errors::ConnectorError::NotImplemented(
+                "Payment methods".to_string(),
+            )),
+        }?;
+
+        let order = NoonOrder {
+            amount: conn_utils::to_currency_base_unit(item.request.amount, item.request.currency)?,
+            currency: item.request.currency,
+            channel: NoonChannels::Web,
+            category: "pay".to_string(),
+            name: item.get_description()?,
+        };
+        let payment_action = if item.request.is_auto_capture()? {
+            NoonPaymentActions::Sale
+        } else {
+            NoonPaymentActions::Authorize
+        };
+        Ok(Self {
+            api_operation: NoonApiOperations::Initiate,
+            order,
+            configuration: NoonConfiguration {
+                payment_action,
+                return_url: item.request.router_return_url.clone(),
+            },
+            payment_data,
+        })
     }
 }
 
-//TODO: Fill the struct with respective fields
 // Auth Struct
 pub struct NoonAuthType {
     pub(super) api_key: String,
+    pub(super) application_identifier: String,
+    pub(super) business_identifier: String,
 }
 
 impl TryFrom<&types::ConnectorAuthType> for NoonAuthType {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
         match auth_type {
-            types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
+            types::ConnectorAuthType::SignatureKey {
+                api_key,
+                key1,
+                api_secret,
+            } => Ok(Self {
                 api_key: api_key.to_string(),
+                application_identifier: api_secret.to_string(),
+                business_identifier: key1.to_string(),
             }),
             _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
         }
     }
 }
-// PaymentsResponse
-//TODO: Append the remaining status flags
-#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "lowercase")]
+#[derive(Default, Debug, Deserialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 pub enum NoonPaymentStatus {
-    Succeeded,
+    Authorized,
+    Captured,
+    PartiallyCaptured,
+    Reversed,
+    #[serde(rename = "3DS_ENROLL_INITIATED")]
+    ThreeDsEnrollInitiated,
     Failed,
     #[default]
-    Processing,
+    Pending,
 }
 
 impl From<NoonPaymentStatus> for enums::AttemptStatus {
     fn from(item: NoonPaymentStatus) -> Self {
         match item {
-            NoonPaymentStatus::Succeeded => Self::Charged,
+            NoonPaymentStatus::Authorized => Self::Authorized,
+            NoonPaymentStatus::Captured | NoonPaymentStatus::PartiallyCaptured => Self::Charged,
+            NoonPaymentStatus::Reversed => Self::Voided,
+            NoonPaymentStatus::ThreeDsEnrollInitiated => Self::AuthenticationPending,
             NoonPaymentStatus::Failed => Self::Failure,
-            NoonPaymentStatus::Processing => Self::Authorizing,
+            NoonPaymentStatus::Pending => Self::Pending,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct NoonPaymentsResponse {
+#[derive(Default, Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonPaymentsOrderResponse {
     status: NoonPaymentStatus,
-    id: String,
+    id: u64,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonCheckoutData {
+    post_url: url::Url,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonPaymentsResponseResult {
+    order: NoonPaymentsOrderResponse,
+    checkout_data: Option<NoonCheckoutData>,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct NoonPaymentsResponse {
+    result: NoonPaymentsResponseResult,
 }
 
 impl<F, T>
@@ -100,11 +198,20 @@ impl<F, T>
     fn try_from(
         item: types::ResponseRouterData<F, NoonPaymentsResponse, T, types::PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
+        let redirection_data = item.response.result.checkout_data.map(|redirection_data| {
+            services::RedirectForm::Form {
+                endpoint: redirection_data.post_url.to_string(),
+                method: services::Method::Post,
+                form_fields: std::collections::HashMap::new(),
+            }
+        });
         Ok(Self {
-            status: enums::AttemptStatus::from(item.response.status),
+            status: enums::AttemptStatus::from(item.response.result.order.status),
             response: Ok(types::PaymentsResponseData::TransactionResponse {
-                resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
-                redirection_data: None,
+                resource_id: types::ResponseId::ConnectorTransactionId(
+                    item.response.result.order.id.to_string(),
+                ),
+                redirection_data,
                 mandate_reference: None,
                 connector_metadata: None,
                 network_txn_id: None,
@@ -114,52 +221,125 @@ impl<F, T>
     }
 }
 
-//TODO: Fill the struct with respective fields
-// REFUND :
-// Type definition for RefundRequest
-#[derive(Default, Debug, Serialize)]
-pub struct NoonRefundRequest {
-    pub amount: i64,
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonActionTransaction {
+    amount: String,
+    currency: storage_models::enums::Currency,
 }
 
-impl<F> TryFrom<&types::RefundsRouterData<F>> for NoonRefundRequest {
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonActionOrder {
+    id: String,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonPaymentsActionRequest {
+    api_operation: NoonApiOperations,
+    order: NoonActionOrder,
+    transaction: NoonActionTransaction,
+}
+
+impl TryFrom<&types::PaymentsCaptureRouterData> for NoonPaymentsActionRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
+    fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> {
+        let order = NoonActionOrder {
+            id: item.request.connector_transaction_id.clone(),
+        };
+        let transaction = NoonActionTransaction {
+            amount: conn_utils::to_currency_base_unit(
+                item.request.amount_to_capture,
+                item.request.currency,
+            )?,
+            currency: item.request.currency,
+        };
+        Ok(Self {
+            api_operation: NoonApiOperations::Capture,
+            order,
+            transaction,
+        })
+    }
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonPaymentsCancelRequest {
+    api_operation: NoonApiOperations,
+    order: NoonActionOrder,
+}
+
+impl TryFrom<&types::PaymentsCancelRouterData> for NoonPaymentsCancelRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
+        let order = NoonActionOrder {
+            id: item.request.connector_transaction_id.clone(),
+        };
         Ok(Self {
-            amount: item.request.amount,
+            api_operation: NoonApiOperations::Reverse,
+            order,
         })
     }
 }
 
-// Type definition for Refund Response
+impl<F> TryFrom<&types::RefundsRouterData<F>> for NoonPaymentsActionRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
+        let order = NoonActionOrder {
+            id: item.request.connector_transaction_id.clone(),
+        };
+        let transaction = NoonActionTransaction {
+            amount: conn_utils::to_currency_base_unit(
+                item.request.refund_amount,
+                item.request.currency,
+            )?,
+            currency: item.request.currency,
+        };
+        Ok(Self {
+            api_operation: NoonApiOperations::Refund,
+            order,
+            transaction,
+        })
+    }
+}
 
-#[allow(dead_code)]
-#[derive(Debug, Serialize, Default, Deserialize, Clone)]
+#[derive(Debug, Default, Deserialize, Clone)]
+#[serde(rename_all = "UPPERCASE")]
 pub enum RefundStatus {
-    Succeeded,
+    Success,
     Failed,
     #[default]
-    Processing,
+    Pending,
 }
 
 impl From<RefundStatus> for enums::RefundStatus {
     fn from(item: RefundStatus) -> Self {
         match item {
-            RefundStatus::Succeeded => Self::Success,
+            RefundStatus::Success => Self::Success,
             RefundStatus::Failed => Self::Failure,
-            RefundStatus::Processing => Self::Pending,
-            //TODO: Review mapping
+            RefundStatus::Pending => Self::Pending,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize)]
-pub struct RefundResponse {
+#[derive(Default, Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NoonPaymentsTransactionResponse {
     id: String,
     status: RefundStatus,
 }
 
+#[derive(Default, Debug, Deserialize)]
+pub struct NoonRefundResponseResult {
+    transaction: NoonPaymentsTransactionResponse,
+}
+
+#[derive(Default, Debug, Deserialize)]
+pub struct RefundResponse {
+    result: NoonRefundResponseResult,
+}
+
 impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
     for types::RefundsRouterData<api::Execute>
 {
@@ -169,36 +349,60 @@ impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
     ) -> Result<Self, Self::Error> {
         Ok(Self {
             response: Ok(types::RefundsResponseData {
-                connector_refund_id: item.response.id.to_string(),
-                refund_status: enums::RefundStatus::from(item.response.status),
+                connector_refund_id: item.response.result.transaction.id,
+                refund_status: enums::RefundStatus::from(item.response.result.transaction.status),
             }),
             ..item.data
         })
     }
 }
 
-impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundResponse>>
+#[derive(Default, Debug, Deserialize)]
+pub struct NoonRefundResponseTransactions {
+    id: String,
+    status: RefundStatus,
+}
+
+#[derive(Default, Debug, Deserialize)]
+pub struct NoonRefundSyncResponseResult {
+    transactions: Vec<NoonRefundResponseTransactions>,
+}
+
+#[derive(Default, Debug, Deserialize)]
+pub struct RefundSyncResponse {
+    result: NoonRefundSyncResponseResult,
+}
+
+impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundSyncResponse>>
     for types::RefundsRouterData<api::RSync>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
-        item: types::RefundsResponseRouterData<api::RSync, RefundResponse>,
+        item: types::RefundsResponseRouterData<api::RSync, RefundSyncResponse>,
     ) -> Result<Self, Self::Error> {
+        let connector_refund_id = item.data.request.get_connector_refund_id()?;
+        let noon_transaction: &NoonRefundResponseTransactions = item
+            .response
+            .result
+            .transactions
+            .iter()
+            .find(|transaction| transaction.id == connector_refund_id)
+            .ok_or(errors::ConnectorError::ResponseHandlingFailed)?;
+
         Ok(Self {
             response: Ok(types::RefundsResponseData {
-                connector_refund_id: item.response.id.to_string(),
-                refund_status: enums::RefundStatus::from(item.response.status),
+                connector_refund_id: noon_transaction.id.to_owned(),
+                refund_status: enums::RefundStatus::from(noon_transaction.status.to_owned()),
             }),
             ..item.data
         })
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
 pub struct NoonErrorResponse {
-    pub status_code: u16,
-    pub code: String,
+    pub result_code: u32,
     pub message: String,
-    pub reason: Option<String>,
+    pub class_description: String,
 }
diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs
index d619e722753..9ac6e9cd3b0 100644
--- a/crates/router/src/core/payments/flows.rs
+++ b/crates/router/src/core/payments/flows.rs
@@ -261,7 +261,6 @@ default_imp_for_connector_redirect_response!(
     connector::Multisafepay,
     connector::Nexinets,
     connector::Nmi,
-    connector::Noon,
     connector::Opennode,
     connector::Payeezy,
     connector::Payu,
diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs
index ce87e7d2cea..0b146547433 100644
--- a/crates/router/src/types/api.rs
+++ b/crates/router/src/types/api.rs
@@ -226,7 +226,7 @@ impl ConnectorData {
                 enums::Connector::Klarna => Ok(Box::new(&connector::Klarna)),
                 enums::Connector::Mollie => Ok(Box::new(&connector::Mollie)),
                 enums::Connector::Nmi => Ok(Box::new(&connector::Nmi)),
-                // "noon" => Ok(Box::new(&connector::Noon)), added as template code for future usage
+                enums::Connector::Noon => Ok(Box::new(&connector::Noon)),
                 enums::Connector::Nuvei => Ok(Box::new(&connector::Nuvei)),
                 enums::Connector::Opennode => Ok(Box::new(&connector::Opennode)),
                 // "payeezy" => Ok(Box::new(&connector::Payeezy)), As psync and rsync are not supported by this connector, it is added as template code for future usage
diff --git a/crates/router/tests/connectors/connector_auth.rs b/crates/router/tests/connectors/connector_auth.rs
index 6c2b1a1b967..7970b8dbd7c 100644
--- a/crates/router/tests/connectors/connector_auth.rs
+++ b/crates/router/tests/connectors/connector_auth.rs
@@ -25,7 +25,7 @@ pub(crate) struct ConnectorAuthentication {
     pub mollie: Option<HeaderKey>,
     pub multisafepay: Option<HeaderKey>,
     pub nexinets: Option<HeaderKey>,
-    pub noon: Option<HeaderKey>,
+    pub noon: Option<SignatureKey>,
     pub nmi: Option<HeaderKey>,
     pub nuvei: Option<SignatureKey>,
     pub opennode: Option<HeaderKey>,
diff --git a/crates/router/tests/connectors/noon.rs b/crates/router/tests/connectors/noon.rs
index 7df526be2fe..c426d977c34 100644
--- a/crates/router/tests/connectors/noon.rs
+++ b/crates/router/tests/connectors/noon.rs
@@ -1,7 +1,10 @@
 use std::str::FromStr;
 
 use masking::Secret;
-use router::types::{self, api, storage::enums};
+use router::types::{
+    self, api,
+    storage::{self, enums},
+};
 
 use crate::{
     connector_auth,
@@ -16,7 +19,7 @@ impl utils::Connector for NoonTest {
         use router::connector::Noon;
         types::api::ConnectorData {
             connector: Box::new(&Noon),
-            connector_name: types::Connector::DummyConnector1,
+            connector_name: types::Connector::Noon,
             get_token: types::api::GetToken::Connector,
         }
     }
@@ -41,7 +44,10 @@ fn get_default_payment_info() -> Option<utils::PaymentInfo> {
 }
 
 fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
-    None
+    Some(types::PaymentsAuthorizeData {
+        currency: storage::enums::Currency::AED,
+        ..utils::PaymentAuthorizeType::default().0
+    })
 }
 
 // Cards Positive Tests
diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml
index a1d441d88cc..77c5aefc776 100644
--- a/crates/router/tests/connectors/sample_auth.toml
+++ b/crates/router/tests/connectors/sample_auth.toml
@@ -112,4 +112,6 @@ api_secret = "secrect"
 api_key = "API Key"
 
 [noon]
-api_key = "API Key"
+api_key = "Application API KEY"
+api_secret = "Application Identifier"
+key1 = "Business Identifier"

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

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

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

Added Card Payments (3DS and Non-3DS) along with all the listed flows:

- [Authorize](https://docs.noonpayments.com/payment-api/reference/initiate)
- [Capture](https://docs.noonpayments.com/payment-api/reference/capture)
- [Void](https://docs.noonpayments.com/payment-api/reference/reverse)
- [Refund](https://docs.noonpayments.com/payment-api/reference/refund)

### 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).
-->

Closes #1185

## 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)?
-->

Unit Tests are not updated as all the tests trigger 3DS

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

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