mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
Refactor(core): interpolate success_based_routing config params with their specific values (#6448)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -615,8 +615,11 @@ impl Default for SuccessBasedRoutingConfig {
|
|||||||
pub enum SuccessBasedRoutingConfigParams {
|
pub enum SuccessBasedRoutingConfigParams {
|
||||||
PaymentMethod,
|
PaymentMethod,
|
||||||
PaymentMethodType,
|
PaymentMethodType,
|
||||||
Currency,
|
|
||||||
AuthenticationType,
|
AuthenticationType,
|
||||||
|
Currency,
|
||||||
|
Country,
|
||||||
|
CardNetwork,
|
||||||
|
CardBin,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
|
||||||
|
|||||||
@ -5,7 +5,6 @@ use std::{fmt::Debug, sync::Arc};
|
|||||||
|
|
||||||
#[cfg(feature = "dynamic_routing")]
|
#[cfg(feature = "dynamic_routing")]
|
||||||
use dynamic_routing::{DynamicRoutingClientConfig, RoutingStrategy};
|
use dynamic_routing::{DynamicRoutingClientConfig, RoutingStrategy};
|
||||||
use router_env::logger;
|
|
||||||
use serde;
|
use serde;
|
||||||
|
|
||||||
/// Struct contains all the gRPC Clients
|
/// Struct contains all the gRPC Clients
|
||||||
@ -38,8 +37,6 @@ impl GrpcClientSettings {
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to establish a connection with the Dynamic Routing Server");
|
.expect("Failed to establish a connection with the Dynamic Routing Server");
|
||||||
|
|
||||||
logger::info!("Connection established with gRPC Server");
|
|
||||||
|
|
||||||
Arc::new(GrpcClients {
|
Arc::new(GrpcClients {
|
||||||
#[cfg(feature = "dynamic_routing")]
|
#[cfg(feature = "dynamic_routing")]
|
||||||
dynamic_routing: dynamic_routing_connection,
|
dynamic_routing: dynamic_routing_connection,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use error_stack::ResultExt;
|
|||||||
use http_body_util::combinators::UnsyncBoxBody;
|
use http_body_util::combinators::UnsyncBoxBody;
|
||||||
use hyper::body::Bytes;
|
use hyper::body::Bytes;
|
||||||
use hyper_util::client::legacy::connect::HttpConnector;
|
use hyper_util::client::legacy::connect::HttpConnector;
|
||||||
|
use router_env::logger;
|
||||||
use serde;
|
use serde;
|
||||||
use success_rate::{
|
use success_rate::{
|
||||||
success_rate_calculator_client::SuccessRateCalculatorClient, CalSuccessRateConfig,
|
success_rate_calculator_client::SuccessRateCalculatorClient, CalSuccessRateConfig,
|
||||||
@ -80,6 +81,7 @@ impl DynamicRoutingClientConfig {
|
|||||||
let success_rate_client = match self {
|
let success_rate_client = match self {
|
||||||
Self::Enabled { host, port } => {
|
Self::Enabled { host, port } => {
|
||||||
let uri = format!("http://{}:{}", host, port).parse::<tonic::transport::Uri>()?;
|
let uri = format!("http://{}:{}", host, port).parse::<tonic::transport::Uri>()?;
|
||||||
|
logger::info!("Connection established with dynamic routing gRPC Server");
|
||||||
Some(SuccessRateCalculatorClient::with_origin(client, uri))
|
Some(SuccessRateCalculatorClient::with_origin(client, uri))
|
||||||
}
|
}
|
||||||
Self::Disabled => None,
|
Self::Disabled => None,
|
||||||
@ -98,6 +100,7 @@ pub trait SuccessBasedDynamicRouting: dyn_clone::DynClone + Send + Sync {
|
|||||||
&self,
|
&self,
|
||||||
id: String,
|
id: String,
|
||||||
success_rate_based_config: SuccessBasedRoutingConfig,
|
success_rate_based_config: SuccessBasedRoutingConfig,
|
||||||
|
params: String,
|
||||||
label_input: Vec<RoutableConnectorChoice>,
|
label_input: Vec<RoutableConnectorChoice>,
|
||||||
) -> DynamicRoutingResult<CalSuccessRateResponse>;
|
) -> DynamicRoutingResult<CalSuccessRateResponse>;
|
||||||
/// To update the success rate with the given label
|
/// To update the success rate with the given label
|
||||||
@ -105,6 +108,7 @@ pub trait SuccessBasedDynamicRouting: dyn_clone::DynClone + Send + Sync {
|
|||||||
&self,
|
&self,
|
||||||
id: String,
|
id: String,
|
||||||
success_rate_based_config: SuccessBasedRoutingConfig,
|
success_rate_based_config: SuccessBasedRoutingConfig,
|
||||||
|
params: String,
|
||||||
response: Vec<RoutableConnectorChoiceWithStatus>,
|
response: Vec<RoutableConnectorChoiceWithStatus>,
|
||||||
) -> DynamicRoutingResult<UpdateSuccessRateWindowResponse>;
|
) -> DynamicRoutingResult<UpdateSuccessRateWindowResponse>;
|
||||||
}
|
}
|
||||||
@ -115,24 +119,9 @@ impl SuccessBasedDynamicRouting for SuccessRateCalculatorClient<Client> {
|
|||||||
&self,
|
&self,
|
||||||
id: String,
|
id: String,
|
||||||
success_rate_based_config: SuccessBasedRoutingConfig,
|
success_rate_based_config: SuccessBasedRoutingConfig,
|
||||||
|
params: String,
|
||||||
label_input: Vec<RoutableConnectorChoice>,
|
label_input: Vec<RoutableConnectorChoice>,
|
||||||
) -> DynamicRoutingResult<CalSuccessRateResponse> {
|
) -> DynamicRoutingResult<CalSuccessRateResponse> {
|
||||||
let params = success_rate_based_config
|
|
||||||
.params
|
|
||||||
.map(|vec| {
|
|
||||||
vec.into_iter().fold(String::new(), |mut acc_str, params| {
|
|
||||||
if !acc_str.is_empty() {
|
|
||||||
acc_str.push(':')
|
|
||||||
}
|
|
||||||
acc_str.push_str(params.to_string().as_str());
|
|
||||||
acc_str
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.get_required_value("params")
|
|
||||||
.change_context(DynamicRoutingError::MissingRequiredField {
|
|
||||||
field: "params".to_string(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let labels = label_input
|
let labels = label_input
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|conn_choice| conn_choice.to_string())
|
.map(|conn_choice| conn_choice.to_string())
|
||||||
@ -167,6 +156,7 @@ impl SuccessBasedDynamicRouting for SuccessRateCalculatorClient<Client> {
|
|||||||
&self,
|
&self,
|
||||||
id: String,
|
id: String,
|
||||||
success_rate_based_config: SuccessBasedRoutingConfig,
|
success_rate_based_config: SuccessBasedRoutingConfig,
|
||||||
|
params: String,
|
||||||
label_input: Vec<RoutableConnectorChoiceWithStatus>,
|
label_input: Vec<RoutableConnectorChoiceWithStatus>,
|
||||||
) -> DynamicRoutingResult<UpdateSuccessRateWindowResponse> {
|
) -> DynamicRoutingResult<UpdateSuccessRateWindowResponse> {
|
||||||
let config = success_rate_based_config
|
let config = success_rate_based_config
|
||||||
@ -182,22 +172,6 @@ impl SuccessBasedDynamicRouting for SuccessRateCalculatorClient<Client> {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let params = success_rate_based_config
|
|
||||||
.params
|
|
||||||
.map(|vec| {
|
|
||||||
vec.into_iter().fold(String::new(), |mut acc_str, params| {
|
|
||||||
if !acc_str.is_empty() {
|
|
||||||
acc_str.push(':')
|
|
||||||
}
|
|
||||||
acc_str.push_str(params.to_string().as_str());
|
|
||||||
acc_str
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.get_required_value("params")
|
|
||||||
.change_context(DynamicRoutingError::MissingRequiredField {
|
|
||||||
field: "params".to_string(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let request = tonic::Request::new(UpdateSuccessRateWindowRequest {
|
let request = tonic::Request::new(UpdateSuccessRateWindowRequest {
|
||||||
id,
|
id,
|
||||||
params,
|
params,
|
||||||
|
|||||||
@ -330,6 +330,8 @@ pub enum RoutingError {
|
|||||||
MetadataParsingError,
|
MetadataParsingError,
|
||||||
#[error("Unable to retrieve success based routing config")]
|
#[error("Unable to retrieve success based routing config")]
|
||||||
SuccessBasedRoutingConfigError,
|
SuccessBasedRoutingConfigError,
|
||||||
|
#[error("Params not found in success based routing config")]
|
||||||
|
SuccessBasedRoutingParamsNotFoundError,
|
||||||
#[error("Unable to calculate success based routing config from dynamic routing service")]
|
#[error("Unable to calculate success based routing config from dynamic routing service")]
|
||||||
SuccessRateCalculationError,
|
SuccessRateCalculationError,
|
||||||
#[error("Success rate client from dynamic routing gRPC service not initialized")]
|
#[error("Success rate client from dynamic routing gRPC service not initialized")]
|
||||||
|
|||||||
@ -72,6 +72,8 @@ use super::{
|
|||||||
#[cfg(feature = "frm")]
|
#[cfg(feature = "frm")]
|
||||||
use crate::core::fraud_check as frm_core;
|
use crate::core::fraud_check as frm_core;
|
||||||
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
||||||
|
use crate::core::routing::helpers as routing_helpers;
|
||||||
|
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
||||||
use crate::types::api::convert_connector_data_to_routable_connectors;
|
use crate::types::api::convert_connector_data_to_routable_connectors;
|
||||||
use crate::{
|
use crate::{
|
||||||
configs::settings::{ApplePayPreDecryptFlow, PaymentMethodTypeTokenFilter},
|
configs::settings::{ApplePayPreDecryptFlow, PaymentMethodTypeTokenFilter},
|
||||||
@ -5580,10 +5582,46 @@ where
|
|||||||
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
||||||
let connectors = {
|
let connectors = {
|
||||||
if business_profile.dynamic_routing_algorithm.is_some() {
|
if business_profile.dynamic_routing_algorithm.is_some() {
|
||||||
routing::perform_success_based_routing(state, connectors.clone(), business_profile)
|
let success_based_routing_config_params_interpolator =
|
||||||
.await
|
routing_helpers::SuccessBasedRoutingConfigParamsInterpolator::new(
|
||||||
.map_err(|e| logger::error!(success_rate_routing_error=?e))
|
payment_data.get_payment_attempt().payment_method,
|
||||||
.unwrap_or(connectors)
|
payment_data.get_payment_attempt().payment_method_type,
|
||||||
|
payment_data.get_payment_attempt().authentication_type,
|
||||||
|
payment_data.get_payment_attempt().currency,
|
||||||
|
payment_data
|
||||||
|
.get_billing_address()
|
||||||
|
.and_then(|address| address.address)
|
||||||
|
.and_then(|address| address.country),
|
||||||
|
payment_data
|
||||||
|
.get_payment_attempt()
|
||||||
|
.payment_method_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card"))
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card_network"))
|
||||||
|
.and_then(|network| network.as_str())
|
||||||
|
.map(|network| network.to_string()),
|
||||||
|
payment_data
|
||||||
|
.get_payment_attempt()
|
||||||
|
.payment_method_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card"))
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card_isin"))
|
||||||
|
.and_then(|card_isin| card_isin.as_str())
|
||||||
|
.map(|card_isin| card_isin.to_string()),
|
||||||
|
);
|
||||||
|
routing::perform_success_based_routing(
|
||||||
|
state,
|
||||||
|
connectors.clone(),
|
||||||
|
business_profile,
|
||||||
|
success_based_routing_config_params_interpolator,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| logger::error!(success_rate_routing_error=?e))
|
||||||
|
.unwrap_or(connectors)
|
||||||
} else {
|
} else {
|
||||||
connectors
|
connectors
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ use tracing_futures::Instrument;
|
|||||||
|
|
||||||
use super::{Operation, OperationSessionSetters, PostUpdateTracker};
|
use super::{Operation, OperationSessionSetters, PostUpdateTracker};
|
||||||
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
||||||
use crate::core::routing::helpers::push_metrics_for_success_based_routing;
|
use crate::core::routing::helpers as routing_helpers;
|
||||||
use crate::{
|
use crate::{
|
||||||
connector::utils::PaymentResponseRouterData,
|
connector::utils::PaymentResponseRouterData,
|
||||||
consts,
|
consts,
|
||||||
@ -1968,13 +1968,44 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
|
|||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
let business_profile = business_profile.clone();
|
let business_profile = business_profile.clone();
|
||||||
let payment_attempt = payment_attempt.clone();
|
let payment_attempt = payment_attempt.clone();
|
||||||
|
let success_based_routing_config_params_interpolator =
|
||||||
|
routing_helpers::SuccessBasedRoutingConfigParamsInterpolator::new(
|
||||||
|
payment_attempt.payment_method,
|
||||||
|
payment_attempt.payment_method_type,
|
||||||
|
payment_attempt.authentication_type,
|
||||||
|
payment_attempt.currency,
|
||||||
|
payment_data
|
||||||
|
.address
|
||||||
|
.get_payment_billing()
|
||||||
|
.and_then(|address| address.clone().address)
|
||||||
|
.and_then(|address| address.country),
|
||||||
|
payment_attempt
|
||||||
|
.payment_method_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card"))
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card_network"))
|
||||||
|
.and_then(|network| network.as_str())
|
||||||
|
.map(|network| network.to_string()),
|
||||||
|
payment_attempt
|
||||||
|
.payment_method_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card"))
|
||||||
|
.and_then(|data| data.as_object())
|
||||||
|
.and_then(|card| card.get("card_isin"))
|
||||||
|
.and_then(|card_isin| card_isin.as_str())
|
||||||
|
.map(|card_isin| card_isin.to_string()),
|
||||||
|
);
|
||||||
tokio::spawn(
|
tokio::spawn(
|
||||||
async move {
|
async move {
|
||||||
push_metrics_for_success_based_routing(
|
routing_helpers::push_metrics_with_update_window_for_success_based_routing(
|
||||||
&state,
|
&state,
|
||||||
&payment_attempt,
|
&payment_attempt,
|
||||||
routable_connectors,
|
routable_connectors,
|
||||||
&business_profile,
|
&business_profile,
|
||||||
|
success_based_routing_config_params_interpolator,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| logger::error!(dynamic_routing_metrics_error=?e))
|
.map_err(|e| logger::error!(dynamic_routing_metrics_error=?e))
|
||||||
@ -1984,6 +2015,7 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_data.payment_intent = payment_intent;
|
payment_data.payment_intent = payment_intent;
|
||||||
payment_data.payment_attempt = payment_attempt;
|
payment_data.payment_attempt = payment_attempt;
|
||||||
router_data.payment_method_status.and_then(|status| {
|
router_data.payment_method_status.and_then(|status| {
|
||||||
|
|||||||
@ -1240,6 +1240,7 @@ pub async fn perform_success_based_routing(
|
|||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
routable_connectors: Vec<api_routing::RoutableConnectorChoice>,
|
routable_connectors: Vec<api_routing::RoutableConnectorChoice>,
|
||||||
business_profile: &domain::Profile,
|
business_profile: &domain::Profile,
|
||||||
|
success_based_routing_config_params_interpolator: routing::helpers::SuccessBasedRoutingConfigParamsInterpolator,
|
||||||
) -> RoutingResult<Vec<api_routing::RoutableConnectorChoice>> {
|
) -> RoutingResult<Vec<api_routing::RoutableConnectorChoice>> {
|
||||||
let success_based_dynamic_routing_algo_ref: api_routing::DynamicRoutingAlgorithmRef =
|
let success_based_dynamic_routing_algo_ref: api_routing::DynamicRoutingAlgorithmRef =
|
||||||
business_profile
|
business_profile
|
||||||
@ -1293,6 +1294,14 @@ pub async fn perform_success_based_routing(
|
|||||||
.change_context(errors::RoutingError::SuccessBasedRoutingConfigError)
|
.change_context(errors::RoutingError::SuccessBasedRoutingConfigError)
|
||||||
.attach_printable("unable to fetch success_rate based dynamic routing configs")?;
|
.attach_printable("unable to fetch success_rate based dynamic routing configs")?;
|
||||||
|
|
||||||
|
let success_based_routing_config_params = success_based_routing_config_params_interpolator
|
||||||
|
.get_string_val(
|
||||||
|
success_based_routing_configs
|
||||||
|
.params
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(errors::RoutingError::SuccessBasedRoutingParamsNotFoundError)?,
|
||||||
|
);
|
||||||
|
|
||||||
let tenant_business_profile_id = routing::helpers::generate_tenant_business_profile_id(
|
let tenant_business_profile_id = routing::helpers::generate_tenant_business_profile_id(
|
||||||
&state.tenant.redis_key_prefix,
|
&state.tenant.redis_key_prefix,
|
||||||
business_profile.get_id().get_string_repr(),
|
business_profile.get_id().get_string_repr(),
|
||||||
@ -1302,6 +1311,7 @@ pub async fn perform_success_based_routing(
|
|||||||
.calculate_success_rate(
|
.calculate_success_rate(
|
||||||
tenant_business_profile_id,
|
tenant_business_profile_id,
|
||||||
success_based_routing_configs,
|
success_based_routing_configs,
|
||||||
|
success_based_routing_config_params,
|
||||||
routable_connectors,
|
routable_connectors,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -640,11 +640,12 @@ pub async fn fetch_success_based_routing_configs(
|
|||||||
/// metrics for success based dynamic routing
|
/// metrics for success based dynamic routing
|
||||||
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn push_metrics_for_success_based_routing(
|
pub async fn push_metrics_with_update_window_for_success_based_routing(
|
||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
payment_attempt: &storage::PaymentAttempt,
|
payment_attempt: &storage::PaymentAttempt,
|
||||||
routable_connectors: Vec<routing_types::RoutableConnectorChoice>,
|
routable_connectors: Vec<routing_types::RoutableConnectorChoice>,
|
||||||
business_profile: &domain::Profile,
|
business_profile: &domain::Profile,
|
||||||
|
success_based_routing_config_params_interpolator: SuccessBasedRoutingConfigParamsInterpolator,
|
||||||
) -> RouterResult<()> {
|
) -> RouterResult<()> {
|
||||||
let success_based_dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef =
|
let success_based_dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef =
|
||||||
business_profile
|
business_profile
|
||||||
@ -697,10 +698,20 @@ pub async fn push_metrics_for_success_based_routing(
|
|||||||
business_profile.get_id().get_string_repr(),
|
business_profile.get_id().get_string_repr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let success_based_routing_config_params = success_based_routing_config_params_interpolator
|
||||||
|
.get_string_val(
|
||||||
|
success_based_routing_configs
|
||||||
|
.params
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(errors::RoutingError::SuccessBasedRoutingParamsNotFoundError)
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)?,
|
||||||
|
);
|
||||||
|
|
||||||
let success_based_connectors = client
|
let success_based_connectors = client
|
||||||
.calculate_success_rate(
|
.calculate_success_rate(
|
||||||
tenant_business_profile_id.clone(),
|
tenant_business_profile_id.clone(),
|
||||||
success_based_routing_configs.clone(),
|
success_based_routing_configs.clone(),
|
||||||
|
success_based_routing_config_params.clone(),
|
||||||
routable_connectors.clone(),
|
routable_connectors.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -725,9 +736,10 @@ pub async fn push_metrics_for_success_based_routing(
|
|||||||
let (first_success_based_connector, merchant_connector_id) = first_success_based_connector_label
|
let (first_success_based_connector, merchant_connector_id) = first_success_based_connector_label
|
||||||
.split_once(':')
|
.split_once(':')
|
||||||
.ok_or(errors::ApiErrorResponse::InternalServerError)
|
.ok_or(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable(
|
.attach_printable(format!(
|
||||||
"unable to split connector_name and mca_id from the first connector obtained from dynamic routing service",
|
"unable to split connector_name and mca_id from the first connector {:?} obtained from dynamic routing service",
|
||||||
)?;
|
first_success_based_connector_label
|
||||||
|
))?;
|
||||||
|
|
||||||
let outcome = get_success_based_metrics_outcome_for_payment(
|
let outcome = get_success_based_metrics_outcome_for_payment(
|
||||||
&payment_status_attribute,
|
&payment_status_attribute,
|
||||||
@ -802,6 +814,7 @@ pub async fn push_metrics_for_success_based_routing(
|
|||||||
.update_success_rate(
|
.update_success_rate(
|
||||||
tenant_business_profile_id,
|
tenant_business_profile_id,
|
||||||
success_based_routing_configs,
|
success_based_routing_configs,
|
||||||
|
success_based_routing_config_params,
|
||||||
vec![routing_types::RoutableConnectorChoiceWithStatus::new(
|
vec![routing_types::RoutableConnectorChoiceWithStatus::new(
|
||||||
routing_types::RoutableConnectorChoice {
|
routing_types::RoutableConnectorChoice {
|
||||||
choice_kind: api_models::routing::RoutableChoiceKind::FullStruct,
|
choice_kind: api_models::routing::RoutableChoiceKind::FullStruct,
|
||||||
@ -956,3 +969,76 @@ pub async fn default_success_based_routing_setup(
|
|||||||
);
|
);
|
||||||
Ok(ApplicationResponse::Json(new_record))
|
Ok(ApplicationResponse::Json(new_record))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SuccessBasedRoutingConfigParamsInterpolator {
|
||||||
|
pub payment_method: Option<common_enums::PaymentMethod>,
|
||||||
|
pub payment_method_type: Option<common_enums::PaymentMethodType>,
|
||||||
|
pub authentication_type: Option<common_enums::AuthenticationType>,
|
||||||
|
pub currency: Option<common_enums::Currency>,
|
||||||
|
pub country: Option<common_enums::CountryAlpha2>,
|
||||||
|
pub card_network: Option<String>,
|
||||||
|
pub card_bin: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SuccessBasedRoutingConfigParamsInterpolator {
|
||||||
|
pub fn new(
|
||||||
|
payment_method: Option<common_enums::PaymentMethod>,
|
||||||
|
payment_method_type: Option<common_enums::PaymentMethodType>,
|
||||||
|
authentication_type: Option<common_enums::AuthenticationType>,
|
||||||
|
currency: Option<common_enums::Currency>,
|
||||||
|
country: Option<common_enums::CountryAlpha2>,
|
||||||
|
card_network: Option<String>,
|
||||||
|
card_bin: Option<String>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
payment_method,
|
||||||
|
payment_method_type,
|
||||||
|
authentication_type,
|
||||||
|
currency,
|
||||||
|
country,
|
||||||
|
card_network,
|
||||||
|
card_bin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_string_val(
|
||||||
|
&self,
|
||||||
|
params: &Vec<routing_types::SuccessBasedRoutingConfigParams>,
|
||||||
|
) -> String {
|
||||||
|
let mut parts: Vec<String> = Vec::new();
|
||||||
|
for param in params {
|
||||||
|
let val = match param {
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::PaymentMethod => self
|
||||||
|
.payment_method
|
||||||
|
.as_ref()
|
||||||
|
.map_or(String::new(), |pm| pm.to_string()),
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::PaymentMethodType => self
|
||||||
|
.payment_method_type
|
||||||
|
.as_ref()
|
||||||
|
.map_or(String::new(), |pmt| pmt.to_string()),
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::AuthenticationType => self
|
||||||
|
.authentication_type
|
||||||
|
.as_ref()
|
||||||
|
.map_or(String::new(), |at| at.to_string()),
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::Currency => self
|
||||||
|
.currency
|
||||||
|
.as_ref()
|
||||||
|
.map_or(String::new(), |cur| cur.to_string()),
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::Country => self
|
||||||
|
.country
|
||||||
|
.as_ref()
|
||||||
|
.map_or(String::new(), |cn| cn.to_string()),
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::CardNetwork => {
|
||||||
|
self.card_network.clone().unwrap_or_default()
|
||||||
|
}
|
||||||
|
routing_types::SuccessBasedRoutingConfigParams::CardBin => {
|
||||||
|
self.card_bin.clone().unwrap_or_default()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if !val.is_empty() {
|
||||||
|
parts.push(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parts.join(":")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user