Bug: [FEATURE]:[PAYSAFE] Integrate no 3ds card



Integrate Paysafe connector - No 3ds Cards

Flows
- Payment
- Psync
- Capture
- Void
- Refund
- Refund Sync
diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index 20040502e11..da17d2d3ff0 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -117,7 +117,7 @@ payload.base_url = "https://api.payload.com"
 payme.base_url = "https://live.payme.io/"
 payone.base_url = "https://payment.payone.com/"
 paypal.base_url = "https://api-m.paypal.com/"
-paysafe.base_url = "https://api.test.paysafe.com/paymenthub/"
+paysafe.base_url = "https://api.paysafe.com/paymenthub/"
 paystack.base_url = "https://api.paystack.co"
 paytm.base_url = "https://securegw-stage.paytm.in/"
 payu.base_url = "https://secure.payu.com/api/"
diff --git a/crates/common_enums/src/connector_enums.rs b/crates/common_enums/src/connector_enums.rs
index 8b1c9e2f9eb..b040182ac7e 100644
--- a/crates/common_enums/src/connector_enums.rs
+++ b/crates/common_enums/src/connector_enums.rs
@@ -132,6 +132,7 @@ pub enum RoutableConnectors {
     Payload,
     Payone,
     Paypal,
+    Paysafe,
     Paystack,
     Paytm,
     Payu,
@@ -308,6 +309,7 @@ pub enum Connector {
     Payme,
     Payone,
     Paypal,
+    Paysafe,
     Paystack,
     Paytm,
     Payu,
@@ -496,6 +498,7 @@ impl Connector {
             | Self::Payme
             | Self::Payone
             | Self::Paypal
+            | Self::Paysafe
             | Self::Paystack
             | Self::Payu
             | Self::Placetopay
@@ -670,6 +673,7 @@ impl From<RoutableConnectors> for Connector {
             RoutableConnectors::Payme => Self::Payme,
             RoutableConnectors::Payone => Self::Payone,
             RoutableConnectors::Paypal => Self::Paypal,
+            RoutableConnectors::Paysafe => Self::Paysafe,
             RoutableConnectors::Paystack => Self::Paystack,
             RoutableConnectors::Payu => Self::Payu,
             RoutableConnectors::Placetopay => Self::Placetopay,
@@ -803,6 +807,7 @@ impl TryFrom<Connector> for RoutableConnectors {
             Connector::Payme => Ok(Self::Payme),
             Connector::Payone => Ok(Self::Payone),
             Connector::Paypal => Ok(Self::Paypal),
+            Connector::Paysafe => Ok(Self::Paysafe),
             Connector::Paystack => Ok(Self::Paystack),
             Connector::Payu => Ok(Self::Payu),
             Connector::Placetopay => Ok(Self::Placetopay),
diff --git a/crates/connector_configs/src/common_config.rs b/crates/connector_configs/src/common_config.rs
index 78f85c82577..b54d9e86da8 100644
--- a/crates/connector_configs/src/common_config.rs
+++ b/crates/connector_configs/src/common_config.rs
@@ -110,6 +110,7 @@ pub struct ApiModelMetaData {
     pub merchant_configuration_id: Option<String>,
     pub tenant_id: Option<String>,
     pub platform_url: Option<String>,
+    pub account_id: Option<String>,
 }
 
 #[serde_with::skip_serializing_none]
diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs
index e67a8136684..18da6b52498 100644
--- a/crates/connector_configs/src/connector.rs
+++ b/crates/connector_configs/src/connector.rs
@@ -149,6 +149,7 @@ pub struct ConfigMetadata {
     pub proxy_url: Option<InputData>,
     pub shop_name: Option<InputData>,
     pub merchant_funding_source: Option<InputData>,
+    pub account_id: Option<String>,
 }
 
 #[serde_with::skip_serializing_none]
@@ -481,6 +482,7 @@ impl ConnectorConfig {
             Connector::Payme => Ok(connector_data.payme),
             Connector::Payone => Err("Use get_payout_connector_config".to_string()),
             Connector::Paypal => Ok(connector_data.paypal),
+            Connector::Paysafe => Ok(connector_data.paysafe),
             Connector::Paystack => Ok(connector_data.paystack),
             Connector::Payu => Ok(connector_data.payu),
             Connector::Placetopay => Ok(connector_data.placetopay),
diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml
index ded3ee24bfd..864b220688f 100644
--- a/crates/connector_configs/toml/development.toml
+++ b/crates/connector_configs/toml/development.toml
@@ -6718,5 +6718,50 @@ api_key = "Password"
 key1 = "Username"
 
 [paysafe]
-[paysafe.connector_auth.HeaderKey]
-api_key = "API Key"
+[[paysafe.credit]]
+payment_method_type = "Mastercard"
+[[paysafe.credit]]
+payment_method_type = "Visa"
+[[paysafe.credit]]
+payment_method_type = "Interac"
+[[paysafe.credit]]
+payment_method_type = "AmericanExpress"
+[[paysafe.credit]]
+payment_method_type = "JCB"
+[[paysafe.credit]]
+payment_method_type = "DinersClub"
+[[paysafe.credit]]
+payment_method_type = "Discover"
+[[paysafe.credit]]
+payment_method_type = "CartesBancaires"
+[[paysafe.credit]]
+payment_method_type = "UnionPay"
+[[paysafe.debit]]
+payment_method_type = "Mastercard"
+[[paysafe.debit]]
+payment_method_type = "Visa"
+[[paysafe.debit]]
+payment_method_type = "Interac"
+[[paysafe.debit]]
+payment_method_type = "AmericanExpress"
+[[paysafe.debit]]
+payment_method_type = "JCB"
+[[paysafe.debit]]
+payment_method_type = "DinersClub"
+[[paysafe.debit]]
+payment_method_type = "Discover"
+[[paysafe.debit]]
+payment_method_type = "CartesBancaires"
+[[paysafe.debit]]
+payment_method_type = "UnionPay"
+[paysafe.connector_auth.BodyKey]
+api_key = "Username"
+key1 = "Password"
+[paysafe.connector_webhook_details]
+merchant_secret = "Source verification key"
+[paysafe.metadata.account_id]
+name="account_id"
+label="Payment Method Account ID"
+placeholder="Enter Account ID"
+required=true
+type="Text"
diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml
index c0332a75daa..2f9ef9019de 100644
--- a/crates/connector_configs/toml/production.toml
+++ b/crates/connector_configs/toml/production.toml
@@ -5387,5 +5387,50 @@ api_key = "Password"
 key1 = "Username"
 
 [paysafe]
-[paysafe.connector_auth.HeaderKey]
-api_key = "API Key"
+[[paysafe.credit]]
+payment_method_type = "Mastercard"
+[[paysafe.credit]]
+payment_method_type = "Visa"
+[[paysafe.credit]]
+payment_method_type = "Interac"
+[[paysafe.credit]]
+payment_method_type = "AmericanExpress"
+[[paysafe.credit]]
+payment_method_type = "JCB"
+[[paysafe.credit]]
+payment_method_type = "DinersClub"
+[[paysafe.credit]]
+payment_method_type = "Discover"
+[[paysafe.credit]]
+payment_method_type = "CartesBancaires"
+[[paysafe.credit]]
+payment_method_type = "UnionPay"
+[[paysafe.debit]]
+payment_method_type = "Mastercard"
+[[paysafe.debit]]
+payment_method_type = "Visa"
+[[paysafe.debit]]
+payment_method_type = "Interac"
+[[paysafe.debit]]
+payment_method_type = "AmericanExpress"
+[[paysafe.debit]]
+payment_method_type = "JCB"
+[[paysafe.debit]]
+payment_method_type = "DinersClub"
+[[paysafe.debit]]
+payment_method_type = "Discover"
+[[paysafe.debit]]
+payment_method_type = "CartesBancaires"
+[[paysafe.debit]]
+payment_method_type = "UnionPay"
+[paysafe.connector_auth.BodyKey]
+api_key = "Username"
+key1 = "Password"
+[paysafe.connector_webhook_details]
+merchant_secret = "Source verification key"
+[paysafe.metadata.account_id]
+name="account_id"
+label="Payment Method Account ID"
+placeholder="Enter Account ID"
+required=true
+type="Text"
diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml
index 7f95cd02c50..89d5f539e73 100644
--- a/crates/connector_configs/toml/sandbox.toml
+++ b/crates/connector_configs/toml/sandbox.toml
@@ -6701,5 +6701,50 @@ api_key = "Password"
 key1 = "Username"
 
 [paysafe]
-[paysafe.connector_auth.HeaderKey]
-api_key = "API Key"
+[[paysafe.credit]]
+payment_method_type = "Mastercard"
+[[paysafe.credit]]
+payment_method_type = "Visa"
+[[paysafe.credit]]
+payment_method_type = "Interac"
+[[paysafe.credit]]
+payment_method_type = "AmericanExpress"
+[[paysafe.credit]]
+payment_method_type = "JCB"
+[[paysafe.credit]]
+payment_method_type = "DinersClub"
+[[paysafe.credit]]
+payment_method_type = "Discover"
+[[paysafe.credit]]
+payment_method_type = "CartesBancaires"
+[[paysafe.credit]]
+payment_method_type = "UnionPay"
+[[paysafe.debit]]
+payment_method_type = "Mastercard"
+[[paysafe.debit]]
+payment_method_type = "Visa"
+[[paysafe.debit]]
+payment_method_type = "Interac"
+[[paysafe.debit]]
+payment_method_type = "AmericanExpress"
+[[paysafe.debit]]
+payment_method_type = "JCB"
+[[paysafe.debit]]
+payment_method_type = "DinersClub"
+[[paysafe.debit]]
+payment_method_type = "Discover"
+[[paysafe.debit]]
+payment_method_type = "CartesBancaires"
+[[paysafe.debit]]
+payment_method_type = "UnionPay"
+[paysafe.connector_auth.BodyKey]
+api_key = "Username"
+key1 = "Password"
+[paysafe.connector_webhook_details]
+merchant_secret = "Source verification key"
+[paysafe.metadata.account_id]
+name="account_id"
+label="Payment Method Account ID"
+placeholder="Enter Account ID"
+required=true
+type="Text"
diff --git a/crates/hyperswitch_connectors/src/connectors/paysafe.rs b/crates/hyperswitch_connectors/src/connectors/paysafe.rs
index fc76cece514..64296c2ebe6 100644
--- a/crates/hyperswitch_connectors/src/connectors/paysafe.rs
+++ b/crates/hyperswitch_connectors/src/connectors/paysafe.rs
@@ -2,33 +2,39 @@ pub mod transformers;
 
 use std::sync::LazyLock;
 
+use base64::Engine;
 use common_enums::enums;
 use common_utils::{
+    consts,
     errors::CustomResult,
     ext_traits::BytesExt,
     request::{Method, Request, RequestBuilder, RequestContent},
-    types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector},
+    types::{AmountConvertor, MinorUnit, MinorUnitForConnector},
 };
 use error_stack::{report, ResultExt};
 use hyperswitch_domain_models::{
-    payment_method_data::PaymentMethodData,
     router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
     router_flow_types::{
         access_token_auth::AccessTokenAuth,
-        payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
+        payments::{
+            Authorize, Capture, PSync, PaymentMethodToken, PreProcessing, Session, SetupMandate,
+            Void,
+        },
         refunds::{Execute, RSync},
     },
     router_request_types::{
         AccessTokenRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData,
-        PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData,
-        RefundsData, SetupMandateRequestData,
+        PaymentsCancelData, PaymentsCaptureData, PaymentsPreProcessingData, PaymentsSessionData,
+        PaymentsSyncData, RefundsData, SetupMandateRequestData,
     },
     router_response_types::{
-        ConnectorInfo, PaymentsResponseData, RefundsResponseData, SupportedPaymentMethods,
+        ConnectorInfo, PaymentMethodDetails, PaymentsResponseData, RefundsResponseData,
+        SupportedPaymentMethods, SupportedPaymentMethodsExt,
     },
     types::{
-        PaymentsAuthorizeRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData,
-        RefundSyncRouterData, RefundsRouterData,
+        PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
+        PaymentsPreProcessingRouterData, PaymentsSyncRouterData, RefundSyncRouterData,
+        RefundsRouterData,
     },
 };
 use hyperswitch_interfaces::{
@@ -42,20 +48,24 @@ use hyperswitch_interfaces::{
     types::{self, Response},
     webhooks,
 };
-use masking::{ExposeInterface, Mask};
+use masking::{Mask, PeekInterface};
 use transformers as paysafe;
 
-use crate::{constants::headers, types::ResponseRouterData, utils};
+use crate::{
+    constants::headers,
+    types::ResponseRouterData,
+    utils::{self, RefundsRequestData as OtherRefundsRequestData},
+};
 
 #[derive(Clone)]
 pub struct Paysafe {
-    amount_converter: &'static (dyn AmountConvertor<Output = StringMinorUnit> + Sync),
+    amount_converter: &'static (dyn AmountConvertor<Output = MinorUnit> + Sync),
 }
 
 impl Paysafe {
     pub fn new() -> &'static Self {
         &Self {
-            amount_converter: &StringMinorUnitForConnector,
+            amount_converter: &MinorUnitForConnector,
         }
     }
 }
@@ -76,7 +86,6 @@ impl api::PaymentToken for Paysafe {}
 impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
     for Paysafe
 {
-    // Not Implemented (R)
 }
 
 impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Paysafe
@@ -121,9 +130,11 @@ impl ConnectorCommon for Paysafe {
     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
         let auth = paysafe::PaysafeAuthType::try_from(auth_type)
             .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
+        let auth_key = format!("{}:{}", auth.username.peek(), auth.password.peek());
+        let auth_header = format!("Basic {}", consts::BASE64_ENGINE.encode(auth_key));
         Ok(vec![(
             headers::AUTHORIZATION.to_string(),
-            auth.api_key.expose().into_masked(),
+            auth_header.into_masked(),
         )])
     }
 
@@ -140,11 +151,29 @@ impl ConnectorCommon for Paysafe {
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
 
+        let detail_message = response
+            .error
+            .details
+            .as_ref()
+            .and_then(|d| d.first().cloned());
+        let field_error_message = response
+            .error
+            .field_errors
+            .as_ref()
+            .and_then(|f| f.first().map(|fe| fe.error.clone()));
+
+        let reason = match (detail_message, field_error_message) {
+            (Some(detail), Some(field)) => Some(format!("{detail}, {field}")),
+            (Some(detail), None) => Some(detail),
+            (None, Some(field)) => Some(field),
+            (None, None) => Some(response.error.message.clone()),
+        };
+
         Ok(ErrorResponse {
             status_code: res.status_code,
-            code: response.code,
-            message: response.message,
-            reason: response.reason,
+            code: response.error.code,
+            message: response.error.message,
+            reason,
             attempt_status: None,
             connector_transaction_id: None,
             network_advice_code: None,
@@ -156,20 +185,6 @@ impl ConnectorCommon for Paysafe {
 }
 
 impl ConnectorValidation for Paysafe {
-    fn validate_mandate_payment(
-        &self,
-        _pm_type: Option<enums::PaymentMethodType>,
-        pm_data: PaymentMethodData,
-    ) -> CustomResult<(), errors::ConnectorError> {
-        match pm_data {
-            PaymentMethodData::Card(_) => Err(errors::ConnectorError::NotImplemented(
-                "validate_mandate_payment does not support cards".to_string(),
-            )
-            .into()),
-            _ => Ok(()),
-        }
-    }
-
     fn validate_psync_reference_id(
         &self,
         _data: &PaymentsSyncData,
@@ -187,7 +202,121 @@ impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> fo
 
 impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken> for Paysafe {}
 
-impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData> for Paysafe {}
+impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData> for Paysafe {
+    // Not Implemented (R)
+    fn build_request(
+        &self,
+        _req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
+        _connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Err(
+            errors::ConnectorError::NotImplemented("Setup Mandate flow for Paysafe".to_string())
+                .into(),
+        )
+    }
+}
+
+impl api::PaymentsPreProcessing for Paysafe {}
+
+impl ConnectorIntegration<PreProcessing, PaymentsPreProcessingData, PaymentsResponseData>
+    for Paysafe
+{
+    fn get_headers(
+        &self,
+        req: &PaymentsPreProcessingRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, masking::Maskable<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: &PaymentsPreProcessingRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        Ok(format!("{}v1/paymenthandles", self.base_url(connectors),))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &PaymentsPreProcessingRouterData,
+        _connectors: &Connectors,
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let minor_amount =
+            req.request
+                .minor_amount
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "minor_amount",
+                })?;
+        let currency =
+            req.request
+                .currency
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "currency",
+                })?;
+        let amount = utils::convert_amount(self.amount_converter, minor_amount, currency)?;
+
+        let connector_router_data = paysafe::PaysafeRouterData::from((amount, req));
+        let connector_req = paysafe::PaysafePaymentHandleRequest::try_from(&connector_router_data)?;
+
+        Ok(RequestContent::Json(Box::new(connector_req)))
+    }
+
+    fn build_request(
+        &self,
+        req: &PaymentsPreProcessingRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Ok(Some(
+            RequestBuilder::new()
+                .method(Method::Post)
+                .url(&types::PaymentsPreProcessingType::get_url(
+                    self, req, connectors,
+                )?)
+                .attach_default_headers()
+                .headers(types::PaymentsPreProcessingType::get_headers(
+                    self, req, connectors,
+                )?)
+                .set_body(types::PaymentsPreProcessingType::get_request_body(
+                    self, req, connectors,
+                )?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &PaymentsPreProcessingRouterData,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<PaymentsPreProcessingRouterData, errors::ConnectorError> {
+        let response: paysafe::PaysafePaymentHandleResponse = res
+            .response
+            .parse_struct("PaysafePaymentHandleResponse")
+            .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)
+    }
+}
 
 impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Paysafe {
     fn get_headers(
@@ -205,9 +334,9 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
     fn get_url(
         &self,
         _req: &PaymentsAuthorizeRouterData,
-        _connectors: &Connectors,
+        connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!("{}v1/payments", self.base_url(connectors),))
     }
 
     fn get_request_body(
@@ -291,10 +420,15 @@ impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Pay
 
     fn get_url(
         &self,
-        _req: &PaymentsSyncRouterData,
-        _connectors: &Connectors,
+        req: &PaymentsSyncRouterData,
+        connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let connector_payment_id = req.connector_request_reference_id.clone();
+        Ok(format!(
+            "{}v1/payments?merchantRefNum={}",
+            self.base_url(connectors),
+            connector_payment_id
+        ))
     }
 
     fn build_request(
@@ -318,9 +452,9 @@ impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Pay
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
     ) -> CustomResult<PaymentsSyncRouterData, errors::ConnectorError> {
-        let response: paysafe::PaysafePaymentsResponse = res
+        let response: paysafe::PaysafePaymentsSyncResponse = res
             .response
-            .parse_struct("paysafe PaymentsSyncResponse")
+            .parse_struct("paysafe PaysafePaymentsSyncResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
@@ -355,18 +489,31 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
 
     fn get_url(
         &self,
-        _req: &PaymentsCaptureRouterData,
-        _connectors: &Connectors,
+        req: &PaymentsCaptureRouterData,
+        connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let connector_payment_id = req.request.connector_transaction_id.clone();
+        Ok(format!(
+            "{}v1/payments/{}/settlements",
+            self.base_url(connectors),
+            connector_payment_id
+        ))
     }
 
     fn get_request_body(
         &self,
-        _req: &PaymentsCaptureRouterData,
+        req: &PaymentsCaptureRouterData,
         _connectors: &Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into())
+        let amount = utils::convert_amount(
+            self.amount_converter,
+            req.request.minor_amount_to_capture,
+            req.request.currency,
+        )?;
+
+        let connector_router_data = paysafe::PaysafeRouterData::from((amount, req));
+        let connector_req = paysafe::PaysafeCaptureRequest::try_from(&connector_router_data)?;
+        Ok(RequestContent::Json(Box::new(connector_req)))
     }
 
     fn build_request(
@@ -395,9 +542,9 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
         event_builder: Option<&mut ConnectorEvent>,
         res: Response,
     ) -> CustomResult<PaymentsCaptureRouterData, errors::ConnectorError> {
-        let response: paysafe::PaysafePaymentsResponse = res
+        let response: paysafe::PaysafeSettlementResponse = res
             .response
-            .parse_struct("Paysafe PaymentsCaptureResponse")
+            .parse_struct("PaysafeSettlementResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
@@ -417,7 +564,97 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
     }
 }
 
-impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Paysafe {}
+impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Paysafe {
+    fn get_headers(
+        &self,
+        req: &PaymentsCancelRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
+        self.build_headers(req, connectors)
+    }
+
+    fn get_url(
+        &self,
+        req: &PaymentsCancelRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let connector_payment_id = req.request.connector_transaction_id.clone();
+        Ok(format!(
+            "{}v1/payments/{}/voidauths",
+            self.base_url(connectors),
+            connector_payment_id
+        ))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &PaymentsCancelRouterData,
+        _connectors: &Connectors,
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let minor_amount =
+            req.request
+                .minor_amount
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "minor_amount",
+                })?;
+        let currency =
+            req.request
+                .currency
+                .ok_or(errors::ConnectorError::MissingRequiredField {
+                    field_name: "currency",
+                })?;
+        let amount = utils::convert_amount(self.amount_converter, minor_amount, currency)?;
+
+        let connector_router_data = paysafe::PaysafeRouterData::from((amount, req));
+        let connector_req = paysafe::PaysafeCaptureRequest::try_from(&connector_router_data)?;
+        Ok(RequestContent::Json(Box::new(connector_req)))
+    }
+    fn build_request(
+        &self,
+        req: &PaymentsCancelRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Ok(Some(
+            RequestBuilder::new()
+                .method(Method::Post)
+                .url(&types::PaymentsVoidType::get_url(self, req, connectors)?)
+                .attach_default_headers()
+                .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?)
+                .set_body(types::PaymentsVoidType::get_request_body(
+                    self, req, connectors,
+                )?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &PaymentsCancelRouterData,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<PaymentsCancelRouterData, errors::ConnectorError> {
+        let response: paysafe::VoidResponse = res
+            .response
+            .parse_struct("PaysafeVoidResponse")
+            .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,
+        })
+        .change_context(errors::ConnectorError::ResponseHandlingFailed)
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+}
 
 impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Paysafe {
     fn get_headers(
@@ -434,10 +671,15 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Paysafe
 
     fn get_url(
         &self,
-        _req: &RefundsRouterData<Execute>,
-        _connectors: &Connectors,
+        req: &RefundsRouterData<Execute>,
+        connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let connector_payment_id = req.request.connector_transaction_id.clone();
+        Ok(format!(
+            "{}v1/settlements/{}/refunds",
+            self.base_url(connectors),
+            connector_payment_id
+        ))
     }
 
     fn get_request_body(
@@ -518,10 +760,15 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Paysafe {
 
     fn get_url(
         &self,
-        _req: &RefundSyncRouterData,
-        _connectors: &Connectors,
+        req: &RefundSyncRouterData,
+        connectors: &Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let connector_refund_id = req.request.get_connector_refund_id()?;
+        Ok(format!(
+            "{}v1/refunds/{}",
+            self.base_url(connectors),
+            connector_refund_id
+        ))
     }
 
     fn build_request(
@@ -594,12 +841,70 @@ impl webhooks::IncomingWebhook for Paysafe {
     }
 }
 
-static PAYSAFE_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> =
-    LazyLock::new(SupportedPaymentMethods::new);
+static PAYSAFE_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> = LazyLock::new(|| {
+    let supported_capture_methods = vec![
+        enums::CaptureMethod::Automatic,
+        enums::CaptureMethod::Manual,
+    ];
+
+    let supported_card_network = vec![
+        common_enums::CardNetwork::Mastercard,
+        common_enums::CardNetwork::Visa,
+        common_enums::CardNetwork::Interac,
+        common_enums::CardNetwork::AmericanExpress,
+        common_enums::CardNetwork::JCB,
+        common_enums::CardNetwork::DinersClub,
+        common_enums::CardNetwork::Discover,
+        common_enums::CardNetwork::CartesBancaires,
+        common_enums::CardNetwork::UnionPay,
+    ];
+
+    let mut paysafe_supported_payment_methods = SupportedPaymentMethods::new();
+
+    paysafe_supported_payment_methods.add(
+        enums::PaymentMethod::Card,
+        enums::PaymentMethodType::Credit,
+        PaymentMethodDetails {
+            mandates: enums::FeatureStatus::NotSupported,
+            refunds: enums::FeatureStatus::Supported,
+            supported_capture_methods: supported_capture_methods.clone(),
+            specific_features: Some(
+                api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
+                    api_models::feature_matrix::CardSpecificFeatures {
+                        three_ds: common_enums::FeatureStatus::NotSupported,
+                        no_three_ds: common_enums::FeatureStatus::Supported,
+                        supported_card_networks: supported_card_network.clone(),
+                    }
+                }),
+            ),
+        },
+    );
+
+    paysafe_supported_payment_methods.add(
+        enums::PaymentMethod::Card,
+        enums::PaymentMethodType::Debit,
+        PaymentMethodDetails {
+            mandates: enums::FeatureStatus::NotSupported,
+            refunds: enums::FeatureStatus::Supported,
+            supported_capture_methods: supported_capture_methods.clone(),
+            specific_features: Some(
+                api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
+                    api_models::feature_matrix::CardSpecificFeatures {
+                        three_ds: common_enums::FeatureStatus::NotSupported,
+                        no_three_ds: common_enums::FeatureStatus::Supported,
+                        supported_card_networks: supported_card_network.clone(),
+                    }
+                }),
+            ),
+        },
+    );
+
+    paysafe_supported_payment_methods
+});
 
 static PAYSAFE_CONNECTOR_INFO: ConnectorInfo = ConnectorInfo {
     display_name: "Paysafe",
-    description: "Paysafe connector",
+    description: "Paysafe gives ambitious businesses a launchpad with safe, secure online payment solutions, and gives consumers the ability to turn their transactions into meaningful experiences.",
     connector_type: enums::HyperswitchConnectorCategory::PaymentGateway,
     integration_status: enums::ConnectorIntegrationStatus::Sandbox,
 };
diff --git a/crates/hyperswitch_connectors/src/connectors/paysafe/transformers.rs b/crates/hyperswitch_connectors/src/connectors/paysafe/transformers.rs
index f1a7dbdc237..50c665a65bd 100644
--- a/crates/hyperswitch_connectors/src/connectors/paysafe/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/paysafe/transformers.rs
@@ -1,28 +1,43 @@
+use cards::CardNumber;
 use common_enums::enums;
-use common_utils::types::StringMinorUnit;
+use common_utils::{
+    pii::{IpAddress, SecretSerdeValue},
+    request::Method,
+    types::MinorUnit,
+};
+use error_stack::ResultExt;
 use hyperswitch_domain_models::{
     payment_method_data::PaymentMethodData,
     router_data::{ConnectorAuthType, RouterData},
     router_flow_types::refunds::{Execute, RSync},
-    router_request_types::ResponseId,
+    router_request_types::{
+        PaymentsAuthorizeData, PaymentsPreProcessingData, PaymentsSyncData, ResponseId,
+    },
     router_response_types::{PaymentsResponseData, RefundsResponseData},
-    types::{PaymentsAuthorizeRouterData, RefundsRouterData},
+    types::{
+        PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
+        PaymentsPreProcessingRouterData, RefundsRouterData,
+    },
 };
 use hyperswitch_interfaces::errors;
-use masking::Secret;
+use masking::{ExposeInterface, PeekInterface, Secret};
 use serde::{Deserialize, Serialize};
 
-use crate::types::{RefundsResponseRouterData, ResponseRouterData};
+use crate::{
+    types::{RefundsResponseRouterData, ResponseRouterData},
+    utils::{
+        self, BrowserInformationData, CardData, PaymentsAuthorizeRequestData,
+        PaymentsPreProcessingRequestData, RouterData as _,
+    },
+};
 
-//TODO: Fill the struct with respective fields
 pub struct PaysafeRouterData<T> {
-    pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
+    pub amount: MinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
     pub router_data: T,
 }
 
-impl<T> From<(StringMinorUnit, T)> for PaysafeRouterData<T> {
-    fn from((amount, item): (StringMinorUnit, T)) -> Self {
-        //Todo :  use utils to convert the amount to the type of amount that a connector accepts
+impl<T> From<(MinorUnit, T)> for PaysafeRouterData<T> {
+    fn from((amount, item): (MinorUnit, T)) -> Self {
         Self {
             amount,
             router_data: item,
@@ -30,20 +45,273 @@ impl<T> From<(StringMinorUnit, T)> for PaysafeRouterData<T> {
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, PartialEq)]
+#[derive(Debug, Default, Serialize, Deserialize)]
+pub struct PaysafeConnectorMetadataObject {
+    pub account_id: Secret<String>,
+}
+
+impl TryFrom<&Option<SecretSerdeValue>> for PaysafeConnectorMetadataObject {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(meta_data: &Option<SecretSerdeValue>) -> Result<Self, Self::Error> {
+        let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
+            .change_context(errors::ConnectorError::InvalidConnectorConfig {
+                config: "merchant_connector_account.metadata",
+            })?;
+        Ok(metadata)
+    }
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PaysafePaymentHandleRequest {
+    pub merchant_ref_num: String,
+    pub amount: MinorUnit,
+    pub settle_with_auth: bool,
+    pub card: PaysafeCard,
+    pub currency_code: enums::Currency,
+    pub payment_type: PaysafePaymentType,
+    pub transaction_type: TransactionType,
+    pub return_links: Vec<ReturnLink>,
+    pub account_id: Secret<String>,
+}
+
+#[derive(Debug, Serialize)]
+pub struct ReturnLink {
+    pub rel: LinkType,
+    pub href: String,
+    pub method: String,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum LinkType {
+    OnCompleted,
+    OnFailed,
+    OnCancelled,
+    Default,
+}
+
+#[derive(Debug, Serialize)]
+pub enum PaysafePaymentType {
+    #[serde(rename = "CARD")]
+    Card,
+}
+
+#[derive(Debug, Serialize)]
+pub enum TransactionType {
+    #[serde(rename = "PAYMENT")]
+    Payment,
+}
+
+impl TryFrom<&PaysafeRouterData<&PaymentsPreProcessingRouterData>> for PaysafePaymentHandleRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: &PaysafeRouterData<&PaymentsPreProcessingRouterData>,
+    ) -> Result<Self, Self::Error> {
+        if item.router_data.is_three_ds() {
+            Err(errors::ConnectorError::NotSupported {
+                message: "Card 3DS".to_string(),
+                connector: "Paysafe",
+            })?
+        };
+        let metadata: PaysafeConnectorMetadataObject =
+            utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())
+                .change_context(errors::ConnectorError::InvalidConnectorConfig {
+                    config: "merchant_connector_account.metadata",
+                })?;
+        match item.router_data.request.get_payment_method_data()?.clone() {
+            PaymentMethodData::Card(req_card) => {
+                let card = PaysafeCard {
+                    card_num: req_card.card_number.clone(),
+                    card_expiry: PaysafeCardExpiry {
+                        month: req_card.card_exp_month.clone(),
+                        year: req_card.get_expiry_year_4_digit(),
+                    },
+                    cvv: if req_card.card_cvc.clone().expose().is_empty() {
+                        None
+                    } else {
+                        Some(req_card.card_cvc.clone())
+                    },
+                    holder_name: item.router_data.get_optional_billing_full_name(),
+                };
+                let account_id = metadata.account_id;
+
+                let amount = item.amount;
+                let payment_type = PaysafePaymentType::Card;
+                let transaction_type = TransactionType::Payment;
+                let redirect_url = item.router_data.request.get_router_return_url()?;
+                let return_links = vec![
+                    ReturnLink {
+                        rel: LinkType::Default,
+                        href: redirect_url.clone(),
+                        method: Method::Get.to_string(),
+                    },
+                    ReturnLink {
+                        rel: LinkType::OnCompleted,
+                        href: redirect_url.clone(),
+                        method: Method::Get.to_string(),
+                    },
+                    ReturnLink {
+                        rel: LinkType::OnFailed,
+                        href: redirect_url.clone(),
+                        method: Method::Get.to_string(),
+                    },
+                    ReturnLink {
+                        rel: LinkType::OnCancelled,
+                        href: redirect_url.clone(),
+                        method: Method::Get.to_string(),
+                    },
+                ];
+
+                Ok(Self {
+                    merchant_ref_num: item.router_data.connector_request_reference_id.clone(),
+                    amount,
+                    settle_with_auth: matches!(
+                        item.router_data.request.capture_method,
+                        Some(enums::CaptureMethod::Automatic) | None
+                    ),
+                    card,
+                    currency_code: item.router_data.request.get_currency()?,
+                    payment_type,
+                    transaction_type,
+                    return_links,
+                    account_id,
+                })
+            }
+            _ => Err(errors::ConnectorError::NotImplemented(
+                "Payment Method".to_string(),
+            ))?,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PaysafePaymentHandleResponse {
+    pub id: String,
+    pub merchant_ref_num: String,
+    pub payment_handle_token: Secret<String>,
+    pub status: PaysafePaymentHandleStatus,
+}
+
+#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum PaysafePaymentHandleStatus {
+    Initiated,
+    Payable,
+    #[default]
+    Processing,
+    Failed,
+    Expired,
+    Completed,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct PaysafeMeta {
+    pub payment_handle_token: Secret<String>,
+}
+
+impl<F>
+    TryFrom<
+        ResponseRouterData<
+            F,
+            PaysafePaymentHandleResponse,
+            PaymentsPreProcessingData,
+            PaymentsResponseData,
+        >,
+    > for RouterData<F, PaymentsPreProcessingData, PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: ResponseRouterData<
+            F,
+            PaysafePaymentHandleResponse,
+            PaymentsPreProcessingData,
+            PaymentsResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            preprocessing_id: Some(
+                item.response
+                    .payment_handle_token
+                    .to_owned()
+                    .peek()
+                    .to_string(),
+            ),
+            response: Ok(PaymentsResponseData::TransactionResponse {
+                resource_id: ResponseId::NoResponseId,
+                redirection_data: Box::new(None),
+                mandate_reference: Box::new(None),
+                connector_metadata: None,
+                network_txn_id: None,
+                connector_response_reference_id: None,
+                incremental_authorization_allowed: None,
+                charges: None,
+            }),
+            ..item.data
+        })
+    }
+}
+
+impl<F>
+    TryFrom<
+        ResponseRouterData<F, PaysafePaymentsResponse, PaymentsAuthorizeData, PaymentsResponseData>,
+    > for RouterData<F, PaymentsAuthorizeData, PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: ResponseRouterData<
+            F,
+            PaysafePaymentsResponse,
+            PaymentsAuthorizeData,
+            PaymentsResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            status: get_paysafe_payment_status(
+                item.response.status,
+                item.data.request.capture_method,
+            ),
+            response: Ok(PaymentsResponseData::TransactionResponse {
+                resource_id: ResponseId::ConnectorTransactionId(item.response.id),
+                redirection_data: Box::new(None),
+                mandate_reference: Box::new(None),
+                connector_metadata: None,
+                network_txn_id: None,
+                connector_response_reference_id: None,
+                incremental_authorization_allowed: None,
+                charges: None,
+            }),
+            ..item.data
+        })
+    }
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
 pub struct PaysafePaymentsRequest {
-    amount: StringMinorUnit,
-    card: PaysafeCard,
+    pub merchant_ref_num: String,
+    pub amount: MinorUnit,
+    pub settle_with_auth: bool,
+    pub payment_handle_token: Secret<String>,
+    pub currency_code: enums::Currency,
+    pub customer_ip: Option<Secret<String, IpAddress>>,
 }
 
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
+#[derive(Debug, Serialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
 pub struct PaysafeCard {
-    number: cards::CardNumber,
-    expiry_month: Secret<String>,
-    expiry_year: Secret<String>,
-    cvc: Secret<String>,
-    complete: bool,
+    pub card_num: CardNumber,
+    pub card_expiry: PaysafeCardExpiry,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub cvv: Option<Secret<String>>,
+    pub holder_name: Option<Secret<String>>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct PaysafeCardExpiry {
+    pub month: Secret<String>,
+    pub year: Secret<String>,
 }
 
 impl TryFrom<&PaysafeRouterData<&PaymentsAuthorizeRouterData>> for PaysafePaymentsRequest {
@@ -51,72 +319,278 @@ impl TryFrom<&PaysafeRouterData<&PaymentsAuthorizeRouterData>> for PaysafePaymen
     fn try_from(
         item: &PaysafeRouterData<&PaymentsAuthorizeRouterData>,
     ) -> Result<Self, Self::Error> {
-        match item.router_data.request.payment_method_data.clone() {
-            PaymentMethodData::Card(_) => Err(errors::ConnectorError::NotImplemented(
-                "Card payment method not implemented".to_string(),
-            )
-            .into()),
-            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
-        }
+        if item.router_data.is_three_ds() {
+            Err(errors::ConnectorError::NotSupported {
+                message: "Card 3DS".to_string(),
+                connector: "Paysafe",
+            })?
+        };
+        let payment_handle_token = Secret::new(item.router_data.get_preprocessing_id()?);
+        let amount = item.amount;
+        let customer_ip = Some(
+            item.router_data
+                .request
+                .get_browser_info()?
+                .get_ip_address()?,
+        );
+
+        Ok(Self {
+            merchant_ref_num: item.router_data.connector_request_reference_id.clone(),
+            payment_handle_token,
+            amount,
+            settle_with_auth: item.router_data.request.is_auto_capture()?,
+            currency_code: item.router_data.request.currency,
+            customer_ip,
+        })
     }
 }
 
-//TODO: Fill the struct with respective fields
-// Auth Struct
 pub struct PaysafeAuthType {
-    pub(super) api_key: Secret<String>,
+    pub(super) username: Secret<String>,
+    pub(super) password: Secret<String>,
 }
 
 impl TryFrom<&ConnectorAuthType> for PaysafeAuthType {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
         match auth_type {
-            ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
-                api_key: api_key.to_owned(),
+            ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
+                username: api_key.to_owned(),
+                password: key1.to_owned(),
             }),
             _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
         }
     }
 }
-// PaymentsResponse
-//TODO: Append the remaining status flags
+
+// Paysafe Payment Status
 #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "lowercase")]
+#[serde(rename_all = "UPPERCASE")]
 pub enum PaysafePaymentStatus {
-    Succeeded,
+    Received,
+    Completed,
+    Held,
     Failed,
     #[default]
+    Pending,
+    Cancelled,
     Processing,
 }
 
-impl From<PaysafePaymentStatus> for common_enums::AttemptStatus {
-    fn from(item: PaysafePaymentStatus) -> Self {
+pub fn get_paysafe_payment_status(
+    status: PaysafePaymentStatus,
+    capture_method: Option<common_enums::CaptureMethod>,
+) -> common_enums::AttemptStatus {
+    match status {
+        PaysafePaymentStatus::Completed => match capture_method {
+            Some(common_enums::CaptureMethod::Manual) => common_enums::AttemptStatus::Authorized,
+            Some(common_enums::CaptureMethod::Automatic) | None => {
+                common_enums::AttemptStatus::Charged
+            }
+            Some(common_enums::CaptureMethod::SequentialAutomatic)
+            | Some(common_enums::CaptureMethod::ManualMultiple)
+            | Some(common_enums::CaptureMethod::Scheduled) => {
+                common_enums::AttemptStatus::Unresolved
+            }
+        },
+        PaysafePaymentStatus::Failed => common_enums::AttemptStatus::Failure,
+        PaysafePaymentStatus::Pending
+        | PaysafePaymentStatus::Processing
+        | PaysafePaymentStatus::Received
+        | PaysafePaymentStatus::Held => common_enums::AttemptStatus::Pending,
+        PaysafePaymentStatus::Cancelled => common_enums::AttemptStatus::Voided,
+    }
+}
+
+// Paysafe Payments Response Structure
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PaysafePaymentsSyncResponse {
+    pub payments: Vec<PaysafePaymentsResponse>,
+}
+
+// Paysafe Payments Response Structure
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+pub struct PaysafePaymentsResponse {
+    pub id: String,
+    pub merchant_ref_num: Option<String>,
+    pub status: PaysafePaymentStatus,
+    pub settlements: Option<Vec<PaysafeSettlementResponse>>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+pub struct PaysafeSettlementResponse {
+    pub merchant_ref_num: Option<String>,
+    pub id: String,
+    pub status: PaysafeSettlementStatus,
+}
+
+impl<F>
+    TryFrom<
+        ResponseRouterData<F, PaysafePaymentsSyncResponse, PaymentsSyncData, PaymentsResponseData>,
+    > for RouterData<F, PaymentsSyncData, PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: ResponseRouterData<
+            F,
+            PaysafePaymentsSyncResponse,
+            PaymentsSyncData,
+            PaymentsResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        let payment_handle = item
+            .response
+            .payments
+            .first()
+            .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?;
+        Ok(Self {
+            status: get_paysafe_payment_status(
+                payment_handle.status,
+                item.data.request.capture_method,
+            ),
+            response: Ok(PaymentsResponseData::TransactionResponse {
+                resource_id: ResponseId::NoResponseId,
+                redirection_data: Box::new(None),
+                mandate_reference: Box::new(None),
+                connector_metadata: None,
+                network_txn_id: None,
+                connector_response_reference_id: None,
+                incremental_authorization_allowed: None,
+                charges: None,
+            }),
+            ..item.data
+        })
+    }
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PaysafeCaptureRequest {
+    pub merchant_ref_num: String,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub amount: Option<MinorUnit>,
+}
+
+impl TryFrom<&PaysafeRouterData<&PaymentsCaptureRouterData>> for PaysafeCaptureRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &PaysafeRouterData<&PaymentsCaptureRouterData>) -> Result<Self, Self::Error> {
+        let amount = Some(item.amount);
+
+        Ok(Self {
+            merchant_ref_num: item.router_data.connector_request_reference_id.clone(),
+            amount,
+        })
+    }
+}
+
+#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum PaysafeSettlementStatus {
+    Received,
+    Initiated,
+    Completed,
+    Expired,
+    Failed,
+    #[default]
+    Pending,
+    Cancelled,
+}
+
+impl From<PaysafeSettlementStatus> for common_enums::AttemptStatus {
+    fn from(item: PaysafeSettlementStatus) -> Self {
         match item {
-            PaysafePaymentStatus::Succeeded => Self::Charged,
-            PaysafePaymentStatus::Failed => Self::Failure,
-            PaysafePaymentStatus::Processing => Self::Authorizing,
+            PaysafeSettlementStatus::Completed
+            | PaysafeSettlementStatus::Pending
+            | PaysafeSettlementStatus::Received => Self::Charged,
+            PaysafeSettlementStatus::Failed | PaysafeSettlementStatus::Expired => Self::Failure,
+            PaysafeSettlementStatus::Cancelled => Self::Voided,
+            PaysafeSettlementStatus::Initiated => Self::Pending,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct PaysafePaymentsResponse {
-    status: PaysafePaymentStatus,
-    id: String,
+impl<F, T> TryFrom<ResponseRouterData<F, PaysafeSettlementResponse, T, PaymentsResponseData>>
+    for RouterData<F, T, PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: ResponseRouterData<F, PaysafeSettlementResponse, T, PaymentsResponseData>,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            status: common_enums::AttemptStatus::from(item.response.status),
+            response: Ok(PaymentsResponseData::TransactionResponse {
+                resource_id: ResponseId::ConnectorTransactionId(item.response.id.clone()),
+                redirection_data: Box::new(None),
+                mandate_reference: Box::new(None),
+                connector_metadata: None,
+                network_txn_id: None,
+                connector_response_reference_id: None,
+                incremental_authorization_allowed: None,
+                charges: None,
+            }),
+            ..item.data
+        })
+    }
+}
+
+impl TryFrom<&PaysafeRouterData<&PaymentsCancelRouterData>> for PaysafeCaptureRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &PaysafeRouterData<&PaymentsCancelRouterData>) -> Result<Self, Self::Error> {
+        let amount = Some(item.amount);
+
+        Ok(Self {
+            merchant_ref_num: item.router_data.connector_request_reference_id.clone(),
+            amount,
+        })
+    }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+pub struct VoidResponse {
+    pub merchant_ref_num: Option<String>,
+    pub id: String,
+    pub status: PaysafeVoidStatus,
+}
+
+#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "UPPERCASE")]
+pub enum PaysafeVoidStatus {
+    Received,
+    Completed,
+    Held,
+    Failed,
+    #[default]
+    Pending,
+    Cancelled,
+}
+
+impl From<PaysafeVoidStatus> for common_enums::AttemptStatus {
+    fn from(item: PaysafeVoidStatus) -> Self {
+        match item {
+            PaysafeVoidStatus::Completed
+            | PaysafeVoidStatus::Pending
+            | PaysafeVoidStatus::Received => Self::Voided,
+            PaysafeVoidStatus::Failed | PaysafeVoidStatus::Held => Self::Failure,
+            PaysafeVoidStatus::Cancelled => Self::Voided,
+        }
+    }
 }
 
-impl<F, T> TryFrom<ResponseRouterData<F, PaysafePaymentsResponse, T, PaymentsResponseData>>
+impl<F, T> TryFrom<ResponseRouterData<F, VoidResponse, T, PaymentsResponseData>>
     for RouterData<F, T, PaymentsResponseData>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
-        item: ResponseRouterData<F, PaysafePaymentsResponse, T, PaymentsResponseData>,
+        item: ResponseRouterData<F, VoidResponse, T, PaymentsResponseData>,
     ) -> Result<Self, Self::Error> {
         Ok(Self {
             status: common_enums::AttemptStatus::from(item.response.status),
             response: Ok(PaymentsResponseData::TransactionResponse {
-                resource_id: ResponseId::ConnectorTransactionId(item.response.id),
+                resource_id: ResponseId::NoResponseId,
                 redirection_data: Box::new(None),
                 mandate_reference: Box::new(None),
                 connector_metadata: None,
@@ -130,46 +604,50 @@ impl<F, T> TryFrom<ResponseRouterData<F, PaysafePaymentsResponse, T, PaymentsRes
     }
 }
 
-//TODO: Fill the struct with respective fields
-// REFUND :
-// Type definition for RefundRequest
-#[derive(Default, Debug, Serialize)]
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
 pub struct PaysafeRefundRequest {
-    pub amount: StringMinorUnit,
+    pub merchant_ref_num: String,
+    pub amount: MinorUnit,
 }
 
 impl<F> TryFrom<&PaysafeRouterData<&RefundsRouterData<F>>> for PaysafeRefundRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &PaysafeRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
+        let amount = item.amount;
+
         Ok(Self {
-            amount: item.amount.to_owned(),
+            merchant_ref_num: item.router_data.request.refund_id.clone(),
+            amount,
         })
     }
 }
 
 // Type definition for Refund Response
 
-#[allow(dead_code)]
 #[derive(Debug, Copy, Serialize, Default, Deserialize, Clone)]
+#[serde(rename_all = "UPPERCASE")]
 pub enum RefundStatus {
-    Succeeded,
+    Received,
+    Initiated,
+    Completed,
+    Expired,
     Failed,
     #[default]
-    Processing,
+    Pending,
+    Cancelled,
 }
 
 impl From<RefundStatus> for enums::RefundStatus {
     fn from(item: RefundStatus) -> Self {
         match item {
-            RefundStatus::Succeeded => Self::Success,
-            RefundStatus::Failed => Self::Failure,
-            RefundStatus::Processing => Self::Pending,
-            //TODO: Review mapping
+            RefundStatus::Received | RefundStatus::Completed => Self::Success,
+            RefundStatus::Failed | RefundStatus::Cancelled | RefundStatus::Expired => Self::Failure,
+            RefundStatus::Pending | RefundStatus::Initiated => Self::Pending,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
 #[derive(Default, Debug, Clone, Serialize, Deserialize)]
 pub struct RefundResponse {
     id: String,
@@ -206,14 +684,22 @@ impl TryFrom<RefundsResponseRouterData<RSync, RefundResponse>> for RefundsRouter
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Serialize, Deserialize)]
 pub struct PaysafeErrorResponse {
-    pub status_code: u16,
+    pub error: Error,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Error {
     pub code: String,
     pub message: String,
-    pub reason: Option<String>,
-    pub network_advice_code: Option<String>,
-    pub network_decline_code: Option<String>,
-    pub network_error_message: Option<String>,
+    pub details: Option<Vec<String>>,
+    #[serde(rename = "fieldErrors")]
+    pub field_errors: Option<Vec<FieldError>>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct FieldError {
+    pub field: String,
+    pub error: String,
 }
diff --git a/crates/hyperswitch_connectors/src/default_implementations.rs b/crates/hyperswitch_connectors/src/default_implementations.rs
index 8b87e0c098a..0535088c884 100644
--- a/crates/hyperswitch_connectors/src/default_implementations.rs
+++ b/crates/hyperswitch_connectors/src/default_implementations.rs
@@ -1664,7 +1664,6 @@ macro_rules! default_imp_for_pre_processing_steps{
 }
 
 default_imp_for_pre_processing_steps!(
-    connectors::Paysafe,
     connectors::Trustpayments,
     connectors::Silverflow,
     connectors::Vgs,
diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs
index d34cb480800..edc6e5a42bb 100644
--- a/crates/hyperswitch_connectors/src/utils.rs
+++ b/crates/hyperswitch_connectors/src/utils.rs
@@ -2411,6 +2411,7 @@ pub trait PaymentsPreProcessingRequestData {
     fn get_browser_info(&self) -> Result<BrowserInformation, Error>;
     fn get_complete_authorize_url(&self) -> Result<String, Error>;
     fn connector_mandate_id(&self) -> Option<String>;
+    fn get_payment_method_data(&self) -> Result<PaymentMethodData, Error>;
 }
 
 impl PaymentsPreProcessingRequestData for PaymentsPreProcessingData {
@@ -2422,6 +2423,11 @@ impl PaymentsPreProcessingRequestData for PaymentsPreProcessingData {
             .to_owned()
             .ok_or_else(missing_field_err("payment_method_type"))
     }
+    fn get_payment_method_data(&self) -> Result<PaymentMethodData, Error> {
+        self.payment_method_data
+            .to_owned()
+            .ok_or_else(missing_field_err("payment_method_data"))
+    }
     fn get_currency(&self) -> Result<enums::Currency, Error> {
         self.currency.ok_or_else(missing_field_err("currency"))
     }
diff --git a/crates/router/src/core/connector_validation.rs b/crates/router/src/core/connector_validation.rs
index 69e8cf96218..77e51e63f38 100644
--- a/crates/router/src/core/connector_validation.rs
+++ b/crates/router/src/core/connector_validation.rs
@@ -396,6 +396,13 @@ impl ConnectorAuthTypeAndMetadataValidation<'_> {
                 paypal::transformers::PaypalAuthType::try_from(self.auth_type)?;
                 Ok(())
             }
+            api_enums::Connector::Paysafe => {
+                paysafe::transformers::PaysafeAuthType::try_from(self.auth_type)?;
+                paysafe::transformers::PaysafeConnectorMetadataObject::try_from(
+                    self.connector_meta_data,
+                )?;
+                Ok(())
+            }
             api_enums::Connector::Payone => {
                 payone::transformers::PayoneAuthType::try_from(self.auth_type)?;
                 Ok(())
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index a87d22191b6..7db83c383d8 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -6593,6 +6593,14 @@ where
                 router_data = router_data.preprocessing_steps(state, connector).await?;
 
                 (router_data, false)
+            } else if connector.connector_name == router_types::Connector::Paysafe
+                && router_data.auth_type == storage_enums::AuthenticationType::NoThreeDs
+            {
+                router_data = router_data.preprocessing_steps(state, connector).await?;
+
+                let is_error_in_response = router_data.response.is_err();
+                // If is_error_in_response is true, should_continue_payment should be false, we should throw the error
+                (router_data, !is_error_in_response)
             } else if (connector.connector_name == router_types::Connector::Cybersource
                 || connector.connector_name == router_types::Connector::Barclaycard)
                 && is_operation_complete_authorize(&operation)
diff --git a/crates/router/src/types/api/connector_mapping.rs b/crates/router/src/types/api/connector_mapping.rs
index 2f93feba334..0e809c628f1 100644
--- a/crates/router/src/types/api/connector_mapping.rs
+++ b/crates/router/src/types/api/connector_mapping.rs
@@ -424,6 +424,9 @@ impl ConnectorData {
                 enums::Connector::Paypal => {
                     Ok(ConnectorEnum::Old(Box::new(connector::Paypal::new())))
                 }
+                enums::Connector::Paysafe => {
+                    Ok(ConnectorEnum::Old(Box::new(connector::Paysafe::new())))
+                }
                 enums::Connector::Paystack => {
                     Ok(ConnectorEnum::Old(Box::new(connector::Paystack::new())))
                 }
diff --git a/crates/router/src/types/api/feature_matrix.rs b/crates/router/src/types/api/feature_matrix.rs
index 77286011ad0..98e00bc893d 100644
--- a/crates/router/src/types/api/feature_matrix.rs
+++ b/crates/router/src/types/api/feature_matrix.rs
@@ -343,6 +343,9 @@ impl FeatureMatrixConnectorData {
                 enums::Connector::Paypal => {
                     Ok(ConnectorEnum::Old(Box::new(connector::Paypal::new())))
                 }
+                enums::Connector::Paysafe => {
+                    Ok(ConnectorEnum::Old(Box::new(connector::Paysafe::new())))
+                }
                 enums::Connector::Paystack => {
                     Ok(ConnectorEnum::Old(Box::new(connector::Paystack::new())))
                 }
diff --git a/crates/router/src/types/connector_transformers.rs b/crates/router/src/types/connector_transformers.rs
index 0688b466558..fb43e8b1360 100644
--- a/crates/router/src/types/connector_transformers.rs
+++ b/crates/router/src/types/connector_transformers.rs
@@ -110,6 +110,7 @@ impl ForeignTryFrom<api_enums::Connector> for common_enums::RoutableConnectors {
             api_enums::Connector::Payme => Self::Payme,
             api_enums::Connector::Payone => Self::Payone,
             api_enums::Connector::Paypal => Self::Paypal,
+            api_enums::Connector::Paysafe => Self::Paysafe,
             api_enums::Connector::Paystack => Self::Paystack,
             api_enums::Connector::Payu => Self::Payu,
             api_models::enums::Connector::Placetopay => Self::Placetopay,
diff --git a/crates/test_utils/src/connector_auth.rs b/crates/test_utils/src/connector_auth.rs
index 1bf84848e47..f6deae24e20 100644
--- a/crates/test_utils/src/connector_auth.rs
+++ b/crates/test_utils/src/connector_auth.rs
@@ -94,7 +94,7 @@ pub struct ConnectorAuthentication {
     pub payme: Option<BodyKey>,
     pub payone: Option<HeaderKey>,
     pub paypal: Option<BodyKey>,
-    pub paysafe: Option<HeaderKey>,
+    pub paysafe: Option<BodyKey>,
     pub paystack: Option<HeaderKey>,
     pub paytm: Option<HeaderKey>,
     pub payu: Option<BodyKey>,

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

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

## Description
Integrate Paysafe connector - No 3ds Cards
Flows 
- Payment
- Psync
- Capture
- Void
- Refund
- Refund Sync

### 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?
1. Create MCA for Paysafe connector
```
curl --location 'http://localhost:8080/account/merchant_1756845023/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: _' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "paysafe",
    "business_country": "US",
    "business_label": "food",
    "connector_account_details": {
        "auth_type": "BodyKey",
         "api_key": "**", 
            "key1": "***"
    },
    "test_mode": false,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "debit",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
    ],
    "metadata": {
        "report_group" : "Hello",
        "merchant_config_currency":"USD",
        "account_id": "_____"
    }
}'
```

Create a Payment 
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: _' \
--data '{
    "amount": 1500,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "customer_id": "aaaa",
    "payment_method": "card",
    "payment_method_type": "credit",
    "profile_id": "pro_Dpwkpk5tMI4H6ZdYjpEW",
    "payment_method_data": {
        "card": {
            "card_number": "4530910000012345", 
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "Joseph",
            "card_cvc": "111"
        }
    },
     "billing": {
        "address": {
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "city": "Downtown Core",
            "state": "Central Indiana America",
            "zip": "039393",
            "country": "SG",
            "first_name": "박성준",
            "last_name": "박성준"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
      "shipping": {
        "address": {
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "city": "Downtown Core",
            "state": "Central Indiana America",
            "zip": "039393",
            "country": "SG",
            "first_name": "박성준",
            "last_name": "박성준"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
        "browser_info": {
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "127.0.0.1"
    }
}'
```
Response
```
{
    "payment_id": "pay_PGOFJN06yH9nEglswyFF",
    "merchant_id": "merchant_1756845023",
    "status": "succeeded",
    "amount": 1500,
    "net_amount": 1500,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 1500,
    "connector": "paysafe",
    "client_secret": "pay_PGOFJN06yH9nEglswyFF_secret_UdTEHyTjQIGYtgESFnqe",
    "created": "2025-09-02T20:31:17.873Z",
    "currency": "USD",
    "customer_id": "aaaa",
    "customer": {
        "id": "aaaa",
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "2345",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "453091",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "Joseph",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "aaaa",
        "created_at": 1756845077,
        "expires": 1756848677,
        "secret": "epk_6ed44431aa3048fc87756aba02f4deb7"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "09ef3d4c-ef25-4234-b6a7-f0e074b16fa0",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_Dpwkpk5tMI4H6ZdYjpEW",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_pliYtewxLmWuyNqYCjxg",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-02T20:46:17.873Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-02T20:31:19.281Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null
}
```
Create a Payment with capture_method as manual 
- Response
```
{
    "payment_id": "pay_NtJnAOrMkNpnmUFaSP3P",
    "merchant_id": "merchant_1756845023",
    "status": "requires_capture",
    "amount": 1500,
    "net_amount": 1500,
    "shipping_cost": null,
    "amount_capturable": 1500,
    "amount_received": null,
    "connector": "paysafe",
    "client_secret": "pay_NtJnAOrMkNpnmUFaSP3P_secret_ScE2jv35Tp7z2ors0vSN",
    "created": "2025-09-02T20:59:00.726Z",
    "currency": "USD",
    "customer_id": "aaaa",
    "customer": {
        "id": "aaaa",
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "2345",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "453091",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "Joseph",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "aaaa",
        "created_at": 1756846740,
        "expires": 1756850340,
        "secret": "epk_725012e7f4524681a43c922269d96501"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "7b6151d0-a81c-4dea-8c65-72053993f1a0",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_Dpwkpk5tMI4H6ZdYjpEW",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_pliYtewxLmWuyNqYCjxg",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-02T21:14:00.726Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-02T20:59:02.385Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null
}
```

Capture the payment
Response
```
{
    "payment_id": "pay_NtJnAOrMkNpnmUFaSP3P",
    "merchant_id": "merchant_1756845023",
    "status": "succeeded",
    "amount": 1500,
    "net_amount": 1500,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 1500,
    "connector": "paysafe",
    "client_secret": "pay_NtJnAOrMkNpnmUFaSP3P_secret_ScE2jv35Tp7z2ors0vSN",
    "created": "2025-09-02T20:59:00.726Z",
    "currency": "USD",
    "customer_id": "aaaa",
    "customer": {
        "id": "aaaa",
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "2345",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "453091",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "Joseph",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "f1063df1-4f29-433c-a97f-f9b3d32dac5d",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_Dpwkpk5tMI4H6ZdYjpEW",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_pliYtewxLmWuyNqYCjxg",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-02T21:14:00.726Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-02T20:59:27.495Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null
}
```

Make one more payment with capture method manual
- Then void it
Response
```
{
    "payment_id": "pay_TaErSsfUWajhzursc4jS",
    "merchant_id": "merchant_1756845023",
    "status": "cancelled",
    "amount": 1500,
    "net_amount": 1500,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": "paysafe",
    "client_secret": "pay_TaErSsfUWajhzursc4jS_secret_l7P3CWNj0vzLmXG6TNiT",
    "created": "2025-09-02T21:00:32.402Z",
    "currency": "USD",
    "customer_id": "aaaa",
    "customer": {
        "id": "aaaa",
        "name": null,
        "email": null,
        "phone": null,
        "phone_country_code": null
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "2345",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "453091",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "Joseph",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "Downtown Core",
            "country": "SG",
            "line1": "Singapore Changi Airport. 2nd flr",
            "line2": "",
            "line3": "",
            "zip": "039393",
            "state": "Central Indiana America",
            "first_name": "박성준",
            "last_name": "박성준",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": "requested_by_customer",
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "2951a54a-c923-48d4-9738-5e16bb440b3e",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_Dpwkpk5tMI4H6ZdYjpEW",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_pliYtewxLmWuyNqYCjxg",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-02T21:15:32.402Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-02T21:00:35.862Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null
}
```


Refunds
Refunds can only be triggered after sometime, as the payment take some time to settle. 
according to doc - This process is typically handled in an overnight batch.


Cypress
<img width="740" height="826" alt="Screenshot 2025-09-04 at 4 45 29 PM" src="https://github.com/user-attachments/assets/1ffe7b71-bc3d-4350-8af9-b7b3cd879b2b" />

<img width="957" height="852" alt="Screenshot 2025-09-08 at 3 57 46 PM" src="https://github.com/user-attachments/assets/e7f144c2-8c20-44b0-84a5-e2b531ec59a4" />



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