Bug: [FEATURE] : [Billwerk] Add Payment and Refund Flows



### Feature Description

Add all the payment flows for non-3ds cards:
Authorise, Capture, Void, Psync
And the refund flows: 
Refund and Rsync

### Possible Implementation

Add all the payment flows for non-3ds cards:
Authorise, Capture, Void, Psync
And the refund flows: 
Refund and Rsync

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

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

### Have you read the Contributing Guidelines?

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

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/config/config.example.toml b/config/config.example.toml
index ee868beb092..c1ba88db019 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -171,6 +171,7 @@ authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://test.bitpay.com"
 bluesnap.base_url = "https://sandbox.bluesnap.com/"
 bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/"
@@ -349,6 +350,7 @@ stax = { long_lived_token = true, payment_method = "card,bank_debit" }
 square = { long_lived_token = false, payment_method = "card" }
 braintree = { long_lived_token = false, payment_method = "card" }
 gocardless = { long_lived_token = true, payment_method = "bank_debit" }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [temp_locker_enable_config]
 stripe = { payment_method = "bank_transfer" }
diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml
index 10776c76678..77040f79a4a 100644
--- a/config/deployments/integration_test.toml
+++ b/config/deployments/integration_test.toml
@@ -21,6 +21,7 @@ authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://test.bitpay.com"
 bluesnap.base_url = "https://sandbox.bluesnap.com/"
 bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/"
@@ -292,6 +293,7 @@ payme = { long_lived_token = false, payment_method = "card" }
 square = { long_lived_token = false, payment_method = "card" }
 stax = { long_lived_token = true, payment_method = "card,bank_debit" }
 stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { list = "google_pay", type = "disable_only" } }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [webhooks]
 outgoing_enabled = true
diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index a6405e4a3b2..23df14862b9 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -25,6 +25,7 @@ authorizedotnet.base_url = "https://api.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://api.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://bitpay.com"
 bluesnap.base_url = "https://ws.bluesnap.com/"
 bluesnap.secondary_base_url = "https://pay.bluesnap.com/"
@@ -306,6 +307,7 @@ payme = { long_lived_token = false, payment_method = "card" }
 square = { long_lived_token = false, payment_method = "card" }
 stax = { long_lived_token = true, payment_method = "card,bank_debit" }
 stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { list = "google_pay", type = "disable_only" } }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [webhooks]
 outgoing_enabled = true
diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml
index 035c90af378..8ae12dc54a6 100644
--- a/config/deployments/sandbox.toml
+++ b/config/deployments/sandbox.toml
@@ -25,6 +25,7 @@ authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://test.bitpay.com"
 bluesnap.base_url = "https://sandbox.bluesnap.com/"
 bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/"
@@ -308,6 +309,7 @@ payme = { long_lived_token = false, payment_method = "card" }
 square = { long_lived_token = false, payment_method = "card" }
 stax = { long_lived_token = true, payment_method = "card,bank_debit" }
 stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { list = "google_pay", type = "disable_only" } }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [webhooks]
 outgoing_enabled = true
diff --git a/config/development.toml b/config/development.toml
index 5c063acf2f7..8ba5c076071 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -167,6 +167,7 @@ authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://test.bitpay.com"
 bluesnap.base_url = "https://sandbox.bluesnap.com/"
 bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/"
@@ -450,6 +451,7 @@ square = { long_lived_token = false, payment_method = "card" }
 braintree = { long_lived_token = false, payment_method = "card" }
 payme = { long_lived_token = false, payment_method = "card" }
 gocardless = { long_lived_token = true, payment_method = "bank_debit" }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [temp_locker_enable_config]
 stripe = { payment_method = "bank_transfer" }
diff --git a/config/docker_compose.toml b/config/docker_compose.toml
index 0e034f2e145..eb32b47e3b4 100644
--- a/config/docker_compose.toml
+++ b/config/docker_compose.toml
@@ -105,6 +105,7 @@ authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://test.bitpay.com"
 bluesnap.base_url = "https://sandbox.bluesnap.com/"
 bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/"
