Bug: [FEATURE]: [Cybersource] Currency Unit Conversion



### :memo: Feature Description

- Each currency can be described in terms of base or minor units. 
- For instance, when dealing with USD currency, the Cent is considered as the minor unit, while the Dollar is considered the base unit. 
- In Hyperswitch, the amount value is expected to be always provided in minor units. 
- For example: In USD, If the amount is 1 in base unit (Dollar), then it will be equivalent to 100 in minor units (Cent)
- Some of the connectors integrated require the amount to be converted to a desirable unit before being passed to them. 
- We have functions `to_currency_base_unit` and `to_currency_lower_unit` in place to convert the minor unit amount to its decimal equivalent and vice versa. These conversions are handled explicitly based on the connector.


### :hammer: Possible Implementation

- ConnectorCommon trait have been implemented for the connector. 
- This trait contains `get_currency_unit` method. This method needs to be implemented. 
- It will define what type of conversion needs to be done during `connector_router_data` creation. Concurrently handle the creation of `connector_router_data` to be passed for the connector request body creation.
- You can check this PR for further reference https://github.com/juspay/hyperswitch/pull/2196

:bookmark: Note: All the changes needed should be contained within `hyperswitch/crates/router/src/connector/`

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

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

### :package: Have you read the Contributing Guidelines?

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

### :sparkles: Are you willing to submit a PR?

diff --git a/crates/router/src/connector/cybersource.rs b/crates/router/src/connector/cybersource.rs
index d1ad36b26d1..0a13aa0cf14 100644
--- a/crates/router/src/connector/cybersource.rs
+++ b/crates/router/src/connector/cybersource.rs
@@ -93,6 +93,10 @@ impl ConnectorCommon for Cybersource {
         connectors.cybersource.base_url.as_ref()
     }
 
+    fn get_currency_unit(&self) -> api::CurrencyUnit {
+        api::CurrencyUnit::Minor
+    }
+
     fn build_error_response(
         &self,
         res: types::Response,
@@ -468,7 +472,14 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
         &self,
         req: &types::PaymentsAuthorizeRouterData,
     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
-        let connector_request = cybersource::CybersourcePaymentsRequest::try_from(req)?;
+        let connector_router_data = cybersource::CybersourceRouterData::try_from((
+            &self.get_currency_unit(),
+            req.request.currency,
+            req.request.amount,
+            req,
+        ))?;
+        let connector_request =
+            cybersource::CybersourcePaymentsRequest::try_from(&connector_router_data)?;
         let cybersource_payments_request = types::RequestBody::log_and_get_request_body(
             &connector_request,
             utils::Encode::<cybersource::CybersourcePaymentsRequest>::encode_to_string_of_json,
diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs
index 5a3060f99eb..55507e4f490 100644
--- a/crates/router/src/connector/cybersource/transformers.rs
+++ b/crates/router/src/connector/cybersource/transformers.rs
@@ -15,6 +15,37 @@ use crate::{
     },
 };
 
+#[derive(Debug, Serialize)]
+pub struct CybersourceRouterData<T> {
+    pub amount: String,
+    pub router_data: T,
+}
+
+impl<T>
+    TryFrom<(
+        &types::api::CurrencyUnit,
+        types::storage::enums::Currency,
+        i64,
+        T,
+    )> for CybersourceRouterData<T>
+{
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(
+        (currency_unit, currency, amount, item): (
+            &types::api::CurrencyUnit,
+            types::storage::enums::Currency,
+            i64,
+            T,
+        ),
+    ) -> Result<Self, Self::Error> {
+        let amount = utils::get_amount_as_string(currency_unit, amount, currency)?;
+        Ok(Self {
+            amount,
+            router_data: item,
+        })
+    }
+}
+
 #[derive(Default, Debug, Serialize, Eq, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub struct CybersourcePaymentsRequest {
@@ -109,27 +140,33 @@ fn build_bill_to(
     })
 }
 
-impl TryFrom<&types::PaymentsAuthorizeRouterData> for CybersourcePaymentsRequest {
+impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
+    for CybersourcePaymentsRequest
+{
     type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
-        match item.request.payment_method_data.clone() {
+    fn try_from(
+        item: &CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
+    ) -> Result<Self, Self::Error> {
+        match item.router_data.request.payment_method_data.clone() {
             api::PaymentMethodData::Card(ccard) => {
-                let phone = item.get_billing_phone()?;
+                let phone = item.router_data.get_billing_phone()?;
                 let phone_number = phone.get_number()?;
                 let country_code = phone.get_country_code()?;
                 let number_with_code =
                     Secret::new(format!("{}{}", country_code, phone_number.peek()));
                 let email = item
+                    .router_data
                     .request
                     .email
                     .clone()
                     .ok_or_else(utils::missing_field_err("email"))?;
-                let bill_to = build_bill_to(item.get_billing()?, email, number_with_code)?;
+                let bill_to =
+                    build_bill_to(item.router_data.get_billing()?, email, number_with_code)?;
 
                 let order_information = OrderInformationWithBill {
                     amount_details: Amount {
-                        total_amount: item.request.amount.to_string(),
-                        currency: item.request.currency.to_string().to_uppercase(),
+                        total_amount: item.amount.to_owned(),
+                        currency: item.router_data.request.currency.to_string().to_uppercase(),
                     },
                     bill_to,
                 };
@@ -145,14 +182,14 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for CybersourcePaymentsRequest
 
                 let processing_information = ProcessingInformation {
                     capture: matches!(
-                        item.request.capture_method,
+                        item.router_data.request.capture_method,
                         Some(enums::CaptureMethod::Automatic) | None
                     ),
                     capture_options: None,
                 };
 
                 let client_reference_information = ClientReferenceInformation {
-                    code: Some(item.connector_request_reference_id.clone()),
+                    code: Some(item.router_data.connector_request_reference_id.clone()),
                 };
 
                 Ok(Self {
diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs
index 3a8cae3a631..6f1566a35b0 100644
--- a/crates/router/src/connector/utils.rs
+++ b/crates/router/src/connector/utils.rs
@@ -1077,7 +1077,7 @@ pub fn get_amount_as_string(
     currency: diesel_models::enums::Currency,
 ) -> Result<String, error_stack::Report<errors::ConnectorError>> {
     let amount = match currency_unit {
-        types::api::CurrencyUnit::Minor => amount.to_string(),
+        types::api::CurrencyUnit::Minor => to_currency_lower_unit(amount.to_string(), currency)?,
         types::api::CurrencyUnit::Base => to_currency_base_unit(amount, currency)?,
     };
     Ok(amount)

## Type of Change

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

## Description
This PR implements `get_currency_unit` for cybersource to convert payments from `Base` to `Minor` it also implements router data to handle the conversion.

### Additional Changes

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

## Motivation and Context
Closes #2222 


## How did you test it?

I tested by sending a payment request & verifying the amount is showed in minor units in the cybersource console

![image](https://github.com/juspay/hyperswitch/assets/33598169/db8bea1c-23ed-4df4-a8a2-72f2e55c6131)


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