fix(connector): [Paypal] fix amount to its currency base unit (#1780)

This commit is contained in:
Prasunna Soppa
2023-07-25 11:28:43 +05:30
committed by GitHub
parent a229c37a7c
commit f40d144178
4 changed files with 266 additions and 12 deletions

View File

@ -387,6 +387,226 @@ impl Currency {
Self::ZAR => "710",
}
}
pub fn is_zero_decimal_currency(self) -> bool {
match self {
Self::JPY | Self::KRW => true,
Self::AED
| Self::ALL
| Self::AMD
| Self::ANG
| Self::ARS
| Self::AUD
| Self::AWG
| Self::AZN
| Self::BBD
| Self::BDT
| Self::BHD
| Self::BMD
| Self::BND
| Self::BOB
| Self::BRL
| Self::BSD
| Self::BWP
| Self::BZD
| Self::CAD
| Self::CHF
| Self::CNY
| Self::COP
| Self::CRC
| Self::CUP
| Self::CZK
| Self::DKK
| Self::DOP
| Self::DZD
| Self::EGP
| Self::ETB
| Self::EUR
| Self::FJD
| Self::GBP
| Self::GHS
| Self::GIP
| Self::GMD
| Self::GTQ
| Self::GYD
| Self::HKD
| Self::HNL
| Self::HRK
| Self::HTG
| Self::HUF
| Self::IDR
| Self::ILS
| Self::INR
| Self::JMD
| Self::JOD
| Self::KES
| Self::KGS
| Self::KHR
| Self::KWD
| Self::KYD
| Self::KZT
| Self::LAK
| Self::LBP
| Self::LKR
| Self::LRD
| Self::LSL
| Self::MAD
| Self::MDL
| Self::MKD
| Self::MMK
| Self::MNT
| Self::MOP
| Self::MUR
| Self::MVR
| Self::MWK
| Self::MXN
| Self::MYR
| Self::NAD
| Self::NGN
| Self::NIO
| Self::NOK
| Self::NPR
| Self::NZD
| Self::OMR
| Self::PEN
| Self::PGK
| Self::PHP
| Self::PKR
| Self::PLN
| Self::QAR
| Self::RON
| Self::RUB
| Self::SAR
| Self::SCR
| Self::SEK
| Self::SGD
| Self::SLL
| Self::SOS
| Self::SSP
| Self::SVC
| Self::SZL
| Self::THB
| Self::TRY
| Self::TTD
| Self::TWD
| Self::TZS
| Self::USD
| Self::UYU
| Self::UZS
| Self::VND
| Self::YER
| Self::ZAR => false,
}
}
pub fn is_three_decimal_currency(self) -> bool {
match self {
Self::BHD | Self::JOD | Self::KWD | Self::OMR => true,
Self::AED
| Self::ALL
| Self::AMD
| Self::ANG
| Self::ARS
| Self::AUD
| Self::AWG
| Self::AZN
| Self::BBD
| Self::BDT
| Self::BMD
| Self::BND
| Self::BOB
| Self::BRL
| Self::BSD
| Self::BWP
| Self::BZD
| Self::CAD
| Self::CHF
| Self::CNY
| Self::COP
| Self::CRC
| Self::CUP
| Self::CZK
| Self::DKK
| Self::DOP
| Self::DZD
| Self::EGP
| Self::ETB
| Self::EUR
| Self::FJD
| Self::GBP
| Self::GHS
| Self::GIP
| Self::GMD
| Self::GTQ
| Self::GYD
| Self::HKD
| Self::HNL
| Self::HRK
| Self::HTG
| Self::HUF
| Self::IDR
| Self::ILS
| Self::INR
| Self::JMD
| Self::JPY
| Self::KES
| Self::KGS
| Self::KHR
| Self::KRW
| Self::KYD
| Self::KZT
| Self::LAK
| Self::LBP
| Self::LKR
| Self::LRD
| Self::LSL
| Self::MAD
| Self::MDL
| Self::MKD
| Self::MMK
| Self::MNT
| Self::MOP
| Self::MUR
| Self::MVR
| Self::MWK
| Self::MXN
| Self::MYR
| Self::NAD
| Self::NGN
| Self::NIO
| Self::NOK
| Self::NPR
| Self::NZD
| Self::PEN
| Self::PGK
| Self::PHP
| Self::PKR
| Self::PLN
| Self::QAR
| Self::RON
| Self::RUB
| Self::SAR
| Self::SCR
| Self::SEK
| Self::SGD
| Self::SLL
| Self::SOS
| Self::SSP
| Self::SVC
| Self::SZL
| Self::THB
| Self::TRY
| Self::TTD
| Self::TWD
| Self::TZS
| Self::USD
| Self::UYU
| Self::UZS
| Self::VND
| Self::YER
| Self::ZAR => false,
}
}
}
#[derive(

