mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
feat(core): add webhook setup event handler (#9420)
This commit is contained in:
@ -66,6 +66,7 @@ pub enum IncomingWebhookEvent {
|
|||||||
RecoveryPaymentPending,
|
RecoveryPaymentPending,
|
||||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
||||||
RecoveryInvoiceCancel,
|
RecoveryInvoiceCancel,
|
||||||
|
SetupWebhook,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IncomingWebhookEvent {
|
impl IncomingWebhookEvent {
|
||||||
@ -143,6 +144,7 @@ pub enum WebhookFlow {
|
|||||||
FraudCheck,
|
FraudCheck,
|
||||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
||||||
Recovery,
|
Recovery,
|
||||||
|
Setup,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
@ -297,6 +299,7 @@ impl From<IncomingWebhookEvent> for WebhookFlow {
|
|||||||
| IncomingWebhookEvent::RecoveryPaymentFailure
|
| IncomingWebhookEvent::RecoveryPaymentFailure
|
||||||
| IncomingWebhookEvent::RecoveryPaymentPending
|
| IncomingWebhookEvent::RecoveryPaymentPending
|
||||||
| IncomingWebhookEvent::RecoveryPaymentSuccess => Self::Recovery,
|
| IncomingWebhookEvent::RecoveryPaymentSuccess => Self::Recovery,
|
||||||
|
IncomingWebhookEvent::SetupWebhook => Self::Setup,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -756,6 +756,16 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Wise {}
|
|||||||
|
|
||||||
impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Wise {}
|
impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Wise {}
|
||||||
|
|
||||||
|
#[cfg(feature = "payouts")]
|
||||||
|
fn is_setup_webhook_event(request: &IncomingWebhookRequestDetails<'_>) -> bool {
|
||||||
|
let test_webhook_header = request
|
||||||
|
.headers
|
||||||
|
.get("X-Test-Notification")
|
||||||
|
.and_then(|header_value| String::from_utf8(header_value.as_bytes().to_vec()).ok());
|
||||||
|
|
||||||
|
test_webhook_header == Some("true".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl IncomingWebhook for Wise {
|
impl IncomingWebhook for Wise {
|
||||||
fn get_webhook_source_verification_algorithm(
|
fn get_webhook_source_verification_algorithm(
|
||||||
@ -833,6 +843,10 @@ impl IncomingWebhook for Wise {
|
|||||||
) -> CustomResult<IncomingWebhookEvent, ConnectorError> {
|
) -> CustomResult<IncomingWebhookEvent, ConnectorError> {
|
||||||
#[cfg(feature = "payouts")]
|
#[cfg(feature = "payouts")]
|
||||||
{
|
{
|
||||||
|
if is_setup_webhook_event(request) {
|
||||||
|
return Ok(IncomingWebhookEvent::SetupWebhook);
|
||||||
|
}
|
||||||
|
|
||||||
let payload: wise::WisePayoutsWebhookBody = request
|
let payload: wise::WisePayoutsWebhookBody = request
|
||||||
.body
|
.body
|
||||||
.parse_struct("WisePayoutsWebhookBody")
|
.parse_struct("WisePayoutsWebhookBody")
|
||||||
|
|||||||
@ -271,6 +271,15 @@ async fn incoming_webhooks_core<W: types::OutgoingWebhookType>(
|
|||||||
.await?
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// if it is a setup webhook event, return ok status
|
||||||
|
if webhook_processing_result.event_type == webhooks::IncomingWebhookEvent::SetupWebhook {
|
||||||
|
return Ok((
|
||||||
|
services::ApplicationResponse::StatusOk,
|
||||||
|
WebhookResponseTracker::NoEffect,
|
||||||
|
serde_json::Value::default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// Update request_details with the appropriate body (decoded for non-UCS, raw for UCS)
|
// Update request_details with the appropriate body (decoded for non-UCS, raw for UCS)
|
||||||
let final_request_details = match &webhook_processing_result.decoded_body {
|
let final_request_details = match &webhook_processing_result.decoded_body {
|
||||||
Some(decoded_body) => IncomingWebhookRequestDetails {
|
Some(decoded_body) => IncomingWebhookRequestDetails {
|
||||||
@ -1443,6 +1452,7 @@ async fn relay_incoming_webhook_flow(
|
|||||||
| webhooks::WebhookFlow::ReturnResponse
|
| webhooks::WebhookFlow::ReturnResponse
|
||||||
| webhooks::WebhookFlow::BankTransfer
|
| webhooks::WebhookFlow::BankTransfer
|
||||||
| webhooks::WebhookFlow::Mandate
|
| webhooks::WebhookFlow::Mandate
|
||||||
|
| webhooks::WebhookFlow::Setup
|
||||||
| webhooks::WebhookFlow::ExternalAuthentication
|
| webhooks::WebhookFlow::ExternalAuthentication
|
||||||
| webhooks::WebhookFlow::FraudCheck => Err(errors::ApiErrorResponse::NotSupported {
|
| webhooks::WebhookFlow::FraudCheck => Err(errors::ApiErrorResponse::NotSupported {
|
||||||
message: "Relay webhook flow types not supported".to_string(),
|
message: "Relay webhook flow types not supported".to_string(),
|
||||||
|
|||||||
@ -221,6 +221,15 @@ async fn incoming_webhooks_core<W: types::OutgoingWebhookType>(
|
|||||||
};
|
};
|
||||||
logger::info!(event_type=?event_type);
|
logger::info!(event_type=?event_type);
|
||||||
|
|
||||||
|
// if it is a setup webhook event, return ok status
|
||||||
|
if event_type == webhooks::IncomingWebhookEvent::SetupWebhook {
|
||||||
|
return Ok((
|
||||||
|
services::ApplicationResponse::StatusOk,
|
||||||
|
WebhookResponseTracker::NoEffect,
|
||||||
|
serde_json::Value::default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let is_webhook_event_supported = !matches!(
|
let is_webhook_event_supported = !matches!(
|
||||||
event_type,
|
event_type,
|
||||||
webhooks::IncomingWebhookEvent::EventNotSupported
|
webhooks::IncomingWebhookEvent::EventNotSupported
|
||||||
@ -360,6 +369,7 @@ async fn incoming_webhooks_core<W: types::OutgoingWebhookType>(
|
|||||||
|
|
||||||
api::WebhookFlow::ExternalAuthentication => todo!(),
|
api::WebhookFlow::ExternalAuthentication => todo!(),
|
||||||
api::WebhookFlow::FraudCheck => todo!(),
|
api::WebhookFlow::FraudCheck => todo!(),
|
||||||
|
api::WebhookFlow::Setup => WebhookResponseTracker::NoEffect,
|
||||||
|
|
||||||
#[cfg(feature = "payouts")]
|
#[cfg(feature = "payouts")]
|
||||||
api::WebhookFlow::Payout => todo!(),
|
api::WebhookFlow::Payout => todo!(),
|
||||||
|
|||||||
@ -1455,7 +1455,8 @@ impl RecoveryAction {
|
|||||||
| webhooks::IncomingWebhookEvent::PayoutCancelled
|
| webhooks::IncomingWebhookEvent::PayoutCancelled
|
||||||
| webhooks::IncomingWebhookEvent::PayoutCreated
|
| webhooks::IncomingWebhookEvent::PayoutCreated
|
||||||
| webhooks::IncomingWebhookEvent::PayoutExpired
|
| webhooks::IncomingWebhookEvent::PayoutExpired
|
||||||
| webhooks::IncomingWebhookEvent::PayoutReversed => {
|
| webhooks::IncomingWebhookEvent::PayoutReversed
|
||||||
|
| webhooks::IncomingWebhookEvent::SetupWebhook => {
|
||||||
common_types::payments::RecoveryAction::InvalidAction
|
common_types::payments::RecoveryAction::InvalidAction
|
||||||
}
|
}
|
||||||
webhooks::IncomingWebhookEvent::RecoveryPaymentFailure => match attempt_triggered_by {
|
webhooks::IncomingWebhookEvent::RecoveryPaymentFailure => match attempt_triggered_by {
|
||||||
|
|||||||
Reference in New Issue
Block a user