mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	feat(connector): [Fiserv] Currency Unit Conversion (#2715)
This commit is contained in:
		| @ -104,6 +104,10 @@ impl ConnectorCommon for Fiserv { | ||||
|         "fiserv" | ||||
|     } | ||||
|  | ||||
|     fn get_currency_unit(&self) -> api::CurrencyUnit { | ||||
|         api::CurrencyUnit::Base | ||||
|     } | ||||
|  | ||||
|     fn common_get_content_type(&self) -> &'static str { | ||||
|         "application/json" | ||||
|     } | ||||
| @ -400,7 +404,13 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme | ||||
|         &self, | ||||
|         req: &types::PaymentsCaptureRouterData, | ||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||
|         let connector_request = fiserv::FiservCaptureRequest::try_from(req)?; | ||||
|         let router_obj = fiserv::FiservRouterData::try_from(( | ||||
|             &self.get_currency_unit(), | ||||
|             req.request.currency, | ||||
|             req.request.amount_to_capture, | ||||
|             req, | ||||
|         ))?; | ||||
|         let connector_request = fiserv::FiservCaptureRequest::try_from(&router_obj)?; | ||||
|         let fiserv_payments_capture_request = types::RequestBody::log_and_get_request_body( | ||||
|             &connector_request, | ||||
|             utils::Encode::<fiserv::FiservCaptureRequest>::encode_to_string_of_json, | ||||
| @ -505,7 +515,13 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P | ||||
|         &self, | ||||
|         req: &types::PaymentsAuthorizeRouterData, | ||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||
|         let connector_request = fiserv::FiservPaymentsRequest::try_from(req)?; | ||||
|         let router_obj = fiserv::FiservRouterData::try_from(( | ||||
|             &self.get_currency_unit(), | ||||
|             req.request.currency, | ||||
|             req.request.amount, | ||||
|             req, | ||||
|         ))?; | ||||
|         let connector_request = fiserv::FiservPaymentsRequest::try_from(&router_obj)?; | ||||
|         let fiserv_payments_request = types::RequestBody::log_and_get_request_body( | ||||
|             &connector_request, | ||||
|             utils::Encode::<fiserv::FiservPaymentsRequest>::encode_to_string_of_json, | ||||
| @ -592,7 +608,13 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon | ||||
|         &self, | ||||
|         req: &types::RefundsRouterData<api::Execute>, | ||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||
|         let connector_request = fiserv::FiservRefundRequest::try_from(req)?; | ||||
|         let router_obj = fiserv::FiservRouterData::try_from(( | ||||
|             &self.get_currency_unit(), | ||||
|             req.request.currency, | ||||
|             req.request.refund_amount, | ||||
|             req, | ||||
|         ))?; | ||||
|         let connector_request = fiserv::FiservRefundRequest::try_from(&router_obj)?; | ||||
|         let fiserv_refund_request = types::RequestBody::log_and_get_request_body( | ||||
|             &connector_request, | ||||
|             utils::Encode::<fiserv::FiservRefundRequest>::encode_to_string_of_json, | ||||
|  | ||||
| @ -9,6 +9,38 @@ use crate::{ | ||||
|     types::{self, api, storage::enums}, | ||||
| }; | ||||
|  | ||||
| #[derive(Debug, Serialize)] | ||||
| pub struct FiservRouterData<T> { | ||||
|     pub amount: String, | ||||
|     pub router_data: T, | ||||
| } | ||||
|  | ||||
| impl<T> | ||||
|     TryFrom<( | ||||
|         &types::api::CurrencyUnit, | ||||
|         types::storage::enums::Currency, | ||||
|         i64, | ||||
|         T, | ||||
|     )> for FiservRouterData<T> | ||||
| { | ||||
|     type Error = error_stack::Report<errors::ConnectorError>; | ||||
|  | ||||
|     fn try_from( | ||||
|         (currency_unit, currency, amount, router_data): ( | ||||
|             &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, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Serialize, Eq, PartialEq)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct FiservPaymentsRequest { | ||||
| @ -99,23 +131,25 @@ pub enum TransactionInteractionPosConditionCode { | ||||
|     CardNotPresentEcom, | ||||
| } | ||||
|  | ||||
| impl TryFrom<&types::PaymentsAuthorizeRouterData> for FiservPaymentsRequest { | ||||
| impl TryFrom<&FiservRouterData<&types::PaymentsAuthorizeRouterData>> for FiservPaymentsRequest { | ||||
|     type Error = error_stack::Report<errors::ConnectorError>; | ||||
|     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> { | ||||
|         let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?; | ||||
|     fn try_from( | ||||
|         item: &FiservRouterData<&types::PaymentsAuthorizeRouterData>, | ||||
|     ) -> Result<Self, Self::Error> { | ||||
|         let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?; | ||||
|         let amount = Amount { | ||||
|             total: utils::to_currency_base_unit(item.request.amount, item.request.currency)?, | ||||
|             currency: item.request.currency.to_string(), | ||||
|             total: item.amount.clone(), | ||||
|             currency: item.router_data.request.currency.to_string(), | ||||
|         }; | ||||
|         let transaction_details = TransactionDetails { | ||||
|             capture_flag: Some(matches!( | ||||
|                 item.request.capture_method, | ||||
|                 item.router_data.request.capture_method, | ||||
|                 Some(enums::CaptureMethod::Automatic) | None | ||||
|             )), | ||||
|             reversal_reason_code: None, | ||||
|             merchant_transaction_id: item.connector_request_reference_id.clone(), | ||||
|             merchant_transaction_id: item.router_data.connector_request_reference_id.clone(), | ||||
|         }; | ||||
|         let metadata = item.get_connector_meta()?; | ||||
|         let metadata = item.router_data.get_connector_meta()?; | ||||
|         let session: SessionObject = metadata | ||||
|             .parse_value("SessionObject") | ||||
|             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||
| @ -133,7 +167,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for FiservPaymentsRequest { | ||||
|             //card not present in online transaction | ||||
|             pos_condition_code: TransactionInteractionPosConditionCode::CardNotPresentEcom, | ||||
|         }; | ||||
|         let source = match item.request.payment_method_data.clone() { | ||||
|         let source = match item.router_data.request.payment_method_data.clone() { | ||||
|             api::PaymentMethodData::Card(ref ccard) => { | ||||
|                 let card = CardData { | ||||
|                     card_data: ccard.card_number.clone(), | ||||
| @ -389,35 +423,40 @@ pub struct SessionObject { | ||||
|     pub terminal_id: String, | ||||
| } | ||||
|  | ||||
| impl TryFrom<&types::PaymentsCaptureRouterData> for FiservCaptureRequest { | ||||
| impl TryFrom<&FiservRouterData<&types::PaymentsCaptureRouterData>> for FiservCaptureRequest { | ||||
|     type Error = error_stack::Report<errors::ConnectorError>; | ||||
|     fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> { | ||||
|         let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?; | ||||
|     fn try_from( | ||||
|         item: &FiservRouterData<&types::PaymentsCaptureRouterData>, | ||||
|     ) -> Result<Self, Self::Error> { | ||||
|         let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?; | ||||
|         let metadata = item | ||||
|             .router_data | ||||
|             .connector_meta_data | ||||
|             .clone() | ||||
|             .ok_or(errors::ConnectorError::RequestEncodingFailed)?; | ||||
|         let session: SessionObject = metadata | ||||
|             .parse_value("SessionObject") | ||||
|             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||
|         let amount = | ||||
|             utils::to_currency_base_unit(item.request.amount_to_capture, item.request.currency)?; | ||||
|         Ok(Self { | ||||
|             amount: Amount { | ||||
|                 total: amount, | ||||
|                 currency: item.request.currency.to_string(), | ||||
|                 total: item.amount.clone(), | ||||
|                 currency: item.router_data.request.currency.to_string(), | ||||
|             }, | ||||
|             transaction_details: TransactionDetails { | ||||
|                 capture_flag: Some(true), | ||||
|                 reversal_reason_code: None, | ||||
|                 merchant_transaction_id: item.connector_request_reference_id.clone(), | ||||
|                 merchant_transaction_id: item.router_data.connector_request_reference_id.clone(), | ||||
|             }, | ||||
|             merchant_details: MerchantDetails { | ||||
|                 merchant_id: auth.merchant_account, | ||||
|                 terminal_id: Some(session.terminal_id), | ||||
|             }, | ||||
|             reference_transaction_details: ReferenceTransactionDetails { | ||||
|                 reference_transaction_id: item.request.connector_transaction_id.to_string(), | ||||
|                 reference_transaction_id: item | ||||
|                     .router_data | ||||
|                     .request | ||||
|                     .connector_transaction_id | ||||
|                     .to_string(), | ||||
|             }, | ||||
|         }) | ||||
|     } | ||||
| @ -477,11 +516,14 @@ pub struct FiservRefundRequest { | ||||
|     reference_transaction_details: ReferenceTransactionDetails, | ||||
| } | ||||
|  | ||||
| impl<F> TryFrom<&types::RefundsRouterData<F>> for FiservRefundRequest { | ||||
| impl<F> TryFrom<&FiservRouterData<&types::RefundsRouterData<F>>> for FiservRefundRequest { | ||||
|     type Error = error_stack::Report<errors::ConnectorError>; | ||||
|     fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> { | ||||
|         let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?; | ||||
|     fn try_from( | ||||
|         item: &FiservRouterData<&types::RefundsRouterData<F>>, | ||||
|     ) -> Result<Self, Self::Error> { | ||||
|         let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?; | ||||
|         let metadata = item | ||||
|             .router_data | ||||
|             .connector_meta_data | ||||
|             .clone() | ||||
|             .ok_or(errors::ConnectorError::RequestEncodingFailed)?; | ||||
| @ -490,18 +532,19 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for FiservRefundRequest { | ||||
|             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||
|         Ok(Self { | ||||
|             amount: Amount { | ||||
|                 total: utils::to_currency_base_unit( | ||||
|                     item.request.refund_amount, | ||||
|                     item.request.currency, | ||||
|                 )?, | ||||
|                 currency: item.request.currency.to_string(), | ||||
|                 total: item.amount.clone(), | ||||
|                 currency: item.router_data.request.currency.to_string(), | ||||
|             }, | ||||
|             merchant_details: MerchantDetails { | ||||
|                 merchant_id: auth.merchant_account, | ||||
|                 terminal_id: Some(session.terminal_id), | ||||
|             }, | ||||
|             reference_transaction_details: ReferenceTransactionDetails { | ||||
|                 reference_transaction_id: item.request.connector_transaction_id.to_string(), | ||||
|                 reference_transaction_id: item | ||||
|                     .router_data | ||||
|                     .request | ||||
|                     .connector_transaction_id | ||||
|                     .to_string(), | ||||
|             }, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Seemebadnekai
					Seemebadnekai