mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
feat(router): dynamically toggle KV for merchant and refactoring around it (#79)
This commit is contained in:
@ -274,7 +274,7 @@ pub async fn create_payment_connector(
|
||||
req: api::PaymentConnectorCreate,
|
||||
merchant_id: &String,
|
||||
) -> RouterResponse<api::PaymentConnectorCreate> {
|
||||
store
|
||||
let _merchant_account = store
|
||||
.find_merchant_account_by_merchant_id(merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -332,6 +332,13 @@ pub async fn retrieve_payment_connector(
|
||||
merchant_id: String,
|
||||
merchant_connector_id: i32,
|
||||
) -> RouterResponse<api::PaymentConnectorCreate> {
|
||||
let _merchant_account = store
|
||||
.find_merchant_account_by_merchant_id(&merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let mca = store
|
||||
.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
|
||||
&merchant_id,
|
||||
@ -366,11 +373,13 @@ pub async fn update_payment_connector(
|
||||
merchant_connector_id: i32,
|
||||
req: api::PaymentConnectorCreate,
|
||||
) -> RouterResponse<api::PaymentConnectorCreate> {
|
||||
db.find_merchant_account_by_merchant_id(merchant_id)
|
||||
let _merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let mca = db
|
||||
.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
|
||||
merchant_id,
|
||||
@ -430,6 +439,13 @@ pub async fn delete_payment_connector(
|
||||
merchant_id: String,
|
||||
merchant_connector_id: i32,
|
||||
) -> RouterResponse<api::DeleteMcaResponse> {
|
||||
let _merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let is_deleted = db
|
||||
.delete_merchant_connector_account_by_merchant_id_merchant_connector_id(
|
||||
&merchant_id,
|
||||
|
||||
@ -65,21 +65,22 @@ where
|
||||
|
||||
let operation: BoxedOperation<F, Req> = Box::new(operation);
|
||||
|
||||
let (operation, merchant_id, payment_id, mandate_type) = operation
|
||||
let (operation, validate_result) = operation
|
||||
.to_validate_request()?
|
||||
.validate_request(&req, &merchant_account)?;
|
||||
|
||||
tracing::Span::current().record("payment_id", &format!("{:?}", payment_id));
|
||||
tracing::Span::current().record("payment_id", &format!("{:?}", validate_result.payment_id));
|
||||
|
||||
let (operation, mut payment_data, customer_details) = operation
|
||||
.to_get_tracker()?
|
||||
.get_trackers(
|
||||
state,
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
&validate_result.payment_id,
|
||||
validate_result.merchant_id,
|
||||
connector.connector_name,
|
||||
&req,
|
||||
mandate_type,
|
||||
validate_result.mandate_type,
|
||||
validate_result.storage_scheme,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -89,7 +90,7 @@ where
|
||||
&*state.store,
|
||||
&mut payment_data,
|
||||
customer_details,
|
||||
merchant_id,
|
||||
validate_result.merchant_id,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
@ -103,13 +104,20 @@ where
|
||||
&payment_data.payment_attempt,
|
||||
&payment_data.payment_method_data,
|
||||
&payment_data.token,
|
||||
validate_result.storage_scheme,
|
||||
)
|
||||
.await?;
|
||||
payment_data.payment_method_data = payment_method_data;
|
||||
|
||||
let (operation, mut payment_data) = operation
|
||||
.to_update_tracker()?
|
||||
.update_trackers(&*state.store, &payment_id, payment_data, customer.clone())
|
||||
.update_trackers(
|
||||
&*state.store,
|
||||
&validate_result.payment_id,
|
||||
payment_data,
|
||||
customer.clone(),
|
||||
validate_result.storage_scheme,
|
||||
)
|
||||
.await?;
|
||||
|
||||
operation
|
||||
@ -121,7 +129,7 @@ where
|
||||
payment_data = call_connector_service(
|
||||
state,
|
||||
&merchant_account,
|
||||
&payment_id,
|
||||
&validate_result.payment_id,
|
||||
connector,
|
||||
&operation,
|
||||
payment_data,
|
||||
@ -295,13 +303,20 @@ where
|
||||
customer,
|
||||
payment_data,
|
||||
call_connector_action,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await;
|
||||
let response = helpers::amap(res, |response| async {
|
||||
let operation = helpers::response_operation::<F, Req>();
|
||||
let payment_data = operation
|
||||
.to_post_update_tracker()?
|
||||
.update_tracker(db, payment_id, payment_data, Some(response))
|
||||
.update_tracker(
|
||||
db,
|
||||
payment_id,
|
||||
payment_data,
|
||||
Some(response),
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await?;
|
||||
Ok(payment_data)
|
||||
})
|
||||
@ -451,9 +466,10 @@ pub async fn list_payments(
|
||||
) -> RouterResponse<api::PaymentListResponse> {
|
||||
validate_payment_list_request(&constraints)?;
|
||||
let merchant_id = &merchant.merchant_id;
|
||||
let payment_intent = filter_by_constraints(db, &constraints, merchant_id)
|
||||
.await
|
||||
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
let payment_intent =
|
||||
filter_by_constraints(db, &constraints, merchant_id, merchant.storage_scheme)
|
||||
.await
|
||||
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
|
||||
let data: Vec<api::PaymentsResponse> = payment_intent.into_iter().map(From::from).collect();
|
||||
utils::when(
|
||||
|
||||
@ -11,7 +11,10 @@ use crate::{
|
||||
core::{errors::RouterResult, payments},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{self, api, storage},
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -33,6 +36,7 @@ pub trait Feature<F, T> {
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
payment_data: PaymentData<F>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> (RouterResult<Self>, PaymentData<F>)
|
||||
where
|
||||
Self: std::marker::Sized,
|
||||
|
||||
@ -60,6 +60,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData>
|
||||
customer: &Option<storage::Customer>,
|
||||
payment_data: PaymentData<api::Authorize>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> (RouterResult<Self>, PaymentData<api::Authorize>)
|
||||
where
|
||||
dyn api::Connector: services::ConnectorIntegration<
|
||||
@ -75,6 +76,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData>
|
||||
customer,
|
||||
Some(true),
|
||||
call_connector_action,
|
||||
storage_scheme,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -92,6 +94,7 @@ impl PaymentsAuthorizeRouterData {
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
confirm: Option<bool>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentsAuthorizeRouterData>
|
||||
where
|
||||
dyn api::Connector + Sync: services::ConnectorIntegration<
|
||||
|
||||
@ -8,7 +8,11 @@ use crate::{
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{self, api, storage, PaymentsCancelRouterData, PaymentsResponseData},
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
PaymentsCancelRouterData, PaymentsResponseData,
|
||||
},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -41,6 +45,7 @@ impl Feature<api::Void, types::PaymentsCancelData>
|
||||
customer: &Option<storage::Customer>,
|
||||
payment_data: PaymentData<api::Void>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> (RouterResult<Self>, PaymentData<api::Void>)
|
||||
where
|
||||
dyn api::Connector: services::ConnectorIntegration<
|
||||
|
||||
@ -9,7 +9,9 @@ use crate::{
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
self, api, storage, PaymentsCaptureData, PaymentsCaptureRouterData, PaymentsResponseData,
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
PaymentsCaptureData, PaymentsCaptureRouterData, PaymentsResponseData,
|
||||
},
|
||||
};
|
||||
|
||||
@ -44,6 +46,7 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
|
||||
customer: &Option<storage::Customer>,
|
||||
payment_data: PaymentData<api::Capture>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> (RouterResult<Self>, PaymentData<api::Capture>)
|
||||
where
|
||||
dyn api::Connector: services::ConnectorIntegration<
|
||||
|
||||
@ -8,7 +8,11 @@ use crate::{
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{self, api, storage, PaymentsResponseData, PaymentsSyncData, PaymentsSyncRouterData},
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
PaymentsResponseData, PaymentsSyncData, PaymentsSyncRouterData,
|
||||
},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -43,6 +47,7 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
customer: &Option<storage::Customer>,
|
||||
payment_data: PaymentData<api::PSync>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> (RouterResult<Self>, PaymentData<api::PSync>)
|
||||
where
|
||||
dyn api::Connector: services::ConnectorIntegration<
|
||||
|
||||
@ -47,6 +47,7 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
|
||||
customer: &Option<storage::Customer>,
|
||||
payment_data: PaymentData<api::Verify>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> (RouterResult<Self>, PaymentData<api::Verify>)
|
||||
where
|
||||
dyn api::Connector: services::ConnectorIntegration<
|
||||
@ -62,6 +63,7 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
|
||||
customer,
|
||||
Some(true),
|
||||
call_connector_action,
|
||||
storage_scheme,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -77,6 +79,7 @@ impl types::VerifyRouterData {
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
confirm: Option<bool>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<Self>
|
||||
where
|
||||
dyn api::Connector + Sync: services::ConnectorIntegration<
|
||||
|
||||
@ -807,9 +807,10 @@ pub(super) async fn filter_by_constraints(
|
||||
db: &dyn StorageInterface,
|
||||
constraints: &api::PaymentListConstraints,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<storage::PaymentIntent>, errors::StorageError> {
|
||||
let result = db
|
||||
.filter_payment_intent_by_constraints(merchant_id, constraints)
|
||||
.filter_payment_intent_by_constraints(merchant_id, constraints, storage_scheme)
|
||||
.await?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@ -68,18 +68,20 @@ pub trait Operation<F: Clone, T>: Send + std::fmt::Debug {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ValidateResult<'a> {
|
||||
pub merchant_id: &'a str,
|
||||
pub payment_id: api::PaymentIdType,
|
||||
pub mandate_type: Option<api::MandateTxnType>,
|
||||
pub storage_scheme: enums::MerchantStorageScheme,
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub trait ValidateRequest<F, R> {
|
||||
fn validate_request<'a, 'b>(
|
||||
&'b self,
|
||||
request: &R,
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, R>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
)>;
|
||||
) -> RouterResult<(BoxedOperation<'b, F, R>, ValidateResult<'a>)>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@ -93,6 +95,7 @@ pub trait GetTracker<F, D, R>: Send {
|
||||
connector: types::Connector,
|
||||
request: &R,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'a, F, R>, D, Option<CustomerDetails>)>;
|
||||
}
|
||||
|
||||
@ -116,6 +119,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
|
||||
payment_attempt: &storage::PaymentAttempt,
|
||||
request: &Option<api::PaymentMethod>,
|
||||
token: &Option<String>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'a, F, R>, Option<api::PaymentMethod>)>;
|
||||
|
||||
async fn add_task_to_process_tracker<'a>(
|
||||
@ -135,6 +139,7 @@ pub trait UpdateTracker<F, D, R>: Send {
|
||||
payment_id: &api::PaymentIdType,
|
||||
payment_data: D,
|
||||
customer: Option<Customer>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, R>, D)>
|
||||
where
|
||||
F: 'b + Send;
|
||||
@ -148,6 +153,7 @@ pub trait PostUpdateTracker<F, D, R>: Send {
|
||||
payment_id: &api::PaymentIdType,
|
||||
payment_data: D,
|
||||
response: Option<types::RouterData<F, R, PaymentsResponseData>>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<D>
|
||||
where
|
||||
F: 'b + Send;
|
||||
@ -192,6 +198,7 @@ where
|
||||
payment_attempt: &storage::PaymentAttempt,
|
||||
request: &Option<api::PaymentMethod>,
|
||||
token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
@ -280,6 +287,7 @@ where
|
||||
payment_attempt: &storage::PaymentAttempt,
|
||||
request: &Option<api::PaymentMethod>,
|
||||
token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
@ -336,6 +344,7 @@ where
|
||||
_payment_attempt: &storage::PaymentAttempt,
|
||||
_request: &Option<api::PaymentMethod>,
|
||||
_token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
@ -384,6 +393,7 @@ where
|
||||
_payment_attempt: &storage::PaymentAttempt,
|
||||
_request: &Option<api::PaymentMethod>,
|
||||
_token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCancelRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
|
||||
@ -9,7 +9,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
},
|
||||
db::StorageInterface,
|
||||
routes::AppState,
|
||||
@ -36,6 +36,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
||||
_connector: Connector,
|
||||
request: &api::PaymentsCancelRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCancelRequest>,
|
||||
PaymentData<F>,
|
||||
@ -47,14 +48,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
let payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?;
|
||||
|
||||
let mut payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -65,6 +70,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
||||
&payment_attempt.payment_id,
|
||||
&payment_attempt.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -116,6 +122,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
|
||||
_payment_id: &api::PaymentIdType,
|
||||
mut payment_data: PaymentData<F>,
|
||||
_customer: Option<Customer>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsCancelRequest>,
|
||||
PaymentData<F>,
|
||||
@ -131,6 +138,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
|
||||
status: enums::AttemptStatus::VoidInitiated,
|
||||
cancellation_reason,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
@ -147,15 +155,16 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsCancelRequest> for Payment
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsCancelRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(request.payment_id.to_owned()),
|
||||
None,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(request.payment_id.to_owned()),
|
||||
mandate_type: None,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,11 +8,16 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{self, helpers},
|
||||
payments::{self, helpers, operations},
|
||||
},
|
||||
db::StorageInterface,
|
||||
routes::AppState,
|
||||
types::{api, api::PaymentsCaptureRequest, storage, Connector},
|
||||
types::{
|
||||
api,
|
||||
api::PaymentsCaptureRequest,
|
||||
storage::{self, enums},
|
||||
Connector,
|
||||
},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
@ -33,6 +38,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
||||
_connector: Connector,
|
||||
request: &PaymentsCaptureRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
|
||||
payments::PaymentData<F>,
|
||||
@ -46,7 +52,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -57,7 +63,11 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
||||
helpers::validate_amount_to_capture(payment_intent.amount, request.amount_to_capture)?;
|
||||
|
||||
payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -82,6 +92,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
||||
&payment_attempt.payment_id,
|
||||
&payment_attempt.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -140,6 +151,7 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRe
|
||||
_payment_id: &api::PaymentIdType,
|
||||
payment_data: payments::PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsCaptureRequest>,
|
||||
payments::PaymentData<F>,
|
||||
@ -159,9 +171,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsCaptureRequest> for Paymen
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsCaptureRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let payment_id = request
|
||||
.payment_id
|
||||
@ -170,9 +180,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsCaptureRequest> for Paymen
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(payment_id.to_owned()),
|
||||
None,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(payment_id.to_owned()),
|
||||
mandate_type: None,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{helpers, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
utils as core_utils,
|
||||
},
|
||||
db::StorageInterface,
|
||||
@ -37,6 +37,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
_connector: Connector,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
PaymentData<F>,
|
||||
@ -54,7 +55,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
.await?;
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -78,7 +79,11 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
})?;
|
||||
|
||||
payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -95,6 +100,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
&payment_attempt.payment_id,
|
||||
&payment_attempt.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -167,6 +173,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
_payment_id: &api::PaymentIdType,
|
||||
mut payment_data: PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
||||
where
|
||||
F: 'b + Send,
|
||||
@ -194,6 +201,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
payment_method,
|
||||
browser_info,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -213,6 +221,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
shipping_address_id: shipping_address,
|
||||
billing_address_id: billing_address,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -231,9 +240,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentConfir
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let given_payment_id = match &request.payment_id {
|
||||
Some(id_type) => Some(
|
||||
@ -256,9 +263,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentConfir
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::{
|
||||
consts,
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{self, helpers, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
utils as core_utils,
|
||||
},
|
||||
db::StorageInterface,
|
||||
@ -40,6 +40,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
connector: types::Connector,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
PaymentData<F>,
|
||||
@ -79,15 +80,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
})?;
|
||||
|
||||
payment_attempt = match db
|
||||
.insert_payment_attempt(Self::make_payment_attempt(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
connector,
|
||||
money,
|
||||
payment_method_type,
|
||||
request,
|
||||
browser_info,
|
||||
))
|
||||
.insert_payment_attempt(
|
||||
Self::make_payment_attempt(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
connector,
|
||||
money,
|
||||
payment_method_type,
|
||||
request,
|
||||
browser_info,
|
||||
),
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(payment_attempt) => Ok(payment_attempt),
|
||||
@ -95,25 +99,32 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
Err(err) => match err.current_context() {
|
||||
errors::StorageError::DatabaseError(errors::DatabaseError::UniqueViolation) => {
|
||||
is_update = true;
|
||||
db.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})
|
||||
db.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})
|
||||
}
|
||||
_ => Err(err).change_context(errors::ApiErrorResponse::InternalServerError),
|
||||
},
|
||||
}?;
|
||||
payment_intent = match db
|
||||
.insert_payment_intent(Self::make_payment_intent(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
&connector.to_string(),
|
||||
money,
|
||||
request,
|
||||
shipping_address.clone().map(|x| x.address_id),
|
||||
billing_address.clone().map(|x| x.address_id),
|
||||
))
|
||||
.insert_payment_intent(
|
||||
Self::make_payment_intent(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
&connector.to_string(),
|
||||
money,
|
||||
request,
|
||||
shipping_address.clone().map(|x| x.address_id),
|
||||
billing_address.clone().map(|x| x.address_id),
|
||||
),
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(payment_intent) => Ok(payment_intent),
|
||||
@ -121,18 +132,25 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
Err(err) => match err.current_context() {
|
||||
errors::StorageError::DatabaseError(errors::DatabaseError::UniqueViolation) => {
|
||||
is_update = true;
|
||||
db.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})
|
||||
db.find_payment_intent_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})
|
||||
}
|
||||
_ => Err(err).change_context(errors::ApiErrorResponse::InternalServerError),
|
||||
},
|
||||
}?;
|
||||
|
||||
connector_response = match db
|
||||
.insert_connector_response(Self::make_connector_response(&payment_attempt))
|
||||
.insert_connector_response(
|
||||
Self::make_connector_response(&payment_attempt),
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(connector_resp) => Ok(connector_resp),
|
||||
@ -195,6 +213,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
_payment_id: &api::PaymentIdType,
|
||||
mut payment_data: PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
||||
where
|
||||
F: 'b + Send,
|
||||
@ -225,6 +244,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
shipping_address_id: None,
|
||||
billing_address_id: None,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -248,9 +268,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let given_payment_id = match &request.payment_id {
|
||||
Some(id_type) => Some(
|
||||
@ -281,9 +299,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::{
|
||||
consts,
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{self, helpers, Operation, PaymentData},
|
||||
payments::{self, helpers, operations, Operation, PaymentData},
|
||||
utils as core_utils,
|
||||
},
|
||||
db::StorageInterface,
|
||||
@ -36,9 +36,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::VerifyRequest> for PaymentMethodVa
|
||||
merchant_account: &'a types::storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::VerifyRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let request_merchant_id = request.merchant_id.as_deref();
|
||||
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
||||
@ -49,9 +47,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::VerifyRequest> for PaymentMethodVa
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(validation_id),
|
||||
mandate_type,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(validation_id),
|
||||
mandate_type,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -67,6 +68,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
||||
connector: types::Connector,
|
||||
request: &api::VerifyRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::VerifyRequest>,
|
||||
PaymentData<F>,
|
||||
@ -80,13 +82,16 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
|
||||
payment_attempt = match db
|
||||
.insert_payment_attempt(Self::make_payment_attempt(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
connector,
|
||||
request.payment_method,
|
||||
request,
|
||||
))
|
||||
.insert_payment_attempt(
|
||||
Self::make_payment_attempt(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
connector,
|
||||
request.payment_method,
|
||||
request,
|
||||
),
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(payment_attempt) => Ok(payment_attempt),
|
||||
@ -96,12 +101,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
||||
}?;
|
||||
|
||||
payment_intent = match db
|
||||
.insert_payment_intent(Self::make_payment_intent(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
connector,
|
||||
request,
|
||||
))
|
||||
.insert_payment_intent(
|
||||
Self::make_payment_intent(&payment_id, merchant_id, connector, request),
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(payment_intent) => Ok(payment_intent),
|
||||
@ -111,7 +114,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
||||
}?;
|
||||
|
||||
connector_response = match db
|
||||
.insert_connector_response(PaymentCreate::make_connector_response(&payment_attempt))
|
||||
.insert_connector_response(
|
||||
PaymentCreate::make_connector_response(&payment_attempt),
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(connector_resp) => Ok(connector_resp),
|
||||
@ -159,6 +165,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::VerifyRequest> for PaymentM
|
||||
_payment_id: &api::PaymentIdType,
|
||||
mut payment_data: PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, api::VerifyRequest>, PaymentData<F>)>
|
||||
where
|
||||
F: 'b + Send,
|
||||
@ -178,6 +185,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::VerifyRequest> for PaymentM
|
||||
shipping_address_id: None,
|
||||
billing_address_id: None,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@ -230,6 +238,7 @@ where
|
||||
payment_attempt: &storage::PaymentAttempt,
|
||||
request: &Option<api::PaymentMethod>,
|
||||
token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::VerifyRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
|
||||
@ -36,6 +36,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthorizeData
|
||||
response: Option<
|
||||
types::RouterData<F, types::PaymentsAuthorizeData, types::PaymentsResponseData>,
|
||||
>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentData<F>>
|
||||
where
|
||||
F: 'b + Send,
|
||||
@ -44,7 +45,14 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthorizeData
|
||||
payment_data.mandate_id = payment_data
|
||||
.mandate_id
|
||||
.or_else(|| router_data.request.mandate_id.clone());
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, Some(router_data)).await?)
|
||||
Ok(payment_response_ut(
|
||||
db,
|
||||
payment_id,
|
||||
payment_data,
|
||||
Some(router_data),
|
||||
storage_scheme,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,11 +66,12 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsSyncData> for
|
||||
response: Option<
|
||||
types::RouterData<F, types::PaymentsSyncData, types::PaymentsResponseData>,
|
||||
>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentData<F>>
|
||||
where
|
||||
F: 'b + Send,
|
||||
{
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response).await?)
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response, storage_scheme).await?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,11 +87,12 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsCaptureData>
|
||||
response: Option<
|
||||
types::RouterData<F, types::PaymentsCaptureData, types::PaymentsResponseData>,
|
||||
>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentData<F>>
|
||||
where
|
||||
F: 'b + Send,
|
||||
{
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response).await?)
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response, storage_scheme).await?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,11 +106,12 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsCancelData> f
|
||||
response: Option<
|
||||
types::RouterData<F, types::PaymentsCancelData, types::PaymentsResponseData>,
|
||||
>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentData<F>>
|
||||
where
|
||||
F: 'b + Send,
|
||||
{
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response).await?)
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response, storage_scheme).await?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,11 +125,12 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::VerifyRequestData> fo
|
||||
response: Option<
|
||||
types::RouterData<F, types::VerifyRequestData, types::PaymentsResponseData>,
|
||||
>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentData<F>>
|
||||
where
|
||||
F: 'b + Send,
|
||||
{
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response).await?)
|
||||
Ok(payment_response_ut(db, payment_id, payment_data, response, storage_scheme).await?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,6 +139,7 @@ async fn payment_response_ut<F: Clone, T>(
|
||||
_payment_id: &api::PaymentIdType,
|
||||
mut payment_data: PaymentData<F>,
|
||||
response: Option<types::RouterData<F, T, types::PaymentsResponseData>>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<PaymentData<F>> {
|
||||
let router_data = response.ok_or(report!(errors::ApiErrorResponse::InternalServerError))?;
|
||||
let mut connector_response_data = None;
|
||||
@ -156,7 +169,11 @@ async fn payment_response_ut<F: Clone, T>(
|
||||
};
|
||||
|
||||
payment_data.payment_attempt = db
|
||||
.update_payment_attempt(payment_data.payment_attempt, payment_attempt_update)
|
||||
.update_payment_attempt(
|
||||
payment_data.payment_attempt,
|
||||
payment_attempt_update,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
|
||||
@ -180,11 +197,15 @@ async fn payment_response_ut<F: Clone, T>(
|
||||
encoded_data: payment_data.connector_response.encoded_data.clone(),
|
||||
};
|
||||
|
||||
db.update_connector_response(payment_data.connector_response, connector_response_update)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?
|
||||
db.update_connector_response(
|
||||
payment_data.connector_response,
|
||||
connector_response_update,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?
|
||||
}
|
||||
None => payment_data.connector_response,
|
||||
};
|
||||
@ -201,7 +222,11 @@ async fn payment_response_ut<F: Clone, T>(
|
||||
};
|
||||
|
||||
payment_data.payment_intent = db
|
||||
.update_payment_intent(payment_data.payment_intent, payment_intent_update)
|
||||
.update_payment_intent(
|
||||
payment_data.payment_intent,
|
||||
payment_intent_update,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{self, helpers, PaymentData},
|
||||
payments::{self, helpers, operations, PaymentData},
|
||||
},
|
||||
db::StorageInterface,
|
||||
routes::AppState,
|
||||
@ -38,6 +38,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
||||
_connector: Connector,
|
||||
request: &api::PaymentsSessionRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsSessionRequest>,
|
||||
PaymentData<F>,
|
||||
@ -50,14 +51,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
||||
let db = &*state.store;
|
||||
|
||||
let mut payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?;
|
||||
|
||||
let mut payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -81,6 +86,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
||||
payment_intent.shipping_address_id.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let billing_address = helpers::get_address_for_payment_request(
|
||||
db,
|
||||
None,
|
||||
@ -97,6 +103,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
||||
&payment_intent.payment_id,
|
||||
&payment_intent.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -140,6 +147,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsSessionRequest> for
|
||||
_payment_id: &api::PaymentIdType,
|
||||
payment_data: PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsSessionRequest>,
|
||||
PaymentData<F>,
|
||||
@ -159,9 +167,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsSessionRequest> for Paymen
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsSessionRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
//paymentid is already generated and should be sent in the request
|
||||
let given_payment_id = request
|
||||
@ -171,9 +177,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsSessionRequest> for Paymen
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(given_payment_id),
|
||||
None,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(given_payment_id),
|
||||
mandate_type: None,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -217,6 +226,7 @@ where
|
||||
_payment_attempt: &storage::PaymentAttempt,
|
||||
_request: &Option<api::PaymentMethod>,
|
||||
_token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsSessionRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
|
||||
@ -9,7 +9,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, CustomResult, RouterResult, StorageErrorExt},
|
||||
payments::{helpers, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
},
|
||||
db::StorageInterface,
|
||||
routes::AppState,
|
||||
@ -36,6 +36,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
||||
_connector: Connector,
|
||||
_request: &api::PaymentsStartRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsStartRequest>,
|
||||
PaymentData<F>,
|
||||
@ -49,14 +50,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?;
|
||||
|
||||
payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -95,6 +100,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
||||
&payment_intent.payment_id,
|
||||
&payment_intent.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -147,6 +153,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsStartRequest> for P
|
||||
_payment_id: &api::PaymentIdType,
|
||||
payment_data: PaymentData<F>,
|
||||
_customer: Option<Customer>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsStartRequest>,
|
||||
PaymentData<F>,
|
||||
@ -166,9 +173,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsStartRequest> for PaymentS
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsStartRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let request_merchant_id = Some(&request.merchant_id[..]);
|
||||
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
||||
@ -181,9 +186,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsStartRequest> for PaymentS
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
None,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type: None,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -227,6 +235,7 @@ where
|
||||
payment_attempt: &storage::PaymentAttempt,
|
||||
request: &Option<api::PaymentMethod>,
|
||||
token: &Option<String>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsStartRequest>,
|
||||
Option<api::PaymentMethod>,
|
||||
|
||||
@ -9,11 +9,15 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, ApiErrorResponse, RouterResult, StorageErrorExt},
|
||||
payments::{helpers, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
},
|
||||
db::StorageInterface,
|
||||
routes::AppState,
|
||||
types::{api, storage, Connector},
|
||||
types::{
|
||||
api,
|
||||
storage::{self, enums},
|
||||
Connector,
|
||||
},
|
||||
utils::{self, OptionExt},
|
||||
};
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
@ -51,6 +55,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
_payment_id: &api::PaymentIdType,
|
||||
payment_data: PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
||||
where
|
||||
F: 'b + Send,
|
||||
@ -67,6 +72,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest> fo
|
||||
_payment_id: &api::PaymentIdType,
|
||||
payment_data: PaymentData<F>,
|
||||
_customer: Option<storage::Customer>,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsRetrieveRequest>,
|
||||
PaymentData<F>,
|
||||
@ -91,12 +97,21 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
|
||||
_connector: Connector,
|
||||
request: &api::PaymentsRetrieveRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
get_tracker_for_sync(payment_id, merchant_id, &*state.store, request, self).await
|
||||
get_tracker_for_sync(
|
||||
payment_id,
|
||||
merchant_id,
|
||||
&*state.store,
|
||||
request,
|
||||
self,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,6 +125,7 @@ async fn get_tracker_for_sync<
|
||||
db: &dyn StorageInterface,
|
||||
request: &api::PaymentsRetrieveRequest,
|
||||
operation: Op,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
|
||||
PaymentData<F>,
|
||||
@ -119,13 +135,13 @@ async fn get_tracker_for_sync<
|
||||
|
||||
payment_attempt = match payment_id {
|
||||
api::PaymentIdType::PaymentIntentId(ref id) => {
|
||||
db.find_payment_attempt_by_payment_id_merchant_id(id, merchant_id)
|
||||
db.find_payment_attempt_by_payment_id_merchant_id(id, merchant_id, storage_scheme)
|
||||
}
|
||||
api::PaymentIdType::ConnectorTransactionId(ref id) => {
|
||||
db.find_payment_attempt_by_merchant_id_connector_txn_id(merchant_id, id)
|
||||
db.find_payment_attempt_by_merchant_id_connector_txn_id(merchant_id, id, storage_scheme)
|
||||
}
|
||||
api::PaymentIdType::PaymentTxnId(ref id) => {
|
||||
db.find_payment_attempt_by_merchant_id_txn_id(merchant_id, id)
|
||||
db.find_payment_attempt_by_merchant_id_txn_id(merchant_id, id, storage_scheme)
|
||||
}
|
||||
}
|
||||
.await
|
||||
@ -134,7 +150,7 @@ async fn get_tracker_for_sync<
|
||||
let payment_id_str = payment_attempt.payment_id.clone();
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id_str, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id_str, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
|
||||
@ -143,6 +159,7 @@ async fn get_tracker_for_sync<
|
||||
&payment_intent.payment_id,
|
||||
&payment_intent.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
@ -168,7 +185,7 @@ async fn get_tracker_for_sync<
|
||||
)?;
|
||||
|
||||
let refunds = db
|
||||
.find_refund_by_payment_id_merchant_id(&payment_id_str, merchant_id)
|
||||
.find_refund_by_payment_id_merchant_id(&payment_id_str, merchant_id, storage_scheme)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
|
||||
@ -204,9 +221,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRetrieveRequest> for Payme
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsRetrieveRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let request_merchant_id = request.merchant_id.as_deref();
|
||||
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
||||
@ -217,9 +232,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRetrieveRequest> for Payme
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
request.resource_id.clone(),
|
||||
None,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: request.resource_id.clone(),
|
||||
mandate_type: None,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, RouterResult, StorageErrorExt},
|
||||
payments::{self, helpers, CustomerDetails, PaymentAddress, PaymentData},
|
||||
payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
utils as core_utils,
|
||||
},
|
||||
db::StorageInterface,
|
||||
@ -36,6 +36,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
_connector: Connector,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
PaymentData<F>,
|
||||
@ -58,7 +59,11 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
.await?;
|
||||
|
||||
payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -78,7 +83,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
amount = request.amount.unwrap_or(payment_attempt.amount);
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
@ -114,6 +119,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
&payment_intent.payment_id,
|
||||
&payment_intent.merchant_id,
|
||||
&payment_attempt.txn_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -172,6 +178,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
_payment_id: &api::PaymentIdType,
|
||||
mut payment_data: PaymentData<F>,
|
||||
customer: Option<storage::Customer>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
||||
where
|
||||
F: 'b + Send,
|
||||
@ -200,6 +207,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
authentication_type: None,
|
||||
payment_method,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -235,6 +243,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
shipping_address_id: shipping_address,
|
||||
billing_address_id: billing_address,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
@ -258,9 +267,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate
|
||||
merchant_account: &'a storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'b, F, api::PaymentsRequest>,
|
||||
&'a str,
|
||||
api::PaymentIdType,
|
||||
Option<api::MandateTxnType>,
|
||||
operations::ValidateResult<'a>,
|
||||
)> {
|
||||
let given_payment_id = match &request.payment_id {
|
||||
Some(id_type) => Some(
|
||||
@ -291,9 +298,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate
|
||||
|
||||
Ok((
|
||||
Box::new(self),
|
||||
&merchant_account.merchant_id,
|
||||
api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type,
|
||||
operations::ValidateResult {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
payment_id: api::PaymentIdType::PaymentIntentId(payment_id),
|
||||
mandate_type,
|
||||
storage_scheme: merchant_account.storage_scheme,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ pub async fn refund_create_core(
|
||||
.find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id(
|
||||
&req.payment_id,
|
||||
merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::SuccessfulPaymentNotFound)?;
|
||||
@ -56,7 +57,11 @@ pub async fn refund_create_core(
|
||||
)?;
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&req.payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(
|
||||
&req.payment_id,
|
||||
merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
@ -142,7 +147,11 @@ pub async fn trigger_refund_to_gateway(
|
||||
|
||||
let response = state
|
||||
.store
|
||||
.update_refund(refund.to_owned(), refund_update)
|
||||
.update_refund(
|
||||
refund.to_owned(),
|
||||
refund_update,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
Ok(response)
|
||||
@ -162,13 +171,21 @@ pub async fn refund_retrieve_core(
|
||||
merchant_id = &merchant_account.merchant_id;
|
||||
|
||||
refund = db
|
||||
.find_refund_by_merchant_id_refund_id(merchant_id, refund_id.as_str())
|
||||
.find_refund_by_merchant_id_refund_id(
|
||||
merchant_id,
|
||||
refund_id.as_str(),
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
||||
|
||||
let payment_id = refund.payment_id.as_str();
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(payment_id, merchant_id)
|
||||
.find_payment_intent_by_payment_id_merchant_id(
|
||||
payment_id,
|
||||
merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
|
||||
@ -177,6 +194,7 @@ pub async fn refund_retrieve_core(
|
||||
&refund.transaction_id,
|
||||
payment_id,
|
||||
merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?;
|
||||
@ -251,7 +269,11 @@ pub async fn sync_refund_with_gateway(
|
||||
|
||||
let response = state
|
||||
.store
|
||||
.update_refund(refund.to_owned(), refund_update)
|
||||
.update_refund(
|
||||
refund.to_owned(),
|
||||
refund_update,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
Ok(response)
|
||||
@ -266,7 +288,11 @@ pub async fn refund_update_core(
|
||||
req: refunds::RefundRequest,
|
||||
) -> RouterResponse<refunds::RefundResponse> {
|
||||
let refund = db
|
||||
.find_refund_by_merchant_id_refund_id(&merchant_account.merchant_id, refund_id)
|
||||
.find_refund_by_merchant_id_refund_id(
|
||||
&merchant_account.merchant_id,
|
||||
refund_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
||||
|
||||
@ -276,6 +302,7 @@ pub async fn refund_update_core(
|
||||
storage::RefundUpdate::MetadataUpdate {
|
||||
metadata: req.metadata,
|
||||
},
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
@ -323,6 +350,7 @@ pub async fn validate_and_create_refund(
|
||||
&payment_intent.payment_id,
|
||||
&merchant_account.merchant_id,
|
||||
&refund_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
@ -338,6 +366,7 @@ pub async fn validate_and_create_refund(
|
||||
.find_refund_by_merchant_id_transaction_id(
|
||||
&merchant_account.merchant_id,
|
||||
connecter_transaction_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::RefundNotFound)
|
||||
@ -371,9 +400,12 @@ pub async fn validate_and_create_refund(
|
||||
refund_amount,
|
||||
);
|
||||
|
||||
refund = db.insert_refund(refund_create_req).await.map_err(|error| {
|
||||
error.to_duplicate_response(errors::ApiErrorResponse::DuplicateRefundRequest)
|
||||
})?;
|
||||
refund = db
|
||||
.insert_refund(refund_create_req, merchant_account.storage_scheme)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_duplicate_response(errors::ApiErrorResponse::DuplicateRefundRequest)
|
||||
})?;
|
||||
schedule_refund_execution(
|
||||
state,
|
||||
refund,
|
||||
@ -548,11 +580,20 @@ pub async fn sync_refund_with_gateway_workflow(
|
||||
refund_tracker.tracking_data
|
||||
)
|
||||
})?;
|
||||
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&refund_core.merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
// FIXME we actually don't use this?
|
||||
let _refund = db
|
||||
.find_refund_by_internal_reference_id_merchant_id(
|
||||
&refund_core.refund_internal_reference_id,
|
||||
&refund_core.merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
||||
@ -592,41 +633,53 @@ pub async fn trigger_refund_execute_workflow(
|
||||
refund_tracker.tracking_data
|
||||
)
|
||||
})?;
|
||||
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&refund_core.merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let refund = db
|
||||
.find_refund_by_internal_reference_id_merchant_id(
|
||||
&refund_core.refund_internal_reference_id,
|
||||
&refund_core.merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
||||
match (&refund.sent_to_gateway, &refund.refund_status) {
|
||||
//FIXME: Conversion should come from trait
|
||||
(false, enums::RefundStatus::Pending) => {
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&refund.merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let payment_attempt = db
|
||||
.find_payment_attempt_by_transaction_id_payment_id_merchant_id(
|
||||
&refund.transaction_id,
|
||||
&refund_core.payment_id,
|
||||
&refund.merchant_id,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?;
|
||||
let payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(
|
||||
&payment_attempt.payment_id,
|
||||
&refund.merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?;
|
||||
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&refund.merchant_id)
|
||||
let payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(
|
||||
&payment_attempt.payment_id,
|
||||
&refund.merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
})?;
|
||||
|
||||
//trigger refund request to gateway
|
||||
|
||||
@ -95,9 +95,10 @@ pub async fn validate_uniqueness_of_refund_id_against_merchant_id(
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
refund_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> RouterResult<Option<storage::Refund>> {
|
||||
let refund = db
|
||||
.find_refund_by_merchant_id_refund_id(merchant_id, refund_id)
|
||||
.find_refund_by_merchant_id_refund_id(merchant_id, refund_id, storage_scheme)
|
||||
.await;
|
||||
logger::debug!(?refund);
|
||||
match refund {
|
||||
|
||||
@ -16,6 +16,7 @@ pub trait AddressInterface {
|
||||
&self,
|
||||
address: AddressNew,
|
||||
) -> CustomResult<Address, errors::StorageError>;
|
||||
|
||||
async fn find_address(&self, address_id: &str) -> CustomResult<Address, errors::StorageError>;
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ use super::MockDb;
|
||||
use crate::{
|
||||
connection::pg_connection,
|
||||
core::errors::{self, CustomResult},
|
||||
types::storage::{ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate},
|
||||
types::storage::{enums, ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate},
|
||||
};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -10,17 +10,22 @@ pub trait ConnectorResponseInterface {
|
||||
async fn insert_connector_response(
|
||||
&self,
|
||||
connector_response: ConnectorResponseNew,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError>;
|
||||
|
||||
async fn find_connector_response_by_payment_id_merchant_id_txn_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError>;
|
||||
|
||||
async fn update_connector_response(
|
||||
&self,
|
||||
this: ConnectorResponse,
|
||||
payment_attempt: ConnectorResponseUpdate,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError>;
|
||||
}
|
||||
|
||||
@ -29,6 +34,7 @@ impl ConnectorResponseInterface for super::Store {
|
||||
async fn insert_connector_response(
|
||||
&self,
|
||||
connector_response: ConnectorResponseNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
connector_response.insert(&conn).await
|
||||
@ -39,6 +45,7 @@ impl ConnectorResponseInterface for super::Store {
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
ConnectorResponse::find_by_payment_id_and_merchant_id_transaction_id(
|
||||
@ -54,6 +61,7 @@ impl ConnectorResponseInterface for super::Store {
|
||||
&self,
|
||||
this: ConnectorResponse,
|
||||
connector_response_update: ConnectorResponseUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
this.update(&conn, connector_response_update).await
|
||||
@ -65,6 +73,7 @@ impl ConnectorResponseInterface for MockDb {
|
||||
async fn insert_connector_response(
|
||||
&self,
|
||||
new: ConnectorResponseNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError> {
|
||||
let mut connector_response = self.connector_response.lock().await;
|
||||
let response = ConnectorResponse {
|
||||
@ -88,6 +97,7 @@ impl ConnectorResponseInterface for MockDb {
|
||||
_payment_id: &str,
|
||||
_merchant_id: &str,
|
||||
_txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -96,6 +106,7 @@ impl ConnectorResponseInterface for MockDb {
|
||||
&self,
|
||||
this: ConnectorResponse,
|
||||
connector_response_update: ConnectorResponseUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<ConnectorResponse, errors::StorageError> {
|
||||
let mut connector_response = self.connector_response.lock().await;
|
||||
let response = connector_response
|
||||
|
||||
@ -5,7 +5,7 @@ use super::MockDb;
|
||||
use crate::{
|
||||
connection::pg_connection,
|
||||
core::errors::{self, CustomResult, DatabaseError, StorageError},
|
||||
types::storage::{MerchantAccount, MerchantAccountNew, MerchantAccountUpdate},
|
||||
types::storage::{enums, MerchantAccount, MerchantAccountNew, MerchantAccountUpdate},
|
||||
};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -122,6 +122,7 @@ impl MerchantAccountInterface for MockDb {
|
||||
sub_merchants_enabled: merchant_account.sub_merchants_enabled,
|
||||
parent_merchant_id: merchant_account.parent_merchant_id,
|
||||
publishable_key: merchant_account.publishable_key,
|
||||
storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
|
||||
};
|
||||
accounts.push(account.clone());
|
||||
Ok(account)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use super::MockDb;
|
||||
use crate::{
|
||||
core::errors::{self, CustomResult},
|
||||
types::storage::{PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
|
||||
types::storage::{enums, PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
|
||||
};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -9,18 +9,21 @@ pub trait PaymentAttemptInterface {
|
||||
async fn insert_payment_attempt(
|
||||
&self,
|
||||
payment_attempt: PaymentAttemptNew,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
|
||||
async fn update_payment_attempt(
|
||||
&self,
|
||||
this: PaymentAttempt,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
|
||||
async fn find_payment_attempt_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
|
||||
async fn find_payment_attempt_by_transaction_id_payment_id_merchant_id(
|
||||
@ -28,24 +31,28 @@ pub trait PaymentAttemptInterface {
|
||||
transaction_id: &str,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
|
||||
async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
|
||||
async fn find_payment_attempt_by_merchant_id_connector_txn_id(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
connector_txn_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
|
||||
async fn find_payment_attempt_by_merchant_id_txn_id(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError>;
|
||||
}
|
||||
|
||||
@ -56,7 +63,7 @@ mod storage {
|
||||
connection::pg_connection,
|
||||
core::errors::{self, CustomResult},
|
||||
services::Store,
|
||||
types::storage::payment_attempt::*,
|
||||
types::storage::{enums, payment_attempt::*},
|
||||
};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -64,6 +71,7 @@ mod storage {
|
||||
async fn insert_payment_attempt(
|
||||
&self,
|
||||
payment_attempt: PaymentAttemptNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
payment_attempt.insert_diesel(&conn).await
|
||||
@ -73,6 +81,7 @@ mod storage {
|
||||
&self,
|
||||
this: PaymentAttempt,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
this.update(&conn, payment_attempt).await
|
||||
@ -82,6 +91,7 @@ mod storage {
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentAttempt::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id).await
|
||||
@ -92,6 +102,7 @@ mod storage {
|
||||
transaction_id: &str,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentAttempt::find_by_transaction_id_payment_id_merchant_id(
|
||||
@ -107,6 +118,7 @@ mod storage {
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentAttempt::find_last_successful_attempt_by_payment_id_merchant_id(
|
||||
@ -121,6 +133,7 @@ mod storage {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
connector_txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
// TODO: update logic to lookup all payment attempts for an intent
|
||||
@ -137,6 +150,7 @@ mod storage {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
|
||||
@ -151,6 +165,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
_txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -159,6 +174,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
_connector_txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -167,6 +183,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
async fn insert_payment_attempt(
|
||||
&self,
|
||||
payment_attempt: PaymentAttemptNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let mut payment_attempts = self.payment_attempts.lock().await;
|
||||
let id = payment_attempts.len() as i32;
|
||||
@ -211,6 +228,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
&self,
|
||||
this: PaymentAttempt,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let mut payment_attempts = self.payment_attempts.lock().await;
|
||||
|
||||
@ -228,6 +246,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
&self,
|
||||
_payment_id: &str,
|
||||
_merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -237,6 +256,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
_transaction_id: &str,
|
||||
_payment_id: &str,
|
||||
_merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -245,6 +265,7 @@ impl PaymentAttemptInterface for MockDb {
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let payment_attempts = self.payment_attempts.lock().await;
|
||||
|
||||
@ -280,69 +301,142 @@ mod storage {
|
||||
async fn insert_payment_attempt(
|
||||
&self,
|
||||
payment_attempt: PaymentAttemptNew,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let key = format!(
|
||||
"{}_{}",
|
||||
payment_attempt.payment_id, payment_attempt.merchant_id
|
||||
);
|
||||
// TODO: need to add an application generated payment attempt id to distinguish between multiple attempts for the same payment id
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
let created_attempt = PaymentAttempt {
|
||||
id: 0i32,
|
||||
payment_id: payment_attempt.payment_id.clone(),
|
||||
merchant_id: payment_attempt.merchant_id.clone(),
|
||||
txn_id: payment_attempt.txn_id.clone(),
|
||||
status: payment_attempt.status,
|
||||
amount: payment_attempt.amount,
|
||||
currency: payment_attempt.currency,
|
||||
save_to_locker: payment_attempt.save_to_locker,
|
||||
connector: payment_attempt.connector.clone(),
|
||||
error_message: payment_attempt.error_message.clone(),
|
||||
offer_amount: payment_attempt.offer_amount,
|
||||
surcharge_amount: payment_attempt.surcharge_amount,
|
||||
tax_amount: payment_attempt.tax_amount,
|
||||
payment_method_id: payment_attempt.payment_method_id.clone(),
|
||||
payment_method: payment_attempt.payment_method,
|
||||
payment_flow: payment_attempt.payment_flow,
|
||||
redirect: payment_attempt.redirect,
|
||||
connector_transaction_id: payment_attempt.connector_transaction_id.clone(),
|
||||
capture_method: payment_attempt.capture_method,
|
||||
capture_on: payment_attempt.capture_on,
|
||||
confirm: payment_attempt.confirm,
|
||||
authentication_type: payment_attempt.authentication_type,
|
||||
created_at: payment_attempt.created_at.unwrap_or_else(date_time::now),
|
||||
modified_at: payment_attempt.created_at.unwrap_or_else(date_time::now),
|
||||
last_synced: payment_attempt.last_synced,
|
||||
amount_to_capture: payment_attempt.amount_to_capture,
|
||||
cancellation_reason: payment_attempt.cancellation_reason.clone(),
|
||||
mandate_id: payment_attempt.mandate_id.clone(),
|
||||
browser_info: payment_attempt.browser_info.clone(),
|
||||
};
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&created_attempt)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
match self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hsetnx::<u8, &str, &str, &str>(&key, "pa", &redis_value)
|
||||
.await
|
||||
{
|
||||
Ok(0) => Err(errors::StorageError::DuplicateValue(format!(
|
||||
"Payment Attempt already exists for payment_id: {}",
|
||||
key
|
||||
)))
|
||||
.into_report(),
|
||||
Ok(1) => {
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = payment_attempt
|
||||
.insert_diesel(&conn)
|
||||
payment_attempt.insert_diesel(&conn).await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
let key = format!(
|
||||
"{}_{}",
|
||||
payment_attempt.payment_id, payment_attempt.merchant_id
|
||||
);
|
||||
// TODO: need to add an application generated payment attempt id to distinguish between multiple attempts for the same payment id
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
let created_attempt = PaymentAttempt {
|
||||
id: 0i32,
|
||||
payment_id: payment_attempt.payment_id.clone(),
|
||||
merchant_id: payment_attempt.merchant_id.clone(),
|
||||
txn_id: payment_attempt.txn_id.clone(),
|
||||
status: payment_attempt.status,
|
||||
amount: payment_attempt.amount,
|
||||
currency: payment_attempt.currency,
|
||||
save_to_locker: payment_attempt.save_to_locker,
|
||||
connector: payment_attempt.connector.clone(),
|
||||
error_message: payment_attempt.error_message.clone(),
|
||||
offer_amount: payment_attempt.offer_amount,
|
||||
surcharge_amount: payment_attempt.surcharge_amount,
|
||||
tax_amount: payment_attempt.tax_amount,
|
||||
payment_method_id: payment_attempt.payment_method_id.clone(),
|
||||
payment_method: payment_attempt.payment_method,
|
||||
payment_flow: payment_attempt.payment_flow,
|
||||
redirect: payment_attempt.redirect,
|
||||
connector_transaction_id: payment_attempt.connector_transaction_id.clone(),
|
||||
capture_method: payment_attempt.capture_method,
|
||||
capture_on: payment_attempt.capture_on,
|
||||
confirm: payment_attempt.confirm,
|
||||
authentication_type: payment_attempt.authentication_type,
|
||||
created_at: payment_attempt.created_at.unwrap_or_else(date_time::now),
|
||||
modified_at: payment_attempt.created_at.unwrap_or_else(date_time::now),
|
||||
last_synced: payment_attempt.last_synced,
|
||||
amount_to_capture: payment_attempt.amount_to_capture,
|
||||
cancellation_reason: payment_attempt.cancellation_reason.clone(),
|
||||
mandate_id: payment_attempt.mandate_id.clone(),
|
||||
browser_info: payment_attempt.browser_info.clone(),
|
||||
};
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&created_attempt)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
match self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hsetnx::<u8, &str, &str, &str>(&key, "pa", &redis_value)
|
||||
.await
|
||||
{
|
||||
Ok(0) => Err(errors::StorageError::DuplicateValue(format!(
|
||||
"Payment Attempt already exists for payment_id: {}",
|
||||
key
|
||||
)))
|
||||
.into_report(),
|
||||
Ok(1) => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = payment_attempt
|
||||
.insert_diesel_query(&conn)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let stream_name = self.drainer_stream(&PaymentAttempt::shard_key(
|
||||
crate::utils::storage_partitioning::PartitionKey::MerchantIdPaymentId {
|
||||
merchant_id: &created_attempt.merchant_id,
|
||||
payment_id: &created_attempt.payment_id,
|
||||
},
|
||||
self.config.drainer_num_partitions,
|
||||
));
|
||||
self.redis_conn
|
||||
.stream_append_entry(
|
||||
&stream_name,
|
||||
&RedisEntryId::AutoGeneratedID,
|
||||
query.to_field_value_pairs(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
Ok(created_attempt)
|
||||
}
|
||||
Ok(i) => Err(errors::StorageError::KVError)
|
||||
.into_report()
|
||||
.attach_printable_lazy(|| {
|
||||
format!("Invalid response for HSETNX: {}", i)
|
||||
}),
|
||||
Err(er) => Err(er)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_payment_attempt(
|
||||
&self,
|
||||
this: PaymentAttempt,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
this.update(&conn, payment_attempt).await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
let key = format!("{}_{}", this.payment_id, this.merchant_id);
|
||||
|
||||
let updated_attempt = payment_attempt.clone().apply_changeset(this.clone());
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&updated_attempt)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let updated_attempt = self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hset::<u8, &str, (&str, String)>(&key, ("pa", redis_value))
|
||||
.await
|
||||
.map(|_| updated_attempt)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = this
|
||||
.update_query(&conn, payment_attempt)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let stream_name = self.drainer_stream(&PaymentAttempt::shard_key(
|
||||
crate::utils::storage_partitioning::PartitionKey::MerchantIdPaymentId {
|
||||
merchant_id: &created_attempt.merchant_id,
|
||||
payment_id: &created_attempt.payment_id,
|
||||
merchant_id: &updated_attempt.merchant_id,
|
||||
payment_id: &updated_attempt.payment_id,
|
||||
},
|
||||
self.config.drainer_num_partitions,
|
||||
));
|
||||
@ -354,80 +448,40 @@ mod storage {
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
Ok(created_attempt)
|
||||
Ok(updated_attempt)
|
||||
}
|
||||
Ok(i) => Err(errors::StorageError::KVError)
|
||||
.into_report()
|
||||
.attach_printable_lazy(|| format!("Invalid response for HSETNX: {}", i)),
|
||||
Err(er) => Err(er)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_payment_attempt(
|
||||
&self,
|
||||
this: PaymentAttempt,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let key = format!("{}_{}", this.payment_id, this.merchant_id);
|
||||
|
||||
let updated_attempt = payment_attempt.clone().apply_changeset(this.clone());
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&updated_attempt)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let updated_attempt = self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hset::<u8, &str, (&str, String)>(&key, ("pa", redis_value))
|
||||
.await
|
||||
.map(|_| updated_attempt)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = this
|
||||
.update(&conn, payment_attempt)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let stream_name = self.drainer_stream(&PaymentAttempt::shard_key(
|
||||
crate::utils::storage_partitioning::PartitionKey::MerchantIdPaymentId {
|
||||
merchant_id: &updated_attempt.merchant_id,
|
||||
payment_id: &updated_attempt.payment_id,
|
||||
},
|
||||
self.config.drainer_num_partitions,
|
||||
));
|
||||
self.redis_conn
|
||||
.stream_append_entry(
|
||||
&stream_name,
|
||||
&RedisEntryId::AutoGeneratedID,
|
||||
query.to_field_value_pairs(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
Ok(updated_attempt)
|
||||
}
|
||||
|
||||
async fn find_payment_attempt_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
let key = format!("{}_{}", payment_id, merchant_id);
|
||||
self.redis_conn
|
||||
.pool
|
||||
.hget::<String, String, &str>(key, "pa")
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)
|
||||
.and_then(|redis_resp| {
|
||||
serde_json::from_str::<PaymentAttempt>(&redis_resp)
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentAttempt::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id)
|
||||
.await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
let key = format!("{}_{}", payment_id, merchant_id);
|
||||
self.redis_conn
|
||||
.pool
|
||||
.hget::<String, String, &str>(key, "pa")
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)
|
||||
})
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
.and_then(|redis_resp| {
|
||||
serde_json::from_str::<PaymentAttempt>(&redis_resp)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)
|
||||
})
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_payment_attempt_by_transaction_id_payment_id_merchant_id(
|
||||
@ -435,54 +489,92 @@ mod storage {
|
||||
transaction_id: &str,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
// We assume that PaymentAttempt <=> PaymentIntent is a one-to-one relation for now
|
||||
self.find_payment_attempt_by_payment_id_merchant_id(payment_id, merchant_id)
|
||||
.await
|
||||
.and_then(|attempt| {
|
||||
if attempt.connector_transaction_id.as_deref() == Some(transaction_id) {
|
||||
Ok(attempt)
|
||||
} else {
|
||||
Err(errors::StorageError::ValueNotFound(format!(
|
||||
"Successful payment attempt does not exist for {}_{}",
|
||||
payment_id, merchant_id
|
||||
)))
|
||||
.into_report()
|
||||
}
|
||||
})
|
||||
self.find_payment_attempt_by_payment_id_merchant_id(
|
||||
payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.and_then(|attempt| {
|
||||
if attempt.connector_transaction_id.as_deref() == Some(transaction_id) {
|
||||
Ok(attempt)
|
||||
} else {
|
||||
Err(errors::StorageError::ValueNotFound(format!(
|
||||
"Successful payment attempt does not exist for {}_{}",
|
||||
payment_id, merchant_id
|
||||
)))
|
||||
.into_report()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
self.find_payment_attempt_by_payment_id_merchant_id(payment_id, merchant_id)
|
||||
.await
|
||||
.and_then(|attempt| match attempt.status {
|
||||
enums::AttemptStatus::Charged => Ok(attempt),
|
||||
_ => Err(errors::StorageError::ValueNotFound(format!(
|
||||
"Successful payment attempt does not exist for {}_{}",
|
||||
payment_id, merchant_id
|
||||
)))
|
||||
.into_report(),
|
||||
})
|
||||
self.find_payment_attempt_by_payment_id_merchant_id(
|
||||
payment_id,
|
||||
merchant_id,
|
||||
storage_scheme,
|
||||
)
|
||||
.await
|
||||
.and_then(|attempt| match attempt.status {
|
||||
enums::AttemptStatus::Charged => Ok(attempt),
|
||||
_ => Err(errors::StorageError::ValueNotFound(format!(
|
||||
"Successful payment attempt does not exist for {}_{}",
|
||||
payment_id, merchant_id
|
||||
)))
|
||||
.into_report(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn find_payment_attempt_by_merchant_id_connector_txn_id(
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
_connector_txn_id: &str,
|
||||
merchant_id: &str,
|
||||
connector_txn_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
Err(errors::StorageError::KVError).into_report()
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
// TODO: update logic to lookup all payment attempts for an intent
|
||||
// and apply filter logic on top of them to get the desired one.
|
||||
PaymentAttempt::find_by_merchant_id_connector_txn_id(
|
||||
&conn,
|
||||
merchant_id,
|
||||
connector_txn_id,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
Err(errors::StorageError::KVError).into_report()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_payment_attempt_by_merchant_id_txn_id(
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
_txn_id: &str,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentAttempt, errors::StorageError> {
|
||||
Err(errors::StorageError::KVError).into_report()
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentAttempt::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id)
|
||||
.await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
Err(errors::StorageError::KVError).into_report()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use crate::{
|
||||
core::errors::{self, CustomResult},
|
||||
types::{
|
||||
api,
|
||||
storage::{PaymentIntent, PaymentIntentNew, PaymentIntentUpdate},
|
||||
storage::{enums, PaymentIntent, PaymentIntentNew, PaymentIntentUpdate},
|
||||
},
|
||||
};
|
||||
|
||||
@ -13,23 +13,27 @@ pub trait PaymentIntentInterface {
|
||||
&self,
|
||||
this: PaymentIntent,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError>;
|
||||
|
||||
async fn insert_payment_intent(
|
||||
&self,
|
||||
new: PaymentIntentNew,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError>;
|
||||
|
||||
async fn find_payment_intent_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError>;
|
||||
|
||||
async fn filter_payment_intent_by_constraints(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
pc: &api::PaymentListConstraints,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<PaymentIntent>, errors::StorageError>;
|
||||
}
|
||||
|
||||
@ -45,7 +49,10 @@ mod storage {
|
||||
connection::pg_connection,
|
||||
core::errors::{self, CustomResult},
|
||||
services::Store,
|
||||
types::{api, storage::payment_intent::*},
|
||||
types::{
|
||||
api,
|
||||
storage::{enums, payment_intent::*},
|
||||
},
|
||||
utils::storage_partitioning::KvStorePartition,
|
||||
};
|
||||
|
||||
@ -54,56 +61,129 @@ mod storage {
|
||||
async fn insert_payment_intent(
|
||||
&self,
|
||||
new: PaymentIntentNew,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let key = format!("{}_{}", new.payment_id, new.merchant_id);
|
||||
let created_intent = PaymentIntent {
|
||||
id: 0i32,
|
||||
payment_id: new.payment_id.clone(),
|
||||
merchant_id: new.merchant_id.clone(),
|
||||
status: new.status,
|
||||
amount: new.amount,
|
||||
currency: new.currency,
|
||||
amount_captured: new.amount_captured,
|
||||
customer_id: new.customer_id.clone(),
|
||||
description: new.description.clone(),
|
||||
return_url: new.return_url.clone(),
|
||||
metadata: new.metadata.clone(),
|
||||
connector_id: new.connector_id.clone(),
|
||||
shipping_address_id: new.shipping_address_id.clone(),
|
||||
billing_address_id: new.billing_address_id.clone(),
|
||||
statement_descriptor_name: new.statement_descriptor_name.clone(),
|
||||
statement_descriptor_suffix: new.statement_descriptor_suffix.clone(),
|
||||
created_at: new.created_at.unwrap_or_else(date_time::now),
|
||||
modified_at: new.created_at.unwrap_or_else(date_time::now),
|
||||
last_synced: new.last_synced,
|
||||
setup_future_usage: new.setup_future_usage,
|
||||
off_session: new.off_session,
|
||||
client_secret: new.client_secret.clone(),
|
||||
};
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&created_intent)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
match self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hsetnx::<u8, &str, &str, &str>(&key, "pi", &redis_value)
|
||||
.await
|
||||
{
|
||||
Ok(0) => Err(errors::StorageError::DuplicateValue(format!(
|
||||
"Payment Intent already exists for payment_id: {key}"
|
||||
)))
|
||||
.into_report(),
|
||||
Ok(1) => {
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = new
|
||||
.insert_diesel(&conn)
|
||||
new.insert_diesel(&conn).await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
let key = format!("{}_{}", new.payment_id, new.merchant_id);
|
||||
let created_intent = PaymentIntent {
|
||||
id: 0i32,
|
||||
payment_id: new.payment_id.clone(),
|
||||
merchant_id: new.merchant_id.clone(),
|
||||
status: new.status,
|
||||
amount: new.amount,
|
||||
currency: new.currency,
|
||||
amount_captured: new.amount_captured,
|
||||
customer_id: new.customer_id.clone(),
|
||||
description: new.description.clone(),
|
||||
return_url: new.return_url.clone(),
|
||||
metadata: new.metadata.clone(),
|
||||
connector_id: new.connector_id.clone(),
|
||||
shipping_address_id: new.shipping_address_id.clone(),
|
||||
billing_address_id: new.billing_address_id.clone(),
|
||||
statement_descriptor_name: new.statement_descriptor_name.clone(),
|
||||
statement_descriptor_suffix: new.statement_descriptor_suffix.clone(),
|
||||
created_at: new.created_at.unwrap_or_else(date_time::now),
|
||||
modified_at: new.created_at.unwrap_or_else(date_time::now),
|
||||
last_synced: new.last_synced,
|
||||
setup_future_usage: new.setup_future_usage,
|
||||
off_session: new.off_session,
|
||||
client_secret: new.client_secret.clone(),
|
||||
};
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&created_intent)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
match self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hsetnx::<u8, &str, &str, &str>(&key, "pi", &redis_value)
|
||||
.await
|
||||
{
|
||||
Ok(0) => Err(errors::StorageError::DuplicateValue(format!(
|
||||
"Payment Intent already exists for payment_id: {key}"
|
||||
)))
|
||||
.into_report(),
|
||||
Ok(1) => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = new
|
||||
.insert_diesel_query(&conn)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let stream_name = self.drainer_stream(&PaymentIntent::shard_key(
|
||||
crate::utils::storage_partitioning::PartitionKey::MerchantIdPaymentId {
|
||||
merchant_id: &created_intent.merchant_id,
|
||||
payment_id: &created_intent.payment_id,
|
||||
},
|
||||
self.config.drainer_num_partitions,
|
||||
));
|
||||
self.redis_conn
|
||||
.stream_append_entry(
|
||||
&stream_name,
|
||||
&RedisEntryId::AutoGeneratedID,
|
||||
query.to_field_value_pairs(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
Ok(created_intent)
|
||||
}
|
||||
Ok(i) => Err(errors::StorageError::KVError)
|
||||
.into_report()
|
||||
.attach_printable_lazy(|| {
|
||||
format!("Invalid response for HSETNX: {}", i)
|
||||
}),
|
||||
Err(er) => Err(er)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_payment_intent(
|
||||
&self,
|
||||
this: PaymentIntent,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
this.update(&conn, payment_intent).await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
let key = format!("{}_{}", this.payment_id, this.merchant_id);
|
||||
|
||||
let updated_intent = payment_intent.clone().apply_changeset(this.clone());
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&updated_intent)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let updated_intent = self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hset::<u8, &str, (&str, String)>(&key, ("pi", redis_value))
|
||||
.await
|
||||
.map(|_| updated_intent)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = this
|
||||
.update_query(&conn, payment_intent)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let stream_name = self.drainer_stream(&PaymentIntent::shard_key(
|
||||
crate::utils::storage_partitioning::PartitionKey::MerchantIdPaymentId {
|
||||
merchant_id: &created_intent.merchant_id,
|
||||
payment_id: &created_intent.payment_id,
|
||||
merchant_id: &updated_intent.merchant_id,
|
||||
payment_id: &updated_intent.payment_id,
|
||||
},
|
||||
self.config.drainer_num_partitions,
|
||||
));
|
||||
@ -115,94 +195,64 @@ mod storage {
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
Ok(created_intent)
|
||||
Ok(updated_intent)
|
||||
}
|
||||
Ok(i) => Err(errors::StorageError::KVError)
|
||||
.into_report()
|
||||
.attach_printable_lazy(|| format!("Invalid response for HSETNX: {}", i)),
|
||||
Err(er) => Err(er)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_payment_intent(
|
||||
&self,
|
||||
this: PaymentIntent,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let key = format!("{}_{}", this.payment_id, this.merchant_id);
|
||||
|
||||
let updated_intent = payment_intent.clone().apply_changeset(this.clone());
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
// TODO: Add a proper error for serialization failure
|
||||
let redis_value = serde_json::to_string(&updated_intent)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let updated_intent = self
|
||||
.redis_conn
|
||||
.pool
|
||||
.hset::<u8, &str, (&str, String)>(&key, ("pi", redis_value))
|
||||
.await
|
||||
.map(|_| updated_intent)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
let query = this
|
||||
.update(&conn, payment_intent)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
let stream_name = self.drainer_stream(&PaymentIntent::shard_key(
|
||||
crate::utils::storage_partitioning::PartitionKey::MerchantIdPaymentId {
|
||||
merchant_id: &updated_intent.merchant_id,
|
||||
payment_id: &updated_intent.payment_id,
|
||||
},
|
||||
self.config.drainer_num_partitions,
|
||||
));
|
||||
self.redis_conn
|
||||
.stream_append_entry(
|
||||
&stream_name,
|
||||
&RedisEntryId::AutoGeneratedID,
|
||||
query.to_field_value_pairs(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::KVError)?;
|
||||
Ok(updated_intent)
|
||||
}
|
||||
|
||||
async fn find_payment_intent_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let key = format!("{}_{}", payment_id, merchant_id);
|
||||
self.redis_conn
|
||||
.pool
|
||||
.hget::<String, &str, &str>(&key, "pi")
|
||||
.await
|
||||
.map_err(|err| match err.kind() {
|
||||
RedisErrorKind::NotFound => errors::StorageError::ValueNotFound(format!(
|
||||
"Payment Intent does not exist for {}",
|
||||
key
|
||||
)),
|
||||
_ => errors::StorageError::KVError,
|
||||
})
|
||||
.into_report()
|
||||
.and_then(|redis_resp| {
|
||||
serde_json::from_str::<PaymentIntent>(&redis_resp)
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentIntent::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id)
|
||||
.await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
let key = format!("{}_{}", payment_id, merchant_id);
|
||||
self.redis_conn
|
||||
.pool
|
||||
.hget::<String, &str, &str>(&key, "pi")
|
||||
.await
|
||||
.map_err(|err| match err.kind() {
|
||||
RedisErrorKind::NotFound => errors::StorageError::ValueNotFound(
|
||||
format!("Payment Intent does not exist for {}", key),
|
||||
),
|
||||
_ => errors::StorageError::KVError,
|
||||
})
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)
|
||||
})
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
.and_then(|redis_resp| {
|
||||
serde_json::from_str::<PaymentIntent>(&redis_resp)
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::KVError)
|
||||
})
|
||||
// Check for database presence as well Maybe use a read replica here ?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn filter_payment_intent_by_constraints(
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
_pc: &api::PaymentListConstraints,
|
||||
merchant_id: &str,
|
||||
pc: &api::PaymentListConstraints,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<PaymentIntent>, errors::StorageError> {
|
||||
//TODO: Implement this
|
||||
Err(errors::StorageError::KVError.into())
|
||||
match storage_scheme {
|
||||
enums::MerchantStorageScheme::PostgresOnly => {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentIntent::filter_by_constraints(&conn, merchant_id, pc).await
|
||||
}
|
||||
|
||||
enums::MerchantStorageScheme::RedisKv => {
|
||||
//TODO: Implement this
|
||||
Err(errors::StorageError::KVError.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,7 +264,10 @@ mod storage {
|
||||
connection::pg_connection,
|
||||
core::errors::{self, CustomResult},
|
||||
services::Store,
|
||||
types::{api, storage::payment_intent::*},
|
||||
types::{
|
||||
api,
|
||||
storage::{enums, payment_intent::*},
|
||||
},
|
||||
};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -222,6 +275,7 @@ mod storage {
|
||||
async fn insert_payment_intent(
|
||||
&self,
|
||||
new: PaymentIntentNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
new.insert_diesel(&conn).await
|
||||
@ -231,6 +285,7 @@ mod storage {
|
||||
&self,
|
||||
this: PaymentIntent,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
this.update(&conn, payment_intent).await
|
||||
@ -240,6 +295,7 @@ mod storage {
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentIntent::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id).await
|
||||
@ -249,6 +305,7 @@ mod storage {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
pc: &api::PaymentListConstraints,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<PaymentIntent>, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
PaymentIntent::filter_by_constraints(&conn, merchant_id, pc).await
|
||||
@ -262,6 +319,7 @@ impl PaymentIntentInterface for MockDb {
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
_pc: &api::PaymentListConstraints,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<PaymentIntent>, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -270,6 +328,7 @@ impl PaymentIntentInterface for MockDb {
|
||||
async fn insert_payment_intent(
|
||||
&self,
|
||||
new: PaymentIntentNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let mut payment_intents = self.payment_intents.lock().await;
|
||||
let time = common_utils::date_time::now();
|
||||
@ -305,6 +364,7 @@ impl PaymentIntentInterface for MockDb {
|
||||
&self,
|
||||
this: PaymentIntent,
|
||||
update: PaymentIntentUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let mut payment_intents = self.payment_intents.lock().await;
|
||||
let payment_intent = payment_intents
|
||||
@ -319,6 +379,7 @@ impl PaymentIntentInterface for MockDb {
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<PaymentIntent, errors::StorageError> {
|
||||
let payment_intents = self.payment_intents.lock().await;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ use super::MockDb;
|
||||
use crate::{
|
||||
connection::pg_connection,
|
||||
core::errors::{self, CustomResult, DatabaseError, StorageError},
|
||||
types::storage::{Refund, RefundNew, RefundUpdate},
|
||||
types::storage::{enums, Refund, RefundNew, RefundUpdate},
|
||||
};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -13,12 +13,14 @@ pub trait RefundInterface {
|
||||
&self,
|
||||
internal_reference_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError>;
|
||||
|
||||
async fn find_refund_by_payment_id_merchant_id(
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<Refund>, errors::StorageError>;
|
||||
|
||||
// async fn find_refund_by_payment_id_merchant_id_refund_id(
|
||||
@ -32,21 +34,28 @@ pub trait RefundInterface {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
refund_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError>;
|
||||
|
||||
async fn update_refund(
|
||||
&self,
|
||||
this: Refund,
|
||||
refund: RefundUpdate,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError>;
|
||||
|
||||
async fn find_refund_by_merchant_id_transaction_id(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<Refund>, errors::StorageError>;
|
||||
|
||||
async fn insert_refund(&self, new: RefundNew) -> CustomResult<Refund, errors::StorageError>;
|
||||
async fn insert_refund(
|
||||
&self,
|
||||
new: RefundNew,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -55,13 +64,18 @@ impl RefundInterface for super::Store {
|
||||
&self,
|
||||
internal_reference_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
Refund::find_by_internal_reference_id_merchant_id(&conn, internal_reference_id, merchant_id)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn insert_refund(&self, new: RefundNew) -> CustomResult<Refund, errors::StorageError> {
|
||||
async fn insert_refund(
|
||||
&self,
|
||||
new: RefundNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
new.insert(&conn).await
|
||||
}
|
||||
@ -69,6 +83,7 @@ impl RefundInterface for super::Store {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<Refund>, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
Refund::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id).await
|
||||
@ -78,6 +93,7 @@ impl RefundInterface for super::Store {
|
||||
&self,
|
||||
this: Refund,
|
||||
refund: RefundUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
this.update(&conn, refund).await
|
||||
@ -87,6 +103,7 @@ impl RefundInterface for super::Store {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
refund_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
Refund::find_by_merchant_id_refund_id(&conn, merchant_id, refund_id).await
|
||||
@ -107,6 +124,7 @@ impl RefundInterface for super::Store {
|
||||
&self,
|
||||
payment_id: &str,
|
||||
merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<Refund>, errors::StorageError> {
|
||||
let conn = pg_connection(&self.master_pool).await;
|
||||
Refund::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id).await
|
||||
@ -119,11 +137,16 @@ impl RefundInterface for MockDb {
|
||||
&self,
|
||||
_internal_reference_id: &str,
|
||||
_merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn insert_refund(&self, new: RefundNew) -> CustomResult<Refund, errors::StorageError> {
|
||||
async fn insert_refund(
|
||||
&self,
|
||||
new: RefundNew,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
let mut refunds = self.refunds.lock().await;
|
||||
let current_time = common_utils::date_time::now();
|
||||
|
||||
@ -157,6 +180,7 @@ impl RefundInterface for MockDb {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
txn_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<Refund>, errors::StorageError> {
|
||||
let refunds = self.refunds.lock().await;
|
||||
|
||||
@ -173,6 +197,7 @@ impl RefundInterface for MockDb {
|
||||
&self,
|
||||
_this: Refund,
|
||||
_refund: RefundUpdate,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
@ -181,6 +206,7 @@ impl RefundInterface for MockDb {
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
refund_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Refund, errors::StorageError> {
|
||||
let refunds = self.refunds.lock().await;
|
||||
|
||||
@ -195,6 +221,7 @@ impl RefundInterface for MockDb {
|
||||
&self,
|
||||
_payment_id: &str,
|
||||
_merchant_id: &str,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<Vec<Refund>, errors::StorageError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@ -121,7 +121,6 @@ pub fn mk_app(
|
||||
/// Unwrap used because without the value we can't start the server
|
||||
pub async fn start_server(conf: Settings) -> BachResult<(Server, AppState)> {
|
||||
logger::debug!(startup_config=?conf);
|
||||
|
||||
let server = conf.server.clone();
|
||||
let state = routes::AppState::new(conf).await;
|
||||
// Cloning to close connections before shutdown
|
||||
|
||||
@ -150,6 +150,7 @@ diesel::table! {
|
||||
sub_merchants_enabled -> Nullable<Bool>,
|
||||
parent_merchant_id -> Nullable<Varchar>,
|
||||
publishable_key -> Nullable<Varchar>,
|
||||
storage_scheme -> MerchantStorageScheme,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,11 @@ use crate::{
|
||||
db::StorageInterface,
|
||||
logger, routes,
|
||||
routes::AppState,
|
||||
types::{self, api, storage, ErrorResponse, Response},
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
ErrorResponse, Response,
|
||||
},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
@ -556,6 +560,7 @@ pub async fn authenticate_merchant<'a>(
|
||||
payment_response_hash_key: None,
|
||||
redirect_to_merchant_with_http_post: false,
|
||||
publishable_key: None,
|
||||
storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,8 @@ pub mod diesel_exports {
|
||||
DbEventClass as EventClass, DbEventObjectType as EventObjectType, DbEventType as EventType,
|
||||
DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus,
|
||||
DbMandateStatus as MandateStatus, DbMandateType as MandateType,
|
||||
DbPaymentFlow as PaymentFlow, DbPaymentMethodIssuerCode as PaymentMethodIssuerCode,
|
||||
DbMerchantStorageScheme as MerchantStorageScheme, DbPaymentFlow as PaymentFlow,
|
||||
DbPaymentMethodIssuerCode as PaymentMethodIssuerCode,
|
||||
DbPaymentMethodSubType as PaymentMethodSubType, DbPaymentMethodType as PaymentMethodType,
|
||||
DbProcessTrackerStatus as ProcessTrackerStatus, DbRefundStatus as RefundStatus,
|
||||
DbRefundType as RefundType, DbRoutingAlgorithm as RoutingAlgorithm,
|
||||
@ -362,6 +363,28 @@ pub enum FutureUsage {
|
||||
OnSession,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Default,
|
||||
Eq,
|
||||
PartialEq,
|
||||
serde::Deserialize,
|
||||
serde::Serialize,
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
router_derive::DieselEnum,
|
||||
)]
|
||||
#[router_derive::diesel_enum]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum MerchantStorageScheme {
|
||||
#[default]
|
||||
PostgresOnly,
|
||||
RedisKv,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
|
||||
@ -20,6 +20,7 @@ pub struct MerchantAccount {
|
||||
pub sub_merchants_enabled: Option<bool>,
|
||||
pub parent_merchant_id: Option<String>,
|
||||
pub publishable_key: Option<String>,
|
||||
pub storage_scheme: enums::MerchantStorageScheme,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)]
|
||||
|
||||
@ -238,7 +238,12 @@ mod tests {
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::*;
|
||||
use crate::{configs::settings::Settings, db::StorageImpl, routes, types};
|
||||
use crate::{
|
||||
configs::settings::Settings,
|
||||
db::StorageImpl,
|
||||
routes,
|
||||
types::{self, storage::enums},
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
#[ignore]
|
||||
@ -259,7 +264,7 @@ mod tests {
|
||||
|
||||
let response = state
|
||||
.store
|
||||
.insert_payment_attempt(payment_attempt)
|
||||
.insert_payment_attempt(payment_attempt, enums::MerchantStorageScheme::PostgresOnly)
|
||||
.await
|
||||
.unwrap();
|
||||
eprintln!("{:?}", response);
|
||||
@ -289,13 +294,17 @@ mod tests {
|
||||
};
|
||||
state
|
||||
.store
|
||||
.insert_payment_attempt(payment_attempt)
|
||||
.insert_payment_attempt(payment_attempt, enums::MerchantStorageScheme::PostgresOnly)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let response = state
|
||||
.store
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&payment_id, &merchant_id)
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&payment_id,
|
||||
&merchant_id,
|
||||
enums::MerchantStorageScheme::PostgresOnly,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -326,13 +335,17 @@ mod tests {
|
||||
};
|
||||
state
|
||||
.store
|
||||
.insert_payment_attempt(payment_attempt)
|
||||
.insert_payment_attempt(payment_attempt, enums::MerchantStorageScheme::PostgresOnly)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let response = state
|
||||
.store
|
||||
.find_payment_attempt_by_payment_id_merchant_id(&uuid, "1")
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
&uuid,
|
||||
"1",
|
||||
enums::MerchantStorageScheme::PostgresOnly,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
// checking it after fetch
|
||||
|
||||
@ -8,7 +8,7 @@ use router_env::tracing::{self, instrument};
|
||||
#[cfg(not(feature = "kv_store"))]
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
#[cfg(feature = "kv_store")]
|
||||
use super::generics::{self, RawQuery, RawSqlQuery};
|
||||
use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery};
|
||||
use crate::{
|
||||
connection::PgPooledConn,
|
||||
core::errors::{self, CustomResult},
|
||||
@ -21,7 +21,6 @@ use crate::{
|
||||
};
|
||||
|
||||
impl PaymentAttemptNew {
|
||||
#[cfg(not(feature = "kv_store"))]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert_diesel(
|
||||
self,
|
||||
@ -32,7 +31,7 @@ impl PaymentAttemptNew {
|
||||
|
||||
#[cfg(feature = "kv_store")]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert_diesel(
|
||||
pub async fn insert_diesel_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<RawSqlQuery, errors::StorageError> {
|
||||
@ -41,7 +40,6 @@ impl PaymentAttemptNew {
|
||||
}
|
||||
|
||||
impl PaymentAttempt {
|
||||
#[cfg(not(feature = "kv_store"))]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn update(
|
||||
self,
|
||||
@ -68,7 +66,7 @@ impl PaymentAttempt {
|
||||
|
||||
#[cfg(feature = "kv_store")]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn update(
|
||||
pub async fn update_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
|
||||
@ -6,7 +6,7 @@ use router_env::tracing::{self, instrument};
|
||||
#[cfg(not(feature = "kv_store"))]
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
#[cfg(feature = "kv_store")]
|
||||
use super::generics::{self, RawQuery, RawSqlQuery};
|
||||
use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery};
|
||||
use crate::{
|
||||
connection::PgPooledConn,
|
||||
core::errors::{self, CustomResult},
|
||||
@ -20,7 +20,6 @@ use crate::{
|
||||
};
|
||||
|
||||
impl PaymentIntentNew {
|
||||
#[cfg(not(feature = "kv_store"))]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert_diesel(
|
||||
self,
|
||||
@ -31,7 +30,7 @@ impl PaymentIntentNew {
|
||||
|
||||
#[cfg(feature = "kv_store")]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert_diesel(
|
||||
pub async fn insert_diesel_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<RawSqlQuery, errors::StorageError> {
|
||||
@ -40,7 +39,6 @@ impl PaymentIntentNew {
|
||||
}
|
||||
|
||||
impl PaymentIntent {
|
||||
#[cfg(not(feature = "kv_store"))]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn update(
|
||||
self,
|
||||
@ -67,7 +65,7 @@ impl PaymentIntent {
|
||||
|
||||
#[cfg(feature = "kv_store")]
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn update(
|
||||
pub async fn update_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
|
||||
Reference in New Issue
Block a user