Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions crates/hyperswitch_connectors/src/connectors/fiserv.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
pub mod transformers;

use std::fmt::Debug;

use base64::Engine;
use common_enums::enums;
use common_utils::{
errors::CustomResult,
ext_traits::BytesExt,
request::{Method, Request, RequestBuilder, RequestContent},
types::{AmountConvertor, FloatMajorUnit, FloatMajorUnitForConnector},
};
use error_stack::{report, ResultExt};
use hyperswitch_domain_models::{
Expand Down Expand Up @@ -44,12 +43,23 @@ use time::OffsetDateTime;
use transformers as fiserv;
use uuid::Uuid;

use crate::{constants::headers, types::ResponseRouterData, utils};
use crate::{
constants::headers,
types::ResponseRouterData,
utils::{construct_not_implemented_error_report, convert_amount},
};

#[derive(Debug, Clone)]
pub struct Fiserv;
#[derive(Clone)]
pub struct Fiserv {
amount_converter: &'static (dyn AmountConvertor<Output = FloatMajorUnit> + Sync),
}

impl Fiserv {
pub fn new() -> &'static Self {
&Self {
amount_converter: &FloatMajorUnitForConnector,
}
}
pub fn generate_authorization_signature(
&self,
auth: fiserv::FiservAuthType,
Expand Down Expand Up @@ -194,7 +204,7 @@ impl ConnectorValidation for Fiserv {
| enums::CaptureMethod::Manual
| enums::CaptureMethod::SequentialAutomatic => Ok(()),
enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(
utils::construct_not_implemented_error_report(capture_method, self.id()),
construct_not_implemented_error_report(capture_method, self.id()),
),
}
}
Expand Down Expand Up @@ -421,12 +431,12 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
req: &PaymentsCaptureRouterData,
_connectors: &Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let router_obj = fiserv::FiservRouterData::try_from((
&self.get_currency_unit(),
let amount_to_capture = convert_amount(
self.amount_converter,
req.request.minor_amount_to_capture,
req.request.currency,
req.request.amount_to_capture,
req,
))?;
)?;
let router_obj = fiserv::FiservRouterData::try_from((amount_to_capture, req))?;
let connector_req = fiserv::FiservCaptureRequest::try_from(&router_obj)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}
Expand Down Expand Up @@ -530,12 +540,12 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
req: &PaymentsAuthorizeRouterData,
_connectors: &Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let router_obj = fiserv::FiservRouterData::try_from((
&self.get_currency_unit(),
let amount = convert_amount(
self.amount_converter,
req.request.minor_amount,
req.request.currency,
req.request.amount,
req,
))?;
)?;
let router_obj = fiserv::FiservRouterData::try_from((amount, req))?;
let connector_req = fiserv::FiservPaymentsRequest::try_from(&router_obj)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}
Expand Down Expand Up @@ -624,12 +634,12 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Fiserv
req: &RefundsRouterData<Execute>,
_connectors: &Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let router_obj = fiserv::FiservRouterData::try_from((
&self.get_currency_unit(),
let refund_amount = convert_amount(
self.amount_converter,
req.request.minor_refund_amount,
req.request.currency,
req.request.refund_amount,
req,
))?;
)?;
let router_obj = fiserv::FiservRouterData::try_from((refund_amount, req))?;
let connector_req = fiserv::FiservRefundRequest::try_from(&router_obj)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use common_enums::enums;
use common_utils::{ext_traits::ValueExt, pii};
use common_utils::{ext_traits::ValueExt, pii, types::FloatMajorUnit};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
payment_method_data::PaymentMethodData,
Expand All @@ -9,7 +9,7 @@ use hyperswitch_domain_models::{
router_response_types::{PaymentsResponseData, RefundsResponseData},
types,
};
use hyperswitch_interfaces::{api, errors};
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};

