refactor(connector): add amount conversion framework for ACI (#5456)

This commit is contained in:
Kiran Kumar
2024-08-13 18:01:47 +05:30
committed by GitHub
parent 051086f7b6
commit 93aa522929
4 changed files with 47 additions and 43 deletions

View File

@ -1,13 +1,15 @@
mod result_codes; mod result_codes;
pub mod transformers; pub mod transformers;
use std::fmt::Debug;
use common_utils::request::RequestContent; use common_utils::{
request::RequestContent,
types::{AmountConvertor, StringMajorUnit, StringMajorUnitForConnector},
};
use error_stack::{report, ResultExt}; use error_stack::{report, ResultExt};
use masking::PeekInterface; use masking::PeekInterface;
use transformers as aci; use transformers as aci;
use super::utils::{is_mandate_supported, PaymentsAuthorizeRequestData}; use super::utils::{convert_amount, is_mandate_supported, PaymentsAuthorizeRequestData};
use crate::{ use crate::{
configs::settings, configs::settings,
connector::utils::PaymentMethodDataType, connector::utils::PaymentMethodDataType,
@ -26,8 +28,18 @@ use crate::{
utils::BytesExt, utils::BytesExt,
}; };
#[derive(Debug, Clone)] #[derive(Clone)]
pub struct Aci; pub struct Aci {
amount_converter: &'static (dyn AmountConvertor<Output = StringMajorUnit> + Sync),
}
impl Aci {
pub fn new() -> &'static Self {
&Self {
amount_converter: &StringMajorUnitForConnector,
}
}
}
impl ConnectorCommon for Aci { impl ConnectorCommon for Aci {
fn id(&self) -> &'static str { fn id(&self) -> &'static str {
@ -312,12 +324,14 @@ impl
_connectors: &settings::Connectors, _connectors: &settings::Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> { ) -> CustomResult<RequestContent, errors::ConnectorError> {
// encode only for for urlencoded things. // encode only for for urlencoded things.
let connector_router_data = aci::AciRouterData::try_from((
&self.get_currency_unit(), let amount = convert_amount(
self.amount_converter,
req.request.minor_amount,
req.request.currency, req.request.currency,
req.request.amount, )?;
req,
))?; let connector_router_data = aci::AciRouterData::from((amount, req));
let connector_req = aci::AciPaymentsRequest::try_from(&connector_router_data)?; let connector_req = aci::AciPaymentsRequest::try_from(&connector_router_data)?;
Ok(RequestContent::FormUrlEncoded(Box::new(connector_req))) Ok(RequestContent::FormUrlEncoded(Box::new(connector_req)))
@ -514,12 +528,13 @@ impl services::ConnectorIntegration<api::Execute, types::RefundsData, types::Ref
req: &types::RefundsRouterData<api::Execute>, req: &types::RefundsRouterData<api::Execute>,
_connectors: &settings::Connectors, _connectors: &settings::Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> { ) -> CustomResult<RequestContent, errors::ConnectorError> {
let connector_router_data = aci::AciRouterData::try_from(( let amount = convert_amount(
&self.get_currency_unit(), self.amount_converter,
req.request.minor_refund_amount,
req.request.currency, req.request.currency,
req.request.refund_amount, )?;
req,
))?; let connector_router_data = aci::AciRouterData::from((amount, req));
let connector_req = aci::AciRefundRequest::try_from(&connector_router_data)?; let connector_req = aci::AciRefundRequest::try_from(&connector_router_data)?;
Ok(RequestContent::FormUrlEncoded(Box::new(connector_req))) Ok(RequestContent::FormUrlEncoded(Box::new(connector_req)))
} }

View File

@ -1,6 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use common_utils::{id_type, pii::Email}; use common_utils::{id_type, pii::Email, types::StringMajorUnit};
use error_stack::report; use error_stack::report;
use masking::{ExposeInterface, Secret}; use masking::{ExposeInterface, Secret};
use reqwest::Url; use reqwest::Url;
@ -18,26 +18,16 @@ type Error = error_stack::Report<errors::ConnectorError>;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct AciRouterData<T> { pub struct AciRouterData<T> {
amount: String, amount: StringMajorUnit,
router_data: T, router_data: T,
} }
impl<T> TryFrom<(&types::api::CurrencyUnit, enums::Currency, i64, T)> for AciRouterData<T> { impl<T> From<(StringMajorUnit, T)> for AciRouterData<T> {
type Error = error_stack::Report<errors::ConnectorError>; fn from((amount, item): (StringMajorUnit, T)) -> Self {
Self {
fn try_from(
(currency_unit, currency, amount, item): (
&types::api::CurrencyUnit,
enums::Currency,
i64,
T,
),
) -> Result<Self, Self::Error> {
let amount = utils::get_amount_as_string(currency_unit, amount, currency)?;
Ok(Self {
amount, amount,
router_data: item, router_data: item,
}) }
} }
} }
@ -76,7 +66,7 @@ pub struct AciPaymentsRequest {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TransactionDetails { pub struct TransactionDetails {
pub entity_id: Secret<String>, pub entity_id: Secret<String>,
pub amount: String, pub amount: StringMajorUnit,
pub currency: String, pub currency: String,
pub payment_type: AciPaymentType, pub payment_type: AciPaymentType,
} }
@ -786,7 +776,7 @@ impl<F, T>
#[derive(Default, Debug, Serialize)] #[derive(Default, Debug, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AciRefundRequest { pub struct AciRefundRequest {
pub amount: String, pub amount: StringMajorUnit,
pub currency: String, pub currency: String,
pub payment_type: AciPaymentType, pub payment_type: AciPaymentType,
pub entity_id: Secret<String>, pub entity_id: Secret<String>,

View File

@ -306,7 +306,7 @@ impl ConnectorData {
) -> CustomResult<ConnectorEnum, errors::ApiErrorResponse> { ) -> CustomResult<ConnectorEnum, errors::ApiErrorResponse> {
match enums::Connector::from_str(connector_name) { match enums::Connector::from_str(connector_name) {
Ok(name) => match name { Ok(name) => match name {
enums::Connector::Aci => Ok(ConnectorEnum::Old(Box::new(&connector::Aci))), enums::Connector::Aci => Ok(ConnectorEnum::Old(Box::new(connector::Aci::new()))),
enums::Connector::Adyen => { enums::Connector::Adyen => {
Ok(ConnectorEnum::Old(Box::new(connector::Adyen::new()))) Ok(ConnectorEnum::Old(Box::new(connector::Adyen::new())))
} }

View File

@ -7,7 +7,6 @@ use common_utils::id_type;
use masking::Secret; use masking::Secret;
use router::{ use router::{
configs::settings::Settings, configs::settings::Settings,
connector::aci,
core::payments, core::payments,
db::StorageImpl, db::StorageImpl,
routes, services, routes, services,
@ -214,9 +213,9 @@ async fn payments_create_success() {
.get_session_state("public", || {}) .get_session_state("public", || {})
.unwrap(); .unwrap();
static CV: aci::Aci = aci::Aci; use router::connector::Aci;
let connector = utils::construct_connector_data_old( let connector = utils::construct_connector_data_old(
Box::new(&CV), Box::new(Aci::new()),
types::Connector::Aci, types::Connector::Aci,
types::api::GetToken::Connector, types::api::GetToken::Connector,
None, None,
@ -247,7 +246,7 @@ async fn payments_create_success() {
async fn payments_create_failure() { async fn payments_create_failure() {
{ {
let conf = Settings::new().unwrap(); let conf = Settings::new().unwrap();
static CV: aci::Aci = aci::Aci; use router::connector::Aci;
let tx: oneshot::Sender<()> = oneshot::channel().0; let tx: oneshot::Sender<()> = oneshot::channel().0;
let app_state = Box::pin(routes::AppState::with_storage( let app_state = Box::pin(routes::AppState::with_storage(
@ -261,7 +260,7 @@ async fn payments_create_failure() {
.get_session_state("public", || {}) .get_session_state("public", || {})
.unwrap(); .unwrap();
let connector = utils::construct_connector_data_old( let connector = utils::construct_connector_data_old(
Box::new(&CV), Box::new(Aci::new()),
types::Connector::Aci, types::Connector::Aci,
types::api::GetToken::Connector, types::api::GetToken::Connector,
None, None,
@ -304,9 +303,9 @@ async fn payments_create_failure() {
async fn refund_for_successful_payments() { async fn refund_for_successful_payments() {
let conf = Settings::new().unwrap(); let conf = Settings::new().unwrap();
static CV: aci::Aci = aci::Aci; use router::connector::Aci;
let connector = utils::construct_connector_data_old( let connector = utils::construct_connector_data_old(
Box::new(&CV), Box::new(Aci::new()),
types::Connector::Aci, types::Connector::Aci,
types::api::GetToken::Connector, types::api::GetToken::Connector,
None, None,
@ -374,9 +373,9 @@ async fn refund_for_successful_payments() {
#[ignore] #[ignore]
async fn refunds_create_failure() { async fn refunds_create_failure() {
let conf = Settings::new().unwrap(); let conf = Settings::new().unwrap();
static CV: aci::Aci = aci::Aci; use router::connector::Aci;
let connector = utils::construct_connector_data_old( let connector = utils::construct_connector_data_old(
Box::new(&CV), Box::new(Aci::new()),
types::Connector::Aci, types::Connector::Aci,
types::api::GetToken::Connector, types::api::GetToken::Connector,
None, None,