mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 11:06:50 +08:00
fix(connector): [Paypal] fix amount to its currency base unit (#1780)
This commit is contained in:
@ -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(
|
||||
|
||||
@ -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,
|
||||
)?,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user