Expand All @@ -23,22 +23,14 @@ use crate::{

#[derive(Debug, Serialize)]
pub struct FiservRouterData<T> {
pub amount: String,
pub amount: FloatMajorUnit,
pub router_data: T,
}

impl<T> TryFrom<(&api::CurrencyUnit, enums::Currency, i64, T)> for FiservRouterData<T> {
impl<T> TryFrom<(FloatMajorUnit, T)> for FiservRouterData<T> {
type Error = error_stack::Report<errors::ConnectorError>;

fn try_from(
(currency_unit, currency, amount, router_data): (
&api::CurrencyUnit,
enums::Currency,
i64,
T,
),
) -> Result<Self, Self::Error> {
let amount = utils::get_amount_as_string(currency_unit, amount, currency)?;
fn try_from((amount, router_data): (FloatMajorUnit, T)) -> Result<Self, Self::Error> {
Ok(Self {
amount,
router_data,
Expand Down Expand Up @@ -89,8 +81,7 @@ pub struct GooglePayToken {

#[derive(Default, Debug, Serialize)]
pub struct Amount {
#[serde(serialize_with = "utils::str_to_f32")]
total: String,
total: FloatMajorUnit,
currency: String,
}

Expand Down Expand Up @@ -143,7 +134,7 @@ impl TryFrom<&FiservRouterData<&types::PaymentsAuthorizeRouterData>> for FiservP
) -> Result<Self, Self::Error> {
let auth: FiservAuthType = FiservAuthType::try_from(&item.router_data.connector_auth_type)?;
let amount = Amount {
total: item.amount.clone(),
total: item.amount,
currency: item.router_data.request.currency.to_string(),
};
let transaction_details = TransactionDetails {
Expand Down Expand Up @@ -484,7 +475,7 @@ impl TryFrom<&FiservRouterData<&types::PaymentsCaptureRouterData>> for FiservCap
})?;
Ok(Self {
amount: Amount {
total: item.amount.clone(),
total: item.amount,
currency: item.router_data.request.currency.to_string(),
},
transaction_details: TransactionDetails {
Expand Down Expand Up @@ -579,7 +570,7 @@ impl<F> TryFrom<&FiservRouterData<&types::RefundsRouterData<F>>> for FiservRefun
})?;
Ok(Self {
amount: Amount {
total: item.amount.clone(),
total: item.amount,
currency: item.router_data.request.currency.to_string(),
},
merchant_details: MerchantDetails {
Expand Down
54 changes: 32 additions & 22 deletions crates/hyperswitch_connectors/src/connectors/helcim.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
pub mod transformers;
use std::fmt::Debug;

use api_models::webhooks::IncomingWebhookEvent;
use common_enums::enums;
use common_utils::{
errors::CustomResult,
ext_traits::BytesExt,
request::{Method, Request, RequestBuilder, RequestContent},
types::{AmountConvertor, FloatMajorUnit, FloatMajorUnitForConnector},
};
use error_stack::{report, ResultExt};
use hyperswitch_domain_models::{
Expand Down Expand Up @@ -49,11 +49,21 @@ use transformers as helcim;
use crate::{
constants::headers,
types::ResponseRouterData,
utils::{to_connector_meta, PaymentsAuthorizeRequestData},
utils::{convert_amount, to_connector_meta, PaymentsAuthorizeRequestData},
};

#[derive(Debug, Clone)]
pub struct Helcim;
#[derive(Clone)]
pub struct Helcim {
amount_convertor: &'static (dyn AmountConvertor<Output = FloatMajorUnit> + Sync),
}

impl Helcim {
pub fn new() -> &'static Self {
&Self {
amount_convertor: &FloatMajorUnitForConnector,
}
}
}

impl api::Payment for Helcim {}
impl api::PaymentSession for Helcim {}
Expand Down Expand Up @@ -305,13 +315,13 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
req: &PaymentsAuthorizeRouterData,
_connectors: &Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let connector_router_data = helcim::HelcimRouterData::try_from((
&self.get_currency_unit(),
let connector_router_data = convert_amount(
self.amount_convertor,
req.request.minor_amount,
req.request.currency,
req.request.amount,
req,
))?;
let connector_req = helcim::HelcimPaymentsRequest::try_from(&connector_router_data)?;
)?;
let router_obj = helcim::HelcimRouterData::try_from((connector_router_data, req))?;
let connector_req = helcim::HelcimPaymentsRequest::try_from(&router_obj)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}

Expand Down Expand Up @@ -484,13 +494,13 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
req: &PaymentsCaptureRouterData,
_connectors: &Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let connector_router_data = helcim::HelcimRouterData::try_from((
&self.get_currency_unit(),
let connector_router_data = convert_amount(
self.amount_convertor,
req.request.minor_amount_to_capture,
req.request.currency,
req.request.amount_to_capture,
req,
))?;
let connector_req = helcim::HelcimCaptureRequest::try_from(&connector_router_data)?;
)?;
let router_obj = helcim::HelcimRouterData::try_from((connector_router_data, req))?;
let connector_req = helcim::HelcimCaptureRequest::try_from(&router_obj)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}

Expand Down Expand Up @@ -651,13 +661,13 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Helcim
req: &RefundsRouterData<Execute>,
_connectors: &Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let connector_router_data = helcim::HelcimRouterData::try_from((
&self.get_currency_unit(),
let connector_router_data = convert_amount(
self.amount_convertor,
req.request.minor_refund_amount,
req.request.currency,
req.request.refund_amount,
req,
))?;
let connector_req = helcim::HelcimRefundRequest::try_from(&connector_router_data)?;
)?;
let router_obj = helcim::HelcimRouterData::try_from((connector_router_data, req))?;
let connector_req = helcim::HelcimRefundRequest::try_from(&router_obj)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use common_enums::enums;
use common_utils::pii::{Email, IpAddress};
use common_utils::{
pii::{Email, IpAddress},
types::FloatMajorUnit,
};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
payment_method_data::{Card, PaymentMethodData},
Expand All @@ -15,10 +18,7 @@ use hyperswitch_domain_models::{
RefundsRouterData, SetupMandateRouterData,
},
};
use hyperswitch_interfaces::{
api::{self},
errors,
};
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};

Expand All @@ -33,16 +33,13 @@ use crate::{

#[derive(Debug, Serialize)]
pub struct HelcimRouterData<T> {
pub amount: f64,
pub amount: FloatMajorUnit,
pub router_data: T,
}

impl<T> TryFrom<(&api::CurrencyUnit, enums::Currency, i64, T)> for HelcimRouterData<T> {
impl<T> TryFrom<(FloatMajorUnit, T)> for HelcimRouterData<T> {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
(currency_unit, currency, amount, item): (&api::CurrencyUnit, enums::Currency, i64, T),
) -> Result<Self, Self::Error> {
let amount = crate::utils::get_amount_as_f64(currency_unit, amount, currency)?;
fn try_from((amount, item): (FloatMajorUnit, T)) -> Result<Self, Self::Error> {
Ok(Self {
amount,
router_data: item,
Expand Down Expand Up @@ -77,7 +74,7 @@ pub struct HelcimVerifyRequest {
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct HelcimPaymentsRequest {
amount: f64,
amount: FloatMajorUnit,
currency: enums::Currency,
ip_address: Secret<String, IpAddress>,
card_data: HelcimCard,
Expand Down Expand Up @@ -115,8 +112,8 @@ pub struct HelcimInvoice {
pub struct HelcimLineItems {
description: String,
quantity: u8,
price: f64,
total: f64,
price: FloatMajorUnit,
total: FloatMajorUnit,
}

#[derive(Debug, Serialize)]
Expand Down Expand Up @@ -514,7 +511,7 @@ impl<F>
#[serde(rename_all = "camelCase")]
pub struct HelcimCaptureRequest {
pre_auth_transaction_id: u64,
amount: f64,
amount: FloatMajorUnit,
ip_address: Secret<String, IpAddress>,
#[serde(skip_serializing_if = "Option::is_none")]
ecommerce: Option<bool>,
Expand Down Expand Up @@ -637,7 +634,7 @@ impl<F>
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct HelcimRefundRequest {
amount: f64,
amount: FloatMajorUnit,
original_transaction_id: u64,
ip_address: Secret<String, IpAddress>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
11 changes: 0 additions & 11 deletions crates/hyperswitch_connectors/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ use masking::{ExposeInterface, PeekInterface, Secret};
use once_cell::sync::Lazy;
use regex::Regex;
use router_env::logger;
use serde::Serializer;
use serde_json::Value;
use time::PrimitiveDateTime;

Expand Down Expand Up @@ -344,16 +343,6 @@ pub(crate) fn construct_not_implemented_error_report(
.into()
}

pub(crate) fn str_to_f32<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let float_value = value.parse::<f64>().map_err(|_| {
serde::ser::Error::custom("Invalid string, cannot be converted to float value")
})?;
serializer.serialize_f64(float_value)
}

pub(crate) const SELECTED_PAYMENT_METHOD: &str = "Selected payment method";

pub(crate) fn get_unimplemented_payment_method_error_message(connector: &str) -> String {
Expand Down
Loading
Loading