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) # ^--- This can be any connector (can be multiple)
paypal = { currency = "USD,INR", country = "US" } paypal = { currency = "USD,INR", country = "US" }
# ^ ^------- comma-separated values # ^ ^------- 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 # 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] [dev-dependencies]
fake = "2.5.0" 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)] #[derive(Debug, Deserialize, Clone, Default)]
#[serde(transparent)] #[serde(transparent)]
pub struct PaymentMethodFilters( pub struct PaymentMethodFilters(pub HashMap<PaymentMethodFilterKey, CurrencyCountryFilter>);
pub HashMap<api_models::enums::PaymentMethodType, 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)] #[derive(Debug, Deserialize, Clone, Default)]
#[serde(default)] #[serde(default)]

View File

@ -758,7 +758,8 @@ async fn filter_payment_methods(
config, config,
&connector, &connector,
&payment_method_object.payment_method_type, &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 payment_attempt
.and_then(|value| value.currency) .and_then(|value| value.currency)
.map(|value| value.foreign_into()), .map(|value| value.foreign_into()),
@ -786,27 +787,67 @@ fn filter_pm_based_on_config<'a>(
config: &'a crate::configs::settings::ConnectorFilters, config: &'a crate::configs::settings::ConnectorFilters,
connector: &'a str, connector: &'a str,
payment_method_type: &'a api_enums::PaymentMethodType, 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>, currency: Option<api_enums::Currency>,
) -> bool { ) -> bool {
config config
.0 .0
.get(connector) .get(connector)
.and_then(|inner| inner.0.get(payment_method_type)) .and_then(|inner| match payment_method_type {
.map(|value| { api_enums::PaymentMethodType::Credit | api_enums::PaymentMethodType::Debit => {
let condition1 = value 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 .country
.as_ref() .as_ref()
.zip(country) .zip(country.as_ref())
.map(|(lhs, rhs)| lhs.contains(&rhs)); .map(|(lhs, rhs)| lhs.contains(rhs));
let condition2 = value let currency_condition = item
.currency .currency
.as_ref() .as_ref()
.zip(currency) .zip(currency)
.map(|(lhs, rhs)| lhs.contains(&rhs)); .map(|(lhs, rhs)| lhs.contains(&rhs));
condition1.unwrap_or(true) && condition2.unwrap_or(true) country_condition.unwrap_or(true) && currency_condition.unwrap_or(true)
})
.unwrap_or(true)
} }
fn filter_pm_card_network_based( fn filter_pm_card_network_based(