mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 17:47:54 +08:00
feat(core): Add support for process tracker retrieve api in v2 (#7602)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -3264,6 +3264,56 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/v2/process_tracker/revenue_recovery_workflow/{revenue_recovery_id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Revenue Recovery"
|
||||||
|
],
|
||||||
|
"summary": "Revenue Recovery - Retrieve",
|
||||||
|
"description": "Retrieve the Revenue Recovery Payment Info",
|
||||||
|
"operationId": "Retrieve Revenue Recovery Info",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "recovery_recovery_id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "The payment intent id",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Revenue Recovery Info Retrieved Successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/RevenueRecoveryResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Resource missing"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Unprocessable request"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"jwt_key": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
@ -19057,6 +19107,17 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"ProcessTrackerStatus": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"processing",
|
||||||
|
"new",
|
||||||
|
"pending",
|
||||||
|
"process_started",
|
||||||
|
"finish",
|
||||||
|
"review"
|
||||||
|
]
|
||||||
|
},
|
||||||
"ProcessorPaymentToken": {
|
"ProcessorPaymentToken": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Processor payment token for MIT payments where payment_method_data is not available",
|
"description": "Processor payment token for MIT payments where payment_method_data is not available",
|
||||||
@ -20560,6 +20621,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"RevenueRecoveryResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"status",
|
||||||
|
"business_status"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"schedule_time_for_payment": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"schedule_time_for_psync": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"$ref": "#/components/schemas/ProcessTrackerStatus"
|
||||||
|
},
|
||||||
|
"business_status": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"RevokeApiKeyResponse": {
|
"RevokeApiKeyResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "The response body for revoking an API Key.",
|
"description": "The response body for revoking an API Key.",
|
||||||
|
|||||||
@ -11,10 +11,11 @@ pub mod payouts;
|
|||||||
#[cfg(feature = "recon")]
|
#[cfg(feature = "recon")]
|
||||||
pub mod recon;
|
pub mod recon;
|
||||||
pub mod refund;
|
pub mod refund;
|
||||||
|
#[cfg(feature = "v2")]
|
||||||
|
pub mod revenue_recovery;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod user_role;
|
pub mod user_role;
|
||||||
|
|
||||||
use common_utils::{
|
use common_utils::{
|
||||||
events::{ApiEventMetric, ApiEventsType},
|
events::{ApiEventMetric, ApiEventsType},
|
||||||
impl_api_event_type,
|
impl_api_event_type,
|
||||||
|
|||||||
14
crates/api_models/src/events/revenue_recovery.rs
Normal file
14
crates/api_models/src/events/revenue_recovery.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||||
|
|
||||||
|
use crate::process_tracker::revenue_recovery::{RevenueRecoveryId, RevenueRecoveryResponse};
|
||||||
|
|
||||||
|
impl ApiEventMetric for RevenueRecoveryResponse {
|
||||||
|
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||||
|
Some(ApiEventsType::ProcessTracker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ApiEventMetric for RevenueRecoveryId {
|
||||||
|
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||||
|
Some(ApiEventsType::ProcessTracker)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,6 +30,7 @@ pub mod payments;
|
|||||||
pub mod payouts;
|
pub mod payouts;
|
||||||
pub mod pm_auth;
|
pub mod pm_auth;
|
||||||
pub mod poll;
|
pub mod poll;
|
||||||
|
pub mod process_tracker;
|
||||||
#[cfg(feature = "recon")]
|
#[cfg(feature = "recon")]
|
||||||
pub mod recon;
|
pub mod recon;
|
||||||
pub mod refunds;
|
pub mod refunds;
|
||||||
|
|||||||
2
crates/api_models/src/process_tracker.rs
Normal file
2
crates/api_models/src/process_tracker.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(feature = "v2")]
|
||||||
|
pub mod revenue_recovery;
|
||||||
21
crates/api_models/src/process_tracker/revenue_recovery.rs
Normal file
21
crates/api_models/src/process_tracker/revenue_recovery.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use common_utils::id_type;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use time::PrimitiveDateTime;
|
||||||
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
|
use crate::enums;
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
pub struct RevenueRecoveryResponse {
|
||||||
|
pub id: String,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub schedule_time_for_payment: Option<PrimitiveDateTime>,
|
||||||
|
pub schedule_time_for_psync: Option<PrimitiveDateTime>,
|
||||||
|
#[schema(value_type = ProcessTrackerStatus, example = "finish")]
|
||||||
|
pub status: enums::ProcessTrackerStatus,
|
||||||
|
pub business_status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
pub struct RevenueRecoveryId {
|
||||||
|
pub revenue_recovery_id: id_type::GlobalPaymentId,
|
||||||
|
}
|
||||||
@ -21,7 +21,8 @@ pub mod diesel_exports {
|
|||||||
DbDisputeStatus as DisputeStatus, DbFraudCheckStatus as FraudCheckStatus,
|
DbDisputeStatus as DisputeStatus, DbFraudCheckStatus as FraudCheckStatus,
|
||||||
DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus,
|
DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus,
|
||||||
DbMandateStatus as MandateStatus, DbPaymentMethodIssuerCode as PaymentMethodIssuerCode,
|
DbMandateStatus as MandateStatus, DbPaymentMethodIssuerCode as PaymentMethodIssuerCode,
|
||||||
DbPaymentType as PaymentType, DbRefundStatus as RefundStatus,
|
DbPaymentType as PaymentType, DbProcessTrackerStatus as ProcessTrackerStatus,
|
||||||
|
DbRefundStatus as RefundStatus,
|
||||||
DbRequestIncrementalAuthorization as RequestIncrementalAuthorization,
|
DbRequestIncrementalAuthorization as RequestIncrementalAuthorization,
|
||||||
DbScaExemptionType as ScaExemptionType,
|
DbScaExemptionType as ScaExemptionType,
|
||||||
DbSuccessBasedRoutingConclusiveState as SuccessBasedRoutingConclusiveState,
|
DbSuccessBasedRoutingConclusiveState as SuccessBasedRoutingConclusiveState,
|
||||||
@ -6980,6 +6981,7 @@ pub enum Resource {
|
|||||||
ReconReports,
|
ReconReports,
|
||||||
RunRecon,
|
RunRecon,
|
||||||
ReconConfig,
|
ReconConfig,
|
||||||
|
RevenueRecovery,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, serde::Serialize, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, serde::Serialize, Hash)]
|
||||||
@ -7819,6 +7821,60 @@ pub enum TriggeredBy {
|
|||||||
External,
|
External,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
PartialEq,
|
||||||
|
serde::Deserialize,
|
||||||
|
serde::Serialize,
|
||||||
|
strum::Display,
|
||||||
|
strum::EnumString,
|
||||||
|
ToSchema,
|
||||||
|
)]
|
||||||
|
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
pub enum ProcessTrackerStatus {
|
||||||
|
// Picked by the producer
|
||||||
|
Processing,
|
||||||
|
// State when the task is added
|
||||||
|
New,
|
||||||
|
// Send to retry
|
||||||
|
Pending,
|
||||||
|
// Picked by consumer
|
||||||
|
ProcessStarted,
|
||||||
|
// Finished by consumer
|
||||||
|
Finish,
|
||||||
|
// Review the task
|
||||||
|
Review,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
serde::Serialize,
|
||||||
|
serde::Deserialize,
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
strum::EnumString,
|
||||||
|
strum::Display,
|
||||||
|
)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
pub enum ProcessTrackerRunner {
|
||||||
|
PaymentsSyncWorkflow,
|
||||||
|
RefundWorkflowRouter,
|
||||||
|
DeleteTokenizeDataWorkflow,
|
||||||
|
ApiKeyExpiryWorkflow,
|
||||||
|
OutgoingWebhookRetryWorkflow,
|
||||||
|
AttachPayoutAccountWorkflow,
|
||||||
|
PaymentMethodStatusUpdateWorkflow,
|
||||||
|
PassiveRecoveryWorkflow,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CryptoPadding {
|
pub enum CryptoPadding {
|
||||||
PKCS7,
|
PKCS7,
|
||||||
|
|||||||
@ -121,6 +121,7 @@ pub enum ApiEventsType {
|
|||||||
PaymentMethodSession {
|
PaymentMethodSession {
|
||||||
payment_method_session_id: id_type::GlobalPaymentMethodSessionId,
|
payment_method_session_id: id_type::GlobalPaymentMethodSessionId,
|
||||||
},
|
},
|
||||||
|
ProcessTracker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiEventMetric for serde_json::Value {}
|
impl ApiEventMetric for serde_json::Value {}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use common_enums::enums;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
|
|
||||||
use crate::{errors, generate_id_with_default_len, generate_time_ordered_id_without_prefix, types};
|
use crate::{errors, generate_id_with_default_len, generate_time_ordered_id_without_prefix, types};
|
||||||
@ -31,6 +32,15 @@ impl GlobalPaymentId {
|
|||||||
pub fn generate_client_secret(&self) -> types::ClientSecret {
|
pub fn generate_client_secret(&self) -> types::ClientSecret {
|
||||||
types::ClientSecret::new(self.clone(), generate_time_ordered_id_without_prefix())
|
types::ClientSecret::new(self.clone(), generate_time_ordered_id_without_prefix())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate the id for revenue recovery Execute PT workflow
|
||||||
|
pub fn get_execute_revenue_recovery_id(
|
||||||
|
&self,
|
||||||
|
task: &str,
|
||||||
|
runner: enums::ProcessTrackerRunner,
|
||||||
|
) -> String {
|
||||||
|
format!("{task}_{runner}_{}", self.get_string_repr())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor the macro to include this id use case as well
|
// TODO: refactor the macro to include this id use case as well
|
||||||
@ -67,6 +77,15 @@ impl GlobalAttemptId {
|
|||||||
pub fn get_string_repr(&self) -> &str {
|
pub fn get_string_repr(&self) -> &str {
|
||||||
self.0.get_string_repr()
|
self.0.get_string_repr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate the id for Revenue Recovery Psync PT workflow
|
||||||
|
pub fn get_psync_revenue_recovery_id(
|
||||||
|
&self,
|
||||||
|
task: &str,
|
||||||
|
runner: enums::ProcessTrackerRunner,
|
||||||
|
) -> String {
|
||||||
|
format!("{runner}_{task}_{}", self.get_string_repr())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<std::borrow::Cow<'static, str>> for GlobalAttemptId {
|
impl TryFrom<std::borrow::Cow<'static, str>> for GlobalAttemptId {
|
||||||
|
|||||||
@ -78,35 +78,6 @@ pub enum EventObjectType {
|
|||||||
PayoutDetails,
|
PayoutDetails,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
|
||||||
Clone,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
Eq,
|
|
||||||
PartialEq,
|
|
||||||
serde::Deserialize,
|
|
||||||
serde::Serialize,
|
|
||||||
strum::Display,
|
|
||||||
strum::EnumString,
|
|
||||||
)]
|
|
||||||
#[diesel_enum(storage_type = "db_enum")]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
#[strum(serialize_all = "snake_case")]
|
|
||||||
pub enum ProcessTrackerStatus {
|
|
||||||
// Picked by the producer
|
|
||||||
Processing,
|
|
||||||
// State when the task is added
|
|
||||||
New,
|
|
||||||
// Send to retry
|
|
||||||
Pending,
|
|
||||||
// Picked by consumer
|
|
||||||
ProcessStarted,
|
|
||||||
// Finished by consumer
|
|
||||||
Finish,
|
|
||||||
// Review the task
|
|
||||||
Review,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refund
|
// Refund
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use common_enums::ApiVersion;
|
pub use common_enums::{enums::ProcessTrackerRunner, ApiVersion};
|
||||||
use common_utils::ext_traits::Encode;
|
use common_utils::ext_traits::Encode;
|
||||||
use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
|
use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
@ -196,30 +196,6 @@ impl From<ProcessTrackerUpdate> for ProcessTrackerUpdateInternal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
|
||||||
serde::Serialize,
|
|
||||||
serde::Deserialize,
|
|
||||||
Clone,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
PartialEq,
|
|
||||||
Eq,
|
|
||||||
strum::EnumString,
|
|
||||||
strum::Display,
|
|
||||||
)]
|
|
||||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
|
||||||
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
|
|
||||||
pub enum ProcessTrackerRunner {
|
|
||||||
PaymentsSyncWorkflow,
|
|
||||||
RefundWorkflowRouter,
|
|
||||||
DeleteTokenizeDataWorkflow,
|
|
||||||
ApiKeyExpiryWorkflow,
|
|
||||||
OutgoingWebhookRetryWorkflow,
|
|
||||||
AttachPayoutAccountWorkflow,
|
|
||||||
PaymentMethodStatusUpdateWorkflow,
|
|
||||||
PassiveRecoveryWorkflow,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
|||||||
@ -148,6 +148,9 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
|
|
||||||
//Routes for refunds
|
//Routes for refunds
|
||||||
routes::refunds::refunds_create,
|
routes::refunds::refunds_create,
|
||||||
|
|
||||||
|
// Routes for Revenue Recovery flow under Process Tracker
|
||||||
|
routes::revenue_recovery::revenue_recovery_pt_retrieve_api
|
||||||
),
|
),
|
||||||
components(schemas(
|
components(schemas(
|
||||||
common_utils::types::MinorUnit,
|
common_utils::types::MinorUnit,
|
||||||
@ -708,6 +711,8 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
api_models::payment_methods::PaymentMethodSessionConfirmRequest,
|
api_models::payment_methods::PaymentMethodSessionConfirmRequest,
|
||||||
api_models::payment_methods::PaymentMethodSessionResponse,
|
api_models::payment_methods::PaymentMethodSessionResponse,
|
||||||
api_models::payment_methods::AuthenticationDetails,
|
api_models::payment_methods::AuthenticationDetails,
|
||||||
|
api_models::process_tracker::revenue_recovery::RevenueRecoveryResponse,
|
||||||
|
api_models::enums::ProcessTrackerStatus,
|
||||||
routes::payments::ForceSync,
|
routes::payments::ForceSync,
|
||||||
)),
|
)),
|
||||||
modifiers(&SecurityAddon)
|
modifiers(&SecurityAddon)
|
||||||
|
|||||||
@ -17,5 +17,6 @@ pub mod poll;
|
|||||||
pub mod profile;
|
pub mod profile;
|
||||||
pub mod refunds;
|
pub mod refunds;
|
||||||
pub mod relay;
|
pub mod relay;
|
||||||
|
pub mod revenue_recovery;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
pub mod webhook_events;
|
pub mod webhook_events;
|
||||||
|
|||||||
22
crates/openapi/src/routes/revenue_recovery.rs
Normal file
22
crates/openapi/src/routes/revenue_recovery.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#[cfg(feature = "v2")]
|
||||||
|
/// Revenue Recovery - Retrieve
|
||||||
|
///
|
||||||
|
/// Retrieve the Revenue Recovery Payment Info
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = "/v2/process_tracker/revenue_recovery_workflow/{revenue_recovery_id}",
|
||||||
|
params(
|
||||||
|
("recovery_recovery_id" = String, Path, description = "The payment intent id"),
|
||||||
|
),
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Revenue Recovery Info Retrieved Successfully", body = RevenueRecoveryResponse),
|
||||||
|
(status = 500, description = "Internal server error"),
|
||||||
|
(status = 404, description = "Resource missing"),
|
||||||
|
(status = 422, description = "Unprocessable request"),
|
||||||
|
(status = 403, description = "Forbidden"),
|
||||||
|
),
|
||||||
|
tag = "Revenue Recovery",
|
||||||
|
operation_id = "Retrieve Revenue Recovery Info",
|
||||||
|
security(("jwt_key" = []))
|
||||||
|
)]
|
||||||
|
pub async fn revenue_recovery_pt_retrieve_api() {}
|
||||||
@ -321,9 +321,9 @@ impl ProcessTrackerWorkflows<routes::SessionState> for WorkflowRunner {
|
|||||||
storage::ProcessTrackerRunner::PaymentMethodStatusUpdateWorkflow => Ok(Box::new(
|
storage::ProcessTrackerRunner::PaymentMethodStatusUpdateWorkflow => Ok(Box::new(
|
||||||
workflows::payment_method_status_update::PaymentMethodStatusUpdateWorkflow,
|
workflows::payment_method_status_update::PaymentMethodStatusUpdateWorkflow,
|
||||||
)),
|
)),
|
||||||
storage::ProcessTrackerRunner::PassiveRecoveryWorkflow => Ok(Box::new(
|
storage::ProcessTrackerRunner::PassiveRecoveryWorkflow => {
|
||||||
workflows::passive_churn_recovery_workflow::ExecutePcrWorkflow,
|
Ok(Box::new(workflows::revenue_recovery::ExecutePcrWorkflow))
|
||||||
)),
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,6 @@ pub mod webhooks;
|
|||||||
|
|
||||||
pub mod unified_authentication_service;
|
pub mod unified_authentication_service;
|
||||||
|
|
||||||
#[cfg(feature = "v2")]
|
|
||||||
pub mod passive_churn_recovery;
|
|
||||||
pub mod relay;
|
pub mod relay;
|
||||||
|
#[cfg(feature = "v2")]
|
||||||
|
pub mod revenue_recovery;
|
||||||
|
|||||||
@ -1,33 +1,40 @@
|
|||||||
pub mod transformers;
|
pub mod transformers;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
use api_models::payments::{PaymentRevenueRecoveryMetadata, PaymentsRetrieveRequest};
|
use api_models::{payments::PaymentsRetrieveRequest, process_tracker::revenue_recovery};
|
||||||
use common_utils::{self, ext_traits::OptionExt, id_type, types::keymanager::KeyManagerState};
|
use common_utils::{
|
||||||
|
self,
|
||||||
|
ext_traits::{OptionExt, ValueExt},
|
||||||
|
id_type,
|
||||||
|
types::keymanager::KeyManagerState,
|
||||||
|
};
|
||||||
use diesel_models::process_tracker::business_status;
|
use diesel_models::process_tracker::business_status;
|
||||||
use error_stack::{self, ResultExt};
|
use error_stack::{self, ResultExt};
|
||||||
use hyperswitch_domain_models::{
|
use hyperswitch_domain_models::{
|
||||||
behaviour::ReverseConversion,
|
api::ApplicationResponse,
|
||||||
errors::api_error_response,
|
|
||||||
payments::{PaymentIntent, PaymentStatusData},
|
payments::{PaymentIntent, PaymentStatusData},
|
||||||
ApiModelToDieselModelConvertor,
|
ApiModelToDieselModelConvertor,
|
||||||
};
|
};
|
||||||
use scheduler::errors;
|
use scheduler::errors as sch_errors;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{
|
core::{
|
||||||
errors::RouterResult,
|
errors::{self, RouterResponse, RouterResult, StorageErrorExt},
|
||||||
passive_churn_recovery::types as pcr_types,
|
|
||||||
payments::{self, operations::Operation},
|
payments::{self, operations::Operation},
|
||||||
|
revenue_recovery::types as pcr_types,
|
||||||
},
|
},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
logger,
|
logger,
|
||||||
routes::{metrics, SessionState},
|
routes::{metrics, SessionState},
|
||||||
types::{
|
types::{
|
||||||
api,
|
api,
|
||||||
storage::{self, passive_churn_recovery as pcr},
|
storage::{self, revenue_recovery as pcr},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const EXECUTE_WORKFLOW: &str = "EXECUTE_WORKFLOW";
|
||||||
|
pub const PSYNC_WORKFLOW: &str = "PSYNC_WORKFLOW";
|
||||||
|
|
||||||
pub async fn perform_execute_payment(
|
pub async fn perform_execute_payment(
|
||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
execute_task_process: &storage::ProcessTracker,
|
execute_task_process: &storage::ProcessTracker,
|
||||||
@ -35,7 +42,7 @@ pub async fn perform_execute_payment(
|
|||||||
pcr_data: &pcr::PcrPaymentData,
|
pcr_data: &pcr::PcrPaymentData,
|
||||||
_key_manager_state: &KeyManagerState,
|
_key_manager_state: &KeyManagerState,
|
||||||
payment_intent: &PaymentIntent,
|
payment_intent: &PaymentIntent,
|
||||||
) -> Result<(), errors::ProcessTrackerError> {
|
) -> Result<(), sch_errors::ProcessTrackerError> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
|
|
||||||
let mut pcr_metadata = payment_intent
|
let mut pcr_metadata = payment_intent
|
||||||
@ -79,9 +86,9 @@ pub async fn perform_execute_payment(
|
|||||||
|
|
||||||
pcr_types::Decision::Psync(attempt_status, attempt_id) => {
|
pcr_types::Decision::Psync(attempt_status, attempt_id) => {
|
||||||
// find if a psync task is already present
|
// find if a psync task is already present
|
||||||
let task = "PSYNC_WORKFLOW";
|
let task = PSYNC_WORKFLOW;
|
||||||
let runner = storage::ProcessTrackerRunner::PassiveRecoveryWorkflow;
|
let runner = storage::ProcessTrackerRunner::PassiveRecoveryWorkflow;
|
||||||
let process_tracker_id = format!("{runner}_{task}_{}", attempt_id.get_string_repr());
|
let process_tracker_id = attempt_id.get_psync_revenue_recovery_id(task, runner);
|
||||||
let psync_process = db.find_process_by_id(&process_tracker_id).await?;
|
let psync_process = db.find_process_by_id(&process_tracker_id).await?;
|
||||||
|
|
||||||
match psync_process {
|
match psync_process {
|
||||||
@ -138,8 +145,8 @@ async fn insert_psync_pcr_task(
|
|||||||
payment_attempt_id: id_type::GlobalAttemptId,
|
payment_attempt_id: id_type::GlobalAttemptId,
|
||||||
runner: storage::ProcessTrackerRunner,
|
runner: storage::ProcessTrackerRunner,
|
||||||
) -> RouterResult<storage::ProcessTracker> {
|
) -> RouterResult<storage::ProcessTracker> {
|
||||||
let task = "PSYNC_WORKFLOW";
|
let task = PSYNC_WORKFLOW;
|
||||||
let process_tracker_id = format!("{runner}_{task}_{}", payment_attempt_id.get_string_repr());
|
let process_tracker_id = payment_attempt_id.get_psync_revenue_recovery_id(task, runner);
|
||||||
let schedule_time = common_utils::date_time::now();
|
let schedule_time = common_utils::date_time::now();
|
||||||
let psync_workflow_tracking_data = pcr::PcrWorkflowTrackingData {
|
let psync_workflow_tracking_data = pcr::PcrWorkflowTrackingData {
|
||||||
global_payment_id: payment_id,
|
global_payment_id: payment_id,
|
||||||
@ -158,13 +165,13 @@ async fn insert_psync_pcr_task(
|
|||||||
schedule_time,
|
schedule_time,
|
||||||
hyperswitch_domain_models::consts::API_VERSION,
|
hyperswitch_domain_models::consts::API_VERSION,
|
||||||
)
|
)
|
||||||
.change_context(api_error_response::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Failed to construct delete tokenized data process tracker task")?;
|
.attach_printable("Failed to construct delete tokenized data process tracker task")?;
|
||||||
|
|
||||||
let response = db
|
let response = db
|
||||||
.insert_process(process_tracker_entry)
|
.insert_process(process_tracker_entry)
|
||||||
.await
|
.await
|
||||||
.change_context(api_error_response::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Failed to construct delete tokenized data process tracker task")?;
|
.attach_printable("Failed to construct delete tokenized data process tracker task")?;
|
||||||
metrics::TASKS_ADDED_COUNT.add(1, router_env::metric_attributes!(("flow", "PsyncPcr")));
|
metrics::TASKS_ADDED_COUNT.add(1, router_env::metric_attributes!(("flow", "PsyncPcr")));
|
||||||
|
|
||||||
@ -219,3 +226,57 @@ pub async fn call_psync_api(
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(payment_data)
|
Ok(payment_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn retrieve_revenue_recovery_process_tracker(
|
||||||
|
state: SessionState,
|
||||||
|
id: id_type::GlobalPaymentId,
|
||||||
|
) -> RouterResponse<revenue_recovery::RevenueRecoveryResponse> {
|
||||||
|
let db = &*state.store;
|
||||||
|
let task = EXECUTE_WORKFLOW;
|
||||||
|
let runner = storage::ProcessTrackerRunner::PassiveRecoveryWorkflow;
|
||||||
|
let process_tracker_id = id.get_execute_revenue_recovery_id(task, runner);
|
||||||
|
|
||||||
|
let process_tracker = db
|
||||||
|
.find_process_by_id(&process_tracker_id)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)
|
||||||
|
.attach_printable("error retrieving the process tracker id")?
|
||||||
|
.get_required_value("Process Tracker")
|
||||||
|
.change_context(errors::ApiErrorResponse::GenericNotFoundError {
|
||||||
|
message: "Entry For the following id doesn't exists".to_owned(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let tracking_data = process_tracker
|
||||||
|
.tracking_data
|
||||||
|
.clone()
|
||||||
|
.parse_value::<pcr::PcrWorkflowTrackingData>("PCRWorkflowTrackingData")
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("unable to deserialize Pcr Workflow Tracking Data")?;
|
||||||
|
|
||||||
|
let psync_task = PSYNC_WORKFLOW;
|
||||||
|
|
||||||
|
let process_tracker_id_for_psync = tracking_data
|
||||||
|
.payment_attempt_id
|
||||||
|
.get_psync_revenue_recovery_id(psync_task, runner);
|
||||||
|
|
||||||
|
let process_tracker_for_psync = db
|
||||||
|
.find_process_by_id(&process_tracker_id_for_psync)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
logger::error!("Error while retreiving psync task : {:?}", e);
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
let schedule_time_for_psync = process_tracker_for_psync.and_then(|pt| pt.schedule_time);
|
||||||
|
|
||||||
|
let response = revenue_recovery::RevenueRecoveryResponse {
|
||||||
|
id: process_tracker.id,
|
||||||
|
name: process_tracker.name,
|
||||||
|
schedule_time_for_payment: process_tracker.schedule_time,
|
||||||
|
schedule_time_for_psync,
|
||||||
|
status: process_tracker.status,
|
||||||
|
business_status: process_tracker.business_status,
|
||||||
|
};
|
||||||
|
Ok(ApplicationResponse::Json(response))
|
||||||
|
}
|
||||||
@ -1,8 +1,6 @@
|
|||||||
use common_enums::AttemptStatus;
|
use common_enums::AttemptStatus;
|
||||||
|
|
||||||
use crate::{
|
use crate::{core::revenue_recovery::types::PcrAttemptStatus, types::transformers::ForeignFrom};
|
||||||
core::passive_churn_recovery::types::PcrAttemptStatus, types::transformers::ForeignFrom,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl ForeignFrom<AttemptStatus> for PcrAttemptStatus {
|
impl ForeignFrom<AttemptStatus> for PcrAttemptStatus {
|
||||||
fn foreign_from(s: AttemptStatus) -> Self {
|
fn foreign_from(s: AttemptStatus) -> Self {
|
||||||
@ -19,14 +19,14 @@ use time::PrimitiveDateTime;
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::{
|
core::{
|
||||||
errors::{self, RouterResult},
|
errors::{self, RouterResult},
|
||||||
passive_churn_recovery::{self as core_pcr},
|
|
||||||
payments::{self, operations::Operation},
|
payments::{self, operations::Operation},
|
||||||
|
revenue_recovery::{self as core_pcr},
|
||||||
},
|
},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
logger,
|
logger,
|
||||||
routes::SessionState,
|
routes::SessionState,
|
||||||
types::{api::payments as api_types, storage, transformers::ForeignInto},
|
types::{api::payments as api_types, storage, transformers::ForeignInto},
|
||||||
workflows::passive_churn_recovery_workflow::get_schedule_time_to_retry_mit_payments,
|
workflows::revenue_recovery::get_schedule_time_to_retry_mit_payments,
|
||||||
};
|
};
|
||||||
|
|
||||||
type RecoveryResult<T> = error_stack::Result<T, errors::RecoveryError>;
|
type RecoveryResult<T> = error_stack::Result<T, errors::RecoveryError>;
|
||||||
@ -87,7 +87,7 @@ impl Decision {
|
|||||||
intent_status: enums::IntentStatus,
|
intent_status: enums::IntentStatus,
|
||||||
called_connector: enums::PaymentConnectorTransmission,
|
called_connector: enums::PaymentConnectorTransmission,
|
||||||
active_attempt_id: Option<id_type::GlobalAttemptId>,
|
active_attempt_id: Option<id_type::GlobalAttemptId>,
|
||||||
pcr_data: &storage::passive_churn_recovery::PcrPaymentData,
|
pcr_data: &storage::revenue_recovery::PcrPaymentData,
|
||||||
payment_id: &id_type::GlobalPaymentId,
|
payment_id: &id_type::GlobalPaymentId,
|
||||||
) -> RecoveryResult<Self> {
|
) -> RecoveryResult<Self> {
|
||||||
Ok(match (intent_status, called_connector, active_attempt_id) {
|
Ok(match (intent_status, called_connector, active_attempt_id) {
|
||||||
@ -132,7 +132,7 @@ impl Action {
|
|||||||
merchant_id: &id_type::MerchantId,
|
merchant_id: &id_type::MerchantId,
|
||||||
payment_intent: &PaymentIntent,
|
payment_intent: &PaymentIntent,
|
||||||
process: &storage::ProcessTracker,
|
process: &storage::ProcessTracker,
|
||||||
pcr_data: &storage::passive_churn_recovery::PcrPaymentData,
|
pcr_data: &storage::revenue_recovery::PcrPaymentData,
|
||||||
revenue_recovery_metadata: &PaymentRevenueRecoveryMetadata,
|
revenue_recovery_metadata: &PaymentRevenueRecoveryMetadata,
|
||||||
) -> RecoveryResult<Self> {
|
) -> RecoveryResult<Self> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
@ -171,7 +171,7 @@ impl Action {
|
|||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
payment_intent: &PaymentIntent,
|
payment_intent: &PaymentIntent,
|
||||||
execute_task_process: &storage::ProcessTracker,
|
execute_task_process: &storage::ProcessTracker,
|
||||||
pcr_data: &storage::passive_churn_recovery::PcrPaymentData,
|
pcr_data: &storage::revenue_recovery::PcrPaymentData,
|
||||||
revenue_recovery_metadata: &mut PaymentRevenueRecoveryMetadata,
|
revenue_recovery_metadata: &mut PaymentRevenueRecoveryMetadata,
|
||||||
) -> Result<(), errors::ProcessTrackerError> {
|
) -> Result<(), errors::ProcessTrackerError> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
@ -290,7 +290,7 @@ impl Action {
|
|||||||
async fn call_proxy_api(
|
async fn call_proxy_api(
|
||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
payment_intent: &PaymentIntent,
|
payment_intent: &PaymentIntent,
|
||||||
pcr_data: &storage::passive_churn_recovery::PcrPaymentData,
|
pcr_data: &storage::revenue_recovery::PcrPaymentData,
|
||||||
revenue_recovery: &PaymentRevenueRecoveryMetadata,
|
revenue_recovery: &PaymentRevenueRecoveryMetadata,
|
||||||
) -> RouterResult<PaymentConfirmData<api_types::Authorize>> {
|
) -> RouterResult<PaymentConfirmData<api_types::Authorize>> {
|
||||||
let operation = payments::operations::proxy_payments_intent::PaymentProxyIntent;
|
let operation = payments::operations::proxy_payments_intent::PaymentProxyIntent;
|
||||||
@ -349,7 +349,7 @@ async fn call_proxy_api(
|
|||||||
pub async fn update_payment_intent_api(
|
pub async fn update_payment_intent_api(
|
||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
global_payment_id: id_type::GlobalPaymentId,
|
global_payment_id: id_type::GlobalPaymentId,
|
||||||
pcr_data: &storage::passive_churn_recovery::PcrPaymentData,
|
pcr_data: &storage::revenue_recovery::PcrPaymentData,
|
||||||
update_req: PaymentsUpdateIntentRequest,
|
update_req: PaymentsUpdateIntentRequest,
|
||||||
) -> RouterResult<PaymentIntentData<api_types::PaymentUpdateIntent>> {
|
) -> RouterResult<PaymentIntentData<api_types::PaymentUpdateIntent>> {
|
||||||
// TODO : Use api handler instead of calling payments_intent_operation_core
|
// TODO : Use api handler instead of calling payments_intent_operation_core
|
||||||
@ -15,8 +15,8 @@ use crate::{
|
|||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
routes::{app::ReqState, metrics, SessionState},
|
routes::{app::ReqState, metrics, SessionState},
|
||||||
services::{self, connector_integration_interface},
|
services::{self, connector_integration_interface},
|
||||||
types::{api, domain, storage::passive_churn_recovery as storage_churn_recovery},
|
types::{api, domain, storage::revenue_recovery as storage_churn_recovery},
|
||||||
workflows::passive_churn_recovery_workflow,
|
workflows::revenue_recovery as revenue_recovery_flow,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@ -466,22 +466,21 @@ impl RevenueRecoveryAttempt {
|
|||||||
.and_then(|feature_metadata| feature_metadata.get_retry_count())
|
.and_then(|feature_metadata| feature_metadata.get_retry_count())
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let schedule_time =
|
let schedule_time = revenue_recovery_flow::get_schedule_time_to_retry_mit_payments(
|
||||||
passive_churn_recovery_workflow::get_schedule_time_to_retry_mit_payments(
|
db,
|
||||||
db,
|
&merchant_id,
|
||||||
&merchant_id,
|
(total_retry_count + 1).into(),
|
||||||
(total_retry_count + 1).into(),
|
)
|
||||||
)
|
.await
|
||||||
.await
|
.map_or_else(
|
||||||
.map_or_else(
|
|| {
|
||||||
|| {
|
Err(
|
||||||
Err(
|
report!(errors::RevenueRecoveryError::ScheduleTimeFetchFailed)
|
||||||
report!(errors::RevenueRecoveryError::ScheduleTimeFetchFailed)
|
.attach_printable("Failed to get schedule time for pcr workflow"),
|
||||||
.attach_printable("Failed to get schedule time for pcr workflow"),
|
)
|
||||||
)
|
},
|
||||||
},
|
Ok, // Simply returns `time` wrapped in `Ok`
|
||||||
Ok, // Simply returns `time` wrapped in `Ok`
|
)?;
|
||||||
)?;
|
|
||||||
|
|
||||||
let payment_attempt_id = payment_attempt_id
|
let payment_attempt_id = payment_attempt_id
|
||||||
.ok_or(report!(
|
.ok_or(report!(
|
||||||
|
|||||||
@ -202,6 +202,11 @@ pub fn mk_app(
|
|||||||
.service(routes::WebhookEvents::server(state.clone()))
|
.service(routes::WebhookEvents::server(state.clone()))
|
||||||
.service(routes::FeatureMatrix::server(state.clone()));
|
.service(routes::FeatureMatrix::server(state.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "v2")]
|
||||||
|
{
|
||||||
|
server_app = server_app.service(routes::ProcessTracker::server(state.clone()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "payouts", feature = "v1"))]
|
#[cfg(all(feature = "payouts", feature = "v1"))]
|
||||||
|
|||||||
@ -65,6 +65,9 @@ pub mod recovery_webhooks;
|
|||||||
|
|
||||||
pub mod relay;
|
pub mod relay;
|
||||||
|
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
pub mod process_tracker;
|
||||||
|
|
||||||
#[cfg(feature = "dummy_connector")]
|
#[cfg(feature = "dummy_connector")]
|
||||||
pub use self::app::DummyConnector;
|
pub use self::app::DummyConnector;
|
||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
@ -75,7 +78,8 @@ pub use self::app::{
|
|||||||
ApiKeys, AppState, ApplePayCertificatesMigration, Cache, Cards, Configs, ConnectorOnboarding,
|
ApiKeys, AppState, ApplePayCertificatesMigration, Cache, Cards, Configs, ConnectorOnboarding,
|
||||||
Customers, Disputes, EphemeralKey, FeatureMatrix, Files, Forex, Gsm, Health, Hypersense,
|
Customers, Disputes, EphemeralKey, FeatureMatrix, Files, Forex, Gsm, Health, Hypersense,
|
||||||
Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink, PaymentMethods, Payments,
|
Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink, PaymentMethods, Payments,
|
||||||
Poll, Profile, ProfileNew, Refunds, Relay, RelayWebhooks, SessionState, User, Webhooks,
|
Poll, ProcessTracker, Profile, ProfileNew, Refunds, Relay, RelayWebhooks, SessionState, User,
|
||||||
|
Webhooks,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "olap")]
|
#[cfg(feature = "olap")]
|
||||||
pub use self::app::{Blocklist, Organization, Routing, Verify, WebhookEvents};
|
pub use self::app::{Blocklist, Organization, Routing, Verify, WebhookEvents};
|
||||||
|
|||||||
@ -2496,3 +2496,19 @@ impl FeatureMatrix {
|
|||||||
.service(web::resource("").route(web::get().to(feature_matrix::fetch_feature_matrix)))
|
.service(web::resource("").route(web::get().to(feature_matrix::fetch_feature_matrix)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
pub struct ProcessTracker;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "olap", feature = "v2"))]
|
||||||
|
impl ProcessTracker {
|
||||||
|
pub fn server(state: AppState) -> Scope {
|
||||||
|
use super::process_tracker::revenue_recovery;
|
||||||
|
web::scope("/v2/process_tracker/revenue_recovery_workflow")
|
||||||
|
.app_data(web::Data::new(state.clone()))
|
||||||
|
.service(
|
||||||
|
web::resource("/{revenue_recovery_id}")
|
||||||
|
.route(web::get().to(revenue_recovery::revenue_recovery_pt_retrieve_api)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -42,6 +42,7 @@ pub enum ApiIdentifier {
|
|||||||
CardNetworkTokenization,
|
CardNetworkTokenization,
|
||||||
Hypersense,
|
Hypersense,
|
||||||
PaymentMethodSession,
|
PaymentMethodSession,
|
||||||
|
ProcessTracker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Flow> for ApiIdentifier {
|
impl From<Flow> for ApiIdentifier {
|
||||||
@ -333,6 +334,8 @@ impl From<Flow> for ApiIdentifier {
|
|||||||
| Flow::PaymentMethodSessionUpdateSavedPaymentMethod
|
| Flow::PaymentMethodSessionUpdateSavedPaymentMethod
|
||||||
| Flow::PaymentMethodSessionDeleteSavedPaymentMethod
|
| Flow::PaymentMethodSessionDeleteSavedPaymentMethod
|
||||||
| Flow::PaymentMethodSessionUpdate => Self::PaymentMethodSession,
|
| Flow::PaymentMethodSessionUpdate => Self::PaymentMethodSession,
|
||||||
|
|
||||||
|
Flow::RevenueRecoveryRetrieve => Self::ProcessTracker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
crates/router/src/routes/process_tracker.rs
Normal file
2
crates/router/src/routes/process_tracker.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(feature = "v2")]
|
||||||
|
pub mod revenue_recovery;
|
||||||
39
crates/router/src/routes/process_tracker/revenue_recovery.rs
Normal file
39
crates/router/src/routes/process_tracker/revenue_recovery.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
|
use api_models::process_tracker::revenue_recovery as revenue_recovery_api;
|
||||||
|
use router_env::Flow;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
core::{api_locking, revenue_recovery},
|
||||||
|
routes::AppState,
|
||||||
|
services::{api, authentication as auth, authorization::permissions::Permission},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub async fn revenue_recovery_pt_retrieve_api(
|
||||||
|
state: web::Data<AppState>,
|
||||||
|
req: HttpRequest,
|
||||||
|
path: web::Path<common_utils::id_type::GlobalPaymentId>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let flow = Flow::RevenueRecoveryRetrieve;
|
||||||
|
let id = path.into_inner();
|
||||||
|
let payload = revenue_recovery_api::RevenueRecoveryId {
|
||||||
|
revenue_recovery_id: id,
|
||||||
|
};
|
||||||
|
|
||||||
|
Box::pin(api::server_wrap(
|
||||||
|
flow,
|
||||||
|
state,
|
||||||
|
&req,
|
||||||
|
payload,
|
||||||
|
|state, _: (), id, _| {
|
||||||
|
revenue_recovery::retrieve_revenue_recovery_process_tracker(
|
||||||
|
state,
|
||||||
|
id.revenue_recovery_id,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
&auth::JWTAuth {
|
||||||
|
permission: Permission::ProfileRevenueRecoveryRead,
|
||||||
|
},
|
||||||
|
api_locking::LockAction::NotApplicable,
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
}
|
||||||
@ -167,11 +167,12 @@ pub static OPERATIONS: [Resource; 8] = [
|
|||||||
|
|
||||||
pub static CONNECTORS: [Resource; 2] = [Resource::Connector, Resource::Account];
|
pub static CONNECTORS: [Resource; 2] = [Resource::Connector, Resource::Account];
|
||||||
|
|
||||||
pub static WORKFLOWS: [Resource; 4] = [
|
pub static WORKFLOWS: [Resource; 5] = [
|
||||||
Resource::Routing,
|
Resource::Routing,
|
||||||
Resource::ThreeDsDecisionManager,
|
Resource::ThreeDsDecisionManager,
|
||||||
Resource::SurchargeDecisionManager,
|
Resource::SurchargeDecisionManager,
|
||||||
Resource::Account,
|
Resource::Account,
|
||||||
|
Resource::RevenueRecovery,
|
||||||
];
|
];
|
||||||
|
|
||||||
pub static ANALYTICS: [Resource; 3] = [Resource::Analytics, Resource::Report, Resource::Account];
|
pub static ANALYTICS: [Resource; 3] = [Resource::Analytics, Resource::Report, Resource::Account];
|
||||||
|
|||||||
@ -95,6 +95,10 @@ generate_permissions! {
|
|||||||
scopes: [Read, Write],
|
scopes: [Read, Write],
|
||||||
entities: [Merchant]
|
entities: [Merchant]
|
||||||
},
|
},
|
||||||
|
RevenueRecovery: {
|
||||||
|
scopes: [Read],
|
||||||
|
entities: [Profile]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +113,7 @@ pub fn get_resource_name(resource: Resource, entity_type: EntityType) -> &'stati
|
|||||||
(Resource::ApiKey, _) => "Api Keys",
|
(Resource::ApiKey, _) => "Api Keys",
|
||||||
(Resource::Connector, _) => "Payment Processors, Payout Processors, Fraud & Risk Managers",
|
(Resource::Connector, _) => "Payment Processors, Payout Processors, Fraud & Risk Managers",
|
||||||
(Resource::Routing, _) => "Routing",
|
(Resource::Routing, _) => "Routing",
|
||||||
|
(Resource::RevenueRecovery, _) => "Revenue Recovery",
|
||||||
(Resource::ThreeDsDecisionManager, _) => "3DS Decision Manager",
|
(Resource::ThreeDsDecisionManager, _) => "3DS Decision Manager",
|
||||||
(Resource::SurchargeDecisionManager, _) => "Surcharge Decision Manager",
|
(Resource::SurchargeDecisionManager, _) => "Surcharge Decision Manager",
|
||||||
(Resource::Analytics, _) => "Analytics",
|
(Resource::Analytics, _) => "Analytics",
|
||||||
|
|||||||
@ -28,14 +28,14 @@ pub mod mandate;
|
|||||||
pub mod merchant_account;
|
pub mod merchant_account;
|
||||||
pub mod merchant_connector_account;
|
pub mod merchant_connector_account;
|
||||||
pub mod merchant_key_store;
|
pub mod merchant_key_store;
|
||||||
#[cfg(feature = "v2")]
|
|
||||||
pub mod passive_churn_recovery;
|
|
||||||
pub mod payment_attempt;
|
pub mod payment_attempt;
|
||||||
pub mod payment_link;
|
pub mod payment_link;
|
||||||
pub mod payment_method;
|
pub mod payment_method;
|
||||||
pub mod payout_attempt;
|
pub mod payout_attempt;
|
||||||
pub mod payouts;
|
pub mod payouts;
|
||||||
pub mod refund;
|
pub mod refund;
|
||||||
|
#[cfg(feature = "v2")]
|
||||||
|
pub mod revenue_recovery;
|
||||||
pub mod reverse_lookup;
|
pub mod reverse_lookup;
|
||||||
pub mod role;
|
pub mod role;
|
||||||
pub mod routing_algorithm;
|
pub mod routing_algorithm;
|
||||||
|
|||||||
@ -10,4 +10,4 @@ pub mod refund_router;
|
|||||||
|
|
||||||
pub mod tokenized_data;
|
pub mod tokenized_data;
|
||||||
|
|
||||||
pub mod passive_churn_recovery_workflow;
|
pub mod revenue_recovery;
|
||||||
|
|||||||
@ -15,14 +15,14 @@ use scheduler::{types::process_data, utils as scheduler_utils};
|
|||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{
|
core::{
|
||||||
passive_churn_recovery::{self as pcr},
|
|
||||||
payments,
|
payments,
|
||||||
|
revenue_recovery::{self as pcr},
|
||||||
},
|
},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
errors::StorageError,
|
errors::StorageError,
|
||||||
types::{
|
types::{
|
||||||
api::{self as api_types},
|
api::{self as api_types},
|
||||||
storage::passive_churn_recovery as pcr_storage_types,
|
storage::revenue_recovery as pcr_storage_types,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::{routes::SessionState, types::storage};
|
use crate::{routes::SessionState, types::storage};
|
||||||
@ -578,6 +578,8 @@ pub enum Flow {
|
|||||||
CardsInfoMigrate,
|
CardsInfoMigrate,
|
||||||
///Total payment method count for merchant
|
///Total payment method count for merchant
|
||||||
TotalPaymentMethodCount,
|
TotalPaymentMethodCount,
|
||||||
|
/// Process Tracker Revenue Recovery Workflow Retrieve
|
||||||
|
RevenueRecoveryRetrieve,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for providing generic behaviour to flow metric
|
/// Trait for providing generic behaviour to flow metric
|
||||||
|
|||||||
Reference in New Issue
Block a user