View File

@ -5,7 +5,7 @@ use url::Url;
use crate::{
connector::utils::{
to_connector_meta, AccessTokenRequestInfo, AddressDetailsData, CardData,
self, to_connector_meta, AccessTokenRequestInfo, AddressDetailsData, CardData,
PaymentsAuthorizeRequestData,
},
core::errors,
@ -105,7 +105,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
};
let amount = OrderAmount {
currency_code: item.request.currency,
value: item.request.amount.to_string(),
value: utils::to_currency_base_unit_with_zero_decimal_check(
item.request.amount,
item.request.currency,
)?,
};
let reference_id = item.attempt_id.clone();
@ -135,7 +138,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
let intent = PaypalPaymentIntent::Capture;
let amount = OrderAmount {
currency_code: item.request.currency,
value: item.request.amount.to_string(),
value: utils::to_currency_base_unit_with_zero_decimal_check(
item.request.amount,
item.request.currency,
)?,
};
let reference_id = item.attempt_id.clone();
let purchase_units = vec![PurchaseUnitRequest {
@ -500,7 +506,10 @@ impl TryFrom<&types::PaymentsCaptureRouterData> for PaypalPaymentsCaptureRequest
fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> {
let amount = OrderAmount {
currency_code: item.request.currency,
value: item.request.amount_to_capture.to_string(),
value: utils::to_currency_base_unit_with_zero_decimal_check(
item.request.amount_to_capture,
item.request.currency,
)?,
};
Ok(Self {
amount,
@ -636,7 +645,10 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for PaypalRefundRequest {
Ok(Self {
amount: OrderAmount {
currency_code: item.request.currency,
value: item.request.refund_amount.to_string(),
value: utils::to_currency_base_unit_with_zero_decimal_check(
item.request.refund_amount,
item.request.currency,
)?,
},
})
}

View File

@ -928,6 +928,14 @@ pub fn to_currency_base_unit(
.change_context(errors::ConnectorError::RequestEncodingFailed)
}
pub fn to_currency_base_unit_with_zero_decimal_check(
amount: i64,
currency: diesel_models::enums::Currency,
) -> Result<String, error_stack::Report<errors::ConnectorError>> {
utils::to_currency_base_unit_with_zero_decimal_check(amount, currency)
.change_context(errors::ConnectorError::RequestEncodingFailed)
}
pub fn to_currency_base_unit_asf64(
amount: i64,
currency: diesel_models::enums::Currency,

View File

@ -138,6 +138,21 @@ pub fn to_currency_base_unit(
Ok(format!("{amount_f64:.2}"))
}
/// Convert the amount to its base denomination based on Currency and check for zero decimal currency and return String
/// Paypal Connector accepts Zero and Two decimal currency but not three decimal and it should be updated as required for 3 decimal currencies.
/// Paypal Ref - https://developer.paypal.com/docs/reports/reference/paypal-supported-currencies/
pub fn to_currency_base_unit_with_zero_decimal_check(
amount: i64,
currency: diesel_models::enums::Currency,
) -> Result<String, error_stack::Report<errors::ValidationError>> {
let amount_f64 = to_currency_base_unit_asf64(amount, currency)?;
if currency.is_zero_decimal_currency() {
Ok(amount_f64.to_string())
} else {
Ok(format!("{amount_f64:.2}"))
}
}
/// Convert the amount to its base denomination based on Currency and return f64
pub fn to_currency_base_unit_asf64(
amount: i64,
@ -149,13 +164,12 @@ pub fn to_currency_base_unit_asf64(
},
)?;
let amount_f64 = f64::from(amount_u32);
let amount = match currency {
diesel_models::enums::Currency::JPY | diesel_models::enums::Currency::KRW => amount_f64,
diesel_models::enums::Currency::BHD
| diesel_models::enums::Currency::JOD
| diesel_models::enums::Currency::KWD
| diesel_models::enums::Currency::OMR => amount_f64 / 1000.00,
_ => amount_f64 / 100.00,
let amount = if currency.is_zero_decimal_currency() {
amount_f64
} else if currency.is_three_decimal_currency() {
amount_f64 / 1000.00
} else {
amount_f64 / 100.00
};
Ok(amount)
}