feat(list): global filter mapping for payment methods via card network (#694)

This commit is contained in:
Nishant Joshi
2023-03-01 16:50:13 +05:30
committed by GitHub
parent 1a8753485c
commit adca6bcac3
4 changed files with 66 additions and 20 deletions

View File

@ -216,5 +216,5 @@ loop_interval = 500 # Specifies how much time to wait after checking
# ^--- This can be any connector (can be multiple)
paypal = { currency = "USD,INR", country = "US" }
# ^ ^------- comma-separated values
# ^------------------------------- any valid payment method type (can be multiple)
# ^------------------------------- any valid payment method type (can be multiple) (for cards this should be card_network)
# If either currency or country isn't provided then, all possible values are accepted

View File

@ -34,4 +34,4 @@ router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra
[dev-dependencies]
fake = "2.5.0"
proptest = "1.0.0"
proptest = "1.1.0"

View File

@ -78,9 +78,14 @@ pub struct ConnectorFilters(pub HashMap<String, PaymentMethodFilters>);
#[derive(Debug, Deserialize, Clone, Default)]
#[serde(transparent)]
pub struct PaymentMethodFilters(
pub HashMap<api_models::enums::PaymentMethodType, CurrencyCountryFilter>,
);
pub struct PaymentMethodFilters(pub HashMap<PaymentMethodFilterKey, CurrencyCountryFilter>);
#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Hash)]
#[serde(untagged)]
pub enum PaymentMethodFilterKey {
PaymentMethodType(api_models::enums::PaymentMethodType),
CardNetwork(api_models::enums::CardNetwork),
}
#[derive(Debug, Deserialize, Clone, Default)]
#[serde(default)]

View File

@ -758,7 +758,8 @@ async fn filter_payment_methods(
config,
&connector,
&payment_method_object.payment_method_type,
address.and_then(|inner| inner.country.clone()),
&mut payment_method_object.card_networks,
&address.and_then(|inner| inner.country.clone()),
payment_attempt
.and_then(|value| value.currency)
.map(|value| value.foreign_into()),
@ -786,27 +787,67 @@ fn filter_pm_based_on_config<'a>(
config: &'a crate::configs::settings::ConnectorFilters,
connector: &'a str,
payment_method_type: &'a api_enums::PaymentMethodType,
country: Option<String>,
card_network: &mut Option<Vec<api_enums::CardNetwork>>,
country: &Option<String>,
currency: Option<api_enums::Currency>,
) -> bool {
config
.0
.get(connector)
.and_then(|inner| inner.0.get(payment_method_type))
.map(|value| {
let condition1 = value
.and_then(|inner| match payment_method_type {
api_enums::PaymentMethodType::Credit | api_enums::PaymentMethodType::Debit => {
card_network_filter(country, currency, card_network, inner);
None
}
payment_method_type => inner
.0
.get(&settings::PaymentMethodFilterKey::PaymentMethodType(
*payment_method_type,
))
.map(|value| global_country_currency_filter(value, country, currency)),
})
.unwrap_or(true)
}
fn card_network_filter(
country: &Option<String>,
currency: Option<api_enums::Currency>,
card_network: &mut Option<Vec<api_enums::CardNetwork>>,
payment_method_filters: &settings::PaymentMethodFilters,
) {
if let Some(value) = card_network.as_mut() {
let filtered_card_networks = value
.iter()
.filter(|&element| {
let key = settings::PaymentMethodFilterKey::CardNetwork(element.clone());
payment_method_filters
.0
.get(&key)
.map(|value| global_country_currency_filter(value, country, currency))
.unwrap_or(true)
})
.cloned()
.collect::<Vec<_>>();
*value = filtered_card_networks;
}
}
fn global_country_currency_filter(
item: &settings::CurrencyCountryFilter,
country: &Option<String>,
currency: Option<api_enums::Currency>,
) -> bool {
let country_condition = item
.country
.as_ref()
.zip(country)
.map(|(lhs, rhs)| lhs.contains(&rhs));
let condition2 = value
.zip(country.as_ref())
.map(|(lhs, rhs)| lhs.contains(rhs));
let currency_condition = item
.currency
.as_ref()
.zip(currency)
.map(|(lhs, rhs)| lhs.contains(&rhs));
condition1.unwrap_or(true) && condition2.unwrap_or(true)
})
.unwrap_or(true)
country_condition.unwrap_or(true) && currency_condition.unwrap_or(true)
}
fn filter_pm_card_network_based(