refactor(connector): [Trustpay] Enhance currency Mapping with ConnectorCurrencyCommon Trait (#2197)

This commit is contained in:
chikke srujan
2023-09-22 17:40:20 +05:30
committed by GitHub
parent b9f25c4a4e
commit 583b9aa33b
2 changed files with 108 additions and 65 deletions

View File

@ -10,7 +10,7 @@ use transformers as trustpay;
use super::utils::{ use super::utils::{
collect_and_sort_values_by_removing_signature, get_error_code_error_message_based_on_priority, collect_and_sort_values_by_removing_signature, get_error_code_error_message_based_on_priority,
ConnectorErrorType, ConnectorErrorTypeMapping, ConnectorErrorType, ConnectorErrorTypeMapping, PaymentsPreProcessingData,
}; };
use crate::{ use crate::{
configs::settings, configs::settings,
@ -80,6 +80,10 @@ impl ConnectorCommon for Trustpay {
"trustpay" "trustpay"
} }
fn get_currency_unit(&self) -> api::CurrencyUnit {
api::CurrencyUnit::Base
}
fn common_get_content_type(&self) -> &'static str { fn common_get_content_type(&self) -> &'static str {
"application/x-www-form-urlencoded" "application/x-www-form-urlencoded"
} }
@ -422,7 +426,16 @@ impl
&self, &self,
req: &types::PaymentsPreProcessingRouterData, req: &types::PaymentsPreProcessingRouterData,
) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
let create_intent_req = trustpay::TrustpayCreateIntentRequest::try_from(req)?; let amount = req.request.get_amount()?;
let currency = req.request.get_currency()?;
let connector_router_data = trustpay::TrustpayRouterData::try_from((
&self.get_currency_unit(),
currency,
amount,
req,
))?;
let create_intent_req =
trustpay::TrustpayCreateIntentRequest::try_from(&connector_router_data)?;
let trustpay_req = types::RequestBody::log_and_get_request_body( let trustpay_req = types::RequestBody::log_and_get_request_body(
&create_intent_req, &create_intent_req,
utils::Encode::<trustpay::TrustpayCreateIntentRequest>::url_encode, utils::Encode::<trustpay::TrustpayCreateIntentRequest>::url_encode,
@ -525,7 +538,13 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
&self, &self,
req: &types::PaymentsAuthorizeRouterData, req: &types::PaymentsAuthorizeRouterData,
) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
let connector_req = trustpay::TrustpayPaymentsRequest::try_from(req)?; let connector_router_data = trustpay::TrustpayRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request.amount,
req,
))?;
let connector_req = trustpay::TrustpayPaymentsRequest::try_from(&connector_router_data)?;
let trustpay_req_string = match req.payment_method { let trustpay_req_string = match req.payment_method {
diesel_models::enums::PaymentMethod::BankRedirect => { diesel_models::enums::PaymentMethod::BankRedirect => {
types::RequestBody::log_and_get_request_body( types::RequestBody::log_and_get_request_body(
@ -628,7 +647,13 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
&self, &self,
req: &types::RefundsRouterData<api::Execute>, req: &types::RefundsRouterData<api::Execute>,
) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
let connector_req = trustpay::TrustpayRefundRequest::try_from(req)?; let connector_router_data = trustpay::TrustpayRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request.refund_amount,
req,
))?;
let connector_req = trustpay::TrustpayRefundRequest::try_from(&connector_router_data)?;
let trustpay_req_string = match req.payment_method { let trustpay_req_string = match req.payment_method {
diesel_models::enums::PaymentMethod::BankRedirect => { diesel_models::enums::PaymentMethod::BankRedirect => {
types::RequestBody::log_and_get_request_body( types::RequestBody::log_and_get_request_body(

View File

@ -5,7 +5,7 @@ use common_utils::{
errors::CustomResult, errors::CustomResult,
pii::{self, Email}, pii::{self, Email},
}; };
use error_stack::{report, IntoReport, ResultExt}; use error_stack::{report, ResultExt};
use masking::{PeekInterface, Secret}; use masking::{PeekInterface, Secret};
use reqwest::Url; use reqwest::Url;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -13,17 +13,47 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
connector::utils::{ connector::utils::{
self, AddressDetailsData, BrowserInformationData, CardData, PaymentsAuthorizeRequestData, self, AddressDetailsData, BrowserInformationData, CardData, PaymentsAuthorizeRequestData,
RouterData, PaymentsPreProcessingData, RouterData,
}, },
consts, consts,
core::errors, core::errors,
services, services,
types::{self, api, storage::enums, BrowserInformation}, types::{self, api, storage::enums, BrowserInformation},
utils::OptionExt,
}; };
type Error = error_stack::Report<errors::ConnectorError>; type Error = error_stack::Report<errors::ConnectorError>;
#[derive(Debug, Serialize)]
pub struct TrustpayRouterData<T> {
pub amount: String,
pub router_data: T,
}
impl<T>
TryFrom<(
&types::api::CurrencyUnit,
types::storage::enums::Currency,
i64,
T,
)> for TrustpayRouterData<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,
})
}
}
pub struct TrustpayAuthType { pub struct TrustpayAuthType {
pub(super) api_key: Secret<String>, pub(super) api_key: Secret<String>,
pub(super) project_id: Secret<String>, pub(super) project_id: Secret<String>,
@ -344,10 +374,17 @@ fn get_bank_redirection_request_data(
Ok(payment_request) Ok(payment_request)
} }
impl TryFrom<&types::PaymentsAuthorizeRouterData> for TrustpayPaymentsRequest { impl TryFrom<&TrustpayRouterData<&types::PaymentsAuthorizeRouterData>> for TrustpayPaymentsRequest {
type Error = Error; type Error = Error;
fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> { fn try_from(
let browser_info = item.request.browser_info.clone().unwrap_or_default(); item: &TrustpayRouterData<&types::PaymentsAuthorizeRouterData>,
) -> Result<Self, Self::Error> {
let browser_info = item
.router_data
.request
.browser_info
.clone()
.unwrap_or_default();
let default_browser_info = BrowserInformation { let default_browser_info = BrowserInformation {
color_depth: Some(browser_info.color_depth.unwrap_or(24)), color_depth: Some(browser_info.color_depth.unwrap_or(24)),
java_enabled: Some(browser_info.java_enabled.unwrap_or(false)), java_enabled: Some(browser_info.java_enabled.unwrap_or(false)),
@ -360,27 +397,27 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for TrustpayPaymentsRequest {
user_agent: browser_info.user_agent, user_agent: browser_info.user_agent,
ip_address: browser_info.ip_address, ip_address: browser_info.ip_address,
}; };
let params = get_mandatory_fields(item)?; let params = get_mandatory_fields(item.router_data)?;
let amount = format!( let amount = item.amount.to_owned();
"{:.2}", let auth = TrustpayAuthType::try_from(&item.router_data.connector_auth_type)
utils::to_currency_base_unit(item.request.amount, item.request.currency)?
.parse::<f64>()
.ok()
.ok_or(errors::ConnectorError::RequestEncodingFailed)?
);
let auth = TrustpayAuthType::try_from(&item.connector_auth_type)
.change_context(errors::ConnectorError::FailedToObtainAuthType)?; .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
match item.request.payment_method_data { match item.router_data.request.payment_method_data {
api::PaymentMethodData::Card(ref ccard) => Ok(get_card_request_data( api::PaymentMethodData::Card(ref ccard) => Ok(get_card_request_data(
item, item.router_data,
&default_browser_info, &default_browser_info,
params, params,
amount, amount,
ccard, ccard,
item.request.get_return_url()?, item.router_data.request.get_return_url()?,
)?), )?),
api::PaymentMethodData::BankRedirect(ref bank_redirection_data) => { api::PaymentMethodData::BankRedirect(ref bank_redirection_data) => {
get_bank_redirection_request_data(item, bank_redirection_data, params, amount, auth) get_bank_redirection_request_data(
item.router_data,
bank_redirection_data,
params,
amount,
auth,
)
} }
_ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
} }
@ -890,51 +927,36 @@ pub struct TrustpayCreateIntentRequest {
pub reference: String, pub reference: String,
} }
impl TryFrom<&types::PaymentsPreProcessingRouterData> for TrustpayCreateIntentRequest { impl TryFrom<&TrustpayRouterData<&types::PaymentsPreProcessingRouterData>>
for TrustpayCreateIntentRequest
{
type Error = Error; type Error = Error;
fn try_from(item: &types::PaymentsPreProcessingRouterData) -> Result<Self, Self::Error> { fn try_from(
item: &TrustpayRouterData<&types::PaymentsPreProcessingRouterData>,
) -> Result<Self, Self::Error> {
let is_apple_pay = item let is_apple_pay = item
.router_data
.request .request
.payment_method_type .payment_method_type
.as_ref() .as_ref()
.map(|pmt| matches!(pmt, diesel_models::enums::PaymentMethodType::ApplePay)); .map(|pmt| matches!(pmt, diesel_models::enums::PaymentMethodType::ApplePay));
let is_google_pay = item let is_google_pay = item
.router_data
.request .request
.payment_method_type .payment_method_type
.as_ref() .as_ref()
.map(|pmt| matches!(pmt, diesel_models::enums::PaymentMethodType::GooglePay)); .map(|pmt| matches!(pmt, diesel_models::enums::PaymentMethodType::GooglePay));
let request_amount = item let currency = item.router_data.request.get_currency()?;
.request let amount = item.amount.to_owned();
.amount
.get_required_value("amount")
.change_context(errors::ConnectorError::MissingRequiredField {
field_name: "amount",
})?;
let currency = item
.request
.currency
.get_required_value("currency")
.change_context(errors::ConnectorError::MissingRequiredField {
field_name: "currency",
})?;
let amount = format!(
"{:.2}",
utils::to_currency_base_unit(request_amount, currency)?
.parse::<f64>()
.into_report()
.change_context(errors::ConnectorError::RequestEncodingFailed)?
);
Ok(Self { Ok(Self {
amount, amount,
currency: currency.to_string(), currency: currency.to_string(),
init_apple_pay: is_apple_pay, init_apple_pay: is_apple_pay,
init_google_pay: is_google_pay, init_google_pay: is_google_pay,
reference: item.payment_id.clone(), reference: item.router_data.payment_id.clone(),
}) })
} }
} }
@ -1278,19 +1300,15 @@ pub enum TrustpayRefundRequest {
BankRedirectRefund(Box<TrustpayRefundRequestBankRedirect>), BankRedirectRefund(Box<TrustpayRefundRequestBankRedirect>),
} }
impl<F> TryFrom<&types::RefundsRouterData<F>> for TrustpayRefundRequest { impl<F> TryFrom<&TrustpayRouterData<&types::RefundsRouterData<F>>> for TrustpayRefundRequest {
type Error = Error; type Error = Error;
fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> { fn try_from(
let amount = format!( item: &TrustpayRouterData<&types::RefundsRouterData<F>>,
"{:.2}", ) -> Result<Self, Self::Error> {
utils::to_currency_base_unit(item.request.refund_amount, item.request.currency)? let amount = item.amount.to_owned();
.parse::<f64>() match item.router_data.payment_method {
.into_report()
.change_context(errors::ConnectorError::RequestEncodingFailed)?
);
match item.payment_method {
diesel_models::enums::PaymentMethod::BankRedirect => { diesel_models::enums::PaymentMethod::BankRedirect => {
let auth = TrustpayAuthType::try_from(&item.connector_auth_type) let auth = TrustpayAuthType::try_from(&item.router_data.connector_auth_type)
.change_context(errors::ConnectorError::FailedToObtainAuthType)?; .change_context(errors::ConnectorError::FailedToObtainAuthType)?;
Ok(Self::BankRedirectRefund(Box::new( Ok(Self::BankRedirectRefund(Box::new(
TrustpayRefundRequestBankRedirect { TrustpayRefundRequestBankRedirect {
@ -1300,10 +1318,10 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for TrustpayRefundRequest {
payment_information: BankPaymentInformation { payment_information: BankPaymentInformation {
amount: Amount { amount: Amount {
amount, amount,
currency: item.request.currency.to_string(), currency: item.router_data.request.currency.to_string(),
}, },
references: References { references: References {
merchant_reference: item.request.refund_id.clone(), merchant_reference: item.router_data.request.refund_id.clone(),
}, },
debtor: None, debtor: None,
}, },
@ -1311,10 +1329,10 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for TrustpayRefundRequest {
))) )))
} }
_ => Ok(Self::CardsRefund(Box::new(TrustpayRefundRequestCards { _ => Ok(Self::CardsRefund(Box::new(TrustpayRefundRequestCards {
instance_id: item.request.connector_transaction_id.clone(), instance_id: item.router_data.request.connector_transaction_id.clone(),
amount, amount,
currency: item.request.currency.to_string(), currency: item.router_data.request.currency.to_string(),
reference: item.request.refund_id.clone(), reference: item.router_data.request.refund_id.clone(),
}))), }))),
} }
} }