mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
refactor(core): query business profile only once (#2830)
This commit is contained in:
@ -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},
|
||||
@ -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,
|
||||
@ -142,6 +146,7 @@ where
|
||||
state,
|
||||
&req,
|
||||
&merchant_account,
|
||||
&business_profile,
|
||||
&key_store,
|
||||
&mut payment_data,
|
||||
eligible_connectors,
|
||||
@ -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>>,
|
||||
@ -2040,6 +2047,7 @@ where
|
||||
connector_selection(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
payment_data,
|
||||
Some(straight_through),
|
||||
@ -2052,6 +2060,7 @@ where
|
||||
connector_selection(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
payment_data,
|
||||
None,
|
||||
@ -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>,
|
||||
@ -2114,6 +2124,7 @@ where
|
||||
let decided_connector = decide_connector(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
payment_data,
|
||||
request_straight_through,
|
||||
@ -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>,
|
||||
@ -2345,6 +2358,7 @@ where
|
||||
route_connector_v1(
|
||||
&state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
payment_data,
|
||||
routing_data,
|
||||
@ -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,
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
@ -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::{
|
||||
@ -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,
|
||||
@ -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]
|
||||
|
||||
@ -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;
|
||||
@ -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,
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payment_methods::PaymentMethodRetrieve,
|
||||
payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{helpers, operations, PaymentAddress, PaymentData},
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
@ -42,11 +42,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_auth_flow: services::AuthFlow,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCancelRequest, Ctx>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsCancelRequest, Ctx>> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
@ -128,45 +124,63 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
.await
|
||||
.transpose()?;
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
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")?;
|
||||
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
let business_profile = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
None,
|
||||
))
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(self),
|
||||
customer_details: None,
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,11 +41,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_auth_flow: services::AuthFlow,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCaptureRequest, Ctx>,
|
||||
payments::PaymentData<F>,
|
||||
Option<payments::CustomerDetails>,
|
||||
)> {
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsCaptureRequest, Ctx>> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
@ -172,44 +168,63 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
.await
|
||||
.transpose()?;
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
payments::PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
force_sync: None,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: payments::PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let payment_data = payments::PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
force_sync: None,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: payments::PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
None,
|
||||
))
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(self),
|
||||
customer_details: None,
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,11 +44,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;
|
||||
@ -202,50 +198,71 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
// The operation merges mandate data from both request and payment_attempt
|
||||
let setup_mandate = setup_mandate.map(Into::into);
|
||||
|
||||
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: None,
|
||||
payment_link_data: None,
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
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: None,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -50,11 +50,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;
|
||||
@ -65,7 +61,6 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
// Stage 1
|
||||
|
||||
let store = state.clone().store;
|
||||
let m_merchant_id = merchant_id.clone();
|
||||
let payment_intent_fut = tokio::spawn(
|
||||
@ -137,8 +132,29 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
let customer_details = helpers::get_customer_details_from_request(request);
|
||||
|
||||
// Stage 2
|
||||
|
||||
let attempt_id = payment_intent.active_attempt.get_id();
|
||||
let profile_id = payment_intent
|
||||
.profile_id
|
||||
.clone()
|
||||
.get_required_value("profile_id")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("'profile_id' not set in payment intent")?;
|
||||
|
||||
let store = state.store.clone();
|
||||
|
||||
let business_profile_fut = tokio::spawn(async move {
|
||||
store
|
||||
.find_business_profile_by_profile_id(&profile_id)
|
||||
.map(|business_profile_result| {
|
||||
business_profile_result.to_not_found_response(
|
||||
errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.await
|
||||
});
|
||||
|
||||
let store = state.clone().store;
|
||||
let m_payment_id = payment_intent.payment_id.clone();
|
||||
let m_merchant_id = merchant_id.clone();
|
||||
@ -235,48 +251,72 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
.in_current_span(),
|
||||
);
|
||||
|
||||
let (mut payment_attempt, shipping_address, billing_address) = match payment_intent.status {
|
||||
api_models::enums::IntentStatus::RequiresCustomerAction
|
||||
| api_models::enums::IntentStatus::RequiresMerchantAction
|
||||
| api_models::enums::IntentStatus::RequiresPaymentMethod
|
||||
| api_models::enums::IntentStatus::RequiresConfirmation => {
|
||||
let (payment_attempt, shipping_address, billing_address, _) = tokio::try_join!(
|
||||
utils::flatten_join_error(payment_attempt_fut),
|
||||
utils::flatten_join_error(shipping_address_fut),
|
||||
utils::flatten_join_error(billing_address_fut),
|
||||
utils::flatten_join_error(config_update_fut)
|
||||
)?;
|
||||
// Based on whether a retry can be performed or not, fetch relevant entities
|
||||
let (mut payment_attempt, shipping_address, billing_address, business_profile) =
|
||||
match payment_intent.status {
|
||||
api_models::enums::IntentStatus::RequiresCustomerAction
|
||||
| api_models::enums::IntentStatus::RequiresMerchantAction
|
||||
| api_models::enums::IntentStatus::RequiresPaymentMethod
|
||||
| api_models::enums::IntentStatus::RequiresConfirmation => {
|
||||
// Normal payment
|
||||
let (payment_attempt, shipping_address, billing_address, business_profile, _) =
|
||||
tokio::try_join!(
|
||||
utils::flatten_join_error(payment_attempt_fut),
|
||||
utils::flatten_join_error(shipping_address_fut),
|
||||
utils::flatten_join_error(billing_address_fut),
|
||||
utils::flatten_join_error(business_profile_fut),
|
||||
utils::flatten_join_error(config_update_fut)
|
||||
)?;
|
||||
|
||||
(payment_attempt, shipping_address, billing_address)
|
||||
}
|
||||
_ => {
|
||||
let (mut payment_attempt, shipping_address, billing_address, _) = tokio::try_join!(
|
||||
utils::flatten_join_error(payment_attempt_fut),
|
||||
utils::flatten_join_error(shipping_address_fut),
|
||||
utils::flatten_join_error(billing_address_fut),
|
||||
utils::flatten_join_error(config_update_fut)
|
||||
)?;
|
||||
|
||||
let attempt_type = helpers::get_attempt_type(
|
||||
&payment_intent,
|
||||
&payment_attempt,
|
||||
request,
|
||||
"confirm",
|
||||
)?;
|
||||
|
||||
(payment_intent, payment_attempt) = attempt_type
|
||||
.modify_payment_intent_and_payment_attempt(
|
||||
request,
|
||||
payment_intent,
|
||||
(
|
||||
payment_attempt,
|
||||
&*state.store,
|
||||
storage_scheme,
|
||||
shipping_address,
|
||||
billing_address,
|
||||
business_profile,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
_ => {
|
||||
// Retry payment
|
||||
let (
|
||||
mut payment_attempt,
|
||||
shipping_address,
|
||||
billing_address,
|
||||
business_profile,
|
||||
_,
|
||||
) = tokio::try_join!(
|
||||
utils::flatten_join_error(payment_attempt_fut),
|
||||
utils::flatten_join_error(shipping_address_fut),
|
||||
utils::flatten_join_error(billing_address_fut),
|
||||
utils::flatten_join_error(business_profile_fut),
|
||||
utils::flatten_join_error(config_update_fut)
|
||||
)?;
|
||||
|
||||
(payment_attempt, shipping_address, billing_address)
|
||||
}
|
||||
};
|
||||
let attempt_type = helpers::get_attempt_type(
|
||||
&payment_intent,
|
||||
&payment_attempt,
|
||||
request,
|
||||
"confirm",
|
||||
)?;
|
||||
|
||||
// 3
|
||||
(payment_intent, payment_attempt) = attempt_type
|
||||
.modify_payment_intent_and_payment_attempt(
|
||||
request,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
&*state.store,
|
||||
storage_scheme,
|
||||
)
|
||||
.await?;
|
||||
|
||||
(
|
||||
payment_attempt,
|
||||
shipping_address,
|
||||
billing_address,
|
||||
business_profile,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
payment_intent.order_details = request
|
||||
.get_order_details_as_value()
|
||||
@ -382,6 +422,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
sm.mandate_type = payment_attempt.mandate_details.clone().or(sm.mandate_type);
|
||||
sm
|
||||
});
|
||||
|
||||
Self::validate_request_surcharge_details_with_session_surcharge_details(
|
||||
state,
|
||||
&payment_attempt,
|
||||
@ -394,44 +435,49 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
&payment_attempt,
|
||||
);
|
||||
|
||||
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,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details,
|
||||
frm_message: None,
|
||||
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(customer_details),
|
||||
))
|
||||
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,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(self),
|
||||
customer_details: Some(customer_details),
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,11 +53,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
merchant_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 ephemeral_key = Self::get_ephemeral_key(request, state, merchant_account).await;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
@ -196,6 +192,20 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
payment_id: payment_id.clone(),
|
||||
})?;
|
||||
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let mandate_id = request
|
||||
.mandate_id
|
||||
.as_ref()
|
||||
@ -246,6 +256,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
request.confirm,
|
||||
self,
|
||||
);
|
||||
|
||||
let creds_identifier = request
|
||||
.merchant_connector_details
|
||||
.as_ref()
|
||||
@ -265,9 +276,8 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
.transpose()?;
|
||||
|
||||
// The operation merges mandate data from both request and payment_attempt
|
||||
let setup_mandate: Option<MandateData> = setup_mandate.map(Into::into);
|
||||
let setup_mandate = setup_mandate.map(MandateData::from);
|
||||
|
||||
// populate payment_data.surcharge_details from request
|
||||
let surcharge_details = request.surcharge_details.map(|surcharge_details| {
|
||||
payment_methods::SurchargeDetailsResponse {
|
||||
surcharge: payment_methods::Surcharge::Fixed(surcharge_details.surcharge_amount),
|
||||
@ -280,44 +290,49 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
}
|
||||
});
|
||||
|
||||
Ok((
|
||||
operation,
|
||||
PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: request.email.clone(),
|
||||
mandate_id,
|
||||
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(),
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
force_sync: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: request.card_cvc.clone(),
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data,
|
||||
ephemeral_key,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details,
|
||||
frm_message: None,
|
||||
payment_link_data,
|
||||
let payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: request.email.clone(),
|
||||
mandate_id,
|
||||
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(customer_details),
|
||||
))
|
||||
confirm: request.confirm,
|
||||
payment_method_data: request.payment_method_data.clone(),
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
force_sync: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: request.card_cvc.clone(),
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data,
|
||||
ephemeral_key,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details,
|
||||
frm_message: None,
|
||||
payment_link_data,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation,
|
||||
customer_details: Some(customer_details),
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payment_methods::PaymentMethodRetrieve,
|
||||
payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{helpers, operations, PaymentAddress, PaymentData},
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
@ -41,11 +41,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_auth_flow: services::AuthFlow,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, PaymentsRejectRequest, Ctx>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, PaymentsRejectRequest, Ctx>> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
@ -114,45 +110,64 @@ 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: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
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")?;
|
||||
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier: None,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: frm_response.ok(),
|
||||
payment_link_data: None,
|
||||
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 payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
None,
|
||||
))
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier: None,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: frm_response.ok(),
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(self),
|
||||
customer_details: None,
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -43,11 +43,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_auth_flow: services::AuthFlow,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsSessionRequest, Ctx>,
|
||||
PaymentData<F>,
|
||||
Option<payments::CustomerDetails>,
|
||||
)> {
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsSessionRequest, Ctx>> {
|
||||
let payment_id = payment_id
|
||||
.get_payment_intent_id()
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
@ -152,44 +148,63 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
.await
|
||||
.transpose()?;
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
token: None,
|
||||
setup_mandate: None,
|
||||
address: payments::PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
token: None,
|
||||
setup_mandate: None,
|
||||
address: payments::PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
Some(customer_details),
|
||||
))
|
||||
confirm: None,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(self),
|
||||
customer_details: Some(customer_details),
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,11 +42,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
mechant_key_store: &domain::MerchantKeyStore,
|
||||
_auth_flow: services::AuthFlow,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsStartRequest, Ctx>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsStartRequest, Ctx>> {
|
||||
let (mut payment_intent, payment_attempt, currency, amount);
|
||||
let db = &*state.store;
|
||||
|
||||
@ -126,44 +122,63 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
..CustomerDetails::default()
|
||||
};
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: payment_attempt.payment_token.clone(),
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
confirm: Some(payment_attempt.confirm),
|
||||
payment_attempt,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier: None,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: None,
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: payment_attempt.payment_token.clone(),
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
Some(customer_details),
|
||||
))
|
||||
confirm: Some(payment_attempt.confirm),
|
||||
payment_attempt,
|
||||
payment_method_data: None,
|
||||
force_sync: None,
|
||||
refunds: vec![],
|
||||
disputes: vec![],
|
||||
attempts: None,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier: None,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details: None,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(self),
|
||||
customer_details: Some(customer_details),
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -190,11 +190,8 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_auth_flow: services::AuthFlow,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRetrieveRequest, Ctx>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsRetrieveRequest, Ctx>>
|
||||
{
|
||||
get_tracker_for_sync(
|
||||
payment_id,
|
||||
merchant_account,
|
||||
@ -221,12 +218,8 @@ async fn get_tracker_for_sync<
|
||||
request: &api::PaymentsRetrieveRequest,
|
||||
operation: Op,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRetrieveRequest, Ctx>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
let (payment_intent, mut payment_attempt, currency, amount);
|
||||
) -> RouterResult<operations::GetTrackerResponse<'a, F, api::PaymentsRetrieveRequest, Ctx>> {
|
||||
let (payment_intent, payment_attempt, currency, amount);
|
||||
|
||||
(payment_intent, payment_attempt) = get_payment_intent_payment_attempt(
|
||||
db,
|
||||
@ -250,7 +243,6 @@ async fn get_tracker_for_sync<
|
||||
|
||||
let payment_id_str = payment_attempt.payment_id.clone();
|
||||
|
||||
payment_attempt.encoded_data = request.param.clone();
|
||||
currency = payment_attempt.currency.get_required_value("currency")?;
|
||||
amount = payment_attempt.amount.into();
|
||||
|
||||
@ -357,53 +349,74 @@ async fn get_tracker_for_sync<
|
||||
})
|
||||
.await
|
||||
.transpose()?;
|
||||
Ok((
|
||||
Box::new(operation),
|
||||
PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: payment_attempt.mandate_id.clone().map(|id| {
|
||||
api_models::payments::MandateIds {
|
||||
mandate_id: id,
|
||||
mandate_reference_id: None,
|
||||
}
|
||||
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
currency,
|
||||
amount,
|
||||
email: None,
|
||||
mandate_id: payment_attempt
|
||||
.mandate_id
|
||||
.clone()
|
||||
.map(|id| api_models::payments::MandateIds {
|
||||
mandate_id: id,
|
||||
mandate_reference_id: None,
|
||||
}),
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
confirm: Some(request.force_sync),
|
||||
payment_method_data: None,
|
||||
force_sync: Some(
|
||||
request.force_sync
|
||||
&& (helpers::check_force_psync_precondition(&payment_attempt.status)
|
||||
|| contains_encoded_data),
|
||||
),
|
||||
payment_attempt,
|
||||
refunds,
|
||||
disputes,
|
||||
attempts,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data,
|
||||
redirect_response: None,
|
||||
payment_link_data: None,
|
||||
surcharge_details: None,
|
||||
frm_message: frm_response.ok(),
|
||||
mandate_connector: None,
|
||||
setup_mandate: None,
|
||||
token: None,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
None,
|
||||
))
|
||||
confirm: Some(request.force_sync),
|
||||
payment_method_data: None,
|
||||
force_sync: Some(
|
||||
request.force_sync
|
||||
&& (helpers::check_force_psync_precondition(&payment_attempt.status)
|
||||
|| contains_encoded_data),
|
||||
),
|
||||
payment_attempt,
|
||||
refunds,
|
||||
disputes,
|
||||
attempts,
|
||||
sessions_token: vec![],
|
||||
card_cvc: None,
|
||||
creds_identifier,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data,
|
||||
redirect_response: None,
|
||||
payment_link_data: None,
|
||||
surcharge_details: None,
|
||||
frm_message: frm_response.ok(),
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: Box::new(operation),
|
||||
customer_details: None,
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
|
||||
impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
|
||||
@ -44,11 +44,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 (mut payment_intent, mut payment_attempt, currency): (_, _, storage_enums::Currency);
|
||||
|
||||
let payment_id = payment_id
|
||||
@ -304,48 +300,67 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
// The operation merges mandate data from both request and payment_attempt
|
||||
let setup_mandate = setup_mandate.map(Into::into);
|
||||
|
||||
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 = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let surcharge_details = request.surcharge_details.map(|request_surcharge_details| {
|
||||
request_surcharge_details.get_surcharge_details_object(payment_attempt.amount)
|
||||
});
|
||||
|
||||
Ok((
|
||||
next_operation,
|
||||
PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: request.email.clone(),
|
||||
mandate_id,
|
||||
mandate_connector,
|
||||
token,
|
||||
setup_mandate,
|
||||
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,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
let payment_data = PaymentData {
|
||||
flow: PhantomData,
|
||||
payment_intent,
|
||||
payment_attempt,
|
||||
currency,
|
||||
amount,
|
||||
email: request.email.clone(),
|
||||
mandate_id,
|
||||
mandate_connector,
|
||||
token,
|
||||
setup_mandate,
|
||||
address: PaymentAddress {
|
||||
shipping: shipping_address.as_ref().map(|a| a.into()),
|
||||
billing: billing_address.as_ref().map(|a| a.into()),
|
||||
},
|
||||
Some(customer_details),
|
||||
))
|
||||
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,
|
||||
pm_token: None,
|
||||
connector_customer_id: None,
|
||||
recurring_mandate_payment_data,
|
||||
ephemeral_key: None,
|
||||
multiple_capture_data: None,
|
||||
redirect_response: None,
|
||||
surcharge_details,
|
||||
frm_message: None,
|
||||
payment_link_data: None,
|
||||
};
|
||||
|
||||
let get_trackers_response = operations::GetTrackerResponse {
|
||||
operation: next_operation,
|
||||
customer_details: Some(customer_details),
|
||||
payment_data,
|
||||
business_profile,
|
||||
};
|
||||
|
||||
Ok(get_trackers_response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user