mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 04:04:43 +08:00
feat(pm_auth): Added balance check for PM auth bank account (#5054)
This commit is contained in:
@ -2023,7 +2023,10 @@ pub async fn list_payment_methods(
|
||||
.await
|
||||
.transpose()?;
|
||||
|
||||
let mut pmt_to_auth_connector = HashMap::new();
|
||||
let mut pmt_to_auth_connector: HashMap<
|
||||
enums::PaymentMethod,
|
||||
HashMap<enums::PaymentMethodType, String>,
|
||||
> = HashMap::new();
|
||||
|
||||
if let Some((payment_attempt, payment_intent)) =
|
||||
payment_attempt.as_ref().zip(payment_intent.as_ref())
|
||||
@ -2197,24 +2200,35 @@ pub async fn list_payment_methods(
|
||||
None
|
||||
});
|
||||
|
||||
let matched_config = match pm_auth_config {
|
||||
Some(config) => {
|
||||
let internal_config = config
|
||||
.enabled_payment_methods
|
||||
.iter()
|
||||
.find(|config| config.payment_method_type == *payment_method_type)
|
||||
.cloned();
|
||||
if let Some(config) = pm_auth_config {
|
||||
config
|
||||
.enabled_payment_methods
|
||||
.iter()
|
||||
.for_each(|inner_config| {
|
||||
if inner_config.payment_method_type == *payment_method_type {
|
||||
let pm = pmt_to_auth_connector
|
||||
.get(&inner_config.payment_method)
|
||||
.cloned();
|
||||
|
||||
internal_config
|
||||
}
|
||||
None => None,
|
||||
let inner_map = if let Some(mut inner_map) = pm {
|
||||
inner_map.insert(
|
||||
*payment_method_type,
|
||||
inner_config.connector_name.clone(),
|
||||
);
|
||||
inner_map
|
||||
} else {
|
||||
HashMap::from([(
|
||||
*payment_method_type,
|
||||
inner_config.connector_name.clone(),
|
||||
)])
|
||||
};
|
||||
|
||||
pmt_to_auth_connector
|
||||
.insert(inner_config.payment_method, inner_map);
|
||||
val.push(inner_config.clone());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if let Some(config) = matched_config {
|
||||
pmt_to_auth_connector
|
||||
.insert(*payment_method_type, config.connector_name.clone());
|
||||
val.push(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2524,7 +2538,8 @@ pub async fn list_payment_methods(
|
||||
.cloned(),
|
||||
surcharge_details: None,
|
||||
pm_auth_connector: pmt_to_auth_connector
|
||||
.get(payment_method_types_hm.0)
|
||||
.get(key.0)
|
||||
.and_then(|pm_map| pm_map.get(payment_method_types_hm.0))
|
||||
.cloned(),
|
||||
})
|
||||
}
|
||||
@ -2561,7 +2576,8 @@ pub async fn list_payment_methods(
|
||||
.cloned(),
|
||||
surcharge_details: None,
|
||||
pm_auth_connector: pmt_to_auth_connector
|
||||
.get(payment_method_types_hm.0)
|
||||
.get(key.0)
|
||||
.and_then(|pm_map| pm_map.get(payment_method_types_hm.0))
|
||||
.cloned(),
|
||||
})
|
||||
}
|
||||
@ -2592,7 +2608,10 @@ pub async fn list_payment_methods(
|
||||
.and_then(|inner_hm| inner_hm.get(key.0))
|
||||
.cloned(),
|
||||
surcharge_details: None,
|
||||
pm_auth_connector: pmt_to_auth_connector.get(&payment_method_type).cloned(),
|
||||
pm_auth_connector: pmt_to_auth_connector
|
||||
.get(&enums::PaymentMethod::BankRedirect)
|
||||
.and_then(|pm_map| pm_map.get(key.0))
|
||||
.cloned(),
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -2625,7 +2644,10 @@ pub async fn list_payment_methods(
|
||||
.and_then(|inner_hm| inner_hm.get(key.0))
|
||||
.cloned(),
|
||||
surcharge_details: None,
|
||||
pm_auth_connector: pmt_to_auth_connector.get(&payment_method_type).cloned(),
|
||||
pm_auth_connector: pmt_to_auth_connector
|
||||
.get(&enums::PaymentMethod::BankDebit)
|
||||
.and_then(|pm_map| pm_map.get(key.0))
|
||||
.cloned(),
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -2658,7 +2680,10 @@ pub async fn list_payment_methods(
|
||||
.and_then(|inner_hm| inner_hm.get(key.0))
|
||||
.cloned(),
|
||||
surcharge_details: None,
|
||||
pm_auth_connector: pmt_to_auth_connector.get(&payment_method_type).cloned(),
|
||||
pm_auth_connector: pmt_to_auth_connector
|
||||
.get(&enums::PaymentMethod::BankTransfer)
|
||||
.and_then(|pm_map| pm_map.get(key.0))
|
||||
.cloned(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ use common_utils::{
|
||||
crypto::{HmacSha256, SignMessage},
|
||||
ext_traits::AsyncExt,
|
||||
generate_id,
|
||||
types::{self as util_types, AmountConvertor},
|
||||
};
|
||||
use error_stack::ResultExt;
|
||||
use helpers::PaymentAuthConnectorDataExt;
|
||||
@ -66,6 +67,19 @@ pub async fn create_link_token(
|
||||
|
||||
let pm_auth_key = format!("pm_auth_{}", payload.payment_id);
|
||||
|
||||
redis_conn
|
||||
.exists::<Vec<u8>>(&pm_auth_key)
|
||||
.await
|
||||
.change_context(ApiErrorResponse::InvalidRequestData {
|
||||
message: "Incorrect payment_id provided in request".to_string(),
|
||||
})
|
||||
.attach_printable("Corresponding pm_auth_key does not exist in redis")?
|
||||
.then_some(())
|
||||
.ok_or(ApiErrorResponse::InvalidRequestData {
|
||||
message: "Incorrect payment_id provided in request".to_string(),
|
||||
})
|
||||
.attach_printable("Corresponding pm_auth_key does not exist in redis")?;
|
||||
|
||||
let pm_auth_configs = redis_conn
|
||||
.get_and_deserialize_key::<Vec<api_models::pm_auth::PaymentMethodAuthConnectorChoice>>(
|
||||
pm_auth_key.as_str(),
|
||||
@ -637,6 +651,19 @@ async fn get_selected_config_from_redis(
|
||||
|
||||
let pm_auth_key = format!("pm_auth_{}", payload.payment_id);
|
||||
|
||||
redis_conn
|
||||
.exists::<Vec<u8>>(&pm_auth_key)
|
||||
.await
|
||||
.change_context(ApiErrorResponse::InvalidRequestData {
|
||||
message: "Incorrect payment_id provided in request".to_string(),
|
||||
})
|
||||
.attach_printable("Corresponding pm_auth_key does not exist in redis")?
|
||||
.then_some(())
|
||||
.ok_or(ApiErrorResponse::InvalidRequestData {
|
||||
message: "Incorrect payment_id provided in request".to_string(),
|
||||
})
|
||||
.attach_printable("Corresponding pm_auth_key does not exist in redis")?;
|
||||
|
||||
let pm_auth_configs = redis_conn
|
||||
.get_and_deserialize_key::<Vec<api_models::pm_auth::PaymentMethodAuthConnectorChoice>>(
|
||||
pm_auth_key.as_str(),
|
||||
@ -720,6 +747,21 @@ pub async fn retrieve_payment_method_from_auth_service(
|
||||
.ok_or(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Bank account details not found")?;
|
||||
|
||||
if let (Some(balance), Some(currency)) = (bank_account.balance, payment_intent.currency) {
|
||||
let required_conversion = util_types::FloatMajorUnitForConnector;
|
||||
let converted_amount = required_conversion
|
||||
.convert_back(balance, currency)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Could not convert FloatMajorUnit to MinorUnit")?;
|
||||
|
||||
if converted_amount < payment_intent.amount {
|
||||
return Err((ApiErrorResponse::PreconditionFailed {
|
||||
message: "selected bank account has insufficient balance".to_string(),
|
||||
})
|
||||
.into());
|
||||
}
|
||||
}
|
||||
|
||||
let mut bank_type = None;
|
||||
if let Some(account_type) = bank_account.account_type.clone() {
|
||||
bank_type = common_enums::BankType::from_str(account_type.as_str())
|
||||
|
||||
Reference in New Issue
Block a user