refactor: Add a GAT Data to Operation trait (#5825)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Arun Raj M
2024-09-11 10:55:01 +05:30
committed by GitHub
parent 022508544f
commit 418ea4e2c6
55 changed files with 1946 additions and 1237 deletions

View File

@ -10,26 +10,23 @@ use super::{
FrmData,
};
use crate::{
core::{
errors::{self, RouterResult},
payments,
},
core::errors::{self, RouterResult},
routes::{app::ReqState, SessionState},
types::{domain, fraud_check::FrmRouterData},
};
pub type BoxedFraudCheckOperation<F> = Box<dyn FraudCheckOperation<F> + Send + Sync>;
pub type BoxedFraudCheckOperation<F, D> = Box<dyn FraudCheckOperation<F, D> + Send + Sync>;
pub trait FraudCheckOperation<F>: Send + std::fmt::Debug {
pub trait FraudCheckOperation<F, D>: Send + std::fmt::Debug {
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<PaymentToFrmData> + Send + Sync)> {
Err(report!(errors::ApiErrorResponse::InternalServerError))
.attach_printable_lazy(|| format!("get tracker interface not found for {self:?}"))
}
fn to_domain(&self) -> RouterResult<&(dyn Domain<F>)> {
fn to_domain(&self) -> RouterResult<&(dyn Domain<F, D>)> {
Err(report!(errors::ApiErrorResponse::InternalServerError))
.attach_printable_lazy(|| format!("domain interface not found for {self:?}"))
}
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F> + Send + Sync)> {
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F, D> + Send + Sync)> {
Err(report!(errors::ApiErrorResponse::InternalServerError))
.attach_printable_lazy(|| format!("get tracker interface not found for {self:?}"))
}
@ -47,12 +44,12 @@ pub trait GetTracker<D>: Send {
#[async_trait]
#[allow(clippy::too_many_arguments)]
pub trait Domain<F>: Send + Sync {
pub trait Domain<F, D>: Send + Sync {
async fn post_payment_frm<'a>(
&'a self,
state: &'a SessionState,
req_state: ReqState,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_data: &mut FrmData,
merchant_account: &domain::MerchantAccount,
customer: &Option<domain::Customer>,
@ -64,7 +61,7 @@ pub trait Domain<F>: Send + Sync {
async fn pre_payment_frm<'a>(
&'a self,
state: &'a SessionState,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_data: &mut FrmData,
merchant_account: &domain::MerchantAccount,
customer: &Option<domain::Customer>,
@ -85,7 +82,7 @@ pub trait Domain<F>: Send + Sync {
_frm_configs: FrmConfigsObject,
_frm_suggestion: &mut Option<FrmSuggestion>,
_key_store: domain::MerchantKeyStore,
_payment_data: &mut payments::PaymentData<F>,
_payment_data: &mut D,
_customer: &Option<domain::Customer>,
_should_continue_capture: &mut bool,
) -> RouterResult<Option<FrmData>>
@ -97,14 +94,14 @@ pub trait Domain<F>: Send + Sync {
}
#[async_trait]
pub trait UpdateTracker<D, F: Clone>: Send {
pub trait UpdateTracker<Fd, F: Clone, D>: Send {
async fn update_tracker<'b>(
&'b self,
state: &SessionState,
key_store: &domain::MerchantKeyStore,
frm_data: D,
payment_data: &mut payments::PaymentData<F>,
frm_data: Fd,
payment_data: &mut D,
_frm_suggestion: Option<FrmSuggestion>,
frm_router_data: FrmRouterData,
) -> RouterResult<D>;
) -> RouterResult<Fd>;
}

View File

@ -43,26 +43,42 @@ use crate::{
#[derive(Debug, Clone, Copy)]
pub struct FraudCheckPost;
impl<F: Clone + Send> FraudCheckOperation<F> for &FraudCheckPost {
impl<F, D> FraudCheckOperation<F, D> for &FraudCheckPost
where
F: Clone + Send,
D: payments::OperationSessionGetters<F>
+ payments::OperationSessionSetters<F>
+ Send
+ Sync
+ Clone,
{
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<PaymentToFrmData> + Send + Sync)> {
Ok(*self)
}
fn to_domain(&self) -> RouterResult<&(dyn Domain<F>)> {
fn to_domain(&self) -> RouterResult<&(dyn Domain<F, D>)> {
Ok(*self)
}
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F> + Send + Sync)> {
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F, D> + Send + Sync)> {
Ok(*self)
}
}
impl<F: Clone + Send> FraudCheckOperation<F> for FraudCheckPost {
impl<F, D> FraudCheckOperation<F, D> for FraudCheckPost
where
F: Clone + Send,
D: payments::OperationSessionGetters<F>
+ payments::OperationSessionSetters<F>
+ Send
+ Sync
+ Clone,
{
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<PaymentToFrmData> + Send + Sync)> {
Ok(self)
}
fn to_domain(&self) -> RouterResult<&(dyn Domain<F>)> {
fn to_domain(&self) -> RouterResult<&(dyn Domain<F, D>)> {
Ok(self)
}
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F> + Send + Sync)> {
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F, D> + Send + Sync)> {
Ok(self)
}
}
@ -137,13 +153,21 @@ impl GetTracker<PaymentToFrmData> for FraudCheckPost {
}
#[async_trait]
impl<F: Send + Clone> Domain<F> for FraudCheckPost {
impl<F, D> Domain<F, D> for FraudCheckPost
where
F: Clone + Send,
D: payments::OperationSessionGetters<F>
+ payments::OperationSessionSetters<F>
+ Send
+ Sync
+ Clone,
{
#[instrument(skip_all)]
async fn post_payment_frm<'a>(
&'a self,
state: &'a SessionState,
_req_state: ReqState,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_data: &mut FrmData,
merchant_account: &domain::MerchantAccount,
customer: &Option<domain::Customer>,
@ -153,7 +177,7 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
logger::debug!("post_flow::Sale Skipped");
return Ok(None);
}
let router_data = frm_core::call_frm_service::<F, frm_api::Sale, _>(
let router_data = frm_core::call_frm_service::<F, frm_api::Sale, _, D>(
state,
payment_data,
&mut frm_data.to_owned(),
@ -188,7 +212,7 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
_frm_configs: FrmConfigsObject,
frm_suggestion: &mut Option<FrmSuggestion>,
key_store: domain::MerchantKeyStore,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
customer: &Option<domain::Customer>,
_should_continue_capture: &mut bool,
) -> RouterResult<Option<FrmData>> {
@ -211,6 +235,7 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
_,
_,
_,
payments::PaymentData<Void>,
>(
state.clone(),
req_state.clone(),
@ -225,13 +250,13 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
HeaderPayload::default(),
))
.await?;
logger::debug!("payment_id : {:?} has been cancelled since it has been found fraudulent by configured frm connector",payment_data.payment_attempt.payment_id);
logger::debug!("payment_id : {:?} has been cancelled since it has been found fraudulent by configured frm connector",payment_data.get_payment_attempt().payment_id);
if let services::ApplicationResponse::JsonWithHeaders((payments_response, _)) =
cancel_res
{
payment_data.payment_intent.status = payments_response.status;
payment_data.set_payment_intent_status(payments_response.status);
}
let _router_data = frm_core::call_frm_service::<F, frm_api::RecordReturn, _>(
let _router_data = frm_core::call_frm_service::<F, frm_api::RecordReturn, _, D>(
state,
payment_data,
&mut frm_data.to_owned(),
@ -267,6 +292,7 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
_,
_,
_,
payments::PaymentData<Capture>,
>(
state.clone(),
req_state.clone(),
@ -281,11 +307,11 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
HeaderPayload::default(),
))
.await?;
logger::debug!("payment_id : {:?} has been captured since it has been found legit by configured frm connector",payment_data.payment_attempt.payment_id);
logger::debug!("payment_id : {:?} has been captured since it has been found legit by configured frm connector",payment_data.get_payment_attempt().payment_id);
if let services::ApplicationResponse::JsonWithHeaders((payments_response, _)) =
capture_response
{
payment_data.payment_intent.status = payments_response.status;
payment_data.set_payment_intent_status(payments_response.status);
}
};
return Ok(Some(frm_data.to_owned()));
@ -295,13 +321,13 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
async fn pre_payment_frm<'a>(
&'a self,
state: &'a SessionState,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_data: &mut FrmData,
merchant_account: &domain::MerchantAccount,
customer: &Option<domain::Customer>,
key_store: domain::MerchantKeyStore,
) -> RouterResult<FrmRouterData> {
let router_data = frm_core::call_frm_service::<F, frm_api::Sale, _>(
let router_data = frm_core::call_frm_service::<F, frm_api::Sale, _, D>(
state,
payment_data,
&mut frm_data.to_owned(),
@ -327,13 +353,21 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
}
#[async_trait]
impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPost {
impl<F, D> UpdateTracker<FrmData, F, D> for FraudCheckPost
where
F: Clone + Send,
D: payments::OperationSessionGetters<F>
+ payments::OperationSessionSetters<F>
+ Send
+ Sync
+ Clone,
{
async fn update_tracker<'b>(
&'b self,
state: &SessionState,
key_store: &domain::MerchantKeyStore,
mut frm_data: FrmData,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_suggestion: Option<FrmSuggestion>,
frm_router_data: FrmRouterData,
) -> RouterResult<FrmData> {
@ -501,9 +535,10 @@ impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPost {
None,
),
};
payment_data.payment_attempt = db
let payment_attempt = db
.update_payment_attempt_with_attempt_id(
payment_data.payment_attempt.clone(),
payment_data.get_payment_attempt().clone(),
PaymentAttemptUpdate::RejectUpdate {
status: payment_attempt_status,
error_code: Some(Some(frm_data.fraud_check.frm_status.to_string())),
@ -515,10 +550,12 @@ impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPost {
.await
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
payment_data.payment_intent = db
payment_data.set_payment_attempt(payment_attempt);
let payment_intent = db
.update_payment_intent(
&state.into(),
payment_data.payment_intent.clone(),
payment_data.get_payment_intent().clone(),
PaymentIntentUpdate::RejectUpdate {
status: payment_intent_status,
merchant_decision,
@ -529,6 +566,8 @@ impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPost {
)
.await
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
payment_data.set_payment_intent(payment_intent);
}
frm_data.fraud_check = match frm_check_update {
Some(fraud_check_update) => db

View File

@ -37,26 +37,34 @@ use crate::{
#[derive(Debug, Clone, Copy)]
pub struct FraudCheckPre;
impl<F: Clone + Send> FraudCheckOperation<F> for &FraudCheckPre {
impl<F, D> FraudCheckOperation<F, D> for &FraudCheckPre
where
F: Clone + Send,
D: payments::OperationSessionGetters<F> + Send + Sync + Clone,
{
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<PaymentToFrmData> + Send + Sync)> {
Ok(*self)
}
fn to_domain(&self) -> RouterResult<&(dyn Domain<F>)> {
fn to_domain(&self) -> RouterResult<&(dyn Domain<F, D>)> {
Ok(*self)
}
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F> + Send + Sync)> {
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F, D> + Send + Sync)> {
Ok(*self)
}
}
impl<F: Clone + Send> FraudCheckOperation<F> for FraudCheckPre {
impl<F, D> FraudCheckOperation<F, D> for FraudCheckPre
where
F: Clone + Send,
D: payments::OperationSessionGetters<F> + Send + Sync + Clone,
{
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<PaymentToFrmData> + Send + Sync)> {
Ok(self)
}
fn to_domain(&self) -> RouterResult<&(dyn Domain<F>)> {
fn to_domain(&self) -> RouterResult<&(dyn Domain<F, D>)> {
Ok(self)
}
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F> + Send + Sync)> {
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<FrmData, F, D> + Send + Sync)> {
Ok(self)
}
}
@ -134,14 +142,18 @@ impl GetTracker<PaymentToFrmData> for FraudCheckPre {
}
#[async_trait]
impl<F: Send + Clone> Domain<F> for FraudCheckPre {
impl<F, D> Domain<F, D> for FraudCheckPre
where
F: Clone + Send,
D: payments::OperationSessionGetters<F> + Send + Sync + Clone,
{
#[cfg(all(feature = "v2", feature = "customer_v2"))]
#[instrument(skip_all)]
async fn post_payment_frm<'a>(
&'a self,
_state: &'a SessionState,
_req_state: ReqState,
_payment_data: &mut payments::PaymentData<F>,
_payment_data: &mut D,
_frm_data: &mut FrmData,
_merchant_account: &domain::MerchantAccount,
_customer: &Option<domain::Customer>,
@ -156,13 +168,13 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPre {
&'a self,
state: &'a SessionState,
_req_state: ReqState,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_data: &mut FrmData,
merchant_account: &domain::MerchantAccount,
customer: &Option<domain::Customer>,
key_store: domain::MerchantKeyStore,
) -> RouterResult<Option<FrmRouterData>> {
let router_data = frm_core::call_frm_service::<F, frm_api::Transaction, _>(
let router_data = frm_core::call_frm_service::<F, frm_api::Transaction, _, D>(
state,
payment_data,
&mut frm_data.to_owned(),
@ -194,13 +206,13 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPre {
async fn pre_payment_frm<'a>(
&'a self,
state: &'a SessionState,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
frm_data: &mut FrmData,
merchant_account: &domain::MerchantAccount,
customer: &Option<domain::Customer>,
key_store: domain::MerchantKeyStore,
) -> RouterResult<FrmRouterData> {
let router_data = frm_core::call_frm_service::<F, frm_api::Checkout, _>(
let router_data = frm_core::call_frm_service::<F, frm_api::Checkout, _, D>(
state,
payment_data,
&mut frm_data.to_owned(),
@ -230,13 +242,17 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPre {
}
#[async_trait]
impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPre {
impl<F, D> UpdateTracker<FrmData, F, D> for FraudCheckPre
where
F: Clone + Send,
D: payments::OperationSessionGetters<F> + Send + Sync + Clone,
{
async fn update_tracker<'b>(
&'b self,
state: &SessionState,
_key_store: &domain::MerchantKeyStore,
mut frm_data: FrmData,
payment_data: &mut payments::PaymentData<F>,
payment_data: &mut D,
_frm_suggestion: Option<FrmSuggestion>,
frm_router_data: FrmRouterData,
) -> RouterResult<FrmData> {
@ -309,7 +325,7 @@ impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPre {
};
let frm_status = payment_data
.frm_message
.get_frm_message()
.as_ref()
.map_or(status, |frm_data| frm_data.frm_status);

View File

@ -60,8 +60,8 @@ pub struct FrmData {
}
#[derive(Debug)]
pub struct FrmInfo<F> {
pub fraud_check_operation: BoxedFraudCheckOperation<F>,
pub struct FrmInfo<F, D> {
pub fraud_check_operation: BoxedFraudCheckOperation<F, D>,
pub frm_data: Option<FrmData>,
pub suggested_action: Option<FrmSuggestion>,
}