feat(process_tracker): make long standing payments failed (#2380)

Co-authored-by: Arun Raj M <jarnura47@gmail.com>
This commit is contained in:
Narayan Bhat
2023-10-09 14:32:46 +05:30
committed by GitHub
parent 17393f5be3
commit 73dfc31f9d
7 changed files with 271 additions and 86 deletions

View File

@ -5,6 +5,8 @@ pub mod ext_traits;
#[cfg(feature = "kv_store")]
pub mod storage_partitioning;
use std::fmt::Debug;
use api_models::{enums, payments, webhooks};
use base64::Engine;
pub use common_utils::{
@ -27,11 +29,12 @@ use crate::{
consts,
core::{
errors::{self, CustomResult, RouterResult, StorageErrorExt},
utils,
utils, webhooks as webhooks_core,
},
db::StorageInterface,
logger,
routes::metrics,
services,
types::{
self,
domain::{
@ -39,6 +42,7 @@ use crate::{
types::{encrypt_optional, AsyncLift},
},
storage,
transformers::{ForeignTryFrom, ForeignTryInto},
},
};
@ -669,3 +673,89 @@ pub fn add_apple_pay_payment_status_metrics(
}
}
}
impl ForeignTryFrom<enums::IntentStatus> for enums::EventType {
type Error = errors::ValidationError;
fn foreign_try_from(value: enums::IntentStatus) -> Result<Self, Self::Error> {
match value {
enums::IntentStatus::Succeeded => Ok(Self::PaymentSucceeded),
enums::IntentStatus::Failed => Ok(Self::PaymentFailed),
enums::IntentStatus::Processing => Ok(Self::PaymentProcessing),
enums::IntentStatus::RequiresMerchantAction
| enums::IntentStatus::RequiresCustomerAction => Ok(Self::ActionRequired),
_ => Err(errors::ValidationError::IncorrectValueProvided {
field_name: "intent_status",
}),
}
}
}
pub async fn trigger_payments_webhook<F, Req, Op>(
merchant_account: domain::MerchantAccount,
payment_data: crate::core::payments::PaymentData<F>,
req: Option<Req>,
customer: Option<domain::Customer>,
state: &crate::routes::AppState,
operation: Op,
) -> RouterResult<()>
where
F: Send + Clone + Sync,
Op: Debug,
{
let status = payment_data.payment_intent.status;
let payment_id = payment_data.payment_intent.payment_id.clone();
let captures = payment_data
.multiple_capture_data
.clone()
.map(|multiple_capture_data| {
multiple_capture_data
.get_all_captures()
.into_iter()
.cloned()
.collect()
});
if matches!(
status,
enums::IntentStatus::Succeeded | enums::IntentStatus::Failed
) {
let payments_response = crate::core::payments::transformers::payments_to_payments_response(
req,
payment_data,
captures,
customer,
services::AuthFlow::Merchant,
&state.conf.server,
&operation,
&state.conf.connector_request_reference_id_config,
None,
)?;
let event_type: enums::EventType = status
.foreign_try_into()
.into_report()
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("payment event type mapping failed")?;
if let services::ApplicationResponse::JsonWithHeaders((payments_response_json, _)) =
payments_response
{
Box::pin(
webhooks_core::create_event_and_trigger_appropriate_outgoing_webhook(
state.clone(),
merchant_account,
event_type,
diesel_models::enums::EventClass::Payments,
None,
payment_id,
diesel_models::enums::EventObjectType::PaymentDetails,
webhooks::OutgoingWebhookContent::PaymentDetails(payments_response_json),
),
)
.await?;
}
}
Ok(())
}