diff --git a/crates/router/src/connector/shift4.rs b/crates/router/src/connector/shift4.rs index 8f8d6cee56..d75a089658 100644 --- a/crates/router/src/connector/shift4.rs +++ b/crates/router/src/connector/shift4.rs @@ -3,7 +3,7 @@ mod transformers; use std::fmt::Debug; use common_utils::ext_traits::ByteSliceExt; -use error_stack::ResultExt; +use error_stack::{IntoReport, ResultExt}; use transformers as shift4; use super::utils::RefundsRequestData; @@ -737,9 +737,25 @@ impl api::IncomingWebhook for Shift4 { .parse_struct("Shift4WebhookObjectId") .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; - Ok(api_models::webhooks::ObjectReferenceId::PaymentId( - api_models::payments::PaymentIdType::ConnectorTransactionId(details.data.id), - )) + if shift4::is_transaction_event(&details.event_type) { + Ok(api_models::webhooks::ObjectReferenceId::PaymentId( + api_models::payments::PaymentIdType::ConnectorTransactionId(details.data.id), + )) + } else if shift4::is_refund_event(&details.event_type) { + Ok(api_models::webhooks::ObjectReferenceId::RefundId( + api_models::webhooks::RefundIdType::ConnectorRefundId( + details + .data + .refunds + .and_then(|refund| { + refund.first().map(|refund_object| refund_object.id.clone()) + }) + .ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?, + ), + )) + } else { + Err(errors::ConnectorError::WebhookReferenceIdNotFound).into_report() + } } fn get_webhook_event_type( @@ -750,12 +766,7 @@ impl api::IncomingWebhook for Shift4 { .body .parse_struct("Shift4WebhookObjectEventType") .change_context(errors::ConnectorError::WebhookEventTypeNotFound)?; - Ok(match details.event_type { - shift4::Shift4WebhookEvent::ChargeSucceeded => { - api::IncomingWebhookEvent::PaymentIntentSuccess - } - shift4::Shift4WebhookEvent::Unknown => api::IncomingWebhookEvent::EventNotSupported, - }) + Ok(api::IncomingWebhookEvent::from(details.event_type)) } fn get_webhook_resource_object( diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs index dc5f4efbeb..22a3ae58a7 100644 --- a/crates/router/src/connector/shift4/transformers.rs +++ b/crates/router/src/connector/shift4/transformers.rs @@ -323,8 +323,13 @@ pub struct Shift4WebhookObjectEventType { } #[derive(Debug, Deserialize)] +#[allow(clippy::enum_variant_names)] pub enum Shift4WebhookEvent { ChargeSucceeded, + ChargeFailed, + ChargeUpdated, + ChargeCaptured, + ChargeRefunded, #[serde(other)] Unknown, } @@ -332,10 +337,18 @@ pub enum Shift4WebhookEvent { #[derive(Debug, Deserialize)] pub struct Shift4WebhookObjectData { pub id: String, + pub refunds: Option>, +} + +#[derive(Debug, Deserialize)] +pub struct RefundIdObject { + pub id: String, } #[derive(Debug, Deserialize)] pub struct Shift4WebhookObjectId { + #[serde(rename = "type")] + pub event_type: Shift4WebhookEvent, pub data: Shift4WebhookObjectData, } @@ -604,3 +617,32 @@ pub struct ApiErrorResponse { pub code: Option, pub message: String, } + +pub fn is_transaction_event(event: &Shift4WebhookEvent) -> bool { + matches!( + event, + Shift4WebhookEvent::ChargeCaptured + | Shift4WebhookEvent::ChargeFailed + | Shift4WebhookEvent::ChargeSucceeded + | Shift4WebhookEvent::ChargeUpdated + ) +} + +pub fn is_refund_event(event: &Shift4WebhookEvent) -> bool { + matches!(event, Shift4WebhookEvent::ChargeRefunded) +} + +impl From for api::IncomingWebhookEvent { + fn from(event: Shift4WebhookEvent) -> Self { + match event { + Shift4WebhookEvent::ChargeSucceeded | Shift4WebhookEvent::ChargeUpdated => { + //reference : https://dev.shift4.com/docs/api#event-types + Self::PaymentIntentProcessing + } + Shift4WebhookEvent::ChargeCaptured => Self::PaymentIntentSuccess, + Shift4WebhookEvent::ChargeFailed => Self::PaymentIntentFailure, + Shift4WebhookEvent::ChargeRefunded => Self::RefundSuccess, + Shift4WebhookEvent::Unknown => Self::EventNotSupported, + } + } +}