Bug: [FEATURE] Nexinets support for auth & capture, bank redirects and paypal



### Feature Description

- [x] Authorize, Capture, Void ThreeDS and non ThreeDS cards #898
- [x] Bank redirects : ideal, sofort, eps and Giropay #898
- [x] Wallet : Paypal redirection #898
- [x] Refund, Psync and Rsync #898

### Possible Implementation

Not applicable

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

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

### Have you read the Contributing Guidelines?

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

### Are you willing to submit a PR?

None
diff --git a/connector-template/mod.rs b/connector-template/mod.rs
index 75f2f02c027..f7653f16189 100644
--- a/connector-template/mod.rs
+++ b/connector-template/mod.rs
@@ -303,6 +303,7 @@ impl
                 .headers(types::PaymentsCaptureType::get_headers(
                     self, req, connectors,
                 )?)
+                .body(types::PaymentsCaptureType::get_request_body(self, req)?)
                 .build(),
         ))
     }
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index 65a2ca11338..5ab3ac128cf 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -601,7 +601,7 @@ pub enum Connector {
     Klarna,
     Mollie,
     Multisafepay,
-    // Nexinets, added as template code for future use
+    Nexinets,
     Nuvei,
     // Payeezy, As psync and rsync are not supported by this connector, it is added as template code for future usage
     Paypal,
@@ -666,7 +666,7 @@ pub enum RoutableConnectors {
     Klarna,
     Mollie,
     Multisafepay,
-    // Nexinets, added as template code for future use
+    Nexinets,
     Nuvei,
     Opennode,
     // Payeezy, As psync and rsync are not supported by this connector, it is added as template code for future usage
diff --git a/crates/router/src/connector/nexinets.rs b/crates/router/src/connector/nexinets.rs
index a7224c27a16..596b5cf6623 100644
--- a/crates/router/src/connector/nexinets.rs
+++ b/crates/router/src/connector/nexinets.rs
@@ -7,12 +7,14 @@ use transformers as nexinets;
 
 use crate::{
     configs::settings,
+    connector::utils::{to_connector_meta, PaymentsSyncRequestData},
     core::errors::{self, CustomResult},
     headers,
     services::{self, ConnectorIntegration},
     types::{
         self,
         api::{self, ConnectorCommon, ConnectorCommonExt},
+        storage::enums,
         ErrorResponse, Response,
     },
     utils::{self, BytesExt},
@@ -33,6 +35,16 @@ impl api::Refund for Nexinets {}
 impl api::RefundExecute for Nexinets {}
 impl api::RefundSync for Nexinets {}
 
+impl Nexinets {
+    pub fn connector_transaction_id(
+        &self,
+        connector_meta: &Option<serde_json::Value>,
+    ) -> CustomResult<Option<String>, errors::ConnectorError> {
+        let meta: nexinets::NexinetsPaymentsMetadata = to_connector_meta(connector_meta.clone())?;
+        Ok(meta.transaction_id)
+    }
+}
+
 impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Nexinets
 where
     Self: ConnectorIntegration<Flow, Request, Response>,
@@ -44,7 +56,7 @@ where
     ) -> CustomResult<Vec<(String, String)>, errors::ConnectorError> {
         let mut header = vec![(
             headers::CONTENT_TYPE.to_string(),
-            types::PaymentsAuthorizeType::get_content_type(self).to_string(),
+            self.get_content_type().to_string(),
         )];
         let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
         header.append(&mut api_key);
@@ -83,27 +95,32 @@ impl ConnectorCommon for Nexinets {
             .parse_struct("NexinetsErrorResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
 
+        let errors = response.errors.clone();
+        let mut message = String::new();
+        for error in errors.iter() {
+            let field = error.field.to_owned().unwrap_or_default();
+            let mut msg = String::new();
+            if !field.is_empty() {
+                msg.push_str(format!("{} : {}", field, error.message).as_str());
+            } else {
+                msg = error.message.to_owned();
+            }
+            if message.is_empty() {
+                message.push_str(&msg);
+            } else {
+                message.push_str(format!(", {}", msg).as_str());
+            }
+        }
+
         Ok(ErrorResponse {
-            status_code: res.status_code,
-            code: response.code,
-            message: response.message,
-            reason: response.reason,
+            status_code: response.status,
+            code: response.code.to_string(),
+            message,
+            reason: Some(response.message),
         })
     }
 }
 
-impl api::PaymentToken for Nexinets {}
-
-impl
-    ConnectorIntegration<
-        api::PaymentMethodToken,
-        types::PaymentMethodTokenizationData,
-        types::PaymentsResponseData,
-    > for Nexinets
-{
-    // Not Implemented (R)
-}
-
 impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
     for Nexinets
 {
@@ -136,10 +153,15 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
 
     fn get_url(
         &self,
-        _req: &types::PaymentsAuthorizeRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::PaymentsAuthorizeRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let url = if req.request.capture_method == Some(enums::CaptureMethod::Automatic) {
+            format!("{}/orders/debit", self.base_url(connectors))
+        } else {
+            format!("{}/orders/preauth", self.base_url(connectors))
+        };
+        Ok(url)
     }
 
     fn get_request_body(
@@ -178,7 +200,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
         data: &types::PaymentsAuthorizeRouterData,
         res: Response,
     ) -> CustomResult<types::PaymentsAuthorizeRouterData, errors::ConnectorError> {
-        let response: nexinets::NexinetsPaymentsResponse = res
+        let response: nexinets::NexinetsPreAuthOrDebitResponse = res
             .response
             .parse_struct("Nexinets PaymentsAuthorizeResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
@@ -187,7 +209,6 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -215,10 +236,23 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
 
     fn get_url(
         &self,
-        _req: &types::PaymentsSyncRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::PaymentsSyncRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let meta: nexinets::NexinetsPaymentsMetadata =
+            to_connector_meta(req.request.connector_meta.clone())?;
+        let order_id = nexinets::get_order_id(&meta)?;
+        let transaction_id = match meta.psync_flow {
+            transformers::NexinetsTransactionType::Debit
+            | transformers::NexinetsTransactionType::Capture => {
+                req.request.get_connector_transaction_id()?
+            }
+            _ => nexinets::get_transaction_id(&meta)?,
+        };
+        Ok(format!(
+            "{}/orders/{order_id}/transactions/{transaction_id}",
+            self.base_url(connectors)
+        ))
     }
 
     fn build_request(
@@ -241,16 +275,15 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
         data: &types::PaymentsSyncRouterData,
         res: Response,
     ) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> {
-        let response: nexinets::NexinetsPaymentsResponse = res
+        let response: nexinets::NexinetsPaymentResponse = res
             .response
-            .parse_struct("nexinets PaymentsSyncResponse")
+            .parse_struct("nexinets NexinetsPaymentResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         types::RouterData::try_from(types::ResponseRouterData {
             response,
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -278,17 +311,30 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
 
     fn get_url(
         &self,
-        _req: &types::PaymentsCaptureRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::PaymentsCaptureRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let meta: nexinets::NexinetsPaymentsMetadata =
+            to_connector_meta(req.request.connector_meta.clone())?;
+        let order_id = nexinets::get_order_id(&meta)?;
+        let transaction_id = nexinets::get_transaction_id(&meta)?;
+        Ok(format!(
+            "{}/orders/{order_id}/transactions/{transaction_id}/capture",
+            self.base_url(connectors)
+        ))
     }
 
     fn get_request_body(
         &self,
-        _req: &types::PaymentsCaptureRouterData,
+        req: &types::PaymentsCaptureRouterData,
     ) -> CustomResult<Option<String>, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into())
+        let connector_req = nexinets::NexinetsCaptureOrVoidRequest::try_from(req)?;
+        let nexinets_req =
+            utils::Encode::<nexinets::NexinetsCaptureOrVoidRequest>::encode_to_string_of_json(
+                &connector_req,
+            )
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        Ok(Some(nexinets_req))
     }
 
     fn build_request(
@@ -304,6 +350,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
                 .headers(types::PaymentsCaptureType::get_headers(
                     self, req, connectors,
                 )?)
+                .body(types::PaymentsCaptureType::get_request_body(self, req)?)
                 .build(),
         ))
     }
@@ -313,16 +360,15 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
         data: &types::PaymentsCaptureRouterData,
         res: Response,
     ) -> CustomResult<types::PaymentsCaptureRouterData, errors::ConnectorError> {
-        let response: nexinets::NexinetsPaymentsResponse = res
+        let response: nexinets::NexinetsPaymentResponse = res
             .response
-            .parse_struct("Nexinets PaymentsCaptureResponse")
+            .parse_struct("NexinetsPaymentResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         types::RouterData::try_from(types::ResponseRouterData {
             response,
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -336,6 +382,83 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
 impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsResponseData>
     for Nexinets
 {
+    fn get_headers(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Vec<(String, String)>, errors::ConnectorError> {
+        self.build_headers(req, connectors)
+    }
+
+    fn get_content_type(&self) -> &'static str {
+        self.common_get_content_type()
+    }
+
+    fn get_url(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let meta: nexinets::NexinetsPaymentsMetadata =
+            to_connector_meta(req.request.connector_meta.clone())?;
+        let order_id = nexinets::get_order_id(&meta)?;
+        let transaction_id = nexinets::get_transaction_id(&meta)?;
+        Ok(format!(
+            "{}/orders/{order_id}/transactions/{transaction_id}/cancel",
+            self.base_url(connectors),
+        ))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+    ) -> CustomResult<Option<String>, errors::ConnectorError> {
+        let connector_req = nexinets::NexinetsCaptureOrVoidRequest::try_from(req)?;
+        let nexinets_req =
+            utils::Encode::<nexinets::NexinetsCaptureOrVoidRequest>::encode_to_string_of_json(
+                &connector_req,
+            )
+            .change_context(errors::ConnectorError::RequestEncodingFailed)?;
+        Ok(Some(nexinets_req))
+    }
+
+    fn build_request(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
+        let request = services::RequestBuilder::new()
+            .method(services::Method::Post)
+            .url(&types::PaymentsVoidType::get_url(self, req, connectors)?)
+            .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?)
+            .body(types::PaymentsVoidType::get_request_body(self, req)?)
+            .build();
+
+        Ok(Some(request))
+    }
+
+    fn handle_response(
+        &self,
+        data: &types::PaymentsCancelRouterData,
+        res: Response,
+    ) -> CustomResult<types::PaymentsCancelRouterData, errors::ConnectorError> {
+        let response: nexinets::NexinetsPaymentResponse = res
+            .response
+            .parse_struct("NexinetsPaymentResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+        types::RouterData::try_from(types::ResponseRouterData {
+            response,
+            data: data.clone(),
+            http_code: res.status_code,
+        })
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res)
+    }
 }
 
 impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData>
@@ -355,10 +478,17 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
 
     fn get_url(
         &self,
-        _req: &types::RefundsRouterData<api::Execute>,
-        _connectors: &settings::Connectors,
+        req: &types::RefundsRouterData<api::Execute>,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let meta: nexinets::NexinetsPaymentsMetadata =
+            to_connector_meta(req.request.connector_metadata.clone())?;
+        let order_id = nexinets::get_order_id(&meta)?;
+        Ok(format!(
+            "{}/orders/{order_id}/transactions/{}/refund",
+            self.base_url(connectors),
+            req.request.connector_transaction_id
+        ))
     }
 
     fn get_request_body(
@@ -394,7 +524,7 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
         data: &types::RefundsRouterData<api::Execute>,
         res: Response,
     ) -> CustomResult<types::RefundsRouterData<api::Execute>, errors::ConnectorError> {
-        let response: nexinets::RefundResponse = res
+        let response: nexinets::NexinetsRefundResponse = res
             .response
             .parse_struct("nexinets RefundResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
@@ -403,7 +533,6 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -429,10 +558,21 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
 
     fn get_url(
         &self,
-        _req: &types::RefundSyncRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::RefundSyncRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let transaction_id = req
+            .request
+            .connector_refund_id
+            .clone()
+            .ok_or(errors::ConnectorError::MissingConnectorRefundID)?;
+        let meta: nexinets::NexinetsPaymentsMetadata =
+            to_connector_meta(req.request.connector_metadata.clone())?;
+        let order_id = nexinets::get_order_id(&meta)?;
+        Ok(format!(
+            "{}/orders/{order_id}/transactions/{transaction_id}",
+            self.base_url(connectors)
+        ))
     }
 
     fn build_request(
@@ -446,7 +586,6 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
                 .url(&types::RefundSyncType::get_url(self, req, connectors)?)
                 .attach_default_headers()
                 .headers(types::RefundSyncType::get_headers(self, req, connectors)?)
-                .body(types::RefundSyncType::get_request_body(self, req)?)
                 .build(),
         ))
     }
@@ -456,7 +595,7 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
         data: &types::RefundSyncRouterData,
         res: Response,
     ) -> CustomResult<types::RefundSyncRouterData, errors::ConnectorError> {
-        let response: nexinets::RefundResponse = res
+        let response: nexinets::NexinetsRefundResponse = res
             .response
             .parse_struct("nexinets RefundSyncResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
@@ -465,7 +604,6 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
             data: data.clone(),
             http_code: res.status_code,
         })
-        .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
 
     fn get_error_response(
@@ -499,3 +637,15 @@ impl api::IncomingWebhook for Nexinets {
         Err(errors::ConnectorError::WebhooksNotImplemented).into_report()
     }
 }
+
+impl api::PaymentToken for Nexinets {}
+
+impl
+    ConnectorIntegration<
+        api::PaymentMethodToken,
+        types::PaymentMethodTokenizationData,
+        types::PaymentsResponseData,
+    > for Nexinets
+{
+    // Not Implemented (R)
+}
diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs
index c2b59960845..fadae497470 100644
--- a/crates/router/src/connector/nexinets/transformers.rs
+++ b/crates/router/src/connector/nexinets/transformers.rs
@@ -1,48 +1,184 @@
+use api_models::payments::PaymentMethodData;
+use base64::Engine;
+use common_utils::errors::CustomResult;
+use error_stack::{IntoReport, ResultExt};
 use masking::Secret;
 use serde::{Deserialize, Serialize};
+use url::Url;
 
 use crate::{
-    connector::utils::PaymentsAuthorizeRequestData,
+    connector::utils::{
+        CardData, PaymentsAuthorizeRequestData, PaymentsCancelRequestData, WalletData,
+    },
+    consts,
     core::errors,
-    types::{self, api, storage::enums},
+    services,
+    types::{self, api, storage::enums, transformers::ForeignFrom},
 };
 
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
 pub struct NexinetsPaymentsRequest {
-    amount: i64,
-    card: NexinetsCard,
+    initial_amount: i64,
+    currency: enums::Currency,
+    channel: NexinetsChannel,
+    product: NexinetsProduct,
+    payment: Option<NexinetsPaymentDetails>,
+    #[serde(rename = "async")]
+    nexinets_async: NexinetsAsyncDetails,
 }
 
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
-pub struct NexinetsCard {
-    name: Secret<String>,
-    number: Secret<String, common_utils::pii::CardNumber>,
+#[derive(Debug, Serialize, Default)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum NexinetsChannel {
+    #[default]
+    Ecom,
+}
+
+#[derive(Default, Debug, Serialize)]
+#[serde(rename_all = "lowercase")]
+pub enum NexinetsProduct {
+    #[default]
+    Creditcard,
+    Paypal,
+    Giropay,
+    Sofort,
+    Eps,
+    Ideal,
+    Applepay,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+#[serde(untagged)]
+pub enum NexinetsPaymentDetails {
+    Card(Box<NexiCardDetails>),
+    Wallet(Box<NexinetsWalletDetails>),
+    BankRedirects(Box<NexinetsBankRedirects>),
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexiCardDetails {
+    #[serde(flatten)]
+    card_data: CardDataDetails,
+    cof_contract: Option<CofContract>,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(untagged)]
+pub enum CardDataDetails {
+    CardDetails(Box<CardDetails>),
+    PaymentInstrument(Box<PaymentInstrument>),
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CardDetails {
+    card_number: Secret<String, common_utils::pii::CardNumber>,
     expiry_month: Secret<String>,
     expiry_year: Secret<String>,
-    cvc: Secret<String>,
-    complete: bool,
+    verification: Secret<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PaymentInstrument {
+    payment_instrument_id: Option<String>,
+}
+
+#[derive(Debug, Serialize)]
+pub struct CofContract {
+    #[serde(rename = "type")]
+    recurring_type: RecurringType,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum RecurringType {
+    Unscheduled,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsBankRedirects {
+    bic: NexinetsBIC,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+
+pub struct NexinetsAsyncDetails {
+    pub success_url: Option<String>,
+    pub cancel_url: Option<String>,
+    pub failure_url: Option<String>,
+}
+
+#[derive(Debug, Serialize)]
+pub enum NexinetsBIC {
+    #[serde(rename = "ABNANL2A")]
+    AbnAmro,
+    #[serde(rename = "ASNBNL21")]
+    AsnBank,
+    #[serde(rename = "BUNQNL2A")]
+    Bunq,
+    #[serde(rename = "INGBNL2A")]
+    Ing,
+    #[serde(rename = "KNABNL2H")]
+    Knab,
+    #[serde(rename = "RABONL2U")]
+    Rabobank,
+    #[serde(rename = "RBRBNL21")]
+    Regiobank,
+    #[serde(rename = "SNSBNL2A")]
+    SnsBank,
+    #[serde(rename = "TRIONL2U")]
+    TriodosBank,
+    #[serde(rename = "FVLBNL22")]
+    VanLanschot,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub enum NexinetsWalletDetails {
+    ApplePayToken(Box<ApplePayDetails>),
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ApplePayDetails {
+    payment_data: serde_json::Value,
+    payment_method: ApplepayPaymentMethod,
+    transaction_identifier: String,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ApplepayPaymentMethod {
+    display_name: String,
+    network: String,
+    #[serde(rename = "type")]
+    token_type: String,
 }
 
 impl TryFrom<&types::PaymentsAuthorizeRouterData> for NexinetsPaymentsRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
-        match item.request.payment_method_data.clone() {
-            api::PaymentMethodData::Card(req_card) => {
-                let card = NexinetsCard {
-                    name: req_card.card_holder_name,
-                    number: req_card.card_number,
-                    expiry_month: req_card.card_exp_month,
-                    expiry_year: req_card.card_exp_year,
-                    cvc: req_card.card_cvc,
-                    complete: item.request.is_auto_capture()?,
-                };
-                Ok(Self {
-                    amount: item.request.amount,
-                    card,
-                })
-            }
-            _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
-        }
+        let return_url = item.request.router_return_url.clone();
+        let nexinets_async = NexinetsAsyncDetails {
+            success_url: return_url.clone(),
+            cancel_url: return_url.clone(),
+            failure_url: return_url,
+        };
+        let (payment, product) = get_payment_details_and_product(item)?;
+        Ok(Self {
+            initial_amount: item.request.amount,
+            currency: item.request.currency,
+            channel: NexinetsChannel::Ecom,
+            product,
+            payment,
+            nexinets_async,
+        })
     }
 }
 
@@ -55,60 +191,251 @@ impl TryFrom<&types::ConnectorAuthType> for NexinetsAuthType {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
         match auth_type {
-            types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
-                api_key: api_key.to_string(),
-            }),
-            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
+            types::ConnectorAuthType::BodyKey { api_key, key1 } => {
+                let auth_key = format!("{key1}:{api_key}");
+                let auth_header = format!("Basic {}", consts::BASE64_ENGINE.encode(auth_key));
+                Ok(Self {
+                    api_key: auth_header,
+                })
+            }
+            _ => Err(errors::ConnectorError::FailedToObtainAuthType)?,
         }
     }
 }
 // PaymentsResponse
-
-#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "lowercase")]
+#[derive(Debug, Deserialize, Clone)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 pub enum NexinetsPaymentStatus {
-    Succeeded,
-    Failed,
-    #[default]
-    Processing,
+    Success,
+    Pending,
+    Ok,
+    Failure,
+    Declined,
+    InProgress,
+    Expired,
+    Aborted,
 }
 
-impl From<NexinetsPaymentStatus> for enums::AttemptStatus {
-    fn from(item: NexinetsPaymentStatus) -> Self {
-        match item {
-            NexinetsPaymentStatus::Succeeded => Self::Charged,
-            NexinetsPaymentStatus::Failed => Self::Failure,
-            NexinetsPaymentStatus::Processing => Self::Authorizing,
+impl ForeignFrom<(NexinetsPaymentStatus, NexinetsTransactionType)> for enums::AttemptStatus {
+    fn foreign_from((status, method): (NexinetsPaymentStatus, NexinetsTransactionType)) -> Self {
+        match status {
+            NexinetsPaymentStatus::Success => match method {
+                NexinetsTransactionType::Preauth => Self::Authorized,
+                NexinetsTransactionType::Debit | NexinetsTransactionType::Capture => Self::Charged,
+                NexinetsTransactionType::Cancel => Self::Voided,
+            },
+            NexinetsPaymentStatus::Declined
+            | NexinetsPaymentStatus::Failure
+            | NexinetsPaymentStatus::Expired
+            | NexinetsPaymentStatus::Aborted => match method {
+                NexinetsTransactionType::Preauth => Self::AuthorizationFailed,
+                NexinetsTransactionType::Debit | NexinetsTransactionType::Capture => {
+                    Self::CaptureFailed
+                }
+                NexinetsTransactionType::Cancel => Self::VoidFailed,
+            },
+            NexinetsPaymentStatus::Ok => match method {
+                NexinetsTransactionType::Preauth => Self::Authorized,
+                _ => Self::Pending,
+            },
+            NexinetsPaymentStatus::Pending => Self::AuthenticationPending,
+            NexinetsPaymentStatus::InProgress => Self::Pending,
+        }
+    }
+}
+
+impl TryFrom<&api_models::enums::BankNames> for NexinetsBIC {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(bank: &api_models::enums::BankNames) -> Result<Self, Self::Error> {
+        match bank {
+            api_models::enums::BankNames::AbnAmro => Ok(Self::AbnAmro),
+            api_models::enums::BankNames::AsnBank => Ok(Self::AsnBank),
+            api_models::enums::BankNames::Bunq => Ok(Self::Bunq),
+            api_models::enums::BankNames::Ing => Ok(Self::Ing),
+            api_models::enums::BankNames::Knab => Ok(Self::Knab),
+            api_models::enums::BankNames::Rabobank => Ok(Self::Rabobank),
+            api_models::enums::BankNames::Regiobank => Ok(Self::Regiobank),
+            api_models::enums::BankNames::SnsBank => Ok(Self::SnsBank),
+            api_models::enums::BankNames::TriodosBank => Ok(Self::TriodosBank),
+            api_models::enums::BankNames::VanLanschot => Ok(Self::VanLanschot),
+            _ => Err(errors::ConnectorError::FlowNotSupported {
+                flow: bank.to_string(),
+                connector: "Nexinets".to_string(),
+            }
+            .into()),
         }
     }
 }
 
-#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct NexinetsPaymentsResponse {
-    status: NexinetsPaymentStatus,
-    id: String,
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsPreAuthOrDebitResponse {
+    order_id: String,
+    transaction_type: NexinetsTransactionType,
+    transactions: Vec<NexinetsTransaction>,
+    payment_instrument: PaymentInstrument,
+    redirect_url: Option<Url>,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsTransaction {
+    pub transaction_id: String,
+    #[serde(rename = "type")]
+    pub transaction_type: NexinetsTransactionType,
+    pub currency: enums::Currency,
+    pub status: NexinetsPaymentStatus,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum NexinetsTransactionType {
+    Preauth,
+    Debit,
+    Capture,
+    Cancel,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct NexinetsPaymentsMetadata {
+    pub transaction_id: Option<String>,
+    pub order_id: Option<String>,
+    pub psync_flow: NexinetsTransactionType,
 }
 
 impl<F, T>
-    TryFrom<types::ResponseRouterData<F, NexinetsPaymentsResponse, T, types::PaymentsResponseData>>
-    for types::RouterData<F, T, types::PaymentsResponseData>
+    TryFrom<
+        types::ResponseRouterData<
+            F,
+            NexinetsPreAuthOrDebitResponse,
+            T,
+            types::PaymentsResponseData,
+        >,
+    > for types::RouterData<F, T, types::PaymentsResponseData>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
         item: types::ResponseRouterData<
             F,
-            NexinetsPaymentsResponse,
+            NexinetsPreAuthOrDebitResponse,
             T,
             types::PaymentsResponseData,
         >,
     ) -> Result<Self, Self::Error> {
+        let transaction = match item.response.transactions.first() {
+            Some(order) => order,
+            _ => Err(errors::ConnectorError::ResponseHandlingFailed)?,
+        };
+        let connector_metadata = serde_json::to_value(NexinetsPaymentsMetadata {
+            transaction_id: Some(transaction.transaction_id.clone()),
+            order_id: Some(item.response.order_id.clone()),
+            psync_flow: item.response.transaction_type.clone(),
+        })
+        .into_report()
+        .change_context(errors::ConnectorError::ResponseHandlingFailed)?;
+        let redirection_data = item
+            .response
+            .redirect_url
+            .map(|url| services::RedirectForm::from((url, services::Method::Get)));
+        let resource_id = match item.response.transaction_type.clone() {
+            NexinetsTransactionType::Preauth => types::ResponseId::NoResponseId,
+            NexinetsTransactionType::Debit => {
+                types::ResponseId::ConnectorTransactionId(transaction.transaction_id.clone())
+            }
+            _ => Err(errors::ConnectorError::ResponseHandlingFailed)?,
+        };
+        let mandate_reference = item.response.payment_instrument.payment_instrument_id;
+        Ok(Self {
+            status: enums::AttemptStatus::foreign_from((
+                transaction.status.clone(),
+                item.response.transaction_type,
+            )),
+            response: Ok(types::PaymentsResponseData::TransactionResponse {
+                resource_id,
+                redirection_data,
+                mandate_reference,
+                connector_metadata: Some(connector_metadata),
+            }),
+            ..item.data
+        })
+    }
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsCaptureOrVoidRequest {
+    pub initial_amount: i64,
+    pub currency: enums::Currency,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsOrder {
+    pub order_id: String,
+}
+
+impl TryFrom<&types::PaymentsCaptureRouterData> for NexinetsCaptureOrVoidRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> {
+        Ok(Self {
+            initial_amount: item.request.amount_to_capture,
+            currency: item.request.currency,
+        })
+    }
+}
+
+impl TryFrom<&types::PaymentsCancelRouterData> for NexinetsCaptureOrVoidRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
+        Ok(Self {
+            initial_amount: item.request.get_amount()?,
+            currency: item.request.get_currency()?,
+        })
+    }
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsPaymentResponse {
+    pub transaction_id: String,
+    pub status: NexinetsPaymentStatus,
+    pub order: NexinetsOrder,
+    #[serde(rename = "type")]
+    pub transaction_type: NexinetsTransactionType,
+}
+
+impl<F, T>
+    TryFrom<types::ResponseRouterData<F, NexinetsPaymentResponse, T, types::PaymentsResponseData>>
+    for types::RouterData<F, T, types::PaymentsResponseData>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: types::ResponseRouterData<F, NexinetsPaymentResponse, T, types::PaymentsResponseData>,
+    ) -> Result<Self, Self::Error> {
+        let transaction_id = Some(item.response.transaction_id.clone());
+        let connector_metadata = serde_json::to_value(NexinetsPaymentsMetadata {
+            transaction_id,
+            order_id: Some(item.response.order.order_id),
+            psync_flow: item.response.transaction_type.clone(),
+        })
+        .into_report()
+        .change_context(errors::ConnectorError::ResponseHandlingFailed)?;
+        let resource_id = match item.response.transaction_type.clone() {
+            NexinetsTransactionType::Debit | NexinetsTransactionType::Capture => {
+                types::ResponseId::ConnectorTransactionId(item.response.transaction_id)
+            }
+            _ => types::ResponseId::NoResponseId,
+        };
         Ok(Self {
-            status: enums::AttemptStatus::from(item.response.status),
+            status: enums::AttemptStatus::foreign_from((
+                item.response.status,
+                item.response.transaction_type,
+            )),
             response: Ok(types::PaymentsResponseData::TransactionResponse {
-                resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
+                resource_id,
                 redirection_data: None,
                 mandate_reference: None,
-                connector_metadata: None,
+                connector_metadata: Some(connector_metadata),
             }),
             ..item.data
         })
@@ -117,57 +444,71 @@ impl<F, T>
 
 // REFUND :
 // Type definition for RefundRequest
-#[derive(Default, Debug, Serialize)]
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
 pub struct NexinetsRefundRequest {
-    pub amount: i64,
+    pub initial_amount: i64,
+    pub currency: enums::Currency,
 }
 
 impl<F> TryFrom<&types::RefundsRouterData<F>> for NexinetsRefundRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
         Ok(Self {
-            amount: item.request.amount,
+            initial_amount: item.request.refund_amount,
+            currency: item.request.currency,
         })
     }
 }
 
 // Type definition for Refund Response
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct NexinetsRefundResponse {
+    pub transaction_id: String,
+    pub status: RefundStatus,
+    pub order: NexinetsOrder,
+    #[serde(rename = "type")]
+    pub transaction_type: RefundType,
+}
 
 #[allow(dead_code)]
-#[derive(Debug, Serialize, Default, Deserialize, Clone)]
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 pub enum RefundStatus {
-    Succeeded,
-    Failed,
-    #[default]
-    Processing,
+    Success,
+    Ok,
+    Failure,
+    Declined,
+    InProgress,
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum RefundType {
+    Refund,
 }
 
 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,
+            RefundStatus::Success => Self::Success,
+            RefundStatus::Failure | RefundStatus::Declined => Self::Failure,
+            RefundStatus::InProgress | RefundStatus::Ok => Self::Pending,
         }
     }
 }
 
-#[derive(Default, Debug, Clone, Serialize, Deserialize)]
-pub struct RefundResponse {
-    id: String,
-    status: RefundStatus,
-}
-
-impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
+impl TryFrom<types::RefundsResponseRouterData<api::Execute, NexinetsRefundResponse>>
     for types::RefundsRouterData<api::Execute>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
-        item: types::RefundsResponseRouterData<api::Execute, RefundResponse>,
+        item: types::RefundsResponseRouterData<api::Execute, NexinetsRefundResponse>,
     ) -> Result<Self, Self::Error> {
         Ok(Self {
             response: Ok(types::RefundsResponseData {
-                connector_refund_id: item.response.id.to_string(),
+                connector_refund_id: item.response.transaction_id,
                 refund_status: enums::RefundStatus::from(item.response.status),
             }),
             ..item.data
@@ -175,16 +516,16 @@ impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
     }
 }
 
-impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundResponse>>
+impl TryFrom<types::RefundsResponseRouterData<api::RSync, NexinetsRefundResponse>>
     for types::RefundsRouterData<api::RSync>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(
-        item: types::RefundsResponseRouterData<api::RSync, RefundResponse>,
+        item: types::RefundsResponseRouterData<api::RSync, NexinetsRefundResponse>,
     ) -> Result<Self, Self::Error> {
         Ok(Self {
             response: Ok(types::RefundsResponseData {
-                connector_refund_id: item.response.id.to_string(),
+                connector_refund_id: item.response.transaction_id,
                 refund_status: enums::RefundStatus::from(item.response.status),
             }),
             ..item.data
@@ -192,10 +533,153 @@ impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundResponse>>
     }
 }
 
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Deserialize)]
 pub struct NexinetsErrorResponse {
-    pub status_code: u16,
-    pub code: String,
+    pub status: u16,
+    pub code: u16,
+    pub message: String,
+    pub errors: Vec<OrderErrorDetails>,
+}
+
+#[derive(Debug, Deserialize, Clone)]
+pub struct OrderErrorDetails {
+    pub code: u16,
     pub message: String,
-    pub reason: Option<String>,
+    pub field: Option<String>,
+}
+
+fn get_payment_details_and_product(
+    item: &types::PaymentsAuthorizeRouterData,
+) -> Result<
+    (Option<NexinetsPaymentDetails>, NexinetsProduct),
+    error_stack::Report<errors::ConnectorError>,
+> {
+    match &item.request.payment_method_data {
+        PaymentMethodData::Card(card) => Ok((
+            Some(get_card_data(item, card)?),
+            NexinetsProduct::Creditcard,
+        )),
+        PaymentMethodData::Wallet(wallet) => Ok(get_wallet_details(wallet)?),
+        PaymentMethodData::BankRedirect(bank_redirect) => match bank_redirect {
+            api_models::payments::BankRedirectData::Eps { .. } => Ok((None, NexinetsProduct::Eps)),
+            api_models::payments::BankRedirectData::Giropay { .. } => {
+                Ok((None, NexinetsProduct::Giropay))
+            }
+            api_models::payments::BankRedirectData::Ideal { bank_name, .. } => Ok((
+                Some(NexinetsPaymentDetails::BankRedirects(Box::new(
+                    NexinetsBankRedirects {
+                        bic: NexinetsBIC::try_from(bank_name)?,
+                    },
+                ))),
+                NexinetsProduct::Ideal,
+            )),
+            api_models::payments::BankRedirectData::Sofort { .. } => {
+                Ok((None, NexinetsProduct::Sofort))
+            }
+            _ => Err(errors::ConnectorError::NotImplemented(
+                "Payment methods".to_string(),
+            ))?,
+        },
+        _ => Err(errors::ConnectorError::NotImplemented(
+            "Payment methods".to_string(),
+        ))?,
+    }
+}
+
+fn get_card_data(
+    item: &types::PaymentsAuthorizeRouterData,
+    card: &api_models::payments::Card,
+) -> Result<NexinetsPaymentDetails, errors::ConnectorError> {
+    let (card_data, cof_contract) = match item.request.is_mandate_payment() {
+        true => {
+            let card_data = match item.request.off_session {
+                Some(true) => CardDataDetails::PaymentInstrument(Box::new(PaymentInstrument {
+                    payment_instrument_id: item.request.connector_mandate_id(),
+                })),
+                _ => CardDataDetails::CardDetails(Box::new(get_card_details(card))),
+            };
+            let cof_contract = Some(CofContract {
+                recurring_type: RecurringType::Unscheduled,
+            });
+            (card_data, cof_contract)
+        }
+        false => (
+            CardDataDetails::CardDetails(Box::new(get_card_details(card))),
+            None,
+        ),
+    };
+    Ok(NexinetsPaymentDetails::Card(Box::new(NexiCardDetails {
+        card_data,
+        cof_contract,
+    })))
+}
+
+fn get_applepay_details(
+    wallet_data: &api_models::payments::WalletData,
+    applepay_data: &api_models::payments::ApplePayWalletData,
+) -> CustomResult<ApplePayDetails, errors::ConnectorError> {
+    let payment_data = wallet_data.get_wallet_token_as_json()?;
+    Ok(ApplePayDetails {
+        payment_data,
+        payment_method: ApplepayPaymentMethod {
+            display_name: applepay_data.payment_method.display_name.to_owned(),
+            network: applepay_data.payment_method.network.to_owned(),
+            token_type: applepay_data.payment_method.pm_type.to_owned(),
+        },
+        transaction_identifier: applepay_data.transaction_identifier.to_owned(),
+    })
+}
+
+fn get_card_details(req_card: &api_models::payments::Card) -> CardDetails {
+    CardDetails {
+        card_number: req_card.card_number.clone(),
+        expiry_month: req_card.card_exp_month.clone(),
+        expiry_year: req_card.get_card_expiry_year_2_digit(),
+        verification: req_card.card_cvc.clone(),
+    }
+}
+
+fn get_wallet_details(
+    wallet: &api_models::payments::WalletData,
+) -> Result<
+    (Option<NexinetsPaymentDetails>, NexinetsProduct),
+    error_stack::Report<errors::ConnectorError>,
+> {
+    match wallet {
+        api_models::payments::WalletData::PaypalRedirect(_) => Ok((None, NexinetsProduct::Paypal)),
+        api_models::payments::WalletData::ApplePay(applepay_data) => Ok((
+            Some(NexinetsPaymentDetails::Wallet(Box::new(
+                NexinetsWalletDetails::ApplePayToken(Box::new(get_applepay_details(
+                    wallet,
+                    applepay_data,
+                )?)),
+            ))),
+            NexinetsProduct::Applepay,
+        )),
+        _ => Err(errors::ConnectorError::NotImplemented(
+            "Payment methods".to_string(),
+        ))?,
+    }
+}
+
+pub fn get_order_id(
+    meta: &NexinetsPaymentsMetadata,
+) -> Result<String, error_stack::Report<errors::ConnectorError>> {
+    let order_id = meta.order_id.clone().ok_or(
+        errors::ConnectorError::MissingConnectorRelatedTransactionID {
+            id: "order_id".to_string(),
+        },
+    )?;
+    Ok(order_id)
+}
+
+pub fn get_transaction_id(
+    meta: &NexinetsPaymentsMetadata,
+) -> Result<String, error_stack::Report<errors::ConnectorError>> {
+    let transaction_id = meta.transaction_id.clone().ok_or(
+        errors::ConnectorError::MissingConnectorRelatedTransactionID {
+            id: "transaction_id".to_string(),
+        },
+    )?;
+    Ok(transaction_id)
 }
diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs
index 5797edcd620..15950cb8632 100644
--- a/crates/router/src/connector/utils.rs
+++ b/crates/router/src/connector/utils.rs
@@ -244,7 +244,7 @@ impl PaymentsCompleteAuthorizeRequestData for types::CompleteAuthorizeData {
 
 pub trait PaymentsSyncRequestData {
     fn is_auto_capture(&self) -> Result<bool, Error>;
-    fn get_connector_transaction_id(&self) -> CustomResult<String, errors::ValidationError>;
+    fn get_connector_transaction_id(&self) -> CustomResult<String, errors::ConnectorError>;
 }
 
 impl PaymentsSyncRequestData for types::PaymentsSyncData {
@@ -255,14 +255,15 @@ impl PaymentsSyncRequestData for types::PaymentsSyncData {
             Some(_) => Err(errors::ConnectorError::CaptureMethodNotSupported.into()),
         }
     }
-    fn get_connector_transaction_id(&self) -> CustomResult<String, errors::ValidationError> {
+    fn get_connector_transaction_id(&self) -> CustomResult<String, errors::ConnectorError> {
         match self.connector_transaction_id.clone() {
             ResponseId::ConnectorTransactionId(txn_id) => Ok(txn_id),
             _ => Err(errors::ValidationError::IncorrectValueProvided {
                 field_name: "connector_transaction_id",
             })
             .into_report()
-            .attach_printable("Expected connector transaction ID not found"),
+            .attach_printable("Expected connector transaction ID not found")
+            .change_context(errors::ConnectorError::MissingConnectorTransactionID)?,
         }
     }
 }
@@ -400,7 +401,7 @@ impl WalletData for api::WalletData {
     fn get_wallet_token(&self) -> Result<String, Error> {
         match self {
             Self::GooglePay(data) => Ok(data.tokenization_data.token.clone()),
-            Self::ApplePay(data) => Ok(data.payment_data.clone()),
+            Self::ApplePay(data) => Ok(data.get_applepay_decoded_payment_data()?),
             Self::PaypalSdk(data) => Ok(data.token.clone()),
             _ => Err(errors::ConnectorError::InvalidWallet.into()),
         }
@@ -415,6 +416,23 @@ impl WalletData for api::WalletData {
     }
 }
 
+pub trait ApplePay {
+    fn get_applepay_decoded_payment_data(&self) -> Result<String, Error>;
+}
+
+impl ApplePay for payments::ApplePayWalletData {
+    fn get_applepay_decoded_payment_data(&self) -> Result<String, Error> {
+        let token = String::from_utf8(
+            consts::BASE64_ENGINE
+                .decode(&self.payment_data)
+                .into_report()
+                .change_context(errors::ConnectorError::InvalidWalletToken)?,
+        )
+        .into_report()
+        .change_context(errors::ConnectorError::InvalidWalletToken)?;
+        Ok(token)
+    }
+}
 pub trait PhoneDetailsData {
     fn get_number(&self) -> Result<Secret<String>, Error>;
     fn get_country_code(&self) -> Result<String, Error>;
diff --git a/crates/router/src/core/errors.rs b/crates/router/src/core/errors.rs
index 1377f3019a7..b6c653f95ab 100644
--- a/crates/router/src/core/errors.rs
+++ b/crates/router/src/core/errors.rs
@@ -295,6 +295,8 @@ pub enum ConnectorError {
     MismatchedPaymentData,
     #[error("Failed to parse Wallet token")]
     InvalidWalletToken,
+    #[error("Missing Connector Related Transaction ID")]
+    MissingConnectorRelatedTransactionID { id: String },
     #[error("File Validation failed")]
     FileValidationFailed { reason: String },
 }
diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs
index 182ec6efe81..8f8a447494a 100644
--- a/crates/router/src/core/payments/flows.rs
+++ b/crates/router/src/core/payments/flows.rs
@@ -177,7 +177,6 @@ default_imp_for_connector_request_id!(
     connector::Klarna,
     connector::Mollie,
     connector::Multisafepay,
-    connector::Nexinets,
     connector::Nuvei,
     connector::Opennode,
     connector::Payeezy,
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index acbca0f48ca..e629cbf2c33 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -6,7 +6,7 @@ use router_env::{instrument, tracing};
 use super::{flows::Feature, PaymentAddress, PaymentData};
 use crate::{
     configs::settings::Server,
-    connector::Paypal,
+    connector::{Nexinets, Paypal},
     core::{
         errors::{self, RouterResponse, RouterResult},
         payments::{self, helpers},
@@ -581,6 +581,16 @@ impl api::ConnectorTransactionId for Paypal {
     }
 }
 
+impl api::ConnectorTransactionId for Nexinets {
+    fn connector_transaction_id(
+        &self,
+        payment_attempt: storage::PaymentAttempt,
+    ) -> Result<Option<String>, errors::ApiErrorResponse> {
+        let metadata = Self::connector_transaction_id(self, &payment_attempt.connector_metadata);
+        metadata.map_err(|_| errors::ApiErrorResponse::ResourceIdNotFound)
+    }
+}
+
 impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCaptureData {
     type Error = error_stack::Report<errors::ApiErrorResponse>;
 
diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs
index 4206c29f0eb..1a60dd3756a 100644
--- a/crates/router/src/types/api.rs
+++ b/crates/router/src/types/api.rs
@@ -218,7 +218,7 @@ impl ConnectorData {
             "worldline" => Ok(Box::new(&connector::Worldline)),
             "worldpay" => Ok(Box::new(&connector::Worldpay)),
             "multisafepay" => Ok(Box::new(&connector::Multisafepay)),
-            // "nexinets" => Ok(Box::new(&connector::Nexinets)), added as template code for future use
+            "nexinets" => Ok(Box::new(&connector::Nexinets)),
             "paypal" => Ok(Box::new(&connector::Paypal)),
             "trustpay" => Ok(Box::new(&connector::Trustpay)),
             "zen" => Ok(Box::new(&connector::Zen)),
diff --git a/crates/router/tests/connectors/connector_auth.rs b/crates/router/tests/connectors/connector_auth.rs
index 7de71b28634..d178c00a0d9 100644
--- a/crates/router/tests/connectors/connector_auth.rs
+++ b/crates/router/tests/connectors/connector_auth.rs
@@ -20,7 +20,7 @@ pub(crate) struct ConnectorAuthentication {
     pub globalpay: Option<HeaderKey>,
     pub mollie: Option<HeaderKey>,
     pub multisafepay: Option<HeaderKey>,
-    pub nexinets: Option<HeaderKey>,
+    pub nexinets: Option<BodyKey>,
     pub nuvei: Option<SignatureKey>,
     pub opennode: Option<HeaderKey>,
     pub payeezy: Option<SignatureKey>,
diff --git a/crates/router/tests/connectors/nexinets.rs b/crates/router/tests/connectors/nexinets.rs
index 93a24320966..86817c2e588 100644
--- a/crates/router/tests/connectors/nexinets.rs
+++ b/crates/router/tests/connectors/nexinets.rs
@@ -1,5 +1,5 @@
 use masking::Secret;
-use router::types::{self, api, storage::enums};
+use router::types::{self, api, storage::enums, PaymentsAuthorizeData};
 
 use crate::{
     connector_auth,
@@ -9,12 +9,13 @@ use crate::{
 #[derive(Clone, Copy)]
 struct NexinetsTest;
 impl ConnectorActions for NexinetsTest {}
+static CONNECTOR: NexinetsTest = NexinetsTest {};
 impl utils::Connector for NexinetsTest {
     fn get_data(&self) -> types::api::ConnectorData {
         use router::connector::Nexinets;
         types::api::ConnectorData {
             connector: Box::new(&Nexinets),
-            connector_name: types::Connector::Dummy,
+            connector_name: types::Connector::Nexinets,
             get_token: types::api::GetToken::Connector,
         }
     }
@@ -32,22 +33,23 @@ impl utils::Connector for NexinetsTest {
     }
 }
 
-static CONNECTOR: NexinetsTest = NexinetsTest {};
-
-fn get_default_payment_info() -> Option<utils::PaymentInfo> {
-    None
-}
-
-fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
-    None
+fn payment_method_details() -> Option<PaymentsAuthorizeData> {
+    Some(PaymentsAuthorizeData {
+        currency: storage_models::enums::Currency::EUR,
+        payment_method_data: types::api::PaymentMethodData::Card(api::Card {
+            card_number: Secret::new("4012001038443335".to_string()),
+            ..utils::CCardType::default().0
+        }),
+        router_return_url: Some("https://google.com".to_string()),
+        ..utils::PaymentAuthorizeType::default().0
+    })
 }
-
 // Cards Positive Tests
 // Creates a payment using the manual capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_only_authorize_payment() {
     let response = CONNECTOR
-        .authorize_payment(payment_method_details(), get_default_payment_info())
+        .authorize_payment(payment_method_details(), None)
         .await
         .expect("Authorize payment response");
     assert_eq!(response.status, enums::AttemptStatus::Authorized);
@@ -57,47 +59,66 @@ async fn should_only_authorize_payment() {
 #[actix_web::test]
 async fn should_capture_authorized_payment() {
     let response = CONNECTOR
-        .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info())
+        .authorize_payment(payment_method_details(), None)
         .await
-        .expect("Capture payment response");
-    assert_eq!(response.status, enums::AttemptStatus::Charged);
+        .unwrap();
+    assert_eq!(response.status, enums::AttemptStatus::Authorized);
+    let connector_payment_id = "".to_string();
+    let connector_meta = utils::get_connector_metadata(response.response);
+    let capture_data = types::PaymentsCaptureData {
+        connector_meta,
+        currency: storage_models::enums::Currency::EUR,
+        ..utils::PaymentCaptureType::default().0
+    };
+    let capture_response = CONNECTOR
+        .capture_payment(connector_payment_id, Some(capture_data), None)
+        .await
+        .unwrap();
+    assert_eq!(capture_response.status, enums::AttemptStatus::Charged);
 }
 
 // Partially captures a payment using the manual capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_partially_capture_authorized_payment() {
     let response = CONNECTOR
-        .authorize_and_capture_payment(
-            payment_method_details(),
-            Some(types::PaymentsCaptureData {
-                amount_to_capture: 50,
-                ..utils::PaymentCaptureType::default().0
-            }),
-            get_default_payment_info(),
-        )
+        .authorize_payment(payment_method_details(), None)
         .await
-        .expect("Capture payment response");
-    assert_eq!(response.status, enums::AttemptStatus::Charged);
+        .unwrap();
+    assert_eq!(response.status, enums::AttemptStatus::Authorized);
+    let connector_payment_id = "".to_string();
+    let connector_meta = utils::get_connector_metadata(response.response);
+    let capture_data = types::PaymentsCaptureData {
+        connector_meta,
+        amount_to_capture: 50,
+        currency: storage_models::enums::Currency::EUR,
+        ..utils::PaymentCaptureType::default().0
+    };
+    let capture_response = CONNECTOR
+        .capture_payment(connector_payment_id, Some(capture_data), None)
+        .await
+        .unwrap();
+    assert_eq!(capture_response.status, enums::AttemptStatus::Charged);
 }
 
 // Synchronizes a payment using the manual capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_sync_authorized_payment() {
     let authorize_response = CONNECTOR
-        .authorize_payment(payment_method_details(), get_default_payment_info())
+        .authorize_payment(payment_method_details(), None)
         .await
         .expect("Authorize payment response");
-    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
+    let txn_id = "".to_string();
+    let connector_meta = utils::get_connector_metadata(authorize_response.response);
     let response = CONNECTOR
         .psync_retry_till_status_matches(
             enums::AttemptStatus::Authorized,
             Some(types::PaymentsSyncData {
-                connector_transaction_id: router::types::ResponseId::ConnectorTransactionId(
-                    txn_id.unwrap(),
-                ),
-                ..Default::default()
+                connector_transaction_id: router::types::ResponseId::ConnectorTransactionId(txn_id),
+                encoded_data: None,
+                capture_method: None,
+                connector_meta,
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .expect("PSync response");
@@ -108,29 +129,63 @@ async fn should_sync_authorized_payment() {
 #[actix_web::test]
 async fn should_void_authorized_payment() {
     let response = CONNECTOR
-        .authorize_and_void_payment(
-            payment_method_details(),
+        .authorize_payment(payment_method_details(), None)
+        .await
+        .unwrap();
+    assert_eq!(response.status, enums::AttemptStatus::Authorized);
+    let connector_payment_id = "".to_string();
+    let connector_meta = utils::get_connector_metadata(response.response);
+    let response = CONNECTOR
+        .void_payment(
+            connector_payment_id,
             Some(types::PaymentsCancelData {
-                connector_transaction_id: String::from(""),
-                cancellation_reason: Some("requested_by_customer".to_string()),
-                ..Default::default()
+                connector_meta,
+                amount: Some(100),
+                currency: Some(storage_models::enums::Currency::EUR),
+                ..utils::PaymentCancelType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
-        .expect("Void payment response");
+        .unwrap();
+
     assert_eq!(response.status, enums::AttemptStatus::Voided);
 }
 
 // Refunds a payment using the manual capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_refund_manually_captured_payment() {
-    let response = CONNECTOR
-        .capture_payment_and_refund(
-            payment_method_details(),
+    let authorize_response = CONNECTOR
+        .authorize_payment(payment_method_details(), None)
+        .await
+        .expect("Authorize payment response");
+    let txn_id = "".to_string();
+    let capture_connector_meta = utils::get_connector_metadata(authorize_response.response);
+    let capture_response = CONNECTOR
+        .capture_payment(
+            txn_id,
+            Some(types::PaymentsCaptureData {
+                currency: storage_models::enums::Currency::EUR,
+                connector_meta: capture_connector_meta,
+                ..utils::PaymentCaptureType::default().0
+            }),
             None,
+        )
+        .await
+        .expect("Capture payment response");
+    let capture_txn_id =
+        utils::get_connector_transaction_id(capture_response.response.clone()).unwrap();
+    let refund_connector_metadata = utils::get_connector_metadata(capture_response.response);
+    let response = CONNECTOR
+        .refund_payment(
+            capture_txn_id.clone(),
+            Some(types::RefundsData {
+                connector_transaction_id: capture_txn_id,
+                currency: storage_models::enums::Currency::EUR,
+                connector_metadata: refund_connector_metadata,
+                ..utils::PaymentRefundType::default().0
+            }),
             None,
-            get_default_payment_info(),
         )
         .await
         .unwrap();
@@ -143,15 +198,38 @@ async fn should_refund_manually_captured_payment() {
 // Partially refunds a payment using the manual capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_partially_refund_manually_captured_payment() {
-    let response = CONNECTOR
-        .capture_payment_and_refund(
-            payment_method_details(),
+    let authorize_response = CONNECTOR
+        .authorize_payment(payment_method_details(), None)
+        .await
+        .expect("Authorize payment response");
+    let txn_id = "".to_string();
+    let capture_connector_meta = utils::get_connector_metadata(authorize_response.response);
+    let capture_response = CONNECTOR
+        .capture_payment(
+            txn_id.clone(),
+            Some(types::PaymentsCaptureData {
+                currency: storage_models::enums::Currency::EUR,
+                connector_meta: capture_connector_meta,
+                ..utils::PaymentCaptureType::default().0
+            }),
             None,
+        )
+        .await
+        .expect("Capture payment response");
+    let capture_txn_id =
+        utils::get_connector_transaction_id(capture_response.response.clone()).unwrap();
+    let refund_connector_metadata = utils::get_connector_metadata(capture_response.response);
+    let response = CONNECTOR
+        .refund_payment(
+            capture_txn_id.clone(),
             Some(types::RefundsData {
-                refund_amount: 50,
+                refund_amount: 10,
+                connector_transaction_id: capture_txn_id,
+                currency: storage_models::enums::Currency::EUR,
+                connector_metadata: refund_connector_metadata,
                 ..utils::PaymentRefundType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
@@ -164,21 +242,63 @@ async fn should_partially_refund_manually_captured_payment() {
 // Synchronizes a refund using the manual capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_sync_manually_captured_refund() {
-    let refund_response = CONNECTOR
-        .capture_payment_and_refund(
-            payment_method_details(),
+    let authorize_response = CONNECTOR
+        .authorize_payment(payment_method_details(), None)
+        .await
+        .expect("Authorize payment response");
+    let txn_id = "".to_string();
+    let capture_connector_meta = utils::get_connector_metadata(authorize_response.response);
+    let capture_response = CONNECTOR
+        .capture_payment(
+            txn_id.clone(),
+            Some(types::PaymentsCaptureData {
+                currency: storage_models::enums::Currency::EUR,
+                connector_meta: capture_connector_meta,
+                ..utils::PaymentCaptureType::default().0
+            }),
             None,
+        )
+        .await
+        .expect("Capture payment response");
+    let capture_txn_id =
+        utils::get_connector_transaction_id(capture_response.response.clone()).unwrap();
+    let refund_connector_metadata = utils::get_connector_metadata(capture_response.response);
+    let refund_response = CONNECTOR
+        .refund_payment(
+            capture_txn_id.clone(),
+            Some(types::RefundsData {
+                refund_amount: 100,
+                connector_transaction_id: capture_txn_id.clone(),
+                currency: storage_models::enums::Currency::EUR,
+                connector_metadata: refund_connector_metadata.clone(),
+                ..utils::PaymentRefundType::default().0
+            }),
             None,
-            get_default_payment_info(),
         )
         .await
         .unwrap();
+    let transaction_id = Some(
+        refund_response
+            .response
+            .clone()
+            .unwrap()
+            .connector_refund_id,
+    );
     let response = CONNECTOR
         .rsync_retry_till_status_matches(
             enums::RefundStatus::Success,
-            refund_response.response.unwrap().connector_refund_id,
+            refund_response
+                .response
+                .clone()
+                .unwrap()
+                .connector_refund_id,
+            Some(types::RefundsData {
+                connector_refund_id: transaction_id,
+                connector_transaction_id: capture_txn_id,
+                connector_metadata: refund_connector_metadata,
+                ..utils::PaymentRefundType::default().0
+            }),
             None,
-            get_default_payment_info(),
         )
         .await
         .unwrap();
@@ -192,7 +312,7 @@ async fn should_sync_manually_captured_refund() {
 #[actix_web::test]
 async fn should_make_payment() {
     let authorize_response = CONNECTOR
-        .make_payment(payment_method_details(), get_default_payment_info())
+        .make_payment(payment_method_details(), None)
         .await
         .unwrap();
     assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
@@ -201,24 +321,23 @@ async fn should_make_payment() {
 // Synchronizes a payment using the automatic capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_sync_auto_captured_payment() {
-    let authorize_response = CONNECTOR
-        .make_payment(payment_method_details(), get_default_payment_info())
+    let cap_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
         .await
         .unwrap();
-    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
-    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
-    assert_ne!(txn_id, None, "Empty connector transaction id");
+    assert_eq!(cap_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(cap_response.response.clone()).unwrap();
+    let connector_meta = utils::get_connector_metadata(cap_response.response);
     let response = CONNECTOR
         .psync_retry_till_status_matches(
             enums::AttemptStatus::Charged,
             Some(types::PaymentsSyncData {
-                connector_transaction_id: router::types::ResponseId::ConnectorTransactionId(
-                    txn_id.unwrap(),
-                ),
+                connector_transaction_id: router::types::ResponseId::ConnectorTransactionId(txn_id),
                 capture_method: Some(enums::CaptureMethod::Automatic),
+                connector_meta,
                 ..Default::default()
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
@@ -228,8 +347,25 @@ async fn should_sync_auto_captured_payment() {
 // Refunds a payment using the automatic capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_refund_auto_captured_payment() {
+    let captured_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
+        .await
+        .unwrap();
+    assert_eq!(captured_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(captured_response.response.clone());
+    let connector_metadata = utils::get_connector_metadata(captured_response.response);
     let response = CONNECTOR
-        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
+        .refund_payment(
+            txn_id.clone().unwrap(),
+            Some(types::RefundsData {
+                refund_amount: 100,
+                currency: storage_models::enums::Currency::EUR,
+                connector_transaction_id: txn_id.unwrap(),
+                connector_metadata,
+                ..utils::PaymentRefundType::default().0
+            }),
+            None,
+        )
         .await
         .unwrap();
     assert_eq!(
@@ -241,19 +377,29 @@ async fn should_refund_auto_captured_payment() {
 // Partially refunds a payment using the automatic capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_partially_refund_succeeded_payment() {
-    let refund_response = CONNECTOR
-        .make_payment_and_refund(
-            payment_method_details(),
+    let captured_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
+        .await
+        .unwrap();
+    assert_eq!(captured_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(captured_response.response.clone());
+    let connector_meta = utils::get_connector_metadata(captured_response.response);
+    let response = CONNECTOR
+        .refund_payment(
+            txn_id.clone().unwrap(),
             Some(types::RefundsData {
                 refund_amount: 50,
+                currency: storage_models::enums::Currency::EUR,
+                connector_transaction_id: txn_id.unwrap(),
+                connector_metadata: connector_meta,
                 ..utils::PaymentRefundType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     assert_eq!(
-        refund_response.response.unwrap().refund_status,
+        response.response.unwrap().refund_status,
         enums::RefundStatus::Success,
     );
 }
@@ -261,31 +407,81 @@ async fn should_partially_refund_succeeded_payment() {
 // Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_refund_succeeded_payment_multiple_times() {
-    CONNECTOR
-        .make_payment_and_multiple_refund(
-            payment_method_details(),
-            Some(types::RefundsData {
-                refund_amount: 50,
-                ..utils::PaymentRefundType::default().0
-            }),
-            get_default_payment_info(),
-        )
-        .await;
+    let captured_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
+        .await
+        .unwrap();
+    assert_eq!(captured_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(captured_response.response.clone());
+    let connector_meta = utils::get_connector_metadata(captured_response.response);
+    for _x in 0..2 {
+        let refund_response = CONNECTOR
+            .refund_payment(
+                txn_id.clone().unwrap(),
+                Some(types::RefundsData {
+                    connector_metadata: connector_meta.clone(),
+                    connector_transaction_id: txn_id.clone().unwrap(),
+                    refund_amount: 50,
+                    currency: storage_models::enums::Currency::EUR,
+                    ..utils::PaymentRefundType::default().0
+                }),
+                None,
+            )
+            .await
+            .unwrap();
+        assert_eq!(
+            refund_response.response.unwrap().refund_status,
+            enums::RefundStatus::Success,
+        );
+    }
 }
 
 // Synchronizes a refund using the automatic capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_sync_refund() {
+    let captured_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
+        .await
+        .unwrap();
+    assert_eq!(captured_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(captured_response.response.clone());
+    let connector_metadata = utils::get_connector_metadata(captured_response.response).clone();
     let refund_response = CONNECTOR
-        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
+        .refund_payment(
+            txn_id.clone().unwrap(),
+            Some(types::RefundsData {
+                connector_transaction_id: txn_id.clone().unwrap(),
+                refund_amount: 100,
+                currency: storage_models::enums::Currency::EUR,
+                connector_metadata: connector_metadata.clone(),
+                ..utils::PaymentRefundType::default().0
+            }),
+            None,
+        )
         .await
         .unwrap();
+    let transaction_id = Some(
+        refund_response
+            .response
+            .clone()
+            .unwrap()
+            .connector_refund_id,
+    );
     let response = CONNECTOR
         .rsync_retry_till_status_matches(
             enums::RefundStatus::Success,
-            refund_response.response.unwrap().connector_refund_id,
+            refund_response
+                .response
+                .clone()
+                .unwrap()
+                .connector_refund_id,
+            Some(types::RefundsData {
+                connector_refund_id: transaction_id,
+                connector_transaction_id: txn_id.unwrap(),
+                connector_metadata,
+                ..utils::PaymentRefundType::default().0
+            }),
             None,
-            get_default_payment_info(),
         )
         .await
         .unwrap();
@@ -301,20 +497,21 @@ async fn should_sync_refund() {
 async fn should_fail_payment_for_incorrect_card_number() {
     let response = CONNECTOR
         .make_payment(
-            Some(types::PaymentsAuthorizeData {
+            Some(PaymentsAuthorizeData {
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
-                    card_number: Secret::new("1234567891011".to_string()),
+                    card_number: Secret::new("12345678910112331".to_string()),
                     ..utils::CCardType::default().0
                 }),
+                currency: storage_models::enums::Currency::EUR,
                 ..utils::PaymentAuthorizeType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     assert_eq!(
         response.response.unwrap_err().message,
-        "Your card number is incorrect.".to_string(),
+        "payment.cardNumber : Bad value for 'payment.cardNumber'. Expected: string of length in range 12 <=> 19 representing a valid creditcard number.".to_string(),
     );
 }
 
@@ -323,21 +520,21 @@ async fn should_fail_payment_for_incorrect_card_number() {
 async fn should_fail_payment_for_empty_card_number() {
     let response = CONNECTOR
         .make_payment(
-            Some(types::PaymentsAuthorizeData {
+            Some(PaymentsAuthorizeData {
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
                     card_number: Secret::new(String::from("")),
                     ..utils::CCardType::default().0
                 }),
                 ..utils::PaymentAuthorizeType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     let x = response.response.unwrap_err();
     assert_eq!(
         x.message,
-        "You passed an empty string for 'payment_method_data[card][number]'.",
+        "payment.cardNumber : Bad value for 'payment.cardNumber'. Expected: string of length in range 12 <=> 19 representing a valid creditcard number.",
     );
 }
 
@@ -346,20 +543,20 @@ async fn should_fail_payment_for_empty_card_number() {
 async fn should_fail_payment_for_incorrect_cvc() {
     let response = CONNECTOR
         .make_payment(
-            Some(types::PaymentsAuthorizeData {
+            Some(PaymentsAuthorizeData {
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
                     card_cvc: Secret::new("12345".to_string()),
                     ..utils::CCardType::default().0
                 }),
                 ..utils::PaymentAuthorizeType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     assert_eq!(
         response.response.unwrap_err().message,
-        "Your card's security code is invalid.".to_string(),
+        "payment.verification : Bad value for 'payment.verification'. Expected: string of length in range 3 <=> 4 representing a valid creditcard verification number.".to_string(),
     );
 }
 
@@ -368,20 +565,20 @@ async fn should_fail_payment_for_incorrect_cvc() {
 async fn should_fail_payment_for_invalid_exp_month() {
     let response = CONNECTOR
         .make_payment(
-            Some(types::PaymentsAuthorizeData {
+            Some(PaymentsAuthorizeData {
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
                     card_exp_month: Secret::new("20".to_string()),
                     ..utils::CCardType::default().0
                 }),
                 ..utils::PaymentAuthorizeType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     assert_eq!(
         response.response.unwrap_err().message,
-        "Your card's expiration month is invalid.".to_string(),
+        "payment.expiryMonth : Bad value for 'payment.expiryMonth'. Expected: string of length 2 in range '01' <=> '12' representing the month in a valid creditcard expiry date >= current date.".to_string(),
     );
 }
 
@@ -390,73 +587,108 @@ async fn should_fail_payment_for_invalid_exp_month() {
 async fn should_fail_payment_for_incorrect_expiry_year() {
     let response = CONNECTOR
         .make_payment(
-            Some(types::PaymentsAuthorizeData {
+            Some(PaymentsAuthorizeData {
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
                     card_exp_year: Secret::new("2000".to_string()),
                     ..utils::CCardType::default().0
                 }),
                 ..utils::PaymentAuthorizeType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     assert_eq!(
         response.response.unwrap_err().message,
-        "Your card's expiration year is invalid.".to_string(),
+        "payment.expiryYear : Bad value for 'payment.expiryYear'. Expected: string of length 2 in range '01' <=> '99' representing the year in a valid creditcard expiry date >= current date.".to_string(),
     );
 }
 
 // Voids a payment using automatic capture flow (Non 3DS).
 #[actix_web::test]
 async fn should_fail_void_payment_for_auto_capture() {
-    let authorize_response = CONNECTOR
-        .make_payment(payment_method_details(), get_default_payment_info())
+    let captured_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
         .await
         .unwrap();
-    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
-    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
-    assert_ne!(txn_id, None, "Empty connector transaction id");
+    assert_eq!(captured_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(captured_response.response.clone()).unwrap();
+    let connector_meta = utils::get_connector_metadata(captured_response.response);
     let void_response = CONNECTOR
-        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
+        .void_payment(
+            txn_id,
+            Some(types::PaymentsCancelData {
+                cancellation_reason: Some("requested_by_customer".to_string()),
+                amount: Some(100),
+                currency: Some(storage_models::enums::Currency::EUR),
+                connector_meta,
+                ..Default::default()
+            }),
+            None,
+        )
         .await
         .unwrap();
     assert_eq!(
         void_response.response.unwrap_err().message,
-        "You cannot cancel this PaymentIntent because it has a status of succeeded."
+        "transactionId : Operation not allowed!"
     );
 }
 
 // Captures a payment using invalid connector payment id.
 #[actix_web::test]
 async fn should_fail_capture_for_invalid_payment() {
+    let connector_payment_id = "".to_string();
     let capture_response = CONNECTOR
-        .capture_payment("123456789".to_string(), None, get_default_payment_info())
+        .capture_payment(
+            connector_payment_id,
+            Some(types::PaymentsCaptureData {
+                connector_meta: Some(
+                    serde_json::json!({"transaction_id" : "transaction_usmh41hymb",
+                        "order_id" : "tjil1ymxsz",
+                        "psync_flow" : "PREAUTH"
+                    }),
+                ),
+                amount_to_capture: 50,
+                currency: storage_models::enums::Currency::EUR,
+                ..utils::PaymentCaptureType::default().0
+            }),
+            None,
+        )
         .await
         .unwrap();
     assert_eq!(
         capture_response.response.unwrap_err().message,
-        String::from("No such payment_intent: '123456789'")
+        String::from("transactionId : Transaction does not belong to order.")
     );
 }
 
 // Refunds a payment with refund amount higher than payment amount.
 #[actix_web::test]
 async fn should_fail_for_refund_amount_higher_than_payment_amount() {
+    let captured_response = CONNECTOR
+        .make_payment(payment_method_details(), None)
+        .await
+        .unwrap();
+    assert_eq!(captured_response.status, enums::AttemptStatus::Charged);
+    let txn_id = utils::get_connector_transaction_id(captured_response.response.clone());
+    let connector_meta = utils::get_connector_metadata(captured_response.response);
     let response = CONNECTOR
-        .make_payment_and_refund(
-            payment_method_details(),
+        .refund_payment(
+            txn_id.clone().unwrap(),
             Some(types::RefundsData {
                 refund_amount: 150,
+                currency: storage_models::enums::Currency::EUR,
+                connector_transaction_id: txn_id.unwrap(),
+                connector_metadata: connector_meta,
                 ..utils::PaymentRefundType::default().0
             }),
-            get_default_payment_info(),
+            None,
         )
         .await
         .unwrap();
     assert_eq!(
         response.response.unwrap_err().message,
-        "Refund amount (₹1.50) is greater than charge amount (₹1.00)",
+        "initialAmount : Bad value for 'initialAmount'. Expected: Positive integer between 1 and maximum available amount (debit/capture.initialAmount - debit/capture.refundedAmount.",
     );
 }
 

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

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates

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

Adding following features to connector Nexinets 
     1) Authorize ,Capture ,Void ,Refund, Psync and Rsync for ThreeDS and non ThreeDS cards 
[connector.rs](https://github.com/juspay/hyperswitch/blob/8950f291dde537bed54271eb39bbf051d66908c1/crates/router/src/connector/nexinets.rs) 
2)bank redirects : ideal, sofort, eps and Giropay
[transformers.rs](https://github.com/juspay/hyperswitch/blob/8950f291dde537bed54271eb39bbf051d66908c1/crates/router/src/connector/nexinets/transformers.rs)
3)Wallet : Paypal redirection
4)[Integration tests for non ThreeDS ](https://github.com/juspay/hyperswitch/blob/8950f291dde537bed54271eb39bbf051d66908c1/crates/router/tests/connectors/nexinets.rs)
5)[applepay and card mandates ](https://github.com/juspay/hyperswitch/pull/1009)




### Additional Changes

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

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

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


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

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless its an obvious bug or documentation fix
that will have little conversation).
-->

**Note** : 
1)In the status mapping for the state  `Ok`,
-Authorize flow => Authorized
-All other flows (Capture, Cancel, AutoCapture, Refund) => Processing.

2)In the response, we get two connector transaction IDs:
-order_id => remains the same for further actions regarding that transaction..
-transaction_id => changes for every subsequent action (cancel, refund, capture, partial refund).
-Both order_id and transaction_id are used for further actions (Psync, Cancel, Rsync, Refund, Capture), which should be passed in the URL.
-We are storing the order_id in the connector_metadata. The transaction_id is stored in the connector_transaction_id once the payment has been captured, until then it is stored in the connector_metadata.



## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
Integration Tests 
<img width="1024" alt="Screenshot 2023-04-17 at 4 27 37 PM" src="https://user-images.githubusercontent.com/121822803/232481485-37ac635f-2500-4d89-8d18-b74fffcfbf12.png"> 

**3ds test cards** 
1)friction less flow : 4111111111111111
2)challenge flow : 4000007000000031

Intiate 3ds transaction : 
<img width="1295" alt="Screenshot 2023-04-18 at 11 19 09 AM" src="https://user-images.githubusercontent.com/121822803/232683418-7a8cec8e-65b5-48af-baab-e1d077566378.png">

redirect to challenge page :

<img width="955" alt="Screenshot 2023-04-18 at 11 19 28 AM" src="https://user-images.githubusercontent.com/121822803/232683466-c5477040-9ba8-4199-b8f4-55fb41c92ef8.png">

successful redirection after successful transaction  :

<img width="1565" alt="Screenshot 2023-04-18 at 11 19 55 AM" src="https://user-images.githubusercontent.com/121822803/232683613-67082a93-eb9f-4bfe-b3fd-e20a7834b1a5.png">


**Bank Redirects Screenshots**
Redirect url in response :
<img width="1281" alt="Screenshot 2023-04-17 at 5 52 01 PM" src="https://user-images.githubusercontent.com/121822803/232483512-321e1267-df7a-479a-addb-fb30da6cb3aa.png">
Redirect to ideal page :
<img width="967" alt="Screenshot 2023-04-17 at 5 52 09 PM" src="https://user-images.githubusercontent.com/121822803/232482973-15827213-139a-43b7-acc6-9b085a9d57c6.png">
Redirection after successful payment :
<img width="976" alt="Screenshot 2023-04-17 at 5 52 23 PM" src="https://user-images.githubusercontent.com/121822803/232482993-51febd87-7fb9-4d0b-b199-cb0bf15aa3bd.png">
Successful updation of  payment status :
<img width="1289" alt="Screenshot 2023-04-17 at 5 52 58 PM" src="https://user-images.githubusercontent.com/121822803/232482855-cdd7e86f-6000-4ac5-909d-8d82692aab24.png">

**Paypal Redirection** 
Redirect url in response:
<img width="1273" alt="Screenshot 2023-04-17 at 5 59 06 PM" src="https://user-images.githubusercontent.com/121822803/232484291-8ff80e39-ae6e-4112-901f-540fb362b6c1.png">
Redirect to paypal page
<img width="1026" alt="Screenshot 2023-04-17 at 5 59 19 PM" src="https://user-images.githubusercontent.com/121822803/232484301-d6af1c0a-ec8d-4a2a-89aa-a2e772654c33.png">
Redirection after successful payment
<img width="989" alt="Screenshot 2023-04-17 at 5 59 31 PM" src="https://user-images.githubusercontent.com/121822803/232484311-66819374-b96d-409c-b30e-96fad905caa9.png">
Successful updation of  payment status 
<img width="1269" alt="Screenshot 2023-04-17 at 5 59 59 PM" src="https://user-images.githubusercontent.com/121822803/232484414-ef6af046-745e-4718-94e9-91132a5d8110.png">



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

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