Call multiple connectors (#90)

This commit is contained in:
Narayan Bhat
2022-12-09 22:49:55 +05:30
committed by GitHub
parent 0e105db216
commit 091d5af42a
18 changed files with 153 additions and 151 deletions

View File

@ -25,6 +25,7 @@ use crate::{
payments, payments,
}, },
db::StorageInterface, db::StorageInterface,
logger,
pii::Email, pii::Email,
routes::AppState, routes::AppState,
scheduler::utils as pt_utils, scheduler::utils as pt_utils,
@ -296,16 +297,17 @@ where
let router_data = payment_data let router_data = payment_data
.construct_router_data(state, connector.connector.id(), merchant_account) .construct_router_data(state, connector.connector.id(), merchant_account)
.await?; .await?;
let (res, payment_data) = router_data
let res = router_data
.decide_flows( .decide_flows(
state, state,
connector, connector,
customer, customer,
payment_data,
call_connector_action, call_connector_action,
merchant_account.storage_scheme, merchant_account.storage_scheme,
) )
.await; .await;
let response = helpers::amap(res, |response| async { let response = helpers::amap(res, |response| async {
let operation = helpers::response_operation::<F, Req>(); let operation = helpers::response_operation::<F, Req>();
let payment_data = operation let payment_data = operation
@ -329,6 +331,84 @@ where
Ok(response) Ok(response)
} }
#[allow(dead_code)]
async fn call_multiple_connectors_service<F, Op, Req>(
state: &AppState,
merchant_account: &storage::MerchantAccount,
connectors: Vec<api::ConnectorData>,
_operation: &Op,
mut payment_data: PaymentData<F>,
customer: &Option<storage::Customer>,
) -> RouterResult<PaymentData<F>>
where
Op: Debug,
F: Send + Clone,
// To create connector flow specific interface data
PaymentData<F>: ConstructFlowSpecificData<F, Req, types::PaymentsResponseData>,
types::RouterData<F, Req, types::PaymentsResponseData>: Feature<F, Req>,
// To construct connector flow specific api
dyn api::Connector: services::api::ConnectorIntegration<F, Req, types::PaymentsResponseData>,
// To perform router related operation for PaymentResponse
PaymentResponse: Operation<F, Req>,
{
let call_connectors_start_time = Instant::now();
let mut router_data_list = Vec::with_capacity(connectors.len());
for connector in connectors {
let connector_id = connector.connector.id();
let router_data = payment_data
.construct_router_data(state, connector_id, merchant_account)
.await?;
router_data_list.push((connector, router_data));
}
for (connector, router_data) in router_data_list {
let connector_name = connector.connector_name.to_owned().to_string();
let res = router_data
.decide_flows(
state,
connector,
customer,
CallConnectorAction::Trigger,
merchant_account.storage_scheme,
)
.await?;
match res.response {
Ok(connector_response) => {
if let types::PaymentsResponseData::SessionResponse { session_token } =
connector_response
{
payment_data
.sessions_token
.push(types::ConnectorSessionToken {
connector_name,
session_token,
});
}
}
Err(connector_error) => {
logger::debug!(
"sessions_connector_error {} {:?}",
connector_name,
connector_error
);
}
}
}
let call_connectors_end_time = Instant::now();
let call_connectors_duration =
call_connectors_end_time.saturating_duration_since(call_connectors_start_time);
tracing::info!(duration = format!("Duration taken: {}", call_connectors_duration.as_millis()));
Ok(payment_data)
}
pub enum CallConnectorAction { pub enum CallConnectorAction {
Trigger, Trigger,
Avoid, Avoid,
@ -361,6 +441,7 @@ where
pub force_sync: Option<bool>, pub force_sync: Option<bool>,
pub payment_method_data: Option<api::PaymentMethod>, pub payment_method_data: Option<api::PaymentMethod>,
pub refunds: Vec<storage::Refund>, pub refunds: Vec<storage::Refund>,
pub sessions_token: Vec<types::ConnectorSessionToken>,
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -7,7 +7,6 @@ mod verfiy_flow;
use async_trait::async_trait; use async_trait::async_trait;
use super::PaymentData;
use crate::{ use crate::{
core::{errors::RouterResult, payments}, core::{errors::RouterResult, payments},
routes::AppState, routes::AppState,
@ -35,10 +34,9 @@ pub trait Feature<F, T> {
state: &AppState, state: &AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
maybe_customer: &Option<storage::Customer>, maybe_customer: &Option<storage::Customer>,
payment_data: PaymentData<F>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
storage_scheme: enums::MerchantStorageScheme, storage_scheme: enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<F>) ) -> RouterResult<Self>
where where
Self: std::marker::Sized, Self: std::marker::Sized,
F: Clone, F: Clone,

View File

@ -57,17 +57,9 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
state: &AppState, state: &AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
customer: &Option<storage::Customer>, customer: &Option<storage::Customer>,
payment_data: PaymentData<api::Authorize>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
storage_scheme: storage_enums::MerchantStorageScheme, storage_scheme: storage_enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<api::Authorize>) ) -> RouterResult<Self> {
where
dyn api::Connector: services::ConnectorIntegration<
api::Authorize,
types::PaymentsAuthorizeData,
types::PaymentsResponseData,
>,
{
let resp = self let resp = self
.decide_flow( .decide_flow(
state, state,
@ -81,7 +73,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
metrics::PAYMENT_COUNT.add(&metrics::CONTEXT, 1, &[]); // Metrics metrics::PAYMENT_COUNT.add(&metrics::CONTEXT, 1, &[]); // Metrics
(resp, payment_data) resp
} }
} }
@ -94,14 +86,7 @@ impl PaymentsAuthorizeRouterData {
confirm: Option<bool>, confirm: Option<bool>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
_storage_scheme: storage_enums::MerchantStorageScheme, _storage_scheme: storage_enums::MerchantStorageScheme,
) -> RouterResult<PaymentsAuthorizeRouterData> ) -> RouterResult<PaymentsAuthorizeRouterData> {
where
dyn api::Connector + Sync: services::ConnectorIntegration<
api::Authorize,
PaymentsAuthorizeData,
PaymentsResponseData,
>,
{
match confirm { match confirm {
Some(true) => { Some(true) => {
let connector_integration: services::BoxedConnectorIntegration< let connector_integration: services::BoxedConnectorIntegration<

View File

@ -44,28 +44,17 @@ impl Feature<api::Void, types::PaymentsCancelData>
state: &AppState, state: &AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
customer: &Option<storage::Customer>, customer: &Option<storage::Customer>,
payment_data: PaymentData<api::Void>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
_storage_scheme: enums::MerchantStorageScheme, _storage_scheme: enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<api::Void>) ) -> RouterResult<Self> {
where self.decide_flow(
dyn api::Connector: services::ConnectorIntegration< state,
api::Void, connector,
types::PaymentsCancelData, customer,
types::PaymentsResponseData, Some(true),
>, call_connector_action,
{ )
let resp = self .await
.decide_flow(
state,
connector,
customer,
Some(true),
call_connector_action,
)
.await;
(resp, payment_data)
} }
} }
@ -78,14 +67,7 @@ impl PaymentsCancelRouterData {
_maybe_customer: &Option<storage::Customer>, _maybe_customer: &Option<storage::Customer>,
_confirm: Option<bool>, _confirm: Option<bool>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
) -> RouterResult<PaymentsCancelRouterData> ) -> RouterResult<PaymentsCancelRouterData> {
where
dyn api::Connector + Sync: services::ConnectorIntegration<
api::Void,
types::PaymentsCancelData,
PaymentsResponseData,
>,
{
let connector_integration: services::BoxedConnectorIntegration< let connector_integration: services::BoxedConnectorIntegration<
api::Void, api::Void,
types::PaymentsCancelData, types::PaymentsCancelData,

View File

@ -45,28 +45,17 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
state: &AppState, state: &AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
customer: &Option<storage::Customer>, customer: &Option<storage::Customer>,
payment_data: PaymentData<api::Capture>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
_storage_scheme: enums::MerchantStorageScheme, _storage_scheme: enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<api::Capture>) ) -> RouterResult<Self> {
where self.decide_flow(
dyn api::Connector: services::ConnectorIntegration< state,
api::Capture, connector,
types::PaymentsCaptureData, customer,
types::PaymentsResponseData, Some(true),
>, call_connector_action,
{ )
let resp = self .await
.decide_flow(
state,
connector,
customer,
Some(true),
call_connector_action,
)
.await;
(resp, payment_data)
} }
} }
@ -79,11 +68,7 @@ impl PaymentsCaptureRouterData {
_maybe_customer: &Option<storage::Customer>, _maybe_customer: &Option<storage::Customer>,
_confirm: Option<bool>, _confirm: Option<bool>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
) -> RouterResult<PaymentsCaptureRouterData> ) -> RouterResult<PaymentsCaptureRouterData> {
where
dyn api::Connector + Sync:
services::ConnectorIntegration<api::Capture, PaymentsCaptureData, PaymentsResponseData>,
{
let connector_integration: services::BoxedConnectorIntegration< let connector_integration: services::BoxedConnectorIntegration<
api::Capture, api::Capture,
PaymentsCaptureData, PaymentsCaptureData,

View File

@ -46,28 +46,17 @@ impl Feature<api::PSync, types::PaymentsSyncData>
state: &AppState, state: &AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
customer: &Option<storage::Customer>, customer: &Option<storage::Customer>,
payment_data: PaymentData<api::PSync>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
_storage_scheme: enums::MerchantStorageScheme, _storage_scheme: enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<api::PSync>) ) -> RouterResult<Self> {
where self.decide_flow(
dyn api::Connector: services::ConnectorIntegration< state,
api::PSync, connector,
types::PaymentsSyncData, customer,
types::PaymentsResponseData, Some(true),
>, call_connector_action,
{ )
let resp = self .await
.decide_flow(
state,
connector,
customer,
Some(true),
call_connector_action,
)
.await;
(resp, payment_data)
} }
} }
@ -79,11 +68,7 @@ impl PaymentsSyncRouterData {
_maybe_customer: &Option<storage::Customer>, _maybe_customer: &Option<storage::Customer>,
_confirm: Option<bool>, _confirm: Option<bool>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
) -> RouterResult<PaymentsSyncRouterData> ) -> RouterResult<PaymentsSyncRouterData> {
where
dyn api::Connector + Sync:
services::ConnectorIntegration<api::PSync, PaymentsSyncData, PaymentsResponseData>,
{
let connector_integration: services::BoxedConnectorIntegration< let connector_integration: services::BoxedConnectorIntegration<
api::PSync, api::PSync,
PaymentsSyncData, PaymentsSyncData,

View File

@ -41,21 +41,17 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
state: &routes::AppState, state: &routes::AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
customer: &Option<storage::Customer>, customer: &Option<storage::Customer>,
payment_data: PaymentData<api::Session>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
_storage_schema: enums::MerchantStorageScheme, _storage_schema: enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<api::Session>) { ) -> RouterResult<Self> {
let resp = self self.decide_flow(
.decide_flow( state,
state, connector,
connector, customer,
customer, Some(true),
Some(true), call_connector_action,
call_connector_action, )
) .await
.await;
(resp, payment_data)
} }
} }
@ -67,14 +63,7 @@ impl types::PaymentsSessionRouterData {
_customer: &Option<storage::Customer>, _customer: &Option<storage::Customer>,
_confirm: Option<bool>, _confirm: Option<bool>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
) -> RouterResult<types::PaymentsSessionRouterData> ) -> RouterResult<types::PaymentsSessionRouterData> {
where
dyn api::Connector + Sync: services::ConnectorIntegration<
api::Session,
types::PaymentsSessionData,
types::PaymentsResponseData,
>,
{
let connector_integration: services::BoxedConnectorIntegration< let connector_integration: services::BoxedConnectorIntegration<
api::Session, api::Session,
types::PaymentsSessionData, types::PaymentsSessionData,

View File

@ -45,29 +45,18 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
state: &AppState, state: &AppState,
connector: api::ConnectorData, connector: api::ConnectorData,
customer: &Option<storage::Customer>, customer: &Option<storage::Customer>,
payment_data: PaymentData<api::Verify>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
storage_scheme: enums::MerchantStorageScheme, storage_scheme: enums::MerchantStorageScheme,
) -> (RouterResult<Self>, PaymentData<api::Verify>) ) -> RouterResult<Self> {
where self.decide_flow(
dyn api::Connector: services::ConnectorIntegration< state,
api::Verify, connector,
types::VerifyRequestData, customer,
types::PaymentsResponseData, Some(true),
>, call_connector_action,
{ storage_scheme,
let resp = self )
.decide_flow( .await
state,
connector,
customer,
Some(true),
call_connector_action,
storage_scheme,
)
.await;
(resp, payment_data)
} }
} }
@ -80,14 +69,7 @@ impl types::VerifyRouterData {
confirm: Option<bool>, confirm: Option<bool>,
call_connector_action: payments::CallConnectorAction, call_connector_action: payments::CallConnectorAction,
_storage_scheme: enums::MerchantStorageScheme, _storage_scheme: enums::MerchantStorageScheme,
) -> RouterResult<Self> ) -> RouterResult<Self> {
where
dyn api::Connector + Sync: services::ConnectorIntegration<
api::Verify,
types::VerifyRequestData,
types::PaymentsResponseData,
>,
{
match confirm { match confirm {
Some(true) => { Some(true) => {
let connector_integration: services::BoxedConnectorIntegration< let connector_integration: services::BoxedConnectorIntegration<

View File

@ -106,6 +106,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
force_sync: None, force_sync: None,
refunds: vec![], refunds: vec![],
connector_response, connector_response,
sessions_token: vec![],
}, },
None, None,
)), )),

