refactor(connector): [Paypal]Enhance currency Mapping with ConnectorCurrencyCommon Trait (#2191)

This commit is contained in:
chikke srujan
2023-09-26 12:02:25 +05:30
committed by GitHub
parent 7fd79e05d5
commit 2e97869fa0
2 changed files with 93 additions and 46 deletions

View File

@ -134,6 +134,10 @@ impl ConnectorCommon for Paypal {
"paypal" "paypal"
} }
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/json" "application/json"
} }
@ -344,7 +348,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 req_obj = paypal::PaypalPaymentsRequest::try_from(req)?; let connector_router_data = paypal::PaypalRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request.amount,
req,
))?;
let req_obj = paypal::PaypalPaymentsRequest::try_from(&connector_router_data)?;
let paypal_req = types::RequestBody::log_and_get_request_body( let paypal_req = types::RequestBody::log_and_get_request_body(
&req_obj, &req_obj,
utils::Encode::<paypal::PaypalPaymentsRequest>::encode_to_string_of_json, utils::Encode::<paypal::PaypalPaymentsRequest>::encode_to_string_of_json,
@ -626,7 +636,13 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
&self, &self,
req: &types::PaymentsCaptureRouterData, req: &types::PaymentsCaptureRouterData,
) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
let connector_req = paypal::PaypalPaymentsCaptureRequest::try_from(req)?; let connector_router_data = paypal::PaypalRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request.amount_to_capture,
req,
))?;
let connector_req = paypal::PaypalPaymentsCaptureRequest::try_from(&connector_router_data)?;
let paypal_req = types::RequestBody::log_and_get_request_body( let paypal_req = types::RequestBody::log_and_get_request_body(
&connector_req, &connector_req,
utils::Encode::<paypal::PaypalPaymentsCaptureRequest>::encode_to_string_of_json, utils::Encode::<paypal::PaypalPaymentsCaptureRequest>::encode_to_string_of_json,
@ -781,7 +797,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 req_obj = paypal::PaypalRefundRequest::try_from(req)?; let connector_router_data = paypal::PaypalRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request.refund_amount,
req,
))?;
let req_obj = paypal::PaypalRefundRequest::try_from(&connector_router_data)?;
let paypal_req = types::RequestBody::log_and_get_request_body( let paypal_req = types::RequestBody::log_and_get_request_body(
&req_obj, &req_obj,
utils::Encode::<paypal::PaypalRefundRequest>::encode_to_string_of_json, utils::Encode::<paypal::PaypalRefundRequest>::encode_to_string_of_json,

View File

@ -18,6 +18,37 @@ use crate::{
}, },
}; };
#[derive(Debug, Serialize)]
pub struct PaypalRouterData<T> {
pub amount: String,
pub router_data: T,
}
impl<T>
TryFrom<(
&types::api::CurrencyUnit,
types::storage::enums::Currency,
i64,
T,
)> for PaypalRouterData<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,
})
}
}
mod webhook_headers { mod webhook_headers {
pub const PAYPAL_TRANSMISSION_ID: &str = "paypal-transmission-id"; pub const PAYPAL_TRANSMISSION_ID: &str = "paypal-transmission-id";
pub const PAYPAL_TRANSMISSION_TIME: &str = "paypal-transmission-time"; pub const PAYPAL_TRANSMISSION_TIME: &str = "paypal-transmission-time";
@ -195,34 +226,33 @@ fn get_payment_source(
} }
} }
impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest { impl TryFrom<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for PaypalPaymentsRequest {
type Error = error_stack::Report<errors::ConnectorError>; type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> { fn try_from(
match item.request.payment_method_data { item: &PaypalRouterData<&types::PaymentsAuthorizeRouterData>,
) -> Result<Self, Self::Error> {
match item.router_data.request.payment_method_data {
api_models::payments::PaymentMethodData::Card(ref ccard) => { api_models::payments::PaymentMethodData::Card(ref ccard) => {
let intent = if item.request.is_auto_capture()? { let intent = if item.router_data.request.is_auto_capture()? {
PaypalPaymentIntent::Capture PaypalPaymentIntent::Capture
} else { } else {
PaypalPaymentIntent::Authorize PaypalPaymentIntent::Authorize
}; };
let amount = OrderAmount { let amount = OrderAmount {
currency_code: item.request.currency, currency_code: item.router_data.request.currency,
value: utils::to_currency_base_unit_with_zero_decimal_check( value: item.amount.to_owned(),
item.request.amount,
item.request.currency,
)?,
}; };
let reference_id = item.attempt_id.clone(); let reference_id = item.router_data.attempt_id.clone();
let purchase_units = vec![PurchaseUnitRequest { let purchase_units = vec![PurchaseUnitRequest {
reference_id, reference_id,
amount, amount,
}]; }];
let card = item.request.get_card()?; let card = item.router_data.request.get_card()?;
let expiry = Some(card.get_expiry_date_as_yyyymm("-")); let expiry = Some(card.get_expiry_date_as_yyyymm("-"));
let payment_source = Some(PaymentSourceItem::Card(CardRequest { let payment_source = Some(PaymentSourceItem::Card(CardRequest {
billing_address: get_address_info(item.address.billing.as_ref())?, billing_address: get_address_info(item.router_data.address.billing.as_ref())?,
expiry, expiry,
name: ccard.card_holder_name.clone(), name: ccard.card_holder_name.clone(),
number: Some(ccard.card_number.clone()), number: Some(ccard.card_number.clone()),
@ -237,19 +267,16 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
} }
api::PaymentMethodData::Wallet(ref wallet_data) => match wallet_data { api::PaymentMethodData::Wallet(ref wallet_data) => match wallet_data {
api_models::payments::WalletData::PaypalRedirect(_) => { api_models::payments::WalletData::PaypalRedirect(_) => {
let intent = if item.request.is_auto_capture()? { let intent = if item.router_data.request.is_auto_capture()? {
PaypalPaymentIntent::Capture PaypalPaymentIntent::Capture
} else { } else {
PaypalPaymentIntent::Authorize PaypalPaymentIntent::Authorize
}; };
let amount = OrderAmount { let amount = OrderAmount {
currency_code: item.request.currency, currency_code: item.router_data.request.currency,
value: utils::to_currency_base_unit_with_zero_decimal_check( value: item.amount.to_owned(),
item.request.amount,
item.request.currency,
)?,
}; };
let reference_id = item.attempt_id.clone(); let reference_id = item.router_data.attempt_id.clone();
let purchase_units = vec![PurchaseUnitRequest { let purchase_units = vec![PurchaseUnitRequest {
reference_id, reference_id,
amount, amount,
@ -257,8 +284,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
let payment_source = let payment_source =
Some(PaymentSourceItem::Paypal(PaypalRedirectionRequest { Some(PaymentSourceItem::Paypal(PaypalRedirectionRequest {
experience_context: ContextStruct { experience_context: ContextStruct {
return_url: item.request.complete_authorize_url.clone(), return_url: item.router_data.request.complete_authorize_url.clone(),
cancel_url: item.request.complete_authorize_url.clone(), cancel_url: item.router_data.request.complete_authorize_url.clone(),
}, },
})); }));
@ -300,7 +327,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
} }
}, },
api::PaymentMethodData::BankRedirect(ref bank_redirection_data) => { api::PaymentMethodData::BankRedirect(ref bank_redirection_data) => {
let intent = if item.request.is_auto_capture()? { let intent = if item.router_data.request.is_auto_capture()? {
PaypalPaymentIntent::Capture PaypalPaymentIntent::Capture
} else { } else {
Err(errors::ConnectorError::FlowNotSupported { Err(errors::ConnectorError::FlowNotSupported {
@ -309,18 +336,16 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
})? })?
}; };
let amount = OrderAmount { let amount = OrderAmount {
currency_code: item.request.currency, currency_code: item.router_data.request.currency,
value: utils::to_currency_base_unit_with_zero_decimal_check( value: item.amount.to_owned(),
item.request.amount,
item.request.currency,
)?,
}; };
let reference_id = item.attempt_id.clone(); let reference_id = item.router_data.attempt_id.clone();
let purchase_units = vec![PurchaseUnitRequest { let purchase_units = vec![PurchaseUnitRequest {
reference_id, reference_id,
amount, amount,
}]; }];
let payment_source = Some(get_payment_source(item, bank_redirection_data)?); let payment_source =
Some(get_payment_source(item.router_data, bank_redirection_data)?);
Ok(Self { Ok(Self {
intent, intent,
@ -869,15 +894,16 @@ pub struct PaypalPaymentsCaptureRequest {
final_capture: bool, final_capture: bool,
} }
impl TryFrom<&types::PaymentsCaptureRouterData> for PaypalPaymentsCaptureRequest { impl TryFrom<&PaypalRouterData<&types::PaymentsCaptureRouterData>>
for PaypalPaymentsCaptureRequest
{
type Error = error_stack::Report<errors::ConnectorError>; type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> { fn try_from(
item: &PaypalRouterData<&types::PaymentsCaptureRouterData>,
) -> Result<Self, Self::Error> {
let amount = OrderAmount { let amount = OrderAmount {
currency_code: item.request.currency, currency_code: item.router_data.request.currency,
value: utils::to_currency_base_unit_with_zero_decimal_check( value: item.amount.to_owned(),
item.request.amount_to_capture,
item.request.currency,
)?,
}; };
Ok(Self { Ok(Self {
amount, amount,
@ -1011,16 +1037,15 @@ pub struct PaypalRefundRequest {
pub amount: OrderAmount, pub amount: OrderAmount,
} }
impl<F> TryFrom<&types::RefundsRouterData<F>> for PaypalRefundRequest { impl<F> TryFrom<&PaypalRouterData<&types::RefundsRouterData<F>>> for PaypalRefundRequest {
type Error = error_stack::Report<errors::ConnectorError>; type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> { fn try_from(
item: &PaypalRouterData<&types::RefundsRouterData<F>>,
) -> Result<Self, Self::Error> {
Ok(Self { Ok(Self {
amount: OrderAmount { amount: OrderAmount {
currency_code: item.request.currency, currency_code: item.router_data.request.currency,
value: utils::to_currency_base_unit_with_zero_decimal_check( value: item.amount.to_owned(),
item.request.refund_amount,
item.request.currency,
)?,
}, },
}) })
} }