Skip to content

Commit

Permalink
refactor(core): query business profile only once (#2830)
Browse files Browse the repository at this point in the history
  • Loading branch information
Narayanbhat166 authored Nov 20, 2023
1 parent 3954001 commit 44deeb7
Show file tree
Hide file tree
Showing 13 changed files with 772 additions and 579 deletions.
64 changes: 27 additions & 37 deletions crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ use scheduler::{db::process_tracker::ProcessTrackerExt, errors as sch_errors, ut
use time;

pub use self::operations::{
PaymentApprove, PaymentCancel, PaymentCapture, PaymentConfirm, PaymentCreate,
PaymentMethodValidate, PaymentReject, PaymentResponse, PaymentSession, PaymentStatus,
PaymentUpdate,
PaymentApprove, PaymentCancel, PaymentCapture, PaymentConfirm, PaymentCreate, PaymentReject,
PaymentResponse, PaymentSession, PaymentStatus, PaymentUpdate,
};
use self::{
flows::{ConstructFlowSpecificData, Feature},
Expand Down Expand Up @@ -112,7 +111,12 @@ where

tracing::Span::current().record("payment_id", &format!("{}", validate_result.payment_id));

let (operation, mut payment_data, customer_details) = operation
let operations::GetTrackerResponse {
operation,
customer_details,
mut payment_data,
business_profile,
} = operation
.to_get_tracker()?
.get_trackers(
state,
Expand Down Expand Up @@ -142,6 +146,7 @@ where
state,
&req,
&merchant_account,
&business_profile,
&key_store,
&mut payment_data,
eligible_connectors,
Expand Down Expand Up @@ -1998,11 +2003,13 @@ where
Ok(())
}

#[allow(clippy::too_many_arguments)]
pub async fn get_connector_choice<F, Req, Ctx>(
operation: &BoxedOperation<'_, F, Req, Ctx>,
state: &AppState,
req: &Req,
merchant_account: &domain::MerchantAccount,
business_profile: &storage::business_profile::BusinessProfile,
key_store: &domain::MerchantKeyStore,
payment_data: &mut PaymentData<F>,
eligible_connectors: Option<Vec<api_models::enums::RoutableConnectors>>,
Expand Down Expand Up @@ -2040,6 +2047,7 @@ where
connector_selection(
state,
merchant_account,
business_profile,
key_store,
payment_data,
Some(straight_through),
Expand All @@ -2052,6 +2060,7 @@ where
connector_selection(
state,
merchant_account,
business_profile,
key_store,
payment_data,
None,
Expand All @@ -2075,6 +2084,7 @@ where
pub async fn connector_selection<F>(
state: &AppState,
merchant_account: &domain::MerchantAccount,
business_profile: &storage::business_profile::BusinessProfile,
key_store: &domain::MerchantKeyStore,
payment_data: &mut PaymentData<F>,
request_straight_through: Option<serde_json::Value>,
Expand Down Expand Up @@ -2114,6 +2124,7 @@ where
let decided_connector = decide_connector(
state.clone(),
merchant_account,
business_profile,
key_store,
payment_data,
request_straight_through,
Expand Down Expand Up @@ -2141,9 +2152,11 @@ where
Ok(decided_connector)
}

#[allow(clippy::too_many_arguments)]
pub async fn decide_connector<F>(
state: AppState,
merchant_account: &domain::MerchantAccount,
business_profile: &storage::business_profile::BusinessProfile,
key_store: &domain::MerchantKeyStore,
payment_data: &mut PaymentData<F>,
request_straight_through: Option<api::routing::StraightThroughAlgorithm>,
Expand Down Expand Up @@ -2345,6 +2358,7 @@ where
route_connector_v1(
&state,
merchant_account,
business_profile,
key_store,
payment_data,
routing_data,
Expand Down Expand Up @@ -2480,6 +2494,7 @@ where
pub async fn route_connector_v1<F>(
state: &AppState,
merchant_account: &domain::MerchantAccount,
business_profile: &storage::business_profile::BusinessProfile,
key_store: &domain::MerchantKeyStore,
payment_data: &mut PaymentData<F>,
routing_data: &mut storage::RoutingData,
Expand All @@ -2488,44 +2503,19 @@ pub async fn route_connector_v1<F>(
where
F: Send + Clone,
{
#[cfg(not(feature = "business_profile_routing"))]
let algorithm_ref: api::routing::RoutingAlgorithmRef = merchant_account
.routing_algorithm
.clone()
.map(|ra| ra.parse_value("RoutingAlgorithmRef"))
let routing_algorithm = if cfg!(feature = "business_profile_routing") {
business_profile.routing_algorithm.clone()
} else {
merchant_account.routing_algorithm.clone()
};

let algorithm_ref = routing_algorithm
.map(|ra| ra.parse_value::<api::routing::RoutingAlgorithmRef>("RoutingAlgorithmRef"))
.transpose()
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Could not decode merchant routing algorithm ref")?
.unwrap_or_default();

#[cfg(feature = "business_profile_routing")]
let algorithm_ref: api::routing::RoutingAlgorithmRef = {
let profile_id = payment_data
.payment_intent
.profile_id
.as_ref()
.get_required_value("profile_id")
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("'profile_id' not set in payment intent")?;

let business_profile = state
.store
.find_business_profile_by_profile_id(profile_id)
.await
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
id: profile_id.to_string(),
})?;

business_profile
.routing_algorithm
.clone()
.map(|ra| ra.parse_value("RoutingAlgorithmRef"))
.transpose()
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Could not decode merchant routing algorithm ref")?
.unwrap_or_default()
};

let connectors = routing::perform_static_routing_v1(
state,
&merchant_account.merchant_id,
Expand Down
19 changes: 12 additions & 7 deletions crates/router/src/core/payments/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub mod payment_capture;
pub mod payment_complete_authorize;
pub mod payment_confirm;
pub mod payment_create;
pub mod payment_method_validate;
pub mod payment_reject;
pub mod payment_response;
pub mod payment_session;
Expand All @@ -20,10 +19,9 @@ use router_env::{instrument, tracing};
pub use self::{
payment_approve::PaymentApprove, payment_cancel::PaymentCancel,
payment_capture::PaymentCapture, payment_confirm::PaymentConfirm,
payment_create::PaymentCreate, payment_method_validate::PaymentMethodValidate,
payment_reject::PaymentReject, payment_response::PaymentResponse,
payment_session::PaymentSession, payment_start::PaymentStart, payment_status::PaymentStatus,
payment_update::PaymentUpdate,
payment_create::PaymentCreate, payment_reject::PaymentReject,
payment_response::PaymentResponse, payment_session::PaymentSession,
payment_start::PaymentStart, payment_status::PaymentStatus, payment_update::PaymentUpdate,
};
use super::{helpers, CustomerDetails, PaymentData};
use crate::{
Expand Down Expand Up @@ -91,8 +89,15 @@ pub trait ValidateRequest<F, R, Ctx: PaymentMethodRetrieve> {
) -> RouterResult<(BoxedOperation<'b, F, R, Ctx>, ValidateResult<'a>)>;
}

pub struct GetTrackerResponse<'a, F: Clone, R, Ctx> {
pub operation: BoxedOperation<'a, F, R, Ctx>,
pub customer_details: Option<CustomerDetails>,
pub payment_data: PaymentData<F>,
pub business_profile: storage::business_profile::BusinessProfile,
}

#[async_trait]
pub trait GetTracker<F, D, R, Ctx: PaymentMethodRetrieve>: Send {
pub trait GetTracker<F: Clone, D, R, Ctx: PaymentMethodRetrieve>: Send {
#[allow(clippy::too_many_arguments)]
async fn get_trackers<'a>(
&'a self,
Expand All @@ -103,7 +108,7 @@ pub trait GetTracker<F, D, R, Ctx: PaymentMethodRetrieve>: Send {
merchant_account: &domain::MerchantAccount,
mechant_key_store: &domain::MerchantKeyStore,
auth_flow: services::AuthFlow,
) -> RouterResult<(BoxedOperation<'a, F, R, Ctx>, D, Option<CustomerDetails>)>;
) -> RouterResult<GetTrackerResponse<'a, F, R, Ctx>>;
}

#[async_trait]
Expand Down
114 changes: 66 additions & 48 deletions crates/router/src/core/payments/operations/payment_approve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
merchant_account: &domain::MerchantAccount,
key_store: &domain::MerchantKeyStore,
_auth_flow: services::AuthFlow,
) -> RouterResult<(
BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
PaymentData<F>,
Option<CustomerDetails>,
)> {
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsRequest, Ctx>> {
let db = &*state.store;
let merchant_id = &merchant_account.merchant_id;
let storage_scheme = merchant_account.storage_scheme;
Expand All @@ -76,6 +72,21 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
"confirm",
)?;

let profile_id = payment_intent
.profile_id
.as_ref()
.get_required_value("profile_id")
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("'profile_id' not set in payment intent")?;

let business_profile = state
.store
.find_business_profile_by_profile_id(profile_id)
.await
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
id: profile_id.to_string(),
})?;

let (
token,
payment_method,
Expand Down Expand Up @@ -207,50 +218,57 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
format!("Error while retrieving frm_response, merchant_id: {}, payment_id: {attempt_id}", &merchant_account.merchant_id)
});

Ok((
Box::new(self),
PaymentData {
flow: PhantomData,
payment_intent,
payment_attempt,
currency,
amount,
email: request.email.clone(),
mandate_id: None,
mandate_connector,
setup_mandate,
token,
address: PaymentAddress {
shipping: shipping_address.as_ref().map(|a| a.into()),
billing: billing_address.as_ref().map(|a| a.into()),
},
confirm: request.confirm,
payment_method_data: request.payment_method_data.clone(),
force_sync: None,
refunds: vec![],
disputes: vec![],
attempts: None,
sessions_token: vec![],
card_cvc: request.card_cvc.clone(),
creds_identifier: None,
pm_token: None,
connector_customer_id: None,
recurring_mandate_payment_data,
ephemeral_key: None,
multiple_capture_data: None,
redirect_response,
surcharge_details: None,
frm_message: frm_response.ok(),
payment_link_data: None,
let payment_data = PaymentData {
flow: PhantomData,
payment_intent,
payment_attempt,
currency,
amount,
email: request.email.clone(),
mandate_id: None,
mandate_connector,
setup_mandate,
token,
address: PaymentAddress {
shipping: shipping_address.as_ref().map(|a| a.into()),
billing: billing_address.as_ref().map(|a| a.into()),
},
Some(CustomerDetails {
customer_id: request.customer_id.clone(),
name: request.name.clone(),
email: request.email.clone(),
phone: request.phone.clone(),
phone_country_code: request.phone_country_code.clone(),
}),
))
confirm: request.confirm,
payment_method_data: request.payment_method_data.clone(),
force_sync: None,
refunds: vec![],
disputes: vec![],
attempts: None,
sessions_token: vec![],
card_cvc: request.card_cvc.clone(),
creds_identifier: None,
pm_token: None,
connector_customer_id: None,
recurring_mandate_payment_data,
ephemeral_key: None,
multiple_capture_data: None,
redirect_response,
surcharge_details: None,
frm_message: frm_response.ok(),
payment_link_data: None,
};

let customer_details = Some(CustomerDetails {
customer_id: request.customer_id.clone(),
name: request.name.clone(),
email: request.email.clone(),
phone: request.phone.clone(),
phone_country_code: request.phone_country_code.clone(),
});

let get_trackers_response = operations::GetTrackerResponse {
operation: Box::new(self),
customer_details,
payment_data,
business_profile,
};

Ok(get_trackers_response)
}
}

Expand Down
Loading

0 comments on commit 44deeb7

Please sign in to comment.