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:
SamraatBansal
2023-08-22 01:18:05 +05:30
committed by GitHub
parent 88d65a62fc
commit 8cf1f75fb1
6 changed files with 99 additions and 97 deletions

View File

@ -1306,11 +1306,11 @@ pub fn should_call_connector<Op: Debug, F: Clone>(
"PaymentStatus" => { "PaymentStatus" => {
matches!( matches!(
payment_data.payment_intent.status, payment_data.payment_intent.status,
storage_enums::IntentStatus::Failed storage_enums::IntentStatus::Processing
| storage_enums::IntentStatus::Processing
| storage_enums::IntentStatus::Succeeded
| storage_enums::IntentStatus::RequiresCustomerAction | storage_enums::IntentStatus::RequiresCustomerAction
| storage_enums::IntentStatus::RequiresMerchantAction | storage_enums::IntentStatus::RequiresMerchantAction
| storage_enums::IntentStatus::RequiresCapture
| storage_enums::IntentStatus::PartiallyCaptured
) && payment_data.force_sync.unwrap_or(false) ) && payment_data.force_sync.unwrap_or(false)
} }
"PaymentCancel" => matches!( "PaymentCancel" => matches!(

View File

@ -1646,7 +1646,6 @@ pub fn check_force_psync_precondition(
| storage_enums::AttemptStatus::AutoRefunded | storage_enums::AttemptStatus::AutoRefunded
| storage_enums::AttemptStatus::Voided | storage_enums::AttemptStatus::Voided
| storage_enums::AttemptStatus::CodInitiated | storage_enums::AttemptStatus::CodInitiated
| storage_enums::AttemptStatus::Authorized
| storage_enums::AttemptStatus::Started | storage_enums::AttemptStatus::Started
| storage_enums::AttemptStatus::Failure | storage_enums::AttemptStatus::Failure
) && connector_transaction_id.is_some() ) && connector_transaction_id.is_some()

View File

@ -101,17 +101,14 @@ pub async fn payments_incoming_webhook_flow<W: types::OutgoingWebhookType>(
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("payment id not received from payments core")?; .attach_printable("payment id not received from payments core")?;
let event_type: enums::EventType = payments_response let event_type: Option<enums::EventType> = payments_response.status.foreign_into();
.status
.foreign_try_into()
.into_report()
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("payment event type mapping failed")?;
// If event is NOT an UnsupportedEvent, trigger Outgoing Webhook
if let Some(outgoing_event_type) = event_type {
create_event_and_trigger_outgoing_webhook::<W>( create_event_and_trigger_outgoing_webhook::<W>(
state, state,
merchant_account, merchant_account,
event_type, outgoing_event_type,
enums::EventClass::Payments, enums::EventClass::Payments,
None, None,
payment_id, payment_id,
@ -120,6 +117,7 @@ pub async fn payments_incoming_webhook_flow<W: types::OutgoingWebhookType>(
) )
.await?; .await?;
} }
}
_ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure)
.into_report() .into_report()
@ -213,17 +211,15 @@ pub async fn refunds_incoming_webhook_flow<W: types::OutgoingWebhookType>(
) )
})? })?
}; };
let event_type: enums::EventType = updated_refund let event_type: Option<enums::EventType> = updated_refund.refund_status.foreign_into();
.refund_status
.foreign_try_into() // If event is NOT an UnsupportedEvent, trigger Outgoing Webhook
.into_report() if let Some(outgoing_event_type) = event_type {
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("refund status to event type mapping failed")?;
let refund_response: api_models::refunds::RefundResponse = updated_refund.foreign_into(); let refund_response: api_models::refunds::RefundResponse = updated_refund.foreign_into();
create_event_and_trigger_outgoing_webhook::<W>( create_event_and_trigger_outgoing_webhook::<W>(
state, state,
merchant_account, merchant_account,
event_type, outgoing_event_type,
enums::EventClass::Refunds, enums::EventClass::Refunds,
None, None,
refund_id, refund_id,
@ -231,6 +227,8 @@ pub async fn refunds_incoming_webhook_flow<W: types::OutgoingWebhookType>(
api::OutgoingWebhookContent::RefundDetails(refund_response), api::OutgoingWebhookContent::RefundDetails(refund_response),
) )
.await?; .await?;
}
Ok(()) Ok(())
} }
@ -385,12 +383,8 @@ pub async fn disputes_incoming_webhook_flow<W: types::OutgoingWebhookType>(
) )
.await?; .await?;
let disputes_response = Box::new(dispute_object.clone().foreign_into()); let disputes_response = Box::new(dispute_object.clone().foreign_into());
let event_type: enums::EventType = dispute_object let event_type: enums::EventType = dispute_object.dispute_status.foreign_into();
.dispute_status
.foreign_try_into()
.into_report()
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("failed to map dispute status to event type")?;
create_event_and_trigger_outgoing_webhook::<W>( create_event_and_trigger_outgoing_webhook::<W>(
state, state,
merchant_account, merchant_account,
@ -457,17 +451,14 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType>(
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("did not receive payment id from payments core response")?; .attach_printable("did not receive payment id from payments core response")?;
let event_type: enums::EventType = payments_response let event_type: Option<enums::EventType> = payments_response.status.foreign_into();
.status
.foreign_try_into()
.into_report()
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("error mapping payments response status to event type")?;
// If event is NOT an UnsupportedEvent, trigger Outgoing Webhook
if let Some(outgoing_event_type) = event_type {
create_event_and_trigger_outgoing_webhook::<W>( create_event_and_trigger_outgoing_webhook::<W>(
state, state,
merchant_account, merchant_account,
event_type, outgoing_event_type,
enums::EventClass::Payments, enums::EventClass::Payments,
None, None,
payment_id, payment_id,
@ -476,6 +467,7 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType>(
) )
.await?; .await?;
} }
}
_ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure)
.into_report() .into_report()

View File

@ -185,19 +185,23 @@ impl ForeignFrom<api_models::payments::MandateAmountData> for storage_enums::Man
} }
} }
impl ForeignTryFrom<api_enums::IntentStatus> for storage_enums::EventType { impl ForeignFrom<api_enums::IntentStatus> for Option<storage_enums::EventType> {
type Error = errors::ValidationError; fn foreign_from(value: api_enums::IntentStatus) -> Self {
fn foreign_try_from(value: api_enums::IntentStatus) -> Result<Self, Self::Error> {
match value { match value {
api_enums::IntentStatus::Succeeded => Ok(Self::PaymentSucceeded), api_enums::IntentStatus::Succeeded => Some(storage_enums::EventType::PaymentSucceeded),
api_enums::IntentStatus::Failed => Ok(Self::PaymentFailed), api_enums::IntentStatus::Failed => Some(storage_enums::EventType::PaymentFailed),
api_enums::IntentStatus::Processing => Ok(Self::PaymentProcessing), api_enums::IntentStatus::Processing => {
Some(storage_enums::EventType::PaymentProcessing)
}
api_enums::IntentStatus::RequiresMerchantAction api_enums::IntentStatus::RequiresMerchantAction
| api_enums::IntentStatus::RequiresCustomerAction => Ok(Self::ActionRequired), | api_enums::IntentStatus::RequiresCustomerAction => {
_ => Err(errors::ValidationError::IncorrectValueProvided { Some(storage_enums::EventType::ActionRequired)
field_name: "intent_status", }
}), 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 { impl ForeignFrom<storage_enums::RefundStatus> for Option<storage_enums::EventType> {
type Error = errors::ValidationError; fn foreign_from(value: storage_enums::RefundStatus) -> Self {
fn foreign_try_from(value: storage_enums::RefundStatus) -> Result<Self, Self::Error> {
match value { match value {
storage_enums::RefundStatus::Success => Ok(Self::RefundSucceeded), storage_enums::RefundStatus::Success => Some(storage_enums::EventType::RefundSucceeded),
storage_enums::RefundStatus::Failure => Ok(Self::RefundFailed), storage_enums::RefundStatus::Failure => Some(storage_enums::EventType::RefundFailed),
_ => Err(errors::ValidationError::IncorrectValueProvided { api_enums::RefundStatus::ManualReview
field_name: "refund_status", | api_enums::RefundStatus::Pending
}), | api_enums::RefundStatus::TransactionFailure => None,
} }
} }
} }
impl ForeignTryFrom<storage_enums::DisputeStatus> for storage_enums::EventType { impl ForeignFrom<storage_enums::DisputeStatus> for storage_enums::EventType {
type Error = errors::ValidationError; fn foreign_from(value: storage_enums::DisputeStatus) -> Self {
fn foreign_try_from(value: storage_enums::DisputeStatus) -> Result<Self, Self::Error> {
match value { match value {
storage_enums::DisputeStatus::DisputeOpened => Ok(Self::DisputeOpened), storage_enums::DisputeStatus::DisputeOpened => Self::DisputeOpened,
storage_enums::DisputeStatus::DisputeExpired => Ok(Self::DisputeExpired), storage_enums::DisputeStatus::DisputeExpired => Self::DisputeExpired,
storage_enums::DisputeStatus::DisputeAccepted => Ok(Self::DisputeAccepted), storage_enums::DisputeStatus::DisputeAccepted => Self::DisputeAccepted,
storage_enums::DisputeStatus::DisputeCancelled => Ok(Self::DisputeCancelled), storage_enums::DisputeStatus::DisputeCancelled => Self::DisputeCancelled,
storage_enums::DisputeStatus::DisputeChallenged => Ok(Self::DisputeChallenged), storage_enums::DisputeStatus::DisputeChallenged => Self::DisputeChallenged,
storage_enums::DisputeStatus::DisputeWon => Ok(Self::DisputeWon), storage_enums::DisputeStatus::DisputeWon => Self::DisputeWon,
storage_enums::DisputeStatus::DisputeLost => Ok(Self::DisputeLost), storage_enums::DisputeStatus::DisputeLost => Self::DisputeLost,
} }
} }
} }

View File

@ -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::Goto(&format!("{CHEKOUT_BASE_URL}/saved/177"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))), Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::SwitchFrame(By::Name("threeDSIframe"))), 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::SendKeys(By::ClassName("input-field"), "password")),
Event::Trigger(Trigger::Click(By::Id("buttonSubmit"))), Event::Trigger(Trigger::Click(By::Id("buttonSubmit"))),
Event::Trigger(Trigger::Sleep(5)), 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::Goto(&format!("{CHEKOUT_BASE_URL}/saved/62"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))), Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::SwitchFrame(By::Name("threeDSIframe"))), 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::SendKeys(By::ClassName("input-field"), "password")),
Event::Trigger(Trigger::Click(By::Id("buttonSubmit"))), Event::Trigger(Trigger::Click(By::Id("buttonSubmit"))),
Event::Trigger(Trigger::Sleep(5)), Event::Trigger(Trigger::Sleep(5)),

View File

@ -9931,6 +9931,11 @@
"description": "The identifier for the payment", "description": "The identifier for the payment",
"nullable": true "nullable": true
}, },
"refund_id": {
"type": "string",
"description": "The identifier for the refund",
"nullable": true
},
"limit": { "limit": {
"type": "integer", "type": "integer",
"format": "int64", "format": "int64",
@ -9974,15 +9979,21 @@
"RefundListResponse": { "RefundListResponse": {
"type": "object", "type": "object",
"required": [ "required": [
"size", "count",
"total_count",
"data" "data"
], ],
"properties": { "properties": {
"size": { "count": {
"type": "integer", "type": "integer",
"description": "The number of refunds included in the list", "description": "The number of refunds included in the list",
"minimum": 0 "minimum": 0
}, },
"total_count": {
"type": "integer",
"format": "int64",
"description": "The total number of refunds in the list"
},
"data": { "data": {
"type": "array", "type": "array",
"items": { "items": {