Skip to content

Commit 44deeb7

Browse files
refactor(core): query business profile only once (#2830)
1 parent 3954001 commit 44deeb7

13 files changed

+772
-579
lines changed

crates/router/src/core/payments.rs

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ use scheduler::{db::process_tracker::ProcessTrackerExt, errors as sch_errors, ut
3131
use time;
3232

3333
pub use self::operations::{
34-
PaymentApprove, PaymentCancel, PaymentCapture, PaymentConfirm, PaymentCreate,
35-
PaymentMethodValidate, PaymentReject, PaymentResponse, PaymentSession, PaymentStatus,
36-
PaymentUpdate,
34+
PaymentApprove, PaymentCancel, PaymentCapture, PaymentConfirm, PaymentCreate, PaymentReject,
35+
PaymentResponse, PaymentSession, PaymentStatus, PaymentUpdate,
3736
};
3837
use self::{
3938
flows::{ConstructFlowSpecificData, Feature},
@@ -112,7 +111,12 @@ where
112111

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

115-
let (operation, mut payment_data, customer_details) = operation
114+
let operations::GetTrackerResponse {
115+
operation,
116+
customer_details,
117+
mut payment_data,
118+
business_profile,
119+
} = operation
116120
.to_get_tracker()?
117121
.get_trackers(
118122
state,
@@ -142,6 +146,7 @@ where
142146
state,
143147
&req,
144148
&merchant_account,
149+
&business_profile,
145150
&key_store,
146151
&mut payment_data,
147152
eligible_connectors,
@@ -1998,11 +2003,13 @@ where
19982003
Ok(())
19992004
}
20002005

2006+
#[allow(clippy::too_many_arguments)]
20012007
pub async fn get_connector_choice<F, Req, Ctx>(
20022008
operation: &BoxedOperation<'_, F, Req, Ctx>,
20032009
state: &AppState,
20042010
req: &Req,
20052011
merchant_account: &domain::MerchantAccount,
2012+
business_profile: &storage::business_profile::BusinessProfile,
20062013
key_store: &domain::MerchantKeyStore,
20072014
payment_data: &mut PaymentData<F>,
20082015
eligible_connectors: Option<Vec<api_models::enums::RoutableConnectors>>,
@@ -2040,6 +2047,7 @@ where
20402047
connector_selection(
20412048
state,
20422049
merchant_account,
2050+
business_profile,
20432051
key_store,
20442052
payment_data,
20452053
Some(straight_through),
@@ -2052,6 +2060,7 @@ where
20522060
connector_selection(
20532061
state,
20542062
merchant_account,
2063+
business_profile,
20552064
key_store,
20562065
payment_data,
20572066
None,
@@ -2075,6 +2084,7 @@ where
20752084
pub async fn connector_selection<F>(
20762085
state: &AppState,
20772086
merchant_account: &domain::MerchantAccount,
2087+
business_profile: &storage::business_profile::BusinessProfile,
20782088
key_store: &domain::MerchantKeyStore,
20792089
payment_data: &mut PaymentData<F>,
20802090
request_straight_through: Option<serde_json::Value>,
@@ -2114,6 +2124,7 @@ where
21142124
let decided_connector = decide_connector(
21152125
state.clone(),
21162126
merchant_account,
2127+
business_profile,
21172128
key_store,
21182129
payment_data,
21192130
request_straight_through,
@@ -2141,9 +2152,11 @@ where
21412152
Ok(decided_connector)
21422153
}
21432154

2155+
#[allow(clippy::too_many_arguments)]
21442156
pub async fn decide_connector<F>(
21452157
state: AppState,
21462158
merchant_account: &domain::MerchantAccount,
2159+
business_profile: &storage::business_profile::BusinessProfile,
21472160
key_store: &domain::MerchantKeyStore,
21482161
payment_data: &mut PaymentData<F>,
21492162
request_straight_through: Option<api::routing::StraightThroughAlgorithm>,
@@ -2345,6 +2358,7 @@ where
23452358
route_connector_v1(
23462359
&state,
23472360
merchant_account,
2361+
business_profile,
23482362
key_store,
23492363
payment_data,
23502364
routing_data,
@@ -2480,6 +2494,7 @@ where
24802494
pub async fn route_connector_v1<F>(
24812495
state: &AppState,
24822496
merchant_account: &domain::MerchantAccount,
2497+
business_profile: &storage::business_profile::BusinessProfile,
24832498
key_store: &domain::MerchantKeyStore,
24842499
payment_data: &mut PaymentData<F>,
24852500
routing_data: &mut storage::RoutingData,
@@ -2488,44 +2503,19 @@ pub async fn route_connector_v1<F>(
24882503
where
24892504
F: Send + Clone,
24902505
{
2491-
#[cfg(not(feature = "business_profile_routing"))]
2492-
let algorithm_ref: api::routing::RoutingAlgorithmRef = merchant_account
2493-
.routing_algorithm
2494-
.clone()
2495-
.map(|ra| ra.parse_value("RoutingAlgorithmRef"))
2506+
let routing_algorithm = if cfg!(feature = "business_profile_routing") {
2507+
business_profile.routing_algorithm.clone()
2508+
} else {
2509+
merchant_account.routing_algorithm.clone()
2510+
};
2511+
2512+
let algorithm_ref = routing_algorithm
2513+
.map(|ra| ra.parse_value::<api::routing::RoutingAlgorithmRef>("RoutingAlgorithmRef"))
24962514
.transpose()
24972515
.change_context(errors::ApiErrorResponse::InternalServerError)
24982516
.attach_printable("Could not decode merchant routing algorithm ref")?
24992517
.unwrap_or_default();
25002518

2501-
#[cfg(feature = "business_profile_routing")]
2502-
let algorithm_ref: api::routing::RoutingAlgorithmRef = {
2503-
let profile_id = payment_data
2504-
.payment_intent
2505-
.profile_id
2506-
.as_ref()
2507-
.get_required_value("profile_id")
2508-
.change_context(errors::ApiErrorResponse::InternalServerError)
2509-
.attach_printable("'profile_id' not set in payment intent")?;
2510-
2511-
let business_profile = state
2512-
.store
2513-
.find_business_profile_by_profile_id(profile_id)
2514-
.await
2515-
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
2516-
id: profile_id.to_string(),
2517-
})?;
2518-
2519-
business_profile
2520-
.routing_algorithm
2521-
.clone()
2522-
.map(|ra| ra.parse_value("RoutingAlgorithmRef"))
2523-
.transpose()
2524-
.change_context(errors::ApiErrorResponse::InternalServerError)
2525-
.attach_printable("Could not decode merchant routing algorithm ref")?
2526-
.unwrap_or_default()
2527-
};
2528-
25292519
let connectors = routing::perform_static_routing_v1(
25302520
state,
25312521
&merchant_account.merchant_id,

crates/router/src/core/payments/operations.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pub mod payment_capture;
44
pub mod payment_complete_authorize;
55
pub mod payment_confirm;
66
pub mod payment_create;
7-
pub mod payment_method_validate;
87
pub mod payment_reject;
98
pub mod payment_response;
109
pub mod payment_session;
@@ -20,10 +19,9 @@ use router_env::{instrument, tracing};
2019
pub use self::{
2120
payment_approve::PaymentApprove, payment_cancel::PaymentCancel,
2221
payment_capture::PaymentCapture, payment_confirm::PaymentConfirm,
23-
payment_create::PaymentCreate, payment_method_validate::PaymentMethodValidate,
24-
payment_reject::PaymentReject, payment_response::PaymentResponse,
25-
payment_session::PaymentSession, payment_start::PaymentStart, payment_status::PaymentStatus,
26-
payment_update::PaymentUpdate,
22+
payment_create::PaymentCreate, payment_reject::PaymentReject,
23+
payment_response::PaymentResponse, payment_session::PaymentSession,
24+
payment_start::PaymentStart, payment_status::PaymentStatus, payment_update::PaymentUpdate,
2725
};
2826
use super::{helpers, CustomerDetails, PaymentData};
2927
use crate::{
@@ -91,8 +89,15 @@ pub trait ValidateRequest<F, R, Ctx: PaymentMethodRetrieve> {
9189
) -> RouterResult<(BoxedOperation<'b, F, R, Ctx>, ValidateResult<'a>)>;
9290
}
9391

92+
pub struct GetTrackerResponse<'a, F: Clone, R, Ctx> {
93+
pub operation: BoxedOperation<'a, F, R, Ctx>,
94+
pub customer_details: Option<CustomerDetails>,
95+
pub payment_data: PaymentData<F>,
96+
pub business_profile: storage::business_profile::BusinessProfile,
97+
}
98+
9499
#[async_trait]
95-
pub trait GetTracker<F, D, R, Ctx: PaymentMethodRetrieve>: Send {
100+
pub trait GetTracker<F: Clone, D, R, Ctx: PaymentMethodRetrieve>: Send {
96101
#[allow(clippy::too_many_arguments)]
97102
async fn get_trackers<'a>(
98103
&'a self,
@@ -103,7 +108,7 @@ pub trait GetTracker<F, D, R, Ctx: PaymentMethodRetrieve>: Send {
103108
merchant_account: &domain::MerchantAccount,
104109
mechant_key_store: &domain::MerchantKeyStore,
105110
auth_flow: services::AuthFlow,
106-
) -> RouterResult<(BoxedOperation<'a, F, R, Ctx>, D, Option<CustomerDetails>)>;
111+
) -> RouterResult<GetTrackerResponse<'a, F, R, Ctx>>;
107112
}
108113

109114
#[async_trait]

crates/router/src/core/payments/operations/payment_approve.rs

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
4545
merchant_account: &domain::MerchantAccount,
4646
key_store: &domain::MerchantKeyStore,
4747
_auth_flow: services::AuthFlow,
48-
) -> RouterResult<(
49-
BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
50-
PaymentData<F>,
51-
Option<CustomerDetails>,
52-
)> {
48+
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsRequest, Ctx>> {
5349
let db = &*state.store;
5450
let merchant_id = &merchant_account.merchant_id;
5551
let storage_scheme = merchant_account.storage_scheme;
@@ -76,6 +72,21 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
7672
"confirm",
7773
)?;
7874

75+
let profile_id = payment_intent
76+
.profile_id
77+
.as_ref()
78+
.get_required_value("profile_id")
79+
.change_context(errors::ApiErrorResponse::InternalServerError)
80+
.attach_printable("'profile_id' not set in payment intent")?;
81+
82+
let business_profile = state
83+
.store
84+
.find_business_profile_by_profile_id(profile_id)
85+
.await
86+
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
87+
id: profile_id.to_string(),
88+
})?;
89+
7990
let (
8091
token,
8192
payment_method,
@@ -207,50 +218,57 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
207218
format!("Error while retrieving frm_response, merchant_id: {}, payment_id: {attempt_id}", &merchant_account.merchant_id)
208219
});
209220

210-
Ok((
211-
Box::new(self),
212-
PaymentData {
213-
flow: PhantomData,
214-
payment_intent,
215-
payment_attempt,
216-
currency,
217-
amount,
218-
email: request.email.clone(),
219-
mandate_id: None,
220-
mandate_connector,
221-
setup_mandate,
222-
token,
223-
address: PaymentAddress {
224-
shipping: shipping_address.as_ref().map(|a| a.into()),
225-
billing: billing_address.as_ref().map(|a| a.into()),
226-
},
227-
confirm: request.confirm,
228-
payment_method_data: request.payment_method_data.clone(),
229-
force_sync: None,
230-
refunds: vec![],
231-
disputes: vec![],
232-
attempts: None,
233-
sessions_token: vec![],
234-
card_cvc: request.card_cvc.clone(),
235-
creds_identifier: None,
236-
pm_token: None,
237-
connector_customer_id: None,
238-
recurring_mandate_payment_data,
239-
ephemeral_key: None,
240-
multiple_capture_data: None,
241-
redirect_response,
242-
surcharge_details: None,
243-
frm_message: frm_response.ok(),
244-
payment_link_data: None,
221+
let payment_data = PaymentData {
222+
flow: PhantomData,
223+
payment_intent,
224+
payment_attempt,
225+
currency,
226+
amount,
227+
email: request.email.clone(),
228+
mandate_id: None,
229+
mandate_connector,
230+
setup_mandate,
231+
token,
232+
address: PaymentAddress {
233+
shipping: shipping_address.as_ref().map(|a| a.into()),
234+
billing: billing_address.as_ref().map(|a| a.into()),
245235
},
246-
Some(CustomerDetails {
247-
customer_id: request.customer_id.clone(),
248-
name: request.name.clone(),
249-
email: request.email.clone(),
250-
phone: request.phone.clone(),
251-
phone_country_code: request.phone_country_code.clone(),
252-
}),
253-
))
236+
confirm: request.confirm,
237+
payment_method_data: request.payment_method_data.clone(),
238+
force_sync: None,
239+
refunds: vec![],
240+
disputes: vec![],
241+
attempts: None,
242+
sessions_token: vec![],
243+
card_cvc: request.card_cvc.clone(),
244+
creds_identifier: None,
245+
pm_token: None,
246+
connector_customer_id: None,
247+
recurring_mandate_payment_data,
248+
ephemeral_key: None,
249+
multiple_capture_data: None,
250+
redirect_response,
251+
surcharge_details: None,
252+
frm_message: frm_response.ok(),
253+
payment_link_data: None,
254+
};
255+
256+
let customer_details = Some(CustomerDetails {
257+
customer_id: request.customer_id.clone(),
258+
name: request.name.clone(),
259+
email: request.email.clone(),
260+
phone: request.phone.clone(),
261+
phone_country_code: request.phone_country_code.clone(),
262+
});
263+
264+
let get_trackers_response = operations::GetTrackerResponse {
265+
operation: Box::new(self),
266+
customer_details,
267+
payment_data,
268+
business_profile,
269+
};
270+
271+
Ok(get_trackers_response)
254272
}
255273
}
256274

0 commit comments

Comments
 (0)