mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 09:38:33 +08:00
fix(core): return surcharge in payment method list response if passed in create request (#3363)
Co-authored-by: Narayan Bhat <48803246+Narayanbhat166@users.noreply.github.com>
This commit is contained in:
@ -2015,9 +2015,9 @@ impl<F>
|
|||||||
resource_id: types::ResponseId::NoResponseId,
|
resource_id: types::ResponseId::NoResponseId,
|
||||||
redirection_data,
|
redirection_data,
|
||||||
mandate_reference: None,
|
mandate_reference: None,
|
||||||
connector_metadata: Some(
|
connector_metadata: Some(serde_json::json!({
|
||||||
serde_json::json!({"three_ds_data":three_ds_data}),
|
"three_ds_data": three_ds_data
|
||||||
),
|
})),
|
||||||
network_txn_id: None,
|
network_txn_id: None,
|
||||||
connector_response_reference_id,
|
connector_response_reference_id,
|
||||||
incremental_authorization_allowed: None,
|
incremental_authorization_allowed: None,
|
||||||
|
|||||||
@ -1864,49 +1864,45 @@ pub async fn call_surcharge_decision_management(
|
|||||||
billing_address: Option<domain::Address>,
|
billing_address: Option<domain::Address>,
|
||||||
response_payment_method_types: &mut [ResponsePaymentMethodsEnabled],
|
response_payment_method_types: &mut [ResponsePaymentMethodsEnabled],
|
||||||
) -> errors::RouterResult<api_surcharge_decision_configs::MerchantSurchargeConfigs> {
|
) -> errors::RouterResult<api_surcharge_decision_configs::MerchantSurchargeConfigs> {
|
||||||
if payment_attempt.surcharge_amount.is_some() {
|
let algorithm_ref: routing_types::RoutingAlgorithmRef = merchant_account
|
||||||
Ok(api_surcharge_decision_configs::MerchantSurchargeConfigs::default())
|
.routing_algorithm
|
||||||
} else {
|
.clone()
|
||||||
let algorithm_ref: routing_types::RoutingAlgorithmRef = merchant_account
|
.map(|val| val.parse_value("routing algorithm"))
|
||||||
.routing_algorithm
|
.transpose()
|
||||||
.clone()
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.map(|val| val.parse_value("routing algorithm"))
|
.attach_printable("Could not decode the routing algorithm")?
|
||||||
.transpose()
|
.unwrap_or_default();
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
let (surcharge_results, merchant_sucharge_configs) =
|
||||||
.attach_printable("Could not decode the routing algorithm")?
|
perform_surcharge_decision_management_for_payment_method_list(
|
||||||
.unwrap_or_default();
|
&state,
|
||||||
let (surcharge_results, merchant_sucharge_configs) =
|
algorithm_ref,
|
||||||
perform_surcharge_decision_management_for_payment_method_list(
|
payment_attempt,
|
||||||
&state,
|
&payment_intent,
|
||||||
algorithm_ref,
|
billing_address.as_ref().map(Into::into),
|
||||||
payment_attempt,
|
response_payment_method_types,
|
||||||
&payment_intent,
|
)
|
||||||
billing_address.as_ref().map(Into::into),
|
.await
|
||||||
response_payment_method_types,
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("error performing surcharge decision operation")?;
|
||||||
|
if !surcharge_results.is_empty_result() {
|
||||||
|
surcharge_results
|
||||||
|
.persist_individual_surcharge_details_in_redis(&state, business_profile)
|
||||||
|
.await?;
|
||||||
|
let _ = state
|
||||||
|
.store
|
||||||
|
.update_payment_intent(
|
||||||
|
payment_intent,
|
||||||
|
storage::PaymentIntentUpdate::SurchargeApplicableUpdate {
|
||||||
|
surcharge_applicable: true,
|
||||||
|
updated_by: merchant_account.storage_scheme.to_string(),
|
||||||
|
},
|
||||||
|
merchant_account.storage_scheme,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||||
.attach_printable("error performing surcharge decision operation")?;
|
.attach_printable("Failed to update surcharge_applicable in Payment Intent");
|
||||||
if !surcharge_results.is_empty_result() {
|
|
||||||
surcharge_results
|
|
||||||
.persist_individual_surcharge_details_in_redis(&state, business_profile)
|
|
||||||
.await?;
|
|
||||||
let _ = state
|
|
||||||
.store
|
|
||||||
.update_payment_intent(
|
|
||||||
payment_intent,
|
|
||||||
storage::PaymentIntentUpdate::SurchargeApplicableUpdate {
|
|
||||||
surcharge_applicable: true,
|
|
||||||
updated_by: merchant_account.storage_scheme.to_string(),
|
|
||||||
},
|
|
||||||
merchant_account.storage_scheme,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
|
||||||
.attach_printable("Failed to update surcharge_applicable in Payment Intent");
|
|
||||||
}
|
|
||||||
Ok(merchant_sucharge_configs)
|
|
||||||
}
|
}
|
||||||
|
Ok(merchant_sucharge_configs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn call_surcharge_decision_management_for_saved_card(
|
pub async fn call_surcharge_decision_management_for_saved_card(
|
||||||
@ -1917,47 +1913,43 @@ pub async fn call_surcharge_decision_management_for_saved_card(
|
|||||||
payment_intent: storage::PaymentIntent,
|
payment_intent: storage::PaymentIntent,
|
||||||
customer_payment_method_response: &mut api::CustomerPaymentMethodsListResponse,
|
customer_payment_method_response: &mut api::CustomerPaymentMethodsListResponse,
|
||||||
) -> errors::RouterResult<()> {
|
) -> errors::RouterResult<()> {
|
||||||
if payment_attempt.surcharge_amount.is_some() {
|
let algorithm_ref: routing_types::RoutingAlgorithmRef = merchant_account
|
||||||
Ok(())
|
.routing_algorithm
|
||||||
} else {
|
.clone()
|
||||||
let algorithm_ref: routing_types::RoutingAlgorithmRef = merchant_account
|
.map(|val| val.parse_value("routing algorithm"))
|
||||||
.routing_algorithm
|
.transpose()
|
||||||
.clone()
|
|
||||||
.map(|val| val.parse_value("routing algorithm"))
|
|
||||||
.transpose()
|
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
|
||||||
.attach_printable("Could not decode the routing algorithm")?
|
|
||||||
.unwrap_or_default();
|
|
||||||
let surcharge_results = perform_surcharge_decision_management_for_saved_cards(
|
|
||||||
state,
|
|
||||||
algorithm_ref,
|
|
||||||
payment_attempt,
|
|
||||||
&payment_intent,
|
|
||||||
&mut customer_payment_method_response.customer_payment_methods,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("error performing surcharge decision operation")?;
|
.attach_printable("Could not decode the routing algorithm")?
|
||||||
if !surcharge_results.is_empty_result() {
|
.unwrap_or_default();
|
||||||
surcharge_results
|
let surcharge_results = perform_surcharge_decision_management_for_saved_cards(
|
||||||
.persist_individual_surcharge_details_in_redis(state, business_profile)
|
state,
|
||||||
.await?;
|
algorithm_ref,
|
||||||
let _ = state
|
payment_attempt,
|
||||||
.store
|
&payment_intent,
|
||||||
.update_payment_intent(
|
&mut customer_payment_method_response.customer_payment_methods,
|
||||||
payment_intent,
|
)
|
||||||
storage::PaymentIntentUpdate::SurchargeApplicableUpdate {
|
.await
|
||||||
surcharge_applicable: true,
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
updated_by: merchant_account.storage_scheme.to_string(),
|
.attach_printable("error performing surcharge decision operation")?;
|
||||||
},
|
if !surcharge_results.is_empty_result() {
|
||||||
merchant_account.storage_scheme,
|
surcharge_results
|
||||||
)
|
.persist_individual_surcharge_details_in_redis(state, business_profile)
|
||||||
.await
|
.await?;
|
||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
let _ = state
|
||||||
.attach_printable("Failed to update surcharge_applicable in Payment Intent");
|
.store
|
||||||
}
|
.update_payment_intent(
|
||||||
Ok(())
|
payment_intent,
|
||||||
|
storage::PaymentIntentUpdate::SurchargeApplicableUpdate {
|
||||||
|
surcharge_applicable: true,
|
||||||
|
updated_by: merchant_account.storage_scheme.to_string(),
|
||||||
|
},
|
||||||
|
merchant_account.storage_scheme,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||||
|
.attach_printable("Failed to update surcharge_applicable in Payment Intent");
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use api_models::{
|
use api_models::{
|
||||||
payment_methods::SurchargeDetailsResponse,
|
payment_methods::SurchargeDetailsResponse,
|
||||||
payments::Address,
|
payments, routing,
|
||||||
routing,
|
|
||||||
surcharge_decision_configs::{self, SurchargeDecisionConfigs, SurchargeDecisionManagerRecord},
|
surcharge_decision_configs::{self, SurchargeDecisionConfigs, SurchargeDecisionManagerRecord},
|
||||||
};
|
};
|
||||||
use common_utils::{ext_traits::StringExt, static_cache::StaticCache, types as common_utils_types};
|
use common_utils::{ext_traits::StringExt, static_cache::StaticCache, types as common_utils_types};
|
||||||
@ -15,7 +16,10 @@ use router_env::{instrument, tracing};
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::payments::{types, PaymentData},
|
core::payments::{types, PaymentData},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
types::{storage as oss_storage, transformers::ForeignTryFrom},
|
types::{
|
||||||
|
storage::{self as oss_storage, payment_attempt::PaymentAttemptExt},
|
||||||
|
transformers::ForeignTryFrom,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
static CONF_CACHE: StaticCache<VirInterpreterBackendCacheWrapper> = StaticCache::new();
|
static CONF_CACHE: StaticCache<VirInterpreterBackendCacheWrapper> = StaticCache::new();
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -49,44 +53,102 @@ impl TryFrom<SurchargeDecisionManagerRecord> for VirInterpreterBackendCacheWrapp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SurchargeSource {
|
||||||
|
/// Surcharge will be generated through the surcharge rules
|
||||||
|
Generate(Arc<VirInterpreterBackendCacheWrapper>),
|
||||||
|
/// Surcharge is predefined by the merchant through payment create request
|
||||||
|
Predetermined(payments::RequestSurchargeDetails),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SurchargeSource {
|
||||||
|
pub fn generate_surcharge_details_and_populate_surcharge_metadata(
|
||||||
|
&self,
|
||||||
|
backend_input: &backend::BackendInput,
|
||||||
|
payment_attempt: &oss_storage::PaymentAttempt,
|
||||||
|
surcharge_metadata_and_key: (&mut types::SurchargeMetadata, types::SurchargeKey),
|
||||||
|
) -> ConditionalConfigResult<Option<types::SurchargeDetails>> {
|
||||||
|
match self {
|
||||||
|
Self::Generate(interpreter) => {
|
||||||
|
let surcharge_output = execute_dsl_and_get_conditional_config(
|
||||||
|
backend_input.clone(),
|
||||||
|
&interpreter.cached_alogorith,
|
||||||
|
)?;
|
||||||
|
Ok(surcharge_output
|
||||||
|
.surcharge_details
|
||||||
|
.map(|surcharge_details| {
|
||||||
|
get_surcharge_details_from_surcharge_output(
|
||||||
|
surcharge_details,
|
||||||
|
payment_attempt,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.map(|surcharge_details| {
|
||||||
|
let (surcharge_metadata, surcharge_key) = surcharge_metadata_and_key;
|
||||||
|
surcharge_metadata
|
||||||
|
.insert_surcharge_details(surcharge_key, surcharge_details.clone());
|
||||||
|
surcharge_details
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Self::Predetermined(request_surcharge_details) => Ok(Some(
|
||||||
|
types::SurchargeDetails::from((request_surcharge_details, payment_attempt)),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn perform_surcharge_decision_management_for_payment_method_list(
|
pub async fn perform_surcharge_decision_management_for_payment_method_list(
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
algorithm_ref: routing::RoutingAlgorithmRef,
|
algorithm_ref: routing::RoutingAlgorithmRef,
|
||||||
payment_attempt: &oss_storage::PaymentAttempt,
|
payment_attempt: &oss_storage::PaymentAttempt,
|
||||||
payment_intent: &oss_storage::PaymentIntent,
|
payment_intent: &oss_storage::PaymentIntent,
|
||||||
billing_address: Option<Address>,
|
billing_address: Option<payments::Address>,
|
||||||
response_payment_method_types: &mut [api_models::payment_methods::ResponsePaymentMethodsEnabled],
|
response_payment_method_types: &mut [api_models::payment_methods::ResponsePaymentMethodsEnabled],
|
||||||
) -> ConditionalConfigResult<(
|
) -> ConditionalConfigResult<(
|
||||||
types::SurchargeMetadata,
|
types::SurchargeMetadata,
|
||||||
surcharge_decision_configs::MerchantSurchargeConfigs,
|
surcharge_decision_configs::MerchantSurchargeConfigs,
|
||||||
)> {
|
)> {
|
||||||
let mut surcharge_metadata = types::SurchargeMetadata::new(payment_attempt.attempt_id.clone());
|
let mut surcharge_metadata = types::SurchargeMetadata::new(payment_attempt.attempt_id.clone());
|
||||||
let algorithm_id = if let Some(id) = algorithm_ref.surcharge_config_algo_id {
|
|
||||||
id
|
let (surcharge_source, merchant_surcharge_configs) = match (
|
||||||
} else {
|
payment_attempt.get_surcharge_details(),
|
||||||
return Ok((
|
algorithm_ref.surcharge_config_algo_id,
|
||||||
surcharge_metadata,
|
) {
|
||||||
|
(Some(request_surcharge_details), _) => (
|
||||||
|
SurchargeSource::Predetermined(request_surcharge_details),
|
||||||
surcharge_decision_configs::MerchantSurchargeConfigs::default(),
|
surcharge_decision_configs::MerchantSurchargeConfigs::default(),
|
||||||
));
|
),
|
||||||
|
(None, Some(algorithm_id)) => {
|
||||||
|
let key = ensure_algorithm_cached(
|
||||||
|
&*state.store,
|
||||||
|
&payment_attempt.merchant_id,
|
||||||
|
algorithm_ref.timestamp,
|
||||||
|
algorithm_id.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let cached_algo = CONF_CACHE
|
||||||
|
.retrieve(&key)
|
||||||
|
.into_report()
|
||||||
|
.change_context(ConfigError::CacheMiss)
|
||||||
|
.attach_printable(
|
||||||
|
"Unable to retrieve cached routing algorithm even after refresh",
|
||||||
|
)?;
|
||||||
|
let merchant_surcharge_config = cached_algo.merchant_surcharge_configs.clone();
|
||||||
|
(
|
||||||
|
SurchargeSource::Generate(cached_algo),
|
||||||
|
merchant_surcharge_config,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(None, None) => {
|
||||||
|
return Ok((
|
||||||
|
surcharge_metadata,
|
||||||
|
surcharge_decision_configs::MerchantSurchargeConfigs::default(),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let key = ensure_algorithm_cached(
|
|
||||||
&*state.store,
|
|
||||||
&payment_attempt.merchant_id,
|
|
||||||
algorithm_ref.timestamp,
|
|
||||||
algorithm_id.as_str(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let cached_algo = CONF_CACHE
|
|
||||||
.retrieve(&key)
|
|
||||||
.into_report()
|
|
||||||
.change_context(ConfigError::CacheMiss)
|
|
||||||
.attach_printable("Unable to retrieve cached routing algorithm even after refresh")?;
|
|
||||||
let mut backend_input =
|
let mut backend_input =
|
||||||
make_dsl_input_for_surcharge(payment_attempt, payment_intent, billing_address)
|
make_dsl_input_for_surcharge(payment_attempt, payment_intent, billing_address)
|
||||||
.change_context(ConfigError::InputConstructionError)?;
|
.change_context(ConfigError::InputConstructionError)?;
|
||||||
let interpreter = &cached_algo.cached_alogorith;
|
|
||||||
let merchant_surcharge_configs = cached_algo.merchant_surcharge_configs.clone();
|
|
||||||
|
|
||||||
for payment_methods_enabled in response_payment_method_types.iter_mut() {
|
for payment_methods_enabled in response_payment_method_types.iter_mut() {
|
||||||
for payment_method_type_response in
|
for payment_method_type_response in
|
||||||
@ -101,24 +163,21 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list(
|
|||||||
for card_network_type in card_network_list.iter_mut() {
|
for card_network_type in card_network_list.iter_mut() {
|
||||||
backend_input.payment_method.card_network =
|
backend_input.payment_method.card_network =
|
||||||
Some(card_network_type.card_network.clone());
|
Some(card_network_type.card_network.clone());
|
||||||
let surcharge_output =
|
let surcharge_details = surcharge_source
|
||||||
execute_dsl_and_get_conditional_config(backend_input.clone(), interpreter)?;
|
.generate_surcharge_details_and_populate_surcharge_metadata(
|
||||||
// let surcharge_details =
|
&backend_input,
|
||||||
card_network_type.surcharge_details = surcharge_output
|
payment_attempt,
|
||||||
.surcharge_details
|
(
|
||||||
.map(|surcharge_details| {
|
&mut surcharge_metadata,
|
||||||
let surcharge_details = get_surcharge_details_from_surcharge_output(
|
|
||||||
surcharge_details,
|
|
||||||
payment_attempt,
|
|
||||||
)?;
|
|
||||||
surcharge_metadata.insert_surcharge_details(
|
|
||||||
types::SurchargeKey::PaymentMethodData(
|
types::SurchargeKey::PaymentMethodData(
|
||||||
payment_methods_enabled.payment_method,
|
payment_methods_enabled.payment_method,
|
||||||
payment_method_type_response.payment_method_type,
|
payment_method_type_response.payment_method_type,
|
||||||
Some(card_network_type.card_network.clone()),
|
Some(card_network_type.card_network.clone()),
|
||||||
),
|
),
|
||||||
surcharge_details.clone(),
|
),
|
||||||
);
|
)?;
|
||||||
|
card_network_type.surcharge_details = surcharge_details
|
||||||
|
.map(|surcharge_details| {
|
||||||
SurchargeDetailsResponse::foreign_try_from((
|
SurchargeDetailsResponse::foreign_try_from((
|
||||||
&surcharge_details,
|
&surcharge_details,
|
||||||
payment_attempt,
|
payment_attempt,
|
||||||
@ -130,23 +189,21 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list(
|
|||||||
.transpose()?;
|
.transpose()?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let surcharge_output =
|
let surcharge_details = surcharge_source
|
||||||
execute_dsl_and_get_conditional_config(backend_input.clone(), interpreter)?;
|
.generate_surcharge_details_and_populate_surcharge_metadata(
|
||||||
payment_method_type_response.surcharge_details = surcharge_output
|
&backend_input,
|
||||||
.surcharge_details
|
payment_attempt,
|
||||||
.map(|surcharge_details| {
|
(
|
||||||
let surcharge_details = get_surcharge_details_from_surcharge_output(
|
&mut surcharge_metadata,
|
||||||
surcharge_details,
|
|
||||||
payment_attempt,
|
|
||||||
)?;
|
|
||||||
surcharge_metadata.insert_surcharge_details(
|
|
||||||
types::SurchargeKey::PaymentMethodData(
|
types::SurchargeKey::PaymentMethodData(
|
||||||
payment_methods_enabled.payment_method,
|
payment_methods_enabled.payment_method,
|
||||||
payment_method_type_response.payment_method_type,
|
payment_method_type_response.payment_method_type,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
surcharge_details.clone(),
|
),
|
||||||
);
|
)?;
|
||||||
|
payment_method_type_response.surcharge_details = surcharge_details
|
||||||
|
.map(|surcharge_details| {
|
||||||
SurchargeDetailsResponse::foreign_try_from((
|
SurchargeDetailsResponse::foreign_try_from((
|
||||||
&surcharge_details,
|
&surcharge_details,
|
||||||
payment_attempt,
|
payment_attempt,
|
||||||
@ -173,51 +230,54 @@ where
|
|||||||
{
|
{
|
||||||
let mut surcharge_metadata =
|
let mut surcharge_metadata =
|
||||||
types::SurchargeMetadata::new(payment_data.payment_attempt.attempt_id.clone());
|
types::SurchargeMetadata::new(payment_data.payment_attempt.attempt_id.clone());
|
||||||
let algorithm_id = if let Some(id) = algorithm_ref.surcharge_config_algo_id {
|
let surcharge_source = match (
|
||||||
id
|
payment_data.payment_attempt.get_surcharge_details(),
|
||||||
} else {
|
algorithm_ref.surcharge_config_algo_id,
|
||||||
return Ok(surcharge_metadata);
|
) {
|
||||||
|
(Some(request_surcharge_details), _) => {
|
||||||
|
SurchargeSource::Predetermined(request_surcharge_details)
|
||||||
|
}
|
||||||
|
(None, Some(algorithm_id)) => {
|
||||||
|
let key = ensure_algorithm_cached(
|
||||||
|
&*state.store,
|
||||||
|
&payment_data.payment_attempt.merchant_id,
|
||||||
|
algorithm_ref.timestamp,
|
||||||
|
algorithm_id.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let cached_algo = CONF_CACHE
|
||||||
|
.retrieve(&key)
|
||||||
|
.into_report()
|
||||||
|
.change_context(ConfigError::CacheMiss)
|
||||||
|
.attach_printable(
|
||||||
|
"Unable to retrieve cached routing algorithm even after refresh",
|
||||||
|
)?;
|
||||||
|
SurchargeSource::Generate(cached_algo)
|
||||||
|
}
|
||||||
|
(None, None) => return Ok(surcharge_metadata),
|
||||||
};
|
};
|
||||||
|
|
||||||
let key = ensure_algorithm_cached(
|
|
||||||
&*state.store,
|
|
||||||
&payment_data.payment_attempt.merchant_id,
|
|
||||||
algorithm_ref.timestamp,
|
|
||||||
algorithm_id.as_str(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let cached_algo = CONF_CACHE
|
|
||||||
.retrieve(&key)
|
|
||||||
.into_report()
|
|
||||||
.change_context(ConfigError::CacheMiss)
|
|
||||||
.attach_printable("Unable to retrieve cached routing algorithm even after refresh")?;
|
|
||||||
let mut backend_input = make_dsl_input_for_surcharge(
|
let mut backend_input = make_dsl_input_for_surcharge(
|
||||||
&payment_data.payment_attempt,
|
&payment_data.payment_attempt,
|
||||||
&payment_data.payment_intent,
|
&payment_data.payment_intent,
|
||||||
payment_data.address.billing.clone(),
|
payment_data.address.billing.clone(),
|
||||||
)
|
)
|
||||||
.change_context(ConfigError::InputConstructionError)?;
|
.change_context(ConfigError::InputConstructionError)?;
|
||||||
let interpreter = &cached_algo.cached_alogorith;
|
|
||||||
for payment_method_type in payment_method_type_list {
|
for payment_method_type in payment_method_type_list {
|
||||||
backend_input.payment_method.payment_method_type = Some(*payment_method_type);
|
backend_input.payment_method.payment_method_type = Some(*payment_method_type);
|
||||||
// in case of session flow, payment_method will always be wallet
|
// in case of session flow, payment_method will always be wallet
|
||||||
backend_input.payment_method.payment_method = Some(payment_method_type.to_owned().into());
|
backend_input.payment_method.payment_method = Some(payment_method_type.to_owned().into());
|
||||||
let surcharge_output =
|
surcharge_source.generate_surcharge_details_and_populate_surcharge_metadata(
|
||||||
execute_dsl_and_get_conditional_config(backend_input.clone(), interpreter)?;
|
&backend_input,
|
||||||
if let Some(surcharge_details) = surcharge_output.surcharge_details {
|
&payment_data.payment_attempt,
|
||||||
let surcharge_details = get_surcharge_details_from_surcharge_output(
|
(
|
||||||
surcharge_details,
|
&mut surcharge_metadata,
|
||||||
&payment_data.payment_attempt,
|
|
||||||
)?;
|
|
||||||
surcharge_metadata.insert_surcharge_details(
|
|
||||||
types::SurchargeKey::PaymentMethodData(
|
types::SurchargeKey::PaymentMethodData(
|
||||||
payment_method_type.to_owned().into(),
|
payment_method_type.to_owned().into(),
|
||||||
*payment_method_type,
|
*payment_method_type,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
surcharge_details,
|
),
|
||||||
);
|
)?;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(surcharge_metadata)
|
Ok(surcharge_metadata)
|
||||||
}
|
}
|
||||||
@ -229,27 +289,34 @@ pub async fn perform_surcharge_decision_management_for_saved_cards(
|
|||||||
customer_payment_method_list: &mut [api_models::payment_methods::CustomerPaymentMethod],
|
customer_payment_method_list: &mut [api_models::payment_methods::CustomerPaymentMethod],
|
||||||
) -> ConditionalConfigResult<types::SurchargeMetadata> {
|
) -> ConditionalConfigResult<types::SurchargeMetadata> {
|
||||||
let mut surcharge_metadata = types::SurchargeMetadata::new(payment_attempt.attempt_id.clone());
|
let mut surcharge_metadata = types::SurchargeMetadata::new(payment_attempt.attempt_id.clone());
|
||||||
let algorithm_id = if let Some(id) = algorithm_ref.surcharge_config_algo_id {
|
let surcharge_source = match (
|
||||||
id
|
payment_attempt.get_surcharge_details(),
|
||||||
} else {
|
algorithm_ref.surcharge_config_algo_id,
|
||||||
return Ok(surcharge_metadata);
|
) {
|
||||||
|
(Some(request_surcharge_details), _) => {
|
||||||
|
SurchargeSource::Predetermined(request_surcharge_details)
|
||||||
|
}
|
||||||
|
(None, Some(algorithm_id)) => {
|
||||||
|
let key = ensure_algorithm_cached(
|
||||||
|
&*state.store,
|
||||||
|
&payment_attempt.merchant_id,
|
||||||
|
algorithm_ref.timestamp,
|
||||||
|
algorithm_id.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let cached_algo = CONF_CACHE
|
||||||
|
.retrieve(&key)
|
||||||
|
.into_report()
|
||||||
|
.change_context(ConfigError::CacheMiss)
|
||||||
|
.attach_printable(
|
||||||
|
"Unable to retrieve cached routing algorithm even after refresh",
|
||||||
|
)?;
|
||||||
|
SurchargeSource::Generate(cached_algo)
|
||||||
|
}
|
||||||
|
(None, None) => return Ok(surcharge_metadata),
|
||||||
};
|
};
|
||||||
|
|
||||||
let key = ensure_algorithm_cached(
|
|
||||||
&*state.store,
|
|
||||||
&payment_attempt.merchant_id,
|
|
||||||
algorithm_ref.timestamp,
|
|
||||||
algorithm_id.as_str(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let cached_algo = CONF_CACHE
|
|
||||||
.retrieve(&key)
|
|
||||||
.into_report()
|
|
||||||
.change_context(ConfigError::CacheMiss)
|
|
||||||
.attach_printable("Unable to retrieve cached routing algorithm even after refresh")?;
|
|
||||||
let mut backend_input = make_dsl_input_for_surcharge(payment_attempt, payment_intent, None)
|
let mut backend_input = make_dsl_input_for_surcharge(payment_attempt, payment_intent, None)
|
||||||
.change_context(ConfigError::InputConstructionError)?;
|
.change_context(ConfigError::InputConstructionError)?;
|
||||||
let interpreter = &cached_algo.cached_alogorith;
|
|
||||||
|
|
||||||
for customer_payment_method in customer_payment_method_list.iter_mut() {
|
for customer_payment_method in customer_payment_method_list.iter_mut() {
|
||||||
backend_input.payment_method.payment_method = Some(customer_payment_method.payment_method);
|
backend_input.payment_method.payment_method = Some(customer_payment_method.payment_method);
|
||||||
@ -266,23 +333,22 @@ pub async fn perform_surcharge_decision_management_for_saved_cards(
|
|||||||
.change_context(ConfigError::DslExecutionError)
|
.change_context(ConfigError::DslExecutionError)
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let surcharge_output =
|
let surcharge_details = surcharge_source
|
||||||
execute_dsl_and_get_conditional_config(backend_input.clone(), interpreter)?;
|
.generate_surcharge_details_and_populate_surcharge_metadata(
|
||||||
if let Some(surcharge_details_output) = surcharge_output.surcharge_details {
|
&backend_input,
|
||||||
let surcharge_details = get_surcharge_details_from_surcharge_output(
|
|
||||||
surcharge_details_output,
|
|
||||||
payment_attempt,
|
payment_attempt,
|
||||||
|
(
|
||||||
|
&mut surcharge_metadata,
|
||||||
|
types::SurchargeKey::Token(customer_payment_method.payment_token.clone()),
|
||||||
|
),
|
||||||
)?;
|
)?;
|
||||||
surcharge_metadata.insert_surcharge_details(
|
customer_payment_method.surcharge_details = surcharge_details
|
||||||
types::SurchargeKey::Token(customer_payment_method.payment_token.clone()),
|
.map(|surcharge_details| {
|
||||||
surcharge_details.clone(),
|
|
||||||
);
|
|
||||||
customer_payment_method.surcharge_details = Some(
|
|
||||||
SurchargeDetailsResponse::foreign_try_from((&surcharge_details, payment_attempt))
|
SurchargeDetailsResponse::foreign_try_from((&surcharge_details, payment_attempt))
|
||||||
.into_report()
|
.into_report()
|
||||||
.change_context(ConfigError::DslParsingError)?,
|
.change_context(ConfigError::DslParsingError)
|
||||||
);
|
})
|
||||||
}
|
.transpose()?;
|
||||||
}
|
}
|
||||||
Ok(surcharge_metadata)
|
Ok(surcharge_metadata)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -366,7 +366,6 @@ where
|
|||||||
call_surcharge_decision_management_for_session_flow(
|
call_surcharge_decision_management_for_session_flow(
|
||||||
state,
|
state,
|
||||||
&merchant_account,
|
&merchant_account,
|
||||||
&business_profile,
|
|
||||||
&mut payment_data,
|
&mut payment_data,
|
||||||
&connectors,
|
&connectors,
|
||||||
)
|
)
|
||||||
@ -599,7 +598,6 @@ pub fn get_connector_data(
|
|||||||
pub async fn call_surcharge_decision_management_for_session_flow<O>(
|
pub async fn call_surcharge_decision_management_for_session_flow<O>(
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
merchant_account: &domain::MerchantAccount,
|
merchant_account: &domain::MerchantAccount,
|
||||||
business_profile: &diesel_models::business_profile::BusinessProfile,
|
|
||||||
payment_data: &mut PaymentData<O>,
|
payment_data: &mut PaymentData<O>,
|
||||||
session_connector_data: &[api::SessionConnectorData],
|
session_connector_data: &[api::SessionConnectorData],
|
||||||
) -> RouterResult<Option<api::SessionSurchargeDetails>>
|
) -> RouterResult<Option<api::SessionSurchargeDetails>>
|
||||||
@ -644,10 +642,6 @@ where
|
|||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("error performing surcharge decision operation")?;
|
.attach_printable("error performing surcharge decision operation")?;
|
||||||
|
|
||||||
surcharge_results
|
|
||||||
.persist_individual_surcharge_details_in_redis(state, business_profile)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(if surcharge_results.is_empty_result() {
|
Ok(if surcharge_results.is_empty_result() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user