View File

@ -134,6 +134,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
payment_method_data: None, payment_method_data: None,
refunds: vec![], refunds: vec![],
connector_response, connector_response,
sessions_token: vec![],
}, },
None, None,
)) ))

View File

@ -151,6 +151,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
payment_method_data: request.payment_method_data.clone(), payment_method_data: request.payment_method_data.clone(),
force_sync: None, force_sync: None,
refunds: vec![], refunds: vec![],
sessions_token: vec![],
}, },
Some(CustomerDetails { Some(CustomerDetails {
customer_id: request.customer_id.clone(), customer_id: request.customer_id.clone(),

View File

@ -192,6 +192,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
refunds: vec![], refunds: vec![],
force_sync: None, force_sync: None,
connector_response, connector_response,
sessions_token: vec![],
}, },
Some(CustomerDetails { Some(CustomerDetails {
customer_id: request.customer_id.clone(), customer_id: request.customer_id.clone(),

View File

@ -145,6 +145,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
address: types::PaymentAddress::default(), address: types::PaymentAddress::default(),
force_sync: None, force_sync: None,
refunds: vec![], refunds: vec![],
sessions_token: vec![],
}, },
Some(payments::CustomerDetails { Some(payments::CustomerDetails {
customer_id: request.customer_id.clone(), customer_id: request.customer_id.clone(),

View File

@ -131,6 +131,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
payment_method_data: None, payment_method_data: None,
force_sync: None, force_sync: None,
refunds: vec![], refunds: vec![],
sessions_token: vec![],
connector_response, connector_response,
}, },
None, None,

View File

@ -137,6 +137,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
payment_method_data: None, payment_method_data: None,
force_sync: None, force_sync: None,
refunds: vec![], refunds: vec![],
sessions_token: vec![],
}, },
Some(customer_details), Some(customer_details),
)), )),

View File

@ -209,6 +209,7 @@ async fn get_tracker_for_sync<
payment_method_data: None, payment_method_data: None,
force_sync: Some(request.force_sync), force_sync: Some(request.force_sync),
refunds, refunds,
sessions_token: vec![],
}, },
None, None,
)) ))

View File

@ -156,6 +156,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
force_sync: None, force_sync: None,
refunds: vec![], refunds: vec![],
connector_response, connector_response,
sessions_token: vec![],
}, },
Some(CustomerDetails { Some(CustomerDetails {
customer_id: request.customer_id.clone(), customer_id: request.customer_id.clone(),

View File

@ -122,6 +122,12 @@ pub struct PaymentsSessionData {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ConnectorSessionToken {
pub connector_name: String,
pub session_token: String,
}
#[derive(serde::Serialize, Debug)]
pub struct PaymentsSessionResponseData { pub struct PaymentsSessionResponseData {
pub client_token: Option<String>, pub client_token: Option<String>,
} }