refactor(connector): added amount framework to paypal, payouts and routing (#4865)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Hrithikesh <61539176+hrithikesh026@users.noreply.github.com>
Co-authored-by: Narayan Bhat <narayan.bhat@juspay.in>
This commit is contained in:
Sahkal Poddar
2024-06-28 12:01:15 +05:30
committed by GitHub
parent 82a75da314
commit b08ce22108
34 changed files with 204 additions and 181 deletions

View File

@ -24,6 +24,7 @@ use common_utils::{
consts,
ext_traits::{AsyncExt, Encode, StringExt, ValueExt},
generate_id, id_type,
types::MinorUnit,
};
use diesel_models::{
business_profile::BusinessProfile, encryption::Encryption, enums as storage_enums,
@ -2862,11 +2863,7 @@ pub async fn filter_payment_methods(
&payment_method_type_info,
req.installment_payment_enabled,
)
&& filter_amount_based(
&payment_method_type_info,
req.amount
.map(|minor_amount| minor_amount.get_amount_as_i64()),
)
&& filter_amount_based(&payment_method_type_info, req.amount)
{
let mut payment_method_object = payment_method_type_info;
@ -3108,6 +3105,19 @@ fn filter_pm_based_on_capture_method_used(
.unwrap_or(true)
}
fn filter_amount_based(
payment_method: &RequestPaymentMethodTypes,
amount: Option<MinorUnit>,
) -> bool {
let min_check = amount
.and_then(|amt| payment_method.minimum_amount.map(|min_amt| amt >= min_amt))
.unwrap_or(true);
let max_check = amount
.and_then(|amt| payment_method.maximum_amount.map(|max_amt| amt <= max_amt))
.unwrap_or(true);
(min_check && max_check) || amount == Some(MinorUnit::zero())
}
fn card_network_filter(
country: &Option<api_enums::CountryAlpha2>,
currency: Option<api_enums::Currency>,
@ -3279,32 +3289,6 @@ fn filter_disabled_enum_based<T: Eq + std::hash::Hash + Clone>(
}
}
fn filter_amount_based(payment_method: &RequestPaymentMethodTypes, amount: Option<i64>) -> bool {
let min_check = amount
.and_then(|amt| {
payment_method
.minimum_amount
.map(|min_amt| amt >= min_amt.into())
})
.unwrap_or(true);
let max_check = amount
.and_then(|amt| {
payment_method
.maximum_amount
.map(|max_amt| amt <= max_amt.into())
})
.unwrap_or(true);
// let min_check = match (amount, payment_method.minimum_amount) {
// (Some(amt), Some(min_amt)) => amt >= min_amt,
// (_, _) => true,
// };
// let max_check = match (amount, payment_method.maximum_amount) {
// (Some(amt), Some(max_amt)) => amt <= max_amt,
// (_, _) => true,
// };
(min_check && max_check) || amount == Some(0)
}
fn filter_pm_based_on_allowed_types(
allowed_types: Option<&Vec<api_enums::PaymentMethodType>>,
payment_method_type: &api_enums::PaymentMethodType,
@ -3360,10 +3344,10 @@ fn filter_payment_amount_based(
payment_intent: &storage::PaymentIntent,
pm: &RequestPaymentMethodTypes,
) -> bool {
let amount = payment_intent.amount.get_amount_as_i64();
(pm.maximum_amount.map_or(true, |amt| amount <= amt.into())
&& pm.minimum_amount.map_or(true, |amt| amount >= amt.into()))
|| payment_intent.amount.get_amount_as_i64() == 0
let amount = payment_intent.amount;
(pm.maximum_amount.map_or(true, |amt| amount <= amt)
&& pm.minimum_amount.map_or(true, |amt| amount >= amt))
|| payment_intent.amount == MinorUnit::zero()
}
async fn filter_payment_mandate_based(

View File

@ -211,7 +211,7 @@ where
};
let payment_input = dsl_inputs::PaymentInput {
amount: payment_data.payment_intent.amount.get_amount_as_i64(),
amount: payment_data.payment_intent.amount,
card_bin: payment_data
.payment_method_data
.as_ref()
@ -904,7 +904,7 @@ pub async fn perform_session_flow_routing(
};
let payment_input = dsl_inputs::PaymentInput {
amount: session_input.payment_intent.amount.get_amount_as_i64(),
amount: session_input.payment_intent.amount,
currency: session_input
.payment_intent
.currency
@ -1138,7 +1138,7 @@ pub fn make_dsl_input_for_surcharge(
payment_type: None,
};
let payment_input = dsl_inputs::PaymentInput {
amount: payment_attempt.amount.get_amount_as_i64(),
amount: payment_attempt.amount,
// currency is always populated in payment_attempt during payment create
currency: payment_attempt
.currency

View File

@ -4,6 +4,7 @@ use api_models::payouts;
use common_utils::{
ext_traits::{Encode, OptionExt},
link_utils,
types::{AmountConvertor, StringMajorUnitForConnector},
};
use diesel_models::PayoutLinkUpdate;
use error_stack::ResultExt;
@ -102,9 +103,9 @@ pub async fn initiate_payout_link(
// Initiate Payout link flow
(_, link_utils::PayoutLinkStatus::Initiated) => {
let customer_id = link_data.customer_id;
let amount = payout
.destination_currency
.to_currency_base_unit(payout.amount)
let required_amount_type = StringMajorUnitForConnector;
let amount = required_amount_type
.convert(payout.amount, payout.destination_currency)
.change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?;
// Fetch customer
let customer = db

View File

@ -1919,7 +1919,7 @@ pub async fn response_handler(
let response = api::PayoutCreateResponse {
payout_id: payouts.payout_id.to_owned(),
merchant_id: merchant_account.merchant_id.to_owned(),
amount: payouts.amount.to_owned(),
amount: payouts.amount,
currency: payouts.destination_currency.to_owned(),
connector: payout_attempt.connector.to_owned(),
payout_type: payouts.payout_type.to_owned(),
@ -2045,7 +2045,7 @@ pub async fn payout_create_db_entries(
consts::ID_LENGTH,
format!("payout_{payout_id}_secret").as_str(),
);
let amount = MinorUnit::from(req.amount.unwrap_or(api::Amount::Zero)).get_amount_as_i64();
let amount = MinorUnit::from(req.amount.unwrap_or(api::Amount::Zero));
let payouts_req = storage::PayoutsNew {
payout_id: payout_id.to_string(),
merchant_id: merchant_id.to_string(),

View File

@ -959,8 +959,7 @@ pub async fn update_payouts_and_payout_attempt(
// Update DB with new data
let payouts = payout_data.payouts.to_owned();
let amount = MinorUnit::from(req.amount.unwrap_or(MinorUnit::new(payouts.amount).into()))
.get_amount_as_i64();
let amount = MinorUnit::from(req.amount.unwrap_or(payouts.amount.into()));
let updated_payouts = storage::PayoutsUpdate::Update {
amount,
destination_currency: req

View File

@ -170,7 +170,8 @@ pub async fn construct_payout_router_data<'a, F>(
payment_method_status: None,
request: types::PayoutsData {
payout_id: payouts.payout_id.to_owned(),
amount: payouts.amount,
amount: payouts.amount.get_amount_as_i64(),
minor_amount: payouts.amount,
connector_payout_id: payout_attempt.connector_payout_id.clone(),
destination_currency: payouts.destination_currency,
source_currency: payouts.source_currency,