Bug: [FEATURE]: [GIGADAT] Implement Interac payouts



Implement Interac payouts 
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index edc6bf78759..de46df2373e 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -48,6 +48,7 @@ pub enum PayoutConnectors {
     Adyenplatform,
     Cybersource,
     Ebanx,
+    Gigadat,
     Nomupay,
     Nuvei,
     Payone,
@@ -75,6 +76,7 @@ impl From<PayoutConnectors> for RoutableConnectors {
             PayoutConnectors::Adyenplatform => Self::Adyenplatform,
             PayoutConnectors::Cybersource => Self::Cybersource,
             PayoutConnectors::Ebanx => Self::Ebanx,
+            PayoutConnectors::Gigadat => Self::Gigadat,
             PayoutConnectors::Nomupay => Self::Nomupay,
             PayoutConnectors::Nuvei => Self::Nuvei,
             PayoutConnectors::Payone => Self::Payone,
@@ -93,6 +95,7 @@ impl From<PayoutConnectors> for Connector {
             PayoutConnectors::Adyenplatform => Self::Adyenplatform,
             PayoutConnectors::Cybersource => Self::Cybersource,
             PayoutConnectors::Ebanx => Self::Ebanx,
+            PayoutConnectors::Gigadat => Self::Gigadat,
             PayoutConnectors::Nomupay => Self::Nomupay,
             PayoutConnectors::Nuvei => Self::Nuvei,
             PayoutConnectors::Payone => Self::Payone,
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 55e13f5b094..5f38ee86f99 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -1597,6 +1597,12 @@ pub struct BrowserInformation {
 
     /// The device model of the client
     pub device_model: Option<String>,
+
+    /// Accept-language of the browser
+    pub accept_language: Option<String>,
+
+    /// Identifier of the source that initiated the request.
+    pub referer: Option<String>,
 }
 
 impl RequestSurchargeDetails {
diff --git a/crates/api_models/src/payouts.rs b/crates/api_models/src/payouts.rs
index a6fdaa2b6e5..d61fc5bbc09 100644
--- a/crates/api_models/src/payouts.rs
+++ b/crates/api_models/src/payouts.rs
@@ -1,6 +1,8 @@
 use std::collections::HashMap;
 
 use cards::CardNumber;
+#[cfg(feature = "v2")]
+use common_utils::types::BrowserInformation;
 use common_utils::{
     consts::default_payouts_list_limit,
     crypto, id_type, link_utils, payout_method_utils,
@@ -9,6 +11,8 @@ use common_utils::{
     types::{UnifiedCode, UnifiedMessage},
 };
 use masking::Secret;
+#[cfg(feature = "v1")]
+use payments::BrowserInformation;
 use router_derive::FlatStruct;
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
@@ -191,6 +195,10 @@ pub struct PayoutCreateRequest {
 
     /// Identifier for payout method
     pub payout_method_id: Option<String>,
+
+    /// Additional details required by 3DS 2.0
+    #[schema(value_type = Option<BrowserInformation>)]
+    pub browser_info: Option<BrowserInformation>,
 }
 
 impl PayoutCreateRequest {
diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs
index a0d7e903068..e69ba486c32 100644
--- a/crates/connector_configs/src/connector.rs
+++ b/crates/connector_configs/src/connector.rs
@@ -285,6 +285,8 @@ pub struct ConnectorConfig {
     pub forte: Option<ConnectorTomlConfig>,
     pub getnet: Option<ConnectorTomlConfig>,
     pub gigadat: Option<ConnectorTomlConfig>,
+    #[cfg(feature = "payouts")]
+    pub gigadat_payout: Option<ConnectorTomlConfig>,
     pub globalpay: Option<ConnectorTomlConfig>,
     pub globepay: Option<ConnectorTomlConfig>,
     pub gocardless: Option<ConnectorTomlConfig>,
@@ -399,6 +401,7 @@ impl ConnectorConfig {
             PayoutConnectors::Adyenplatform => Ok(connector_data.adyenplatform_payout),
             PayoutConnectors::Cybersource => Ok(connector_data.cybersource_payout),
             PayoutConnectors::Ebanx => Ok(connector_data.ebanx_payout),
+            PayoutConnectors::Gigadat => Ok(connector_data.gigadat_payout),
             PayoutConnectors::Nomupay => Ok(connector_data.nomupay_payout),
             PayoutConnectors::Nuvei => Ok(connector_data.nuvei_payout),
             PayoutConnectors::Payone => Ok(connector_data.payone_payout),
diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml
index 11f17b69880..1a1b9b1efbb 100644
--- a/crates/connector_configs/toml/development.toml
+++ b/crates/connector_configs/toml/development.toml
@@ -7221,6 +7221,20 @@ placeholder = "Enter site where transaction is initiated"
 required = true
 type = "Text"
 
+[gigadat_payout]
+[gigadat_payout.connector_auth.SignatureKey]
+api_key = "Access Token"
+api_secret = "Security Token"
+key1 = "Campaign ID"
+[[gigadat_payout.bank_redirect]]
+payment_method_type = "interac"
+[gigadat_payout.metadata.site]
+name = "site"
+label = "Site where transaction is initiated"
+placeholder = "Enter site where transaction is initiated"
+required = true
+type = "Text"
+
 [finix]
 [finix.connector_auth.HeaderKey]
 api_key = "API Key"
diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml
index cc39c1fbc48..a65dcde1e2e 100644
--- a/crates/connector_configs/toml/production.toml
+++ b/crates/connector_configs/toml/production.toml
@@ -5959,6 +5959,20 @@ placeholder = "Enter site where transaction is initiated"
 required = true
 type = "Text"
 
+[gigadat_payout]
+[gigadat_payout.connector_auth.SignatureKey]
+api_key = "Access Token"
+api_secret = "Security Token"
+key1 = "Campaign ID"
+[[gigadat_payout.bank_redirect]]
+payment_method_type = "interac"
+[gigadat_payout.metadata.site]
+name = "site"
+label = "Site where transaction is initiated"
+placeholder = "Enter site where transaction is initiated"
+required = true
+type = "Text"
+
 [finix]
 [finix.connector_auth.HeaderKey]
 api_key = "API Key"
diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml
index 0bc4aa79ed7..124286a88a3 100644
--- a/crates/connector_configs/toml/sandbox.toml
+++ b/crates/connector_configs/toml/sandbox.toml
@@ -7200,6 +7200,19 @@ placeholder = "Enter site where transaction is initiated"
 required = true
 type = "Text"
 
+[gigadat_payout]
+[gigadat_payout.connector_auth.SignatureKey]
+api_key = "Access Token"
+api_secret = "Security Token"
+key1 = "Campaign ID"
+[[gigadat_payout.bank_redirect]]
+payment_method_type = "interac"
+[gigadat_payout.metadata.site]
+name = "site"
+label = "Site where transaction is initiated"
+placeholder = "Enter site where transaction is initiated"
+required = true
+type = "Text"
 
 [finix]
 [finix.connector_auth.HeaderKey]
diff --git a/crates/hyperswitch_connectors/src/connectors/gigadat.rs b/crates/hyperswitch_connectors/src/connectors/gigadat.rs
index 973e1ae6f30..33910dce4b3 100644
--- a/crates/hyperswitch_connectors/src/connectors/gigadat.rs
+++ b/crates/hyperswitch_connectors/src/connectors/gigadat.rs
@@ -32,6 +32,13 @@ use hyperswitch_domain_models::{
         RefundsRouterData,
     },
 };
+#[cfg(feature = "payouts")]
+use hyperswitch_domain_models::{
+    router_flow_types::{PoCreate, PoFulfill, PoQuote},
+    types::{PayoutsData, PayoutsResponseData, PayoutsRouterData},
+};
+#[cfg(feature = "payouts")]
+use hyperswitch_interfaces::types::{PayoutCreateType, PayoutFulfillType, PayoutQuoteType};
 use hyperswitch_interfaces::{
     api::{
         self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorSpecifications,
@@ -45,6 +52,8 @@ use hyperswitch_interfaces::{
 };
 use lazy_static::lazy_static;
 use masking::{Mask, PeekInterface};
+#[cfg(feature = "payouts")]
+use router_env::{instrument, tracing};
 use transformers as gigadat;
 use uuid::Uuid;
 
@@ -75,6 +84,12 @@ impl api::Refund for Gigadat {}
 impl api::RefundExecute for Gigadat {}
 impl api::RefundSync for Gigadat {}
 impl api::PaymentToken for Gigadat {}
+#[cfg(feature = "payouts")]
+impl api::PayoutQuote for Gigadat {}
+#[cfg(feature = "payouts")]
+impl api::PayoutCreate for Gigadat {}
+#[cfg(feature = "payouts")]
+impl api::PayoutFulfill for Gigadat {}
 
 impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
     for Gigadat
@@ -578,6 +593,245 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Gigadat {
     //Gigadat does not support Refund Sync
 }
 
+#[cfg(feature = "payouts")]
+impl ConnectorIntegration<PoQuote, PayoutsData, PayoutsResponseData> for Gigadat {
+    fn get_headers(
+        &self,
+        req: &PayoutsRouterData<PoQuote>,
+        connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
+        self.build_headers(req, connectors)
+    }
+
+    fn get_url(
+        &self,
+        req: &PayoutsRouterData<PoQuote>,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let auth = gigadat::GigadatAuthType::try_from(&req.connector_auth_type)
+            .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
+        Ok(format!(
+            "{}api/payment-token/{}",
+            self.base_url(connectors),
+            auth.campaign_id.peek()
+        ))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &PayoutsRouterData<PoQuote>,
+        _connectors: &Connectors,
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let amount = utils::convert_amount(
+            self.amount_converter,
+            req.request.minor_amount,
+            req.request.destination_currency,
+        )?;
+
+        let connector_router_data = gigadat::GigadatRouterData::from((amount, req));
+        let connector_req = gigadat::GigadatPayoutQuoteRequest::try_from(&connector_router_data)?;
+        Ok(RequestContent::Json(Box::new(connector_req)))
+    }
+
+    fn build_request(
+        &self,
+        req: &PayoutsRouterData<PoQuote>,
+        connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        let request = RequestBuilder::new()
+            .method(Method::Post)
+            .url(&PayoutQuoteType::get_url(self, req, connectors)?)
+            .attach_default_headers()
+            .headers(PayoutQuoteType::get_headers(self, req, connectors)?)
+            .set_body(PayoutQuoteType::get_request_body(self, req, connectors)?)
+            .build();
+
+        Ok(Some(request))
+    }
+
+    #[instrument(skip_all)]
+    fn handle_response(
+        &self,
+        data: &PayoutsRouterData<PoQuote>,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<PayoutsRouterData<PoQuote>, errors::ConnectorError> {
+        let response: gigadat::GigadatPayoutResponse = res
+            .response
+            .parse_struct("GigadatPayoutResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+
+        event_builder.map(|i| i.set_response_body(&response));
+        router_env::logger::info!(connector_response=?response);
+
+        RouterData::try_from(ResponseRouterData {
+            response,
+            data: data.clone(),
+            http_code: res.status_code,
+        })
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+}
+
+#[async_trait::async_trait]
+#[cfg(feature = "payouts")]
+impl ConnectorIntegration<PoCreate, PayoutsData, PayoutsResponseData> for Gigadat {
+    fn get_headers(
+        &self,
+        req: &PayoutsRouterData<PoCreate>,
+        connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
+        self.build_headers(req, connectors)
+    }
+
+    fn get_url(
+        &self,
+        req: &PayoutsRouterData<PoCreate>,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let transfer_id = req.request.connector_payout_id.to_owned().ok_or(
+            errors::ConnectorError::MissingRequiredField {
+                field_name: "transfer_id",
+            },
+        )?;
+        Ok(format!(
+            "{}webflow?transaction={}",
+            self.base_url(connectors),
+            transfer_id,
+        ))
+    }
+
+    fn build_request(
+        &self,
+        req: &PayoutsRouterData<PoCreate>,
+        connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        let request = RequestBuilder::new()
+            .method(Method::Post)
+            .url(&PayoutCreateType::get_url(self, req, connectors)?)
+            .attach_default_headers()
+            .headers(PayoutCreateType::get_headers(self, req, connectors)?)
+            .build();
+
+        Ok(Some(request))
+    }
+
+    #[instrument(skip_all)]
+    fn handle_response(
+        &self,
+        data: &PayoutsRouterData<PoCreate>,
+        _event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<PayoutsRouterData<PoCreate>, errors::ConnectorError> {
+        router_env::logger::debug!("Expected zero bytes response, skipped parsing of the response");
+
+        let status = if res.status_code == 200 {
+            enums::PayoutStatus::RequiresFulfillment
+        } else {
+            enums::PayoutStatus::Failed
+        };
+        Ok(PayoutsRouterData {
+            response: Ok(PayoutsResponseData {
+                status: Some(status),
+                connector_payout_id: None,
+                payout_eligible: None,
+                should_add_next_step_to_process_tracker: false,
+                error_code: None,
+                error_message: None,
+            }),
+            ..data.clone()
+        })
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+}
+
+#[cfg(feature = "payouts")]
+impl ConnectorIntegration<PoFulfill, PayoutsData, PayoutsResponseData> for Gigadat {
+    fn get_headers(
+        &self,
+        req: &PayoutsRouterData<PoFulfill>,
+        connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
+        self.build_headers(req, connectors)
+    }
+
+    fn get_url(
+        &self,
+        req: &PayoutsRouterData<PoFulfill>,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let transfer_id = req.request.connector_payout_id.to_owned().ok_or(
+            errors::ConnectorError::MissingRequiredField {
+                field_name: "transfer_id",
+            },
+        )?;
+        Ok(format!(
+            "{}webflow?transaction={}",
+            self.base_url(connectors),
+            transfer_id,
+        ))
+    }
+
+    fn build_request(
+        &self,
+        req: &PayoutsRouterData<PoFulfill>,
+        connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        let request = RequestBuilder::new()
+            .method(Method::Get)
+            .url(&PayoutFulfillType::get_url(self, req, connectors)?)
+            .attach_default_headers()
+            .headers(PayoutFulfillType::get_headers(self, req, connectors)?)
+            .build();
+
+        Ok(Some(request))
+    }
+
+    #[instrument(skip_all)]
+    fn handle_response(
+        &self,
+        data: &PayoutsRouterData<PoFulfill>,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<PayoutsRouterData<PoFulfill>, errors::ConnectorError> {
+        let response: gigadat::GigadatPayoutResponse = res
+            .response
+            .parse_struct("GigadatPayoutResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+
+        event_builder.map(|i| i.set_response_body(&response));
+        router_env::logger::info!(connector_response=?response);
+
+        RouterData::try_from(ResponseRouterData {
+            response,
+            data: data.clone(),
+            http_code: res.status_code,
+        })
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+}
+
 #[async_trait::async_trait]
 impl webhooks::IncomingWebhook for Gigadat {
     fn get_webhook_object_reference_id(
diff --git a/crates/hyperswitch_connectors/src/connectors/gigadat/transformers.rs b/crates/hyperswitch_connectors/src/connectors/gigadat/transformers.rs
index 060628f7a4b..a4bfc9c01a8 100644
--- a/crates/hyperswitch_connectors/src/connectors/gigadat/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/gigadat/transformers.rs
@@ -14,10 +14,17 @@ use hyperswitch_domain_models::{
     router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData},
     types::{PaymentsAuthorizeRouterData, RefundsRouterData},
 };
+#[cfg(feature = "payouts")]
+use hyperswitch_domain_models::{
+    router_flow_types::PoQuote, router_response_types::PayoutsResponseData,
+    types::PayoutsRouterData,
+};
 use hyperswitch_interfaces::errors;
 use masking::{PeekInterface, Secret};
 use serde::{Deserialize, Serialize};
 
+#[cfg(feature = "payouts")]
+use crate::{types::PayoutsResponseRouterData, utils::PayoutsData as _};
 use crate::{
     types::{RefundsResponseRouterData, ResponseRouterData},
     utils::{self, BrowserInformationData, PaymentsAuthorizeRequestData, RouterData as _},
@@ -56,7 +63,7 @@ impl TryFrom<&Option<pii::SecretSerdeValue>> for GigadatConnectorMetadataObject
 }
 
 // CPI (Combined Pay-in) Request Structure for Gigadat
-#[derive(Debug, Serialize, PartialEq)]
+#[derive(Debug, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct GigadatCpiRequest {
     pub user_id: id_type::CustomerId,
@@ -73,10 +80,11 @@ pub struct GigadatCpiRequest {
     pub mobile: Secret<String>,
 }
 
-#[derive(Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Serialize, Deserialize)]
 #[serde(rename_all = "UPPERCASE")]
 pub enum GidadatTransactionType {
     Cpi,
+    Eto,
 }
 
 impl TryFrom<&GigadatRouterData<&PaymentsAuthorizeRouterData>> for GigadatCpiRequest {
@@ -153,19 +161,19 @@ impl TryFrom<&ConnectorAuthType> for GigadatAuthType {
     }
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct GigadatPaymentResponse {
     pub token: Secret<String>,
     pub data: GigadatPaymentData,
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct GigadatPaymentData {
     pub transaction_id: String,
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 pub enum GigadatPaymentStatus {
     StatusInited,
@@ -194,7 +202,7 @@ impl From<GigadatPaymentStatus> for enums::AttemptStatus {
     }
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct GigadatTransactionStatusResponse {
     pub status: GigadatPaymentStatus,
 }
@@ -310,18 +318,107 @@ impl TryFrom<RefundsResponseRouterData<Execute, RefundResponse>> for RefundsRout
     }
 }
 
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GigadatPayoutQuoteRequest {
+    pub amount: FloatMajorUnit,
+    pub campaign: Secret<String>,
+    pub currency: Currency,
+    pub email: Email,
+    pub mobile: Secret<String>,
+    pub name: Secret<String>,
+    pub site: String,
+    pub transaction_id: String,
+    #[serde(rename = "type")]
+    pub transaction_type: GidadatTransactionType,
+    pub user_id: id_type::CustomerId,
+    pub user_ip: Secret<String, IpAddress>,
+}
+
+// Payouts fulfill request transform
+#[cfg(feature = "payouts")]
+impl TryFrom<&GigadatRouterData<&PayoutsRouterData<PoQuote>>> for GigadatPayoutQuoteRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: &GigadatRouterData<&PayoutsRouterData<PoQuote>>,
+    ) -> Result<Self, Self::Error> {
+        let metadata: GigadatConnectorMetadataObject =
+            utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())
+                .change_context(errors::ConnectorError::InvalidConnectorConfig {
+                    config: "merchant_connector_account.metadata",
+                })?;
+
+        let router_data = item.router_data;
+        let name = router_data.get_billing_full_name()?;
+        let email = router_data.get_billing_email()?;
+        let mobile = router_data.get_billing_phone_number()?;
+        let currency = item.router_data.request.destination_currency;
+
+        let user_ip = router_data.request.get_browser_info()?.get_ip_address()?;
+        let auth_type = GigadatAuthType::try_from(&item.router_data.connector_auth_type)?;
+
+        Ok(Self {
+            user_id: router_data.get_customer_id()?,
+            site: metadata.site,
+            user_ip,
+            currency,
+            amount: item.amount,
+            transaction_id: router_data.connector_request_reference_id.clone(),
+            transaction_type: GidadatTransactionType::Eto,
+            name,
+            email,
+            mobile,
+            campaign: auth_type.campaign_id,
+        })
+    }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct GigadatPayoutResponse {
+    pub token: Secret<String>,
+    pub data: GigadatPayoutData,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GigadatPayoutData {
+    pub transaction_id: String,
+    #[serde(rename = "type")]
+    pub transaction_type: String,
+}
+
+#[cfg(feature = "payouts")]
+impl<F> TryFrom<PayoutsResponseRouterData<F, GigadatPayoutResponse>> for PayoutsRouterData<F> {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: PayoutsResponseRouterData<F, GigadatPayoutResponse>,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            response: Ok(PayoutsResponseData {
+                status: None,
+                connector_payout_id: Some(item.response.data.transaction_id),
+                payout_eligible: None,
+                should_add_next_step_to_process_tracker: false,
+                error_code: None,
+                error_message: None,
+            }),
+            ..item.data
+        })
+    }
+}
+
+#[derive(Default, Debug, Serialize, Deserialize)]
 pub struct GigadatErrorResponse {
     pub err: String,
 }
 
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Default, Debug, Serialize, Deserialize)]
 pub struct GigadatRefundErrorResponse {
     pub error: Vec<Error>,
     pub message: String,
 }
 
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Default, Debug, Serialize, Deserialize)]
 pub struct Error {
     pub code: Option<String>,
     pub detail: String,
diff --git a/crates/hyperswitch_connectors/src/default_implementations.rs b/crates/hyperswitch_connectors/src/default_implementations.rs
index 31b474cd3c3..b3eb01ba92a 100644
--- a/crates/hyperswitch_connectors/src/default_implementations.rs
+++ b/crates/hyperswitch_connectors/src/default_implementations.rs
@@ -3992,7 +3992,6 @@ default_imp_for_payouts_create!(
     connectors::Flexiti,
     connectors::Forte,
     connectors::Getnet,
-    connectors::Gigadat,
     connectors::Globalpay,
     connectors::Globepay,
     connectors::Gocardless,
@@ -4433,7 +4432,6 @@ default_imp_for_payouts_fulfill!(
     connectors::Flexiti,
     connectors::Forte,
     connectors::Getnet,
-    connectors::Gigadat,
     connectors::Globalpay,
     connectors::Globepay,
     connectors::Gocardless,
@@ -4724,7 +4722,6 @@ default_imp_for_payouts_quote!(
     connectors::Flexiti,
     connectors::Forte,
     connectors::Getnet,
-    connectors::Gigadat,
     connectors::Globalpay,
     connectors::Globepay,
     connectors::Gocardless,
diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs
index 182c6067201..fd3e68f8019 100644
--- a/crates/hyperswitch_connectors/src/utils.rs
+++ b/crates/hyperswitch_connectors/src/utils.rs
@@ -6399,6 +6399,7 @@ pub trait PayoutsData {
     fn get_vendor_details(&self) -> Result<PayoutVendorAccountDetails, Error>;
     fn get_payout_type(&self) -> Result<enums::PayoutType, Error>;
     fn get_webhook_url(&self) -> Result<String, Error>;
+    fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
 }
 
 #[cfg(feature = "payouts")]
@@ -6430,6 +6431,11 @@ impl PayoutsData for hyperswitch_domain_models::router_request_types::PayoutsDat
             .to_owned()
             .ok_or_else(missing_field_err("webhook_url"))
     }
+    fn get_browser_info(&self) -> Result<BrowserInformation, Error> {
+        self.browser_info
+            .clone()
+            .ok_or_else(missing_field_err("browser_info"))
+    }
 }
 pub trait RevokeMandateRequestData {
     fn get_connector_mandate_id(&self) -> Result<String, Error>;
diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs
index e035af3b074..415b97d1af0 100644
--- a/crates/hyperswitch_domain_models/src/router_request_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_request_types.rs
@@ -939,6 +939,29 @@ impl From<common_utils::types::BrowserInformation> for BrowserInformation {
     }
 }
 
+#[cfg(feature = "v1")]
+impl From<api_models::payments::BrowserInformation> for BrowserInformation {
+    fn from(value: api_models::payments::BrowserInformation) -> Self {
+        Self {
+            color_depth: value.color_depth,
+            java_enabled: value.java_enabled,
+            java_script_enabled: value.java_script_enabled,
+            language: value.language,
+            screen_height: value.screen_height,
+            screen_width: value.screen_width,
+            time_zone: value.time_zone,
+            ip_address: value.ip_address,
+            accept_header: value.accept_header,
+            user_agent: value.user_agent,
+            os_type: value.os_type,
+            os_version: value.os_version,
+            device_model: value.device_model,
+            accept_language: value.accept_language,
+            referer: value.referer,
+        }
+    }
+}
+
 #[derive(Debug, Clone, Default, Serialize)]
 pub enum ResponseId {
     ConnectorTransactionId(String),
@@ -1316,6 +1339,7 @@ pub struct PayoutsData {
     pub priority: Option<storage_enums::PayoutSendPriority>,
     pub connector_transfer_method_id: Option<String>,
     pub webhook_url: Option<String>,
+    pub browser_info: Option<BrowserInformation>,
 }
 
 #[derive(Debug, Default, Clone)]
diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs
index c132ec8d128..90ba7f161be 100644
--- a/crates/router/src/core/payouts.rs
+++ b/crates/router/src/core/payouts.rs
@@ -79,6 +79,7 @@ pub struct PayoutData {
     pub current_locale: String,
     pub payment_method: Option<PaymentMethod>,
     pub connector_transfer_method_id: Option<String>,
+    pub browser_info: Option<domain_models::router_request_types::BrowserInformation>,
 }
 
 // ********************************************** CORE FLOWS **********************************************
@@ -533,12 +534,12 @@ pub async fn payouts_retrieve_core(
         )
         .await?;
 
-        complete_payout_retrieve(
+        Box::pin(complete_payout_retrieve(
             &state,
             &merchant_context,
             connector_call_type,
             &mut payout_data,
-        )
+        ))
         .await?;
     }
 
@@ -2874,6 +2875,7 @@ pub async fn payout_create_db_entries(
         current_locale: locale.to_string(),
         payment_method,
         connector_transfer_method_id: None,
+        browser_info: req.browser_info.clone().map(Into::into),
     })
 }
 
@@ -2906,6 +2908,12 @@ pub async fn make_payout_data(
         payouts::PayoutRequest::PayoutRetrieveRequest(r) => r.payout_id.clone(),
     };
 
+    let browser_info = match req {
+        payouts::PayoutRequest::PayoutActionRequest(_) => None,
+        payouts::PayoutRequest::PayoutCreateRequest(r) => r.browser_info.clone().map(Into::into),
+        payouts::PayoutRequest::PayoutRetrieveRequest(_) => None,
+    };
+
     let payouts = db
         .find_payout_by_merchant_id_payout_id(
             merchant_id,
@@ -3100,6 +3108,7 @@ pub async fn make_payout_data(
         current_locale: locale.to_string(),
         payment_method,
         connector_transfer_method_id: None,
+        browser_info,
     })
 }
 
diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs
index 30bc466063b..367973ddbd5 100644
--- a/crates/router/src/core/utils.rs
+++ b/crates/router/src/core/utils.rs
@@ -152,6 +152,8 @@ pub async fn construct_payout_router_data<'a, F>(
     let connector_transfer_method_id =
         payout_helpers::should_create_connector_transfer_method(&*payout_data, connector_data)?;
 
+    let browser_info = payout_data.browser_info.to_owned();
+
     let router_data = types::RouterData {
         flow: PhantomData,
         merchant_id: merchant_context.get_merchant_account().get_id().to_owned(),
@@ -197,6 +199,7 @@ pub async fn construct_payout_router_data<'a, F>(
                 }),
             connector_transfer_method_id,
             webhook_url: Some(webhook_url),
+            browser_info,
         },
         response: Ok(types::PayoutsResponseData::default()),
         access_token: None,
diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs
index 7537b9117bb..8d7493d0c4f 100644
--- a/crates/router/tests/connectors/utils.rs
+++ b/crates/router/tests/connectors/utils.rs
@@ -478,6 +478,7 @@ pub trait ConnectorActions: Connector {
                 priority: None,
                 connector_transfer_method_id: None,
                 webhook_url: None,
+                browser_info: None,
             },
             payment_info,
         )

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

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

## Description
 Implement Interac payouts

### 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 it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
Not tested as we don't have creds


## Checklis
<!-- 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 the submitted code
- [ ] I added unit tests for my changes where possible