@@ -251,6 +252,7 @@ stax = { long_lived_token = true, payment_method = "card,bank_debit" }
 square = { long_lived_token = false, payment_method = "card" }
 braintree = { long_lived_token = false, payment_method = "card" }
 gocardless = { long_lived_token = true, payment_method = "bank_debit" }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [temp_locker_enable_config]
 stripe = { payment_method = "bank_transfer" }
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index b29377886d5..354dec29237 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -78,7 +78,7 @@ pub enum Connector {
     Authorizedotnet,
     Bambora,
     Bankofamerica,
-    // Billwerk, Added as template code for future usage
+    Billwerk,
     Bitpay,
     Bluesnap,
     Boku,
@@ -166,7 +166,7 @@ impl Connector {
             | Self::Authorizedotnet
             | Self::Bambora
             | Self::Bankofamerica
-            // | Self::Billwerk Added as template code for future usage
+            | Self::Billwerk
             | Self::Bitpay
             | Self::Bluesnap
             | Self::Boku
@@ -223,7 +223,7 @@ impl Connector {
             | Self::Authorizedotnet
             | Self::Bambora
             | Self::Bankofamerica
-            // | Self::Billwerk Added as template for future usage
+            | Self::Billwerk
             | Self::Bitpay
             | Self::Bluesnap
             | Self::Boku
diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 548e721f0d3..497f1f58729 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -115,7 +115,7 @@ pub enum RoutableConnectors {
     Airwallex,
     Authorizedotnet,
     Bankofamerica,
-    // Billwerk, Added as template code for future usage
+    Billwerk,
     Bitpay,
     Bambora,
     Bluesnap,
diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs
index 74317319f50..5a67847a9e5 100644
--- a/crates/connector_configs/src/connector.rs
+++ b/crates/connector_configs/src/connector.rs
@@ -228,7 +228,7 @@ impl ConnectorConfig {
             Connector::Airwallex => Ok(connector_data.airwallex),
             Connector::Authorizedotnet => Ok(connector_data.authorizedotnet),
             Connector::Bankofamerica => Ok(connector_data.bankofamerica),
-            // Connector::Billwerk => Ok(connector_data.billwerk), Added as template code for future usage
+            Connector::Billwerk => Ok(connector_data.billwerk),
             Connector::Bitpay => Ok(connector_data.bitpay),
             Connector::Bluesnap => Ok(connector_data.bluesnap),
             Connector::Boku => Ok(connector_data.boku),
diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml
index 0e18bb33ed2..0233b916668 100644
--- a/crates/connector_configs/toml/development.toml
+++ b/crates/connector_configs/toml/development.toml
@@ -2587,4 +2587,45 @@ api_key="Api Key"
 [threedsecureio.metadata]
 mcc="MCC"
 merchant_country_code="3 digit numeric country code"
-merchant_name="Name of the merchant"
\ No newline at end of file
+merchant_name="Name of the merchant"
+
+[billwerk]
+[[billwerk.credit]]
+  payment_method_type = "Mastercard"
+[[billwerk.credit]]
+  payment_method_type = "Visa"
+[[billwerk.credit]]
+  payment_method_type = "Interac"
+[[billwerk.credit]]
+  payment_method_type = "AmericanExpress"
+[[billwerk.credit]]
+  payment_method_type = "JCB"
+[[billwerk.credit]]
+  payment_method_type = "DinersClub"
+[[billwerk.credit]]
+  payment_method_type = "Discover"
+[[billwerk.credit]]
+  payment_method_type = "CartesBancaires"
+[[billwerk.credit]]
+  payment_method_type = "UnionPay"
+[[billwerk.debit]]
+  payment_method_type = "Mastercard"
+[[billwerk.debit]]
+  payment_method_type = "Visa"
+[[billwerk.debit]]
+  payment_method_type = "Interac"
+[[billwerk.debit]]
+  payment_method_type = "AmericanExpress"
+[[billwerk.debit]]
+  payment_method_type = "JCB"
+[[billwerk.debit]]
+  payment_method_type = "DinersClub"
+[[billwerk.debit]]
+  payment_method_type = "Discover"
+[[billwerk.debit]]
+  payment_method_type = "CartesBancaires"
+[[billwerk.debit]]
+  payment_method_type = "UnionPay"
+[billwerk.connector_auth.BodyKey]
+api_key="Private Api Key"
+key1="Public Api Key"
\ No newline at end of file
diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml
index 079ead7e4ce..58f9ccfa2c3 100644
--- a/crates/connector_configs/toml/production.toml
+++ b/crates/connector_configs/toml/production.toml
@@ -1913,4 +1913,45 @@ terminal_uuid="Terminal UUID"
 pay_wall_secret="Pay Wall Secret"
 [zen.metadata.google_pay]
 terminal_uuid="Terminal UUID"
-pay_wall_secret="Pay Wall Secret"
\ No newline at end of file
+pay_wall_secret="Pay Wall Secret"
+
+[billwerk]
+[[billwerk.credit]]
+  payment_method_type = "Mastercard"
+[[billwerk.credit]]
+  payment_method_type = "Visa"
+[[billwerk.credit]]
+  payment_method_type = "Interac"
+[[billwerk.credit]]
+  payment_method_type = "AmericanExpress"
+[[billwerk.credit]]
+  payment_method_type = "JCB"
+[[billwerk.credit]]
+  payment_method_type = "DinersClub"
+[[billwerk.credit]]
+  payment_method_type = "Discover"
+[[billwerk.credit]]
+  payment_method_type = "CartesBancaires"
+[[billwerk.credit]]
+  payment_method_type = "UnionPay"
+[[billwerk.debit]]
+  payment_method_type = "Mastercard"
+[[billwerk.debit]]
+  payment_method_type = "Visa"
+[[billwerk.debit]]
+  payment_method_type = "Interac"
+[[billwerk.debit]]
+  payment_method_type = "AmericanExpress"
+[[billwerk.debit]]
+  payment_method_type = "JCB"
+[[billwerk.debit]]
+  payment_method_type = "DinersClub"
+[[billwerk.debit]]
+  payment_method_type = "Discover"
+[[billwerk.debit]]
+  payment_method_type = "CartesBancaires"
+[[billwerk.debit]]
+  payment_method_type = "UnionPay"
+[billwerk.connector_auth.BodyKey]
+api_key="Private Api Key"
+key1="Public Api Key"
\ No newline at end of file
diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml
index f484e914531..9103c548e65 100644
--- a/crates/connector_configs/toml/sandbox.toml
+++ b/crates/connector_configs/toml/sandbox.toml
@@ -2589,4 +2589,45 @@ api_key="Api Key"
 [threedsecureio.metadata]
 mcc="MCC"
 merchant_country_code="3 digit numeric country code"
-merchant_name="Name of the merchant"
\ No newline at end of file
+merchant_name="Name of the merchant"
+
+[billwerk]
+[[billwerk.credit]]
+  payment_method_type = "Mastercard"
+[[billwerk.credit]]
+  payment_method_type = "Visa"
+[[billwerk.credit]]
+  payment_method_type = "Interac"
+[[billwerk.credit]]
+  payment_method_type = "AmericanExpress"
+[[billwerk.credit]]
+  payment_method_type = "JCB"
+[[billwerk.credit]]
+  payment_method_type = "DinersClub"
+[[billwerk.credit]]
+  payment_method_type = "Discover"
+[[billwerk.credit]]
+  payment_method_type = "CartesBancaires"
+[[billwerk.credit]]
+  payment_method_type = "UnionPay"
+[[billwerk.debit]]
+  payment_method_type = "Mastercard"
+[[billwerk.debit]]
+  payment_method_type = "Visa"
+[[billwerk.debit]]
+  payment_method_type = "Interac"
+[[billwerk.debit]]
+  payment_method_type = "AmericanExpress"
+[[billwerk.debit]]
+  payment_method_type = "JCB"
+[[billwerk.debit]]
+  payment_method_type = "DinersClub"
+[[billwerk.debit]]
+  payment_method_type = "Discover"
+[[billwerk.debit]]
+  payment_method_type = "CartesBancaires"
+[[billwerk.debit]]
+  payment_method_type = "UnionPay"
+[billwerk.connector_auth.BodyKey]
+api_key="Private Api Key"
+key1="Public Api Key"
diff --git a/crates/router/src/connector/billwerk.rs b/crates/router/src/connector/billwerk.rs
index 154b729abc9..b6839f5de24 100644
--- a/crates/router/src/connector/billwerk.rs
+++ b/crates/router/src/connector/billwerk.rs
@@ -2,12 +2,15 @@ pub mod transformers;
 
 use std::fmt::Debug;
 
+use base64::Engine;
 use error_stack::{report, ResultExt};
-use masking::ExposeInterface;
+use masking::PeekInterface;
 use transformers as billwerk;
 
+use super::utils::RefundsRequestData;
 use crate::{
     configs::settings,
+    consts,
     core::errors::{self, CustomResult},
     events::connector_api_logs::ConnectorEvent,
     headers,
@@ -40,16 +43,6 @@ impl api::RefundExecute for Billwerk {}
 impl api::RefundSync for Billwerk {}
 impl api::PaymentToken for Billwerk {}
 
-impl
-    ConnectorIntegration<
-        api::PaymentMethodToken,
-        types::PaymentMethodTokenizationData,
-        types::PaymentsResponseData,
-    > for Billwerk
-{
-    // Not Implemented (R)
-}
-
 impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Billwerk
 where
     Self: ConnectorIntegration<Flow, Request, Response>,
@@ -92,9 +85,10 @@ impl ConnectorCommon for Billwerk {
     ) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
         let auth = billwerk::BillwerkAuthType::try_from(auth_type)
             .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
+        let encoded_api_key = consts::BASE64_ENGINE.encode(format!("{}:", auth.api_key.peek()));
         Ok(vec![(
             headers::AUTHORIZATION.to_string(),
-            auth.api_key.expose().into_masked(),
+            format!("Basic {encoded_api_key}").into_masked(),
         )])
     }
 
@@ -113,9 +107,13 @@ impl ConnectorCommon for Billwerk {
 
         Ok(ErrorResponse {
             status_code: res.status_code,
-            code: response.code,
-            message: response.message,
-            reason: response.reason,
+            code: response
+                .code
+                .map_or(consts::NO_ERROR_CODE.to_string(), |code| code.to_string()),
+            message: response
+                .message
+                .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
+            reason: Some(response.error),
             attempt_status: None,
             connector_transaction_id: None,
         })
@@ -123,7 +121,20 @@ impl ConnectorCommon for Billwerk {
 }
 
 impl ConnectorValidation for Billwerk {
-    //TODO: implement functions when support enabled
+    fn validate_capture_method(
+        &self,
+        capture_method: Option<common_enums::CaptureMethod>,
+        _pmt: Option<common_enums::PaymentMethodType>,
+    ) -> CustomResult<(), errors::ConnectorError> {
+        let capture_method = capture_method.unwrap_or_default();
+        match capture_method {
+            common_enums::CaptureMethod::Automatic | common_enums::CaptureMethod::Manual => Ok(()),
+            common_enums::CaptureMethod::ManualMultiple
+            | common_enums::CaptureMethod::Scheduled => Err(
+                super::utils::construct_not_implemented_error_report(capture_method, self.id()),
+            ),
+        }
+    }
 }
 
 impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
@@ -146,6 +157,105 @@ impl
 {
 }
 
+impl
+    ConnectorIntegration<
+        api::PaymentMethodToken,
+        types::PaymentMethodTokenizationData,
+        types::PaymentsResponseData,
+    > for Billwerk
+{
+    fn get_headers(
+        &self,
+        req: &types::TokenizationRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Vec<(String, request::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: &types::TokenizationRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let base_url = connectors
+            .billwerk
+            .secondary_base_url
+            .as_ref()
+            .ok_or(errors::ConnectorError::FailedToObtainIntegrationUrl)?;
+        Ok(format!("{base_url}v1/token"))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &types::TokenizationRouterData,
+        _connectors: &settings::Connectors,
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let connector_req = billwerk::BillwerkTokenRequest::try_from(req)?;
+        Ok(RequestContent::Json(Box::new(connector_req)))
+    }
+
+    fn build_request(
+        &self,
+        req: &types::TokenizationRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
+        Ok(Some(
+            services::RequestBuilder::new()
+                .method(services::Method::Post)
+                .url(&types::TokenizationType::get_url(self, req, connectors)?)
+                .attach_default_headers()
+                .headers(types::TokenizationType::get_headers(self, req, connectors)?)
+                .set_body(types::TokenizationType::get_request_body(
+                    self, req, connectors,
+                )?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &types::TokenizationRouterData,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<types::TokenizationRouterData, errors::ConnectorError>
+    where
+        types::PaymentsResponseData: Clone,
+    {
+        let response: billwerk::BillwerkTokenResponse = res
+            .response
+            .parse_struct("BillwerkTokenResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+        event_builder.map(|i| i.set_response_body(&response));
+        router_env::logger::info!(connector_response=?response);
+        types::RouterData::try_from(types::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)
+    }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+}
+
 impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::PaymentsResponseData>
     for Billwerk
 {
@@ -164,9 +274,9 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
     fn get_url(
         &self,
         _req: &types::PaymentsAuthorizeRouterData,
-        _connectors: &settings::Connectors,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!("{}v1/charge", self.base_url(connectors)))
     }
 
     fn get_request_body(
@@ -214,7 +324,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
     ) -> CustomResult<types::PaymentsAuthorizeRouterData, errors::ConnectorError> {
         let response: billwerk::BillwerkPaymentsResponse = res
             .response
-            .parse_struct("Billwerk PaymentsAuthorizeResponse")
+            .parse_struct("Billwerk BillwerkPaymentsResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
@@ -232,6 +342,14 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
     ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
         self.build_error_response(res, event_builder)
     }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
 }
 
 impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>
@@ -251,10 +369,14 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
 
     fn get_url(
         &self,
-        _req: &types::PaymentsSyncRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::PaymentsSyncRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!(
+            "{}v1/charge/{}",
+            self.base_url(connectors),
+            req.connector_request_reference_id
+        ))
     }
 
     fn build_request(
@@ -280,7 +402,7 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
     ) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> {
         let response: billwerk::BillwerkPaymentsResponse = res
             .response
-            .parse_struct("billwerk PaymentsSyncResponse")
+            .parse_struct("billwerk BillwerkPaymentsResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
@@ -298,6 +420,14 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
     ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
         self.build_error_response(res, event_builder)
     }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
 }
 
 impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::PaymentsResponseData>
@@ -317,18 +447,29 @@ 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 connector_transaction_id = &req.request.connector_transaction_id;
+        Ok(format!(
+            "{}v1/charge/{connector_transaction_id}/settle",
+            self.base_url(connectors)
+        ))
     }
 
     fn get_request_body(
         &self,
-        _req: &types::PaymentsCaptureRouterData,
+        req: &types::PaymentsCaptureRouterData,
         _connectors: &settings::Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into())
+        let connector_router_data = billwerk::BillwerkRouterData::try_from((
+            &self.get_currency_unit(),
+            req.request.currency,
+            req.request.amount_to_capture,
+            req,
+        ))?;
+        let connector_req = billwerk::BillwerkCaptureRequest::try_from(&connector_router_data)?;
+        Ok(RequestContent::Json(Box::new(connector_req)))
     }
 
     fn build_request(
@@ -359,7 +500,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
     ) -> CustomResult<types::PaymentsCaptureRouterData, errors::ConnectorError> {
         let response: billwerk::BillwerkPaymentsResponse = res
             .response
-            .parse_struct("Billwerk PaymentsCaptureResponse")
+            .parse_struct("Billwerk BillwerkPaymentsResponse")
             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
         event_builder.map(|i| i.set_response_body(&response));
         router_env::logger::info!(connector_response=?response);
@@ -377,11 +518,92 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
     ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
         self.build_error_response(res, event_builder)
     }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
 }
 
 impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsResponseData>
     for Billwerk
 {
+    fn get_headers(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Vec<(String, request::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: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let connector_transaction_id = &req.request.connector_transaction_id;
+        Ok(format!(
+            "{}v1/charge/{connector_transaction_id}/cancel",
+            self.base_url(connectors)
+        ))
+    }
+
+    fn build_request(
+        &self,
+        req: &types::PaymentsCancelRouterData,
+        connectors: &settings::Connectors,
+    ) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
+        Ok(Some(
+            services::RequestBuilder::new()
+                .method(services::Method::Post)
+                .url(&types::PaymentsVoidType::get_url(self, req, connectors)?)
+                .attach_default_headers()
+                .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &types::PaymentsCancelRouterData,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<types::PaymentsCancelRouterData, errors::ConnectorError> {
+        let response: billwerk::BillwerkPaymentsResponse = res
+            .response
+            .parse_struct("Billwerk BillwerkPaymentsResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+        event_builder.map(|i| i.set_response_body(&response));
+        router_env::logger::info!(connector_response=?response);
+        types::RouterData::try_from(types::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)
+    }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
 }
 
 impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData>
@@ -402,9 +624,9 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
     fn get_url(
         &self,
         _req: &types::RefundsRouterData<api::Execute>,
-        _connectors: &settings::Connectors,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        Ok(format!("{}v1/refund", self.base_url(connectors)))
     }
 
     fn get_request_body(
@@ -467,6 +689,14 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
     ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
         self.build_error_response(res, event_builder)
     }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
 }
 
 impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponseData> for Billwerk {
@@ -484,10 +714,14 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
 
     fn get_url(
         &self,
-        _req: &types::RefundSyncRouterData,
-        _connectors: &settings::Connectors,
+        req: &types::RefundSyncRouterData,
+        connectors: &settings::Connectors,
     ) -> CustomResult<String, errors::ConnectorError> {
-        Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
+        let refund_id = req.request.get_connector_refund_id()?;
+        Ok(format!(
+            "{}v1/refund/{refund_id}",
+            self.base_url(connectors)
+        ))
     }
 
     fn build_request(
@@ -534,6 +768,14 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
     ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
         self.build_error_response(res, event_builder)
     }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
 }
 
 #[async_trait::async_trait]
diff --git a/crates/router/src/connector/billwerk/transformers.rs b/crates/router/src/connector/billwerk/transformers.rs
index c6f025b7898..ffcd14bf05f 100644
--- a/crates/router/src/connector/billwerk/transformers.rs
+++ b/crates/router/src/connector/billwerk/transformers.rs
@@ -1,15 +1,16 @@
-use masking::Secret;
+use common_utils::pii::{Email, SecretSerdeValue};
+use masking::{ExposeInterface, Secret};
 use serde::{Deserialize, Serialize};
 
 use crate::{
-    connector::utils::PaymentsAuthorizeRequestData,
+    connector::utils::{self, CardData, PaymentsAuthorizeRequestData, RouterData},
+    consts,
     core::errors,
     types::{self, api, storage::enums},
 };
 
-//TODO: Fill the struct with respective fields
 pub struct BillwerkRouterData<T> {
-    pub amount: i64, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
+    pub amount: i64,
     pub router_data: T,
 }
 
@@ -30,7 +31,6 @@ impl<T>
             T,
         ),
     ) -> Result<Self, Self::Error> {
-        //Todo :  use utils to convert the amount to the type of amount that a connector accepts
         Ok(Self {
             amount,
             router_data: item,
@@ -38,89 +38,213 @@ impl<T>
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
-pub struct BillwerkPaymentsRequest {
-    amount: i64,
-    card: BillwerkCard,
+pub struct BillwerkAuthType {
+    pub(super) api_key: Secret<String>,
+    pub(super) public_api_key: Secret<String>,
 }
 
-#[derive(Default, Debug, Serialize, Eq, PartialEq)]
-pub struct BillwerkCard {
+impl TryFrom<&types::ConnectorAuthType> for BillwerkAuthType {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
+        match auth_type {
+            types::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
+                api_key: api_key.to_owned(),
+                public_api_key: key1.to_owned(),
+            }),
+            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
+        }
+    }
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum BillwerkTokenRequestIntent {
+    ChargeAndStore,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum BillwerkStrongAuthRule {
+    UseScaIfAvailableAuth,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct BillwerkTokenRequest {
     number: cards::CardNumber,
-    expiry_month: Secret<String>,
-    expiry_year: Secret<String>,
-    cvc: Secret<String>,
-    complete: bool,
+    month: Secret<String>,
+    year: Secret<String>,
+    cvv: Secret<String>,
+    pkey: Secret<String>,
+    recurring: Option<bool>,
+    intent: Option<BillwerkTokenRequestIntent>,
+    strong_authentication_rule: Option<BillwerkStrongAuthRule>,
 }
 
-impl TryFrom<&BillwerkRouterData<&types::PaymentsAuthorizeRouterData>> for BillwerkPaymentsRequest {
+impl TryFrom<&types::TokenizationRouterData> for BillwerkTokenRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(
-        item: &BillwerkRouterData<&types::PaymentsAuthorizeRouterData>,
-    ) -> Result<Self, Self::Error> {
-        match item.router_data.request.payment_method_data.clone() {
-            api::PaymentMethodData::Card(req_card) => {
-                let card = BillwerkCard {
-                    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.router_data.request.is_auto_capture()?,
-                };
+    fn try_from(item: &types::TokenizationRouterData) -> Result<Self, Self::Error> {
+        match item.request.payment_method_data.clone() {
+            api::PaymentMethodData::Card(ccard) => {
+                let connector_auth = &item.connector_auth_type;
+                let auth_type = BillwerkAuthType::try_from(connector_auth)?;
                 Ok(Self {
-                    amount: item.amount.to_owned(),
-                    card,
+                    number: ccard.card_number.clone(),
+                    month: ccard.card_exp_month.clone(),
+                    year: ccard.get_card_expiry_year_2_digit()?,
+                    cvv: ccard.card_cvc,
+                    pkey: auth_type.public_api_key,
+                    recurring: None,
+                    intent: None,
+                    strong_authentication_rule: None,
                 })
             }
-            _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
+            api_models::payments::PaymentMethodData::Wallet(_)
+            | api_models::payments::PaymentMethodData::CardRedirect(_)
+            | api_models::payments::PaymentMethodData::PayLater(_)
+            | api_models::payments::PaymentMethodData::BankRedirect(_)
+            | api_models::payments::PaymentMethodData::BankDebit(_)
+            | api_models::payments::PaymentMethodData::BankTransfer(_)
+            | api_models::payments::PaymentMethodData::Crypto(_)
+            | api_models::payments::PaymentMethodData::MandatePayment
+            | api_models::payments::PaymentMethodData::Reward
+            | api_models::payments::PaymentMethodData::Upi(_)
+            | api_models::payments::PaymentMethodData::Voucher(_)
+            | api_models::payments::PaymentMethodData::GiftCard(_)
+            | api_models::payments::PaymentMethodData::CardToken(_) => {
+                Err(errors::ConnectorError::NotImplemented(
+                    utils::get_unimplemented_payment_method_error_message("billwerk"),
+                )
+                .into())
+            }
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-// Auth Struct
-pub struct BillwerkAuthType {
-    pub(super) api_key: Secret<String>,
+#[derive(Debug, Deserialize, Serialize)]
+pub struct BillwerkTokenResponse {
+    id: Secret<String>,
+    recurring: Option<bool>,
 }
 
-impl TryFrom<&types::ConnectorAuthType> for BillwerkAuthType {
+impl<T>
+    TryFrom<
+        types::ResponseRouterData<
+            api::PaymentMethodToken,
+            BillwerkTokenResponse,
+            T,
+            types::PaymentsResponseData,
+        >,
+    > for types::RouterData<api::PaymentMethodToken, T, types::PaymentsResponseData>
+{
     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_owned(),
+    fn try_from(
+        item: types::ResponseRouterData<
+            api::PaymentMethodToken,
+            BillwerkTokenResponse,
+            T,
+            types::PaymentsResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            response: Ok(types::PaymentsResponseData::TokenizationResponse {
+                token: item.response.id.expose(),
             }),
-            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
-        }
+            ..item.data
+        })
+    }
+}
+
+#[derive(Debug, Serialize)]
+pub struct BillwerkCustomerObject {
+    handle: Option<String>,
+    email: Option<Email>,
+    address: Option<Secret<String>>,
+    address2: Option<Secret<String>>,
+    city: Option<String>,
+    country: Option<common_enums::CountryAlpha2>,
+    first_name: Option<Secret<String>>,
+    last_name: Option<Secret<String>>,
+}
+
+#[derive(Debug, Serialize)]
+pub struct BillwerkPaymentsRequest {
+    handle: String,
+    amount: i64,
+    source: Secret<String>,
+    currency: common_enums::Currency,
+    customer: BillwerkCustomerObject,
+    metadata: Option<SecretSerdeValue>,
+    settle: bool,
+}
+
+impl TryFrom<&BillwerkRouterData<&types::PaymentsAuthorizeRouterData>> for BillwerkPaymentsRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: &BillwerkRouterData<&types::PaymentsAuthorizeRouterData>,
+    ) -> Result<Self, Self::Error> {
+        if item.router_data.is_three_ds() {
+            return Err(errors::ConnectorError::NotImplemented(
+                "Three_ds payments through Billwerk".to_string(),
+            )
+            .into());
+        };
+        let source = match item.router_data.get_payment_method_token()? {
+            types::PaymentMethodToken::Token(pm_token) => Ok(Secret::new(pm_token)),
+            _ => Err(errors::ConnectorError::MissingRequiredField {
+                field_name: "payment_method_token",
+            }),
+        }?;
+        Ok(Self {
+            handle: item.router_data.connector_request_reference_id.clone(),
+            amount: item.amount,
+            source,
+            currency: item.router_data.request.currency,
+            customer: BillwerkCustomerObject {
+                handle: item.router_data.customer_id.clone(),
+                email: item.router_data.request.email.clone(),
+                address: item.router_data.get_optional_billing_line1(),
+                address2: item.router_data.get_optional_billing_line2(),
+                city: item.router_data.get_optional_billing_city(),
+                country: item.router_data.get_optional_billing_country(),
+                first_name: item.router_data.get_optional_billing_first_name(),
+                last_name: item.router_data.get_optional_billing_last_name(),
+            },
+            metadata: item.router_data.request.metadata.clone(),
+            settle: item.router_data.request.is_auto_capture()?,
+        })
     }
 }
-// PaymentsResponse
-//TODO: Append the remaining status flags
-#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 #[serde(rename_all = "lowercase")]
-pub enum BillwerkPaymentStatus {
-    Succeeded,
+pub enum BillwerkPaymentState {
+    Created,
+    Authorized,
+    Pending,
+    Settled,
     Failed,
-    #[default]
-    Processing,
+    Cancelled,
 }
 
-impl From<BillwerkPaymentStatus> for enums::AttemptStatus {
-    fn from(item: BillwerkPaymentStatus) -> Self {
+impl From<BillwerkPaymentState> for enums::AttemptStatus {
+    fn from(item: BillwerkPaymentState) -> Self {
         match item {
-            BillwerkPaymentStatus::Succeeded => Self::Charged,
-            BillwerkPaymentStatus::Failed => Self::Failure,
-            BillwerkPaymentStatus::Processing => Self::Authorizing,
+            BillwerkPaymentState::Created | BillwerkPaymentState::Pending => Self::Pending,
+            BillwerkPaymentState::Authorized => Self::Authorized,
+            BillwerkPaymentState::Settled => Self::Charged,
+            BillwerkPaymentState::Failed => Self::Failure,
+            BillwerkPaymentState::Cancelled => Self::Voided,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 pub struct BillwerkPaymentsResponse {
-    status: BillwerkPaymentStatus,
-    id: String,
+    state: BillwerkPaymentState,
+    handle: String,
+    error: Option<String>,
+    error_state: Option<String>,
 }
 
 impl<F, T>
@@ -136,28 +260,65 @@ impl<F, T>
             types::PaymentsResponseData,
         >,
     ) -> Result<Self, Self::Error> {
+        let error_response = if item.response.error.is_some() || item.response.error_state.is_some()
+        {
+            Some(types::ErrorResponse {
+                code: item
+                    .response
+                    .error_state
+                    .clone()
+                    .unwrap_or(consts::NO_ERROR_CODE.to_string()),
+                message: item
+                    .response
+                    .error_state
+                    .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
+                reason: item.response.error,
+                status_code: item.http_code,
+                attempt_status: None,
+                connector_transaction_id: Some(item.response.handle.clone()),
+            })
+        } else {
+            None
+        };
+        let payments_response = types::PaymentsResponseData::TransactionResponse {
+            resource_id: types::ResponseId::ConnectorTransactionId(item.response.handle.clone()),
+            redirection_data: None,
+            mandate_reference: None,
+            connector_metadata: None,
+            network_txn_id: None,
+            connector_response_reference_id: Some(item.response.handle),
+            incremental_authorization_allowed: None,
+        };
         Ok(Self {
-            status: enums::AttemptStatus::from(item.response.status),
-            response: Ok(types::PaymentsResponseData::TransactionResponse {
-                resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
-                redirection_data: None,
-                mandate_reference: None,
-                connector_metadata: None,
-                network_txn_id: None,
-                connector_response_reference_id: None,
-                incremental_authorization_allowed: None,
-            }),
+            status: enums::AttemptStatus::from(item.response.state),
+            response: error_response.map_or_else(|| Ok(payments_response), Err),
             ..item.data
         })
     }
 }
 
-//TODO: Fill the struct with respective fields
-// REFUND :
+#[derive(Debug, Serialize)]
+pub struct BillwerkCaptureRequest {
+    amount: i64,
+}
+
+impl TryFrom<&BillwerkRouterData<&types::PaymentsCaptureRouterData>> for BillwerkCaptureRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        item: &BillwerkRouterData<&types::PaymentsCaptureRouterData>,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            amount: item.amount,
+        })
+    }
+}
+
 // Type definition for RefundRequest
-#[derive(Default, Debug, Serialize)]
+#[derive(Debug, Serialize)]
 pub struct BillwerkRefundRequest {
+    pub invoice: String,
     pub amount: i64,
+    pub text: Option<String>,
 }
 
 impl<F> TryFrom<&BillwerkRouterData<&types::RefundsRouterData<F>>> for BillwerkRefundRequest {
@@ -166,38 +327,36 @@ impl<F> TryFrom<&BillwerkRouterData<&types::RefundsRouterData<F>>> for BillwerkR
         item: &BillwerkRouterData<&types::RefundsRouterData<F>>,
     ) -> Result<Self, Self::Error> {
         Ok(Self {
-            amount: item.amount.to_owned(),
+            amount: item.amount,
+            invoice: item.router_data.request.connector_transaction_id.clone(),
+            text: item.router_data.request.reason.clone(),
         })
     }
 }
 
 // Type definition for Refund Response
-
-#[allow(dead_code)]
-#[derive(Debug, Serialize, Default, Deserialize, Clone)]
-pub enum RefundStatus {
-    Succeeded,
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum RefundState {
+    Refunded,
     Failed,
-    #[default]
     Processing,
 }
 
-impl From<RefundStatus> for enums::RefundStatus {
-    fn from(item: RefundStatus) -> Self {
+impl From<RefundState> for enums::RefundStatus {
+    fn from(item: RefundState) -> Self {
         match item {
-            RefundStatus::Succeeded => Self::Success,
-            RefundStatus::Failed => Self::Failure,
-            RefundStatus::Processing => Self::Pending,
-            //TODO: Review mapping
+            RefundState::Refunded => Self::Success,
+            RefundState::Failed => Self::Failure,
+            RefundState::Processing => Self::Pending,
         }
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Clone, Serialize, Deserialize)]
+#[derive(Debug, Serialize, Deserialize)]
 pub struct RefundResponse {
     id: String,
-    status: RefundStatus,
+    state: RefundState,
 }
 
 impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
@@ -210,7 +369,7 @@ impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
         Ok(Self {
             response: Ok(types::RefundsResponseData {
                 connector_refund_id: item.response.id.to_string(),
-                refund_status: enums::RefundStatus::from(item.response.status),
+                refund_status: enums::RefundStatus::from(item.response.state),
             }),
             ..item.data
         })
@@ -227,18 +386,16 @@ impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundResponse>>
         Ok(Self {
             response: Ok(types::RefundsResponseData {
                 connector_refund_id: item.response.id.to_string(),
-                refund_status: enums::RefundStatus::from(item.response.status),
+                refund_status: enums::RefundStatus::from(item.response.state),
             }),
             ..item.data
         })
     }
 }
 
-//TODO: Fill the struct with respective fields
-#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Serialize, Deserialize)]
 pub struct BillwerkErrorResponse {
-    pub status_code: u16,
-    pub code: String,
-    pub message: String,
-    pub reason: Option<String>,
+    pub code: Option<i32>,
+    pub error: String,
+    pub message: Option<String>,
 }
diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs
index 89b88243057..804ad3ef3d0 100644
--- a/crates/router/src/connector/utils.rs
+++ b/crates/router/src/connector/utils.rs
@@ -88,6 +88,14 @@ pub trait RouterData {
 
     fn get_optional_billing(&self) -> Option<&api::Address>;
     fn get_optional_shipping(&self) -> Option<&api::Address>;
+    fn get_optional_billing_line1(&self) -> Option<Secret<String>>;
+    fn get_optional_billing_line2(&self) -> Option<Secret<String>>;
+    fn get_optional_billing_city(&self) -> Option<String>;
+    fn get_optional_billing_country(&self) -> Option<enums::CountryAlpha2>;
+    fn get_optional_billing_zip(&self) -> Option<Secret<String>>;
+    fn get_optional_billing_state(&self) -> Option<Secret<String>>;
+    fn get_optional_billing_first_name(&self) -> Option<Secret<String>>;
+    fn get_optional_billing_last_name(&self) -> Option<Secret<String>>;
 }
 
 pub trait PaymentResponseRouterData {
@@ -202,6 +210,94 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
             .ok_or_else(missing_field_err("session_token"))
     }
 
+    fn get_optional_billing_line1(&self) -> Option<Secret<String>> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.line1)
+            })
+    }
+
+    fn get_optional_billing_line2(&self) -> Option<Secret<String>> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.line2)
+            })
+    }
+
+    fn get_optional_billing_city(&self) -> Option<String> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.city)
+            })
+    }
+
+    fn get_optional_billing_country(&self) -> Option<enums::CountryAlpha2> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.country)
+            })
+    }
+
+    fn get_optional_billing_zip(&self) -> Option<Secret<String>> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.zip)
+            })
+    }
+
+    fn get_optional_billing_state(&self) -> Option<Secret<String>> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.state)
+            })
+    }
+
+    fn get_optional_billing_first_name(&self) -> Option<Secret<String>> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.first_name)
+            })
+    }
+
+    fn get_optional_billing_last_name(&self) -> Option<Secret<String>> {
+        self.address
+            .get_payment_method_billing()
+            .and_then(|billing_address| {
+                billing_address
+                    .clone()
+                    .address
+                    .and_then(|billing_address_details| billing_address_details.last_name)
+            })
+    }
+
     fn to_connector_meta<T>(&self) -> Result<T, Error>
     where
         T: serde::de::DeserializeOwned,
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index f48227b926e..ab402f3a891 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -1731,10 +1731,10 @@ pub(crate) fn validate_auth_and_metadata_type(
             bankofamerica::transformers::BankOfAmericaAuthType::try_from(val)?;
             Ok(())
         }
