mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 09:38:33 +08:00
fix(core): Update Webhooks Event Mapping and Forced Psync preconditions (#1970)
Co-authored-by: swangi-kumari <swangi.12015941@lpu.in>
This commit is contained in:
@ -1306,11 +1306,11 @@ pub fn should_call_connector<Op: Debug, F: Clone>(
|
||||
"PaymentStatus" => {
|
||||
matches!(
|
||||
payment_data.payment_intent.status,
|
||||
storage_enums::IntentStatus::Failed
|
||||
| storage_enums::IntentStatus::Processing
|
||||
| storage_enums::IntentStatus::Succeeded
|
||||
storage_enums::IntentStatus::Processing
|
||||
| storage_enums::IntentStatus::RequiresCustomerAction
|
||||
| storage_enums::IntentStatus::RequiresMerchantAction
|
||||
| storage_enums::IntentStatus::RequiresCapture
|
||||
| storage_enums::IntentStatus::PartiallyCaptured
|
||||
) && payment_data.force_sync.unwrap_or(false)
|
||||
}
|
||||
"PaymentCancel" => matches!(
|
||||
|
||||
@ -1646,7 +1646,6 @@ pub fn check_force_psync_precondition(
|
||||
| storage_enums::AttemptStatus::AutoRefunded
|
||||
| storage_enums::AttemptStatus::Voided
|
||||
| storage_enums::AttemptStatus::CodInitiated
|
||||
| storage_enums::AttemptStatus::Authorized
|
||||
| storage_enums::AttemptStatus::Started
|
||||
| storage_enums::AttemptStatus::Failure
|
||||
) && connector_transaction_id.is_some()
|
||||
|
||||
@ -101,17 +101,14 @@ pub async fn payments_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.attach_printable("payment id not received from payments core")?;
|
||||
|
||||
let event_type: enums::EventType = payments_response
|
||||
.status
|
||||
.foreign_try_into()
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.attach_printable("payment event type mapping failed")?;
|
||||
let event_type: Option<enums::EventType> = payments_response.status.foreign_into();
|
||||
|
||||
// If event is NOT an UnsupportedEvent, trigger Outgoing Webhook
|
||||
if let Some(outgoing_event_type) = event_type {
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
event_type,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Payments,
|
||||
None,
|
||||
payment_id,
|
||||
@ -120,6 +117,7 @@ pub async fn payments_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
_ => Err(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.into_report()
|
||||
@ -213,17 +211,15 @@ pub async fn refunds_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
)
|
||||
})?
|
||||
};
|
||||
let event_type: enums::EventType = updated_refund
|
||||
.refund_status
|
||||
.foreign_try_into()
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.attach_printable("refund status to event type mapping failed")?;
|
||||
let event_type: Option<enums::EventType> = updated_refund.refund_status.foreign_into();
|
||||
|
||||
// If event is NOT an UnsupportedEvent, trigger Outgoing Webhook
|
||||
if let Some(outgoing_event_type) = event_type {
|
||||
let refund_response: api_models::refunds::RefundResponse = updated_refund.foreign_into();
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
event_type,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Refunds,
|
||||
None,
|
||||
refund_id,
|
||||
@ -231,6 +227,8 @@ pub async fn refunds_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
api::OutgoingWebhookContent::RefundDetails(refund_response),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -385,12 +383,8 @@ pub async fn disputes_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
)
|
||||
.await?;
|
||||
let disputes_response = Box::new(dispute_object.clone().foreign_into());
|
||||
let event_type: enums::EventType = dispute_object
|
||||
.dispute_status
|
||||
.foreign_try_into()
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.attach_printable("failed to map dispute status to event type")?;
|
||||
let event_type: enums::EventType = dispute_object.dispute_status.foreign_into();
|
||||
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
@ -457,17 +451,14 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.attach_printable("did not receive payment id from payments core response")?;
|
||||
|
||||
let event_type: enums::EventType = payments_response
|
||||
.status
|
||||
.foreign_try_into()
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.attach_printable("error mapping payments response status to event type")?;
|
||||
let event_type: Option<enums::EventType> = payments_response.status.foreign_into();
|
||||
|
||||
// If event is NOT an UnsupportedEvent, trigger Outgoing Webhook
|
||||
if let Some(outgoing_event_type) = event_type {
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
event_type,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Payments,
|
||||
None,
|
||||
payment_id,
|
||||
@ -476,6 +467,7 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
_ => Err(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.into_report()
|
||||
|
||||
@ -185,19 +185,23 @@ impl ForeignFrom<api_models::payments::MandateAmountData> for storage_enums::Man
|
||||
}
|
||||
}
|
||||
|
||||
impl ForeignTryFrom<api_enums::IntentStatus> for storage_enums::EventType {
|
||||
type Error = errors::ValidationError;
|
||||
|
||||
fn foreign_try_from(value: api_enums::IntentStatus) -> Result<Self, Self::Error> {
|
||||
impl ForeignFrom<api_enums::IntentStatus> for Option<storage_enums::EventType> {
|
||||
fn foreign_from(value: api_enums::IntentStatus) -> Self {
|
||||
match value {
|
||||
api_enums::IntentStatus::Succeeded => Ok(Self::PaymentSucceeded),
|
||||
api_enums::IntentStatus::Failed => Ok(Self::PaymentFailed),
|
||||
api_enums::IntentStatus::Processing => Ok(Self::PaymentProcessing),
|
||||
api_enums::IntentStatus::Succeeded => Some(storage_enums::EventType::PaymentSucceeded),
|
||||
api_enums::IntentStatus::Failed => Some(storage_enums::EventType::PaymentFailed),
|
||||
api_enums::IntentStatus::Processing => {
|
||||
Some(storage_enums::EventType::PaymentProcessing)
|
||||
}
|
||||
api_enums::IntentStatus::RequiresMerchantAction
|
||||
| api_enums::IntentStatus::RequiresCustomerAction => Ok(Self::ActionRequired),
|
||||
_ => Err(errors::ValidationError::IncorrectValueProvided {
|
||||
field_name: "intent_status",
|
||||
}),
|
||||
| api_enums::IntentStatus::RequiresCustomerAction => {
|
||||
Some(storage_enums::EventType::ActionRequired)
|
||||
}
|
||||
api_enums::IntentStatus::Cancelled
|
||||
| api_enums::IntentStatus::RequiresPaymentMethod
|
||||
| api_enums::IntentStatus::RequiresConfirmation
|
||||
| api_enums::IntentStatus::RequiresCapture
|
||||
| api_enums::IntentStatus::PartiallyCaptured => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -320,32 +324,28 @@ impl ForeignTryFrom<api_models::payments::PaymentMethodData> for api_enums::Paym
|
||||
}
|
||||
}
|
||||
|
||||
impl ForeignTryFrom<storage_enums::RefundStatus> for storage_enums::EventType {
|
||||
type Error = errors::ValidationError;
|
||||
|
||||
fn foreign_try_from(value: storage_enums::RefundStatus) -> Result<Self, Self::Error> {
|
||||
impl ForeignFrom<storage_enums::RefundStatus> for Option<storage_enums::EventType> {
|
||||
fn foreign_from(value: storage_enums::RefundStatus) -> Self {
|
||||
match value {
|
||||
storage_enums::RefundStatus::Success => Ok(Self::RefundSucceeded),
|
||||
storage_enums::RefundStatus::Failure => Ok(Self::RefundFailed),
|
||||
_ => Err(errors::ValidationError::IncorrectValueProvided {
|
||||
field_name: "refund_status",
|
||||
}),
|
||||
storage_enums::RefundStatus::Success => Some(storage_enums::EventType::RefundSucceeded),
|
||||
storage_enums::RefundStatus::Failure => Some(storage_enums::EventType::RefundFailed),
|
||||
api_enums::RefundStatus::ManualReview
|
||||
| api_enums::RefundStatus::Pending
|
||||
| api_enums::RefundStatus::TransactionFailure => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ForeignTryFrom<storage_enums::DisputeStatus> for storage_enums::EventType {
|
||||
type Error = errors::ValidationError;
|
||||
|
||||
fn foreign_try_from(value: storage_enums::DisputeStatus) -> Result<Self, Self::Error> {
|
||||
impl ForeignFrom<storage_enums::DisputeStatus> for storage_enums::EventType {
|
||||
fn foreign_from(value: storage_enums::DisputeStatus) -> Self {
|
||||
match value {
|
||||
storage_enums::DisputeStatus::DisputeOpened => Ok(Self::DisputeOpened),
|
||||
storage_enums::DisputeStatus::DisputeExpired => Ok(Self::DisputeExpired),
|
||||
storage_enums::DisputeStatus::DisputeAccepted => Ok(Self::DisputeAccepted),
|
||||
storage_enums::DisputeStatus::DisputeCancelled => Ok(Self::DisputeCancelled),
|
||||
storage_enums::DisputeStatus::DisputeChallenged => Ok(Self::DisputeChallenged),
|
||||
storage_enums::DisputeStatus::DisputeWon => Ok(Self::DisputeWon),
|
||||
storage_enums::DisputeStatus::DisputeLost => Ok(Self::DisputeLost),
|
||||
storage_enums::DisputeStatus::DisputeOpened => Self::DisputeOpened,
|
||||
storage_enums::DisputeStatus::DisputeExpired => Self::DisputeExpired,
|
||||
storage_enums::DisputeStatus::DisputeAccepted => Self::DisputeAccepted,
|
||||
storage_enums::DisputeStatus::DisputeCancelled => Self::DisputeCancelled,
|
||||
storage_enums::DisputeStatus::DisputeChallenged => Self::DisputeChallenged,
|
||||
storage_enums::DisputeStatus::DisputeWon => Self::DisputeWon,
|
||||
storage_enums::DisputeStatus::DisputeLost => Self::DisputeLost,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ async fn should_make_adyen_3ds_payment_failed(web_driver: WebDriver) -> Result<(
|
||||
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/177"))),
|
||||
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
|
||||
Event::Trigger(Trigger::SwitchFrame(By::Name("threeDSIframe"))),
|
||||
Event::Assert(Assert::Eq(Selector::Title, "Payment Authentication")),
|
||||
Event::Assert(Assert::IsPresent("AUTHENTICATION DETAILS")),
|
||||
Event::Trigger(Trigger::SendKeys(By::ClassName("input-field"), "password")),
|
||||
Event::Trigger(Trigger::Click(By::Id("buttonSubmit"))),
|
||||
Event::Trigger(Trigger::Sleep(5)),
|
||||
@ -40,7 +40,7 @@ async fn should_make_adyen_3ds_payment_success(
|
||||
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/62"))),
|
||||
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
|
||||
Event::Trigger(Trigger::SwitchFrame(By::Name("threeDSIframe"))),
|
||||
Event::Assert(Assert::Eq(Selector::Title, "Payment Authentication")),
|
||||
Event::Assert(Assert::IsPresent("AUTHENTICATION DETAILS")),
|
||||
Event::Trigger(Trigger::SendKeys(By::ClassName("input-field"), "password")),
|
||||
Event::Trigger(Trigger::Click(By::Id("buttonSubmit"))),
|
||||
Event::Trigger(Trigger::Sleep(5)),
|
||||
|
||||
@ -9931,6 +9931,11 @@
|
||||
"description": "The identifier for the payment",
|
||||
"nullable": true
|
||||
},
|
||||
"refund_id": {
|
||||
"type": "string",
|
||||
"description": "The identifier for the refund",
|
||||
"nullable": true
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
@ -9974,15 +9979,21 @@
|
||||
"RefundListResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"size",
|
||||
"count",
|
||||
"total_count",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"size": {
|
||||
"count": {
|
||||
"type": "integer",
|
||||
"description": "The number of refunds included in the list",
|
||||
"minimum": 0
|
||||
},
|
||||
"total_count": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The total number of refunds in the list"
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
Reference in New Issue
Block a user