-        // api_enums::Connector::Billwerk => {
-        //     billwerk::transformers::BillwerkAuthType::try_from(val)?;
-        //     Ok(())
-        // } Added as template code for future usage
+        api_enums::Connector::Billwerk => {
+            billwerk::transformers::BillwerkAuthType::try_from(val)?;
+            Ok(())
+        }
         api_enums::Connector::Bitpay => {
             bitpay::transformers::BitpayAuthType::try_from(val)?;
             Ok(())
diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs
index 4b72c7ac2e6..b5a4d04c927 100644
--- a/crates/router/src/types/api.rs
+++ b/crates/router/src/types/api.rs
@@ -326,7 +326,7 @@ impl ConnectorData {
                 enums::Connector::Authorizedotnet => Ok(Box::new(&connector::Authorizedotnet)),
                 enums::Connector::Bambora => Ok(Box::new(&connector::Bambora)),
                 enums::Connector::Bankofamerica => Ok(Box::new(&connector::Bankofamerica)),
-                // enums::Connector::Billwerk => Ok(Box::new(&connector::Billwerk)), Added as template code for future usage
+                enums::Connector::Billwerk => Ok(Box::new(&connector::Billwerk)),
                 enums::Connector::Bitpay => Ok(Box::new(&connector::Bitpay)),
                 enums::Connector::Bluesnap => Ok(Box::new(&connector::Bluesnap)),
                 enums::Connector::Boku => Ok(Box::new(&connector::Boku)),
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index 8a53a58aabd..be3cec3c3d9 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -188,7 +188,7 @@ impl ForeignTryFrom<api_enums::Connector> for common_enums::RoutableConnectors {
             api_enums::Connector::Authorizedotnet => Self::Authorizedotnet,
             api_enums::Connector::Bambora => Self::Bambora,
             api_enums::Connector::Bankofamerica => Self::Bankofamerica,
-            // api_enums::Connector::Billwerk => Self::Billwerk, Added as template code for future usage
+            api_enums::Connector::Billwerk => Self::Billwerk,
             api_enums::Connector::Bitpay => Self::Bitpay,
             api_enums::Connector::Bluesnap => Self::Bluesnap,
             api_enums::Connector::Boku => Self::Boku,
diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml
index 9a9a7606ca1..72eb6f25559 100644
--- a/loadtest/config/development.toml
+++ b/loadtest/config/development.toml
@@ -72,6 +72,7 @@ authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
 billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://test.bitpay.com"
 bluesnap.base_url = "https://sandbox.bluesnap.com/"
 bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/"
@@ -219,6 +220,7 @@ checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_
 mollie = {long_lived_token = false, payment_method = "card"}
 braintree = { long_lived_token = false, payment_method = "card" }
 gocardless = {long_lived_token = true, payment_method = "bank_debit"}
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [connector_customer]
 connector_list = "gocardless,stax,stripe"
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index fa9c7435632..227bdd5a0b1 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -7067,6 +7067,7 @@
           "authorizedotnet",
           "bambora",
           "bankofamerica",
+          "billwerk",
           "bitpay",
           "bluesnap",
           "boku",
@@ -16805,6 +16806,7 @@
           "airwallex",
           "authorizedotnet",
           "bankofamerica",
+          "billwerk",
           "bitpay",
           "bambora",
           "bluesnap",

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

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

## Description
<!-- Describe your changes in detail -->
implement all the basic flows for Billwerk (Reepay):

- [Authorise/Charge](https://optimize-docs.billwerk.com/reference/createcharge)
- [Capture](https://optimize-docs.billwerk.com/reference/settlecharge)
- [Void](https://optimize-docs.billwerk.com/reference/cancelcharge)
- [Payments Sync](https://optimize-docs.billwerk.com/reference/getcharge)
- [Refund](https://optimize-docs.billwerk.com/reference/createrefund)
- [Refunds Sync](https://optimize-docs.billwerk.com/reference/getrefund)

### 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`
-->
 Add Secondary Base Url and tokenisation 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).
-->
#4246 

## 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)?
-->
Test all the basic (no-3DS) and error cases for above mentioned flows. Refer to this [link](https://optimize-docs.billwerk.com/reference/testing) for test cards, Visa and MasterCard are not enabled on this account.

- ### Create Automatic Charge
```
curl --location 'http://localhost:8080/payments' \
--header 'Accept: application/json' \
--header 'api-key: dev_sLGOvjA9xpMI1LxK7CJ9wHVMdEkncSpHcT8LB5MwNmaA32bD8LTVMuWO9tXmyBjs' \
--header 'x-feature: router-custom' \
--header 'Content-Type: application/json' \
--data-raw '{
	"amount": 1337,
	"currency": "USD",
	"confirm": true,
	"capture_method": "automatic",
	"capture_on": "2022-09-10T10:11:12Z",
	"amount_to_capture": 1337,
	"customer_id": "customerg1",
	"email": "guest2@example.com",
	"name": "John Doe",
	"phone": "999999999",
	"phone_country_code": "+1",
	"description": "Its my first payment request",
	"authentication_type": "no_three_ds",
	"return_url": "https://duck.com",
	"payment_method": "card",
	"payment_method_type": "credit",
	"payment_method_data": {
		"card": {
			"card_number": "340000000000009",
			"card_exp_month": "12",
			"card_exp_year": "2099",
			"card_holder_name": "joseph Doe",
			"card_cvc": "123"
		}
	},
	"billing": {
		"address": {
			"line1": "1467",
			"line2": "Harrison Street",
			"line3": "Harrison Street",
			"city": "San Fransico",
			"state": "California",
			"zip": "94122",
			"country": "US",
			"first_name": "joseph",
			"last_name": "Doe"
		},
		"phone": {
			"number": "8056594427",
			"country_code": "+91"
		}
	},
	"shipping": {
		"address": {
			"line1": "1467",
			"line2": "Harrison Street",
			"line3": "Harrison Street",
			"city": "San Fransico",
			"state": "California",
			"zip": "94122",
			"country": "US",
			"first_name": "joseph",
			"last_name": "Doe"
		},
		"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"
    },
	"statement_descriptor_name": "joseph",
	"statement_descriptor_suffix": "JS",
    "metadata": {
        "test": "ket"
    }
}'
```
- ### Create Manual Charge
```
curl --location 'http://localhost:8080/payments' \
--header 'Accept: application/json' \
--header 'api-key: dev_sLGOvjA9xpMI1LxK7CJ9wHVMdEkncSpHcT8LB5MwNmaA32bD8LTVMuWO9tXmyBjs' \
--header 'x-feature: router-custom' \
--header 'Content-Type: application/json' \
--data-raw '{
	"amount": 1337,
	"currency": "USD",
	"confirm": true,
	"capture_method": "manual",
	"capture_on": "2022-09-10T10:11:12Z",
	"amount_to_capture": 1337,
	"customer_id": "customerg1",
	"email": "guest2@example.com",
	"name": "John Doe",
	"phone": "999999999",
	"phone_country_code": "+1",
	"description": "Its my first payment request",
	"authentication_type": "no_three_ds",
	"return_url": "https://duck.com",
	"payment_method": "card",
	"payment_method_type": "credit",
	"payment_method_data": {
		"card": {
			"card_number": "340000000000009",
			"card_exp_month": "12",
			"card_exp_year": "2099",
			"card_holder_name": "joseph Doe",
			"card_cvc": "123"
		}
	},
	"billing": {
		"address": {
			"line1": "1467",
			"line2": "Harrison Street",
			"line3": "Harrison Street",
			"city": "San Fransico",
			"state": "California",
			"zip": "94122",
			"country": "US",
			"first_name": "joseph",
			"last_name": "Doe"
		},
		"phone": {
			"number": "8056594427",
			"country_code": "+91"
		}
	},
	"shipping": {
		"address": {
			"line1": "1467",
			"line2": "Harrison Street",
			"line3": "Harrison Street",
			"city": "San Fransico",
			"state": "California",
			"zip": "94122",
			"country": "US",
			"first_name": "joseph",
			"last_name": "Doe"
		},
		"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"
    },
	"statement_descriptor_name": "joseph",
	"statement_descriptor_suffix": "JS",
    "metadata": {
        "test": "ket"
    }
}'
```
- ### Capture an authorised Payment
```
curl --location 'http://localhost:8080/payments/pay_8CO6aT7MPI3WAh2le81B/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_sLGOvjA9xpMI1LxK7CJ9wHVMdEkncSpHcT8LB5MwNmaA32bD8LTVMuWO9tXmyBjs' \
--data '{
  "amount_to_capture": 1006,
  "statement_descriptor_name": "Joseph",
  "statement_descriptor_suffix": "JS"
}'
```
- Void an Authorised Payment
```
curl --location 'http://localhost:8080/payments/pay_JH4ZARpgdDBt4akRLGAR/cancel' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_sLGOvjA9xpMI1LxK7CJ9wHVMdEkncSpHcT8LB5MwNmaA32bD8LTVMuWO9tXmyBjs' \
--data '{
  "cancellation_reason": "TIMEOUT"
}'
```
- ### Refund a Payment
```
curl --location 'http://localhost:8080/refunds' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_sLGOvjA9xpMI1LxK7CJ9wHVMdEkncSpHcT8LB5MwNmaA32bD8LTVMuWO9tXmyBjs' \
--data '{
    "payment_id": "pay_6NDVXkL2qRWXh0Gq443H",
    "amount": 100,
    "reason": "Customer returned product",
    "refund_type": "instant",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```

## 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
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
