From a998443ceb819c152c60e555591b6de2490aba9d Mon Sep 17 00:00:00 2001 From: Prasunna Soppa Date: Sun, 12 Nov 2023 15:48:07 +0530 Subject: [PATCH 1/2] feat(events): add support for masking incoming webhook payload when logged --- Cargo.lock | 1 + connector-template/mod.rs | 2 +- crates/common_utils/src/ext_traits.rs | 1 + crates/router/Cargo.toml | 1 + crates/router/src/connector/aci.rs | 2 +- crates/router/src/connector/adyen.rs | 8 +--- crates/router/src/connector/airwallex.rs | 4 +- .../src/connector/airwallex/transformers.rs | 3 +- .../router/src/connector/authorizedotnet.rs | 10 ++--- crates/router/src/connector/bambora.rs | 2 +- crates/router/src/connector/bankofamerica.rs | 2 +- crates/router/src/connector/bitpay.rs | 7 ++- crates/router/src/connector/bluesnap.rs | 6 +-- crates/router/src/connector/boku.rs | 2 +- crates/router/src/connector/braintree.rs | 10 ++--- crates/router/src/connector/cashtocode.rs | 10 ++--- crates/router/src/connector/checkout.rs | 7 ++- crates/router/src/connector/coinbase.rs | 7 +-- crates/router/src/connector/cryptopay.rs | 7 +-- crates/router/src/connector/cybersource.rs | 2 +- crates/router/src/connector/dlocal.rs | 2 +- crates/router/src/connector/dummyconnector.rs | 2 +- crates/router/src/connector/fiserv.rs | 2 +- crates/router/src/connector/forte.rs | 2 +- crates/router/src/connector/globalpay.rs | 4 +- crates/router/src/connector/globepay.rs | 2 +- crates/router/src/connector/gocardless.rs | 21 ++++----- .../src/connector/gocardless/transformers.rs | 20 ++++----- crates/router/src/connector/helcim.rs | 2 +- crates/router/src/connector/iatapay.rs | 7 +-- crates/router/src/connector/klarna.rs | 2 +- crates/router/src/connector/mollie.rs | 2 +- crates/router/src/connector/multisafepay.rs | 2 +- crates/router/src/connector/nexinets.rs | 2 +- crates/router/src/connector/nmi.rs | 2 +- crates/router/src/connector/noon.rs | 10 ++--- crates/router/src/connector/nuvei.rs | 7 +-- crates/router/src/connector/opayo.rs | 2 +- crates/router/src/connector/opennode.rs | 7 +-- crates/router/src/connector/payeezy.rs | 2 +- crates/router/src/connector/payme.rs | 34 ++++++++------ crates/router/src/connector/paypal.rs | 29 +++++------- crates/router/src/connector/payu.rs | 2 +- crates/router/src/connector/powertranz.rs | 2 +- crates/router/src/connector/prophetpay.rs | 2 +- crates/router/src/connector/rapyd.rs | 4 +- crates/router/src/connector/shift4.rs | 6 ++- crates/router/src/connector/square.rs | 15 +++---- crates/router/src/connector/stax.rs | 4 +- crates/router/src/connector/stripe.rs | 4 +- crates/router/src/connector/trustpay.rs | 12 ++--- crates/router/src/connector/tsys.rs | 2 +- crates/router/src/connector/volt.rs | 2 +- crates/router/src/connector/wise.rs | 2 +- crates/router/src/connector/worldline.rs | 6 ++- crates/router/src/connector/worldpay.rs | 10 ++--- crates/router/src/connector/zen.rs | 4 +- crates/router/src/core/webhooks.rs | 44 ++++++++++++------- crates/router/src/types/api/webhooks.rs | 2 +- 59 files changed, 193 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac7fde55d8e3..ec4c12ddc91c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4458,6 +4458,7 @@ dependencies = [ "digest 0.9.0", "dyn-clone", "encoding_rs", + "erased-serde", "error-stack", "euclid", "external_services", diff --git a/connector-template/mod.rs b/connector-template/mod.rs index 7f21962109de..e441b0e5879a 100644 --- a/connector-template/mod.rs +++ b/connector-template/mod.rs @@ -485,7 +485,7 @@ impl api::IncomingWebhook for {{project-name | downcase | pascal_case}} { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/common_utils/src/ext_traits.rs b/crates/common_utils/src/ext_traits.rs index e76fe7dff5fb..d3296f989533 100644 --- a/crates/common_utils/src/ext_traits.rs +++ b/crates/common_utils/src/ext_traits.rs @@ -223,6 +223,7 @@ pub trait ByteSliceExt { } impl ByteSliceExt for [u8] { + #[track_caller] fn parse_struct<'de, T>( &'de self, type_name: &'static str, diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index 9ab955813336..4f956c37d405 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -111,6 +111,7 @@ scheduler = { version = "0.1.0", path = "../scheduler", default-features = false data_models = { version = "0.1.0", path = "../data_models", default-features = false } kgraph_utils = { version = "0.1.0", path = "../kgraph_utils" } storage_impl = { version = "0.1.0", path = "../storage_impl", default-features = false } +erased-serde = "0.3.31" [target.'cfg(not(target_os = "windows"))'.dependencies] signal-hook-tokio = { version = "0.3.1", features = ["futures-v0_3"] } diff --git a/crates/router/src/connector/aci.rs b/crates/router/src/connector/aci.rs index f6389c802f9e..774752b7ec53 100644 --- a/crates/router/src/connector/aci.rs +++ b/crates/router/src/connector/aci.rs @@ -572,7 +572,7 @@ impl api::IncomingWebhook for Aci { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/adyen.rs b/crates/router/src/connector/adyen.rs index ef10fbb692fd..e5f4fcc220e6 100644 --- a/crates/router/src/connector/adyen.rs +++ b/crates/router/src/connector/adyen.rs @@ -1600,17 +1600,13 @@ impl api::IncomingWebhook for Adyen { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif = get_webhook_object_from_body(request.body) .change_context(errors::ConnectorError::WebhookEventTypeNotFound)?; let response: adyen::Response = notif.into(); - let res_json = serde_json::to_value(response) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - - Ok(res_json) + Ok(Box::new(response)) } fn get_webhook_api_response( diff --git a/crates/router/src/connector/airwallex.rs b/crates/router/src/connector/airwallex.rs index 5de7fc065e80..68e82b76fce4 100644 --- a/crates/router/src/connector/airwallex.rs +++ b/crates/router/src/connector/airwallex.rs @@ -1081,13 +1081,13 @@ impl api::IncomingWebhook for Airwallex { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: airwallex::AirwallexWebhookObjectResource = request .body .parse_struct("AirwallexWebhookObjectResource") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(details.data.object) + Ok(Box::new(details.data.object)) } fn get_dispute_details( diff --git a/crates/router/src/connector/airwallex/transformers.rs b/crates/router/src/connector/airwallex/transformers.rs index 031a8276bb0d..457b8d075487 100644 --- a/crates/router/src/connector/airwallex/transformers.rs +++ b/crates/router/src/connector/airwallex/transformers.rs @@ -824,7 +824,8 @@ pub enum AirwallexDisputeStage { #[derive(Debug, Deserialize)] pub struct AirwallexWebhookDataResource { - pub object: serde_json::Value, + // Should this be a secret by default since it represents webhook payload + pub object: Secret, } #[derive(Debug, Deserialize)] diff --git a/crates/router/src/connector/authorizedotnet.rs b/crates/router/src/connector/authorizedotnet.rs index 7c3c234daecf..f04b8bcd6272 100644 --- a/crates/router/src/connector/authorizedotnet.rs +++ b/crates/router/src/connector/authorizedotnet.rs @@ -875,17 +875,15 @@ impl api::IncomingWebhook for Authorizedotnet { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let payload: authorizedotnet::AuthorizedotnetWebhookObjectId = request .body .parse_struct("AuthorizedotnetWebhookObjectId") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - let sync_payload = serde_json::to_value( + + Ok(Box::new( authorizedotnet::AuthorizedotnetSyncResponse::try_from(payload)?, - ) - .into_report() - .change_context(errors::ConnectorError::ResponseHandlingFailed)?; - Ok(sync_payload) + )) } } diff --git a/crates/router/src/connector/bambora.rs b/crates/router/src/connector/bambora.rs index 802be26408df..6319ed347260 100644 --- a/crates/router/src/connector/bambora.rs +++ b/crates/router/src/connector/bambora.rs @@ -685,7 +685,7 @@ impl api::IncomingWebhook for Bambora { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 84870f7407fb..4ef83cbeafcb 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -542,7 +542,7 @@ impl api::IncomingWebhook for Bankofamerica { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/bitpay.rs b/crates/router/src/connector/bitpay.rs index dc4571b75746..28b9b26fb4f0 100644 --- a/crates/router/src/connector/bitpay.rs +++ b/crates/router/src/connector/bitpay.rs @@ -23,7 +23,7 @@ use crate::{ api::{self, ConnectorCommon, ConnectorCommonExt}, ErrorResponse, Response, }, - utils::{self, BytesExt, Encode}, + utils::{self, BytesExt}, }; #[derive(Debug, Clone)] @@ -393,12 +393,11 @@ impl api::IncomingWebhook for Bitpay { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif: BitpayWebhookDetails = request .body .parse_struct("BitpayWebhookDetails") .change_context(errors::ConnectorError::WebhookEventTypeNotFound)?; - Encode::::encode_to_value(¬if) - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif)) } } diff --git a/crates/router/src/connector/bluesnap.rs b/crates/router/src/connector/bluesnap.rs index 7bd2ce052538..7b7e6b94bbe1 100644 --- a/crates/router/src/connector/bluesnap.rs +++ b/crates/router/src/connector/bluesnap.rs @@ -1119,15 +1119,13 @@ impl api::IncomingWebhook for Bluesnap { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let resource: bluesnap::BluesnapWebhookObjectResource = serde_urlencoded::from_bytes(request.body) .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - let res_json = serde_json::Value::try_from(resource)?; - - Ok(res_json) + Ok(Box::new(resource)) } } diff --git a/crates/router/src/connector/boku.rs b/crates/router/src/connector/boku.rs index 7c2c1af0986b..1fa7c4f15905 100644 --- a/crates/router/src/connector/boku.rs +++ b/crates/router/src/connector/boku.rs @@ -627,7 +627,7 @@ impl api::IncomingWebhook for Boku { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/braintree.rs b/crates/router/src/connector/braintree.rs index 6f5b13890367..ea0b7aa72ed5 100644 --- a/crates/router/src/connector/braintree.rs +++ b/crates/router/src/connector/braintree.rs @@ -1418,17 +1418,17 @@ impl api::IncomingWebhook for Braintree { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif = get_webhook_object_from_body(request.body) .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let response = decode_webhook_payload(notif.bt_payload.replace('\n', "").as_bytes())?; - let res_json = serde_json::to_value(response) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; + // let res_json = serde_json::to_value(response) + // .into_report() + // .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(res_json) + Ok(Box::new(response)) } fn get_webhook_api_response( diff --git a/crates/router/src/connector/cashtocode.rs b/crates/router/src/connector/cashtocode.rs index 12a52e485396..1381d5f3408d 100644 --- a/crates/router/src/connector/cashtocode.rs +++ b/crates/router/src/connector/cashtocode.rs @@ -391,16 +391,16 @@ impl api::IncomingWebhook for Cashtocode { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let webhook: transformers::CashtocodeIncomingWebhook = request .body .parse_struct("CashtocodeIncomingWebhook") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - let res_json = - utils::Encode::::encode_to_value(&webhook) - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; + // let res_json = + // utils::Encode::::encode_to_value(&webhook) + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Ok(res_json) + Ok(Box::new(webhook)) } fn get_webhook_api_response( diff --git a/crates/router/src/connector/checkout.rs b/crates/router/src/connector/checkout.rs index f24c08233ed7..1c5d4c99fee5 100644 --- a/crates/router/src/connector/checkout.rs +++ b/crates/router/src/connector/checkout.rs @@ -1261,7 +1261,7 @@ impl api::IncomingWebhook for Checkout { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let event_type_data: checkout::CheckoutWebhookEventTypeBody = request .body .parse_struct("CheckoutWebhookBody") @@ -1281,7 +1281,10 @@ impl api::IncomingWebhook for Checkout { utils::Encode::::encode_to_value(&payment_response) .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)? }; - Ok(resource_object) + // Ideally this should be a strict type that has type information + // PII information is likely being logged here when this response will be logged. + + Ok(Box::new(resource_object)) } fn get_dispute_details( diff --git a/crates/router/src/connector/coinbase.rs b/crates/router/src/connector/coinbase.rs index 5704ea15b005..853267d20a84 100644 --- a/crates/router/src/connector/coinbase.rs +++ b/crates/router/src/connector/coinbase.rs @@ -426,12 +426,13 @@ impl api::IncomingWebhook for Coinbase { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif: CoinbaseWebhookDetails = request .body .parse_struct("CoinbaseWebhookDetails") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Encode::::encode_to_value(¬if.event) - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + // Encode::::encode_to_value(¬if.event) + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif.event)) } } diff --git a/crates/router/src/connector/cryptopay.rs b/crates/router/src/connector/cryptopay.rs index d2d8fa0f1ec2..00dd221428dc 100644 --- a/crates/router/src/connector/cryptopay.rs +++ b/crates/router/src/connector/cryptopay.rs @@ -455,13 +455,14 @@ impl api::IncomingWebhook for Cryptopay { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif: CryptopayWebhookDetails = request .body .parse_struct("CryptopayWebhookDetails") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Encode::::encode_to_value(¬if) - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + // Encode::::encode_to_value(¬if) + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif)) } } diff --git a/crates/router/src/connector/cybersource.rs b/crates/router/src/connector/cybersource.rs index ee6e93aebbd0..43ed550dbb56 100644 --- a/crates/router/src/connector/cybersource.rs +++ b/crates/router/src/connector/cybersource.rs @@ -805,7 +805,7 @@ impl api::IncomingWebhook for Cybersource { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/dlocal.rs b/crates/router/src/connector/dlocal.rs index 64d3e6f1c12f..9133e16874d6 100644 --- a/crates/router/src/connector/dlocal.rs +++ b/crates/router/src/connector/dlocal.rs @@ -674,7 +674,7 @@ impl api::IncomingWebhook for Dlocal { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/dummyconnector.rs b/crates/router/src/connector/dummyconnector.rs index b501936b8713..b7018688a47d 100644 --- a/crates/router/src/connector/dummyconnector.rs +++ b/crates/router/src/connector/dummyconnector.rs @@ -579,7 +579,7 @@ impl api::IncomingWebhook for DummyConnector { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/fiserv.rs b/crates/router/src/connector/fiserv.rs index 093f71b3da14..d9cf1b992f89 100644 --- a/crates/router/src/connector/fiserv.rs +++ b/crates/router/src/connector/fiserv.rs @@ -787,7 +787,7 @@ impl api::IncomingWebhook for Fiserv { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/forte.rs b/crates/router/src/connector/forte.rs index 40448c01fabf..3fb9c1313a3e 100644 --- a/crates/router/src/connector/forte.rs +++ b/crates/router/src/connector/forte.rs @@ -669,7 +669,7 @@ impl api::IncomingWebhook for Forte { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/globalpay.rs b/crates/router/src/connector/globalpay.rs index cfa1349633b2..68aff8e561c0 100644 --- a/crates/router/src/connector/globalpay.rs +++ b/crates/router/src/connector/globalpay.rs @@ -932,14 +932,14 @@ impl api::IncomingWebhook for Globalpay { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details = std::str::from_utf8(request.body) .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let res_json = serde_json::from_str(details) .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(res_json) + Ok(Box::new(res_json)) } } diff --git a/crates/router/src/connector/globepay.rs b/crates/router/src/connector/globepay.rs index 547bf66fb7d5..d8e4b57d1146 100644 --- a/crates/router/src/connector/globepay.rs +++ b/crates/router/src/connector/globepay.rs @@ -508,7 +508,7 @@ impl api::IncomingWebhook for Globepay { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/gocardless.rs b/crates/router/src/connector/gocardless.rs index 1a6ac8441652..759bfadaf4ed 100644 --- a/crates/router/src/connector/gocardless.rs +++ b/crates/router/src/connector/gocardless.rs @@ -843,7 +843,7 @@ impl api::IncomingWebhook for Gocardless { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: gocardless::GocardlessWebhookEvent = request .body .parse_struct("GocardlessWebhookEvent") @@ -851,19 +851,14 @@ impl api::IncomingWebhook for Gocardless { let first_event = details .events .first() - .ok_or_else(|| errors::ConnectorError::WebhookReferenceIdNotFound)?; + .ok_or_else(|| errors::ConnectorError::WebhookReferenceIdNotFound)? + .clone(); match first_event.resource_type { - transformers::WebhookResourceType::Payments => serde_json::to_value( - gocardless::GocardlessPaymentsResponse::try_from(first_event)?, - ) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed), - transformers::WebhookResourceType::Refunds => serde_json::to_value(first_event) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed), - transformers::WebhookResourceType::Mandates => serde_json::to_value(first_event) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed), + transformers::WebhookResourceType::Payments => Ok(Box::new( + gocardless::GocardlessPaymentsResponse::try_from(&first_event)?, + )), + transformers::WebhookResourceType::Refunds + | transformers::WebhookResourceType::Mandates => Ok(Box::new(first_event)), } } } diff --git a/crates/router/src/connector/gocardless/transformers.rs b/crates/router/src/connector/gocardless/transformers.rs index d3b2d244760f..72204b511518 100644 --- a/crates/router/src/connector/gocardless/transformers.rs +++ b/crates/router/src/connector/gocardless/transformers.rs @@ -862,14 +862,14 @@ pub struct GocardlessWebhookEvent { pub events: Vec, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct WebhookEvent { pub resource_type: WebhookResourceType, pub action: WebhookAction, pub links: WebhooksLink, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum WebhookResourceType { Payments, @@ -877,7 +877,7 @@ pub enum WebhookResourceType { Mandates, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(untagged)] pub enum WebhookAction { PaymentsAction(PaymentsAction), @@ -885,7 +885,7 @@ pub enum WebhookAction { MandatesAction(MandatesAction), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum PaymentsAction { Created, @@ -901,7 +901,7 @@ pub enum PaymentsAction { ResubmissionRequired, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum RefundsAction { Created, @@ -912,7 +912,7 @@ pub enum RefundsAction { FundsReturned, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum MandatesAction { Created, @@ -931,7 +931,7 @@ pub enum MandatesAction { Blocked, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(untagged)] pub enum WebhooksLink { PaymentWebhooksLink(PaymentWebhooksLink), @@ -939,17 +939,17 @@ pub enum WebhooksLink { MandateWebhookLink(MandateWebhookLink), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct RefundWebhookLink { pub refund: String, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct PaymentWebhooksLink { pub payment: String, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct MandateWebhookLink { pub mandate: String, } diff --git a/crates/router/src/connector/helcim.rs b/crates/router/src/connector/helcim.rs index f7089bbd41b5..6e6dcacaead1 100644 --- a/crates/router/src/connector/helcim.rs +++ b/crates/router/src/connector/helcim.rs @@ -771,7 +771,7 @@ impl api::IncomingWebhook for Helcim { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/iatapay.rs b/crates/router/src/connector/iatapay.rs index 008047c1d366..c78542a98e82 100644 --- a/crates/router/src/connector/iatapay.rs +++ b/crates/router/src/connector/iatapay.rs @@ -691,13 +691,14 @@ impl api::IncomingWebhook for Iatapay { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif: IatapayPaymentsResponse = request .body .parse_struct("IatapayPaymentsResponse") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Encode::::encode_to_value(¬if) - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + // Encode::::encode_to_value(¬if) + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif)) } } diff --git a/crates/router/src/connector/klarna.rs b/crates/router/src/connector/klarna.rs index 8737d2b30474..d6fd6671a38a 100644 --- a/crates/router/src/connector/klarna.rs +++ b/crates/router/src/connector/klarna.rs @@ -519,7 +519,7 @@ impl api::IncomingWebhook for Klarna { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/mollie.rs b/crates/router/src/connector/mollie.rs index ef3eb6a3e7b3..e5a60f830b18 100644 --- a/crates/router/src/connector/mollie.rs +++ b/crates/router/src/connector/mollie.rs @@ -582,7 +582,7 @@ impl api::IncomingWebhook for Mollie { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/multisafepay.rs b/crates/router/src/connector/multisafepay.rs index 9dc54e7b72e3..ea091d2008a4 100644 --- a/crates/router/src/connector/multisafepay.rs +++ b/crates/router/src/connector/multisafepay.rs @@ -523,7 +523,7 @@ impl api::IncomingWebhook for Multisafepay { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/nexinets.rs b/crates/router/src/connector/nexinets.rs index f2e57792f284..e4668fcb8b53 100644 --- a/crates/router/src/connector/nexinets.rs +++ b/crates/router/src/connector/nexinets.rs @@ -682,7 +682,7 @@ impl api::IncomingWebhook for Nexinets { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/nmi.rs b/crates/router/src/connector/nmi.rs index d7e9cd78bb88..d96dba7475f9 100644 --- a/crates/router/src/connector/nmi.rs +++ b/crates/router/src/connector/nmi.rs @@ -667,7 +667,7 @@ impl api::IncomingWebhook for Nmi { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/noon.rs b/crates/router/src/connector/noon.rs index 866f8f4c58fa..95465e7a2d57 100644 --- a/crates/router/src/connector/noon.rs +++ b/crates/router/src/connector/noon.rs @@ -736,16 +736,16 @@ impl api::IncomingWebhook for Noon { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let resource: noon::NoonWebhookObject = request .body .parse_struct("NoonWebhookObject") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - let res_json = serde_json::to_value(noon::NoonPaymentsResponse::from(resource)) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; + // let res_json = serde_json::to_value(noon::NoonPaymentsResponse::from(resource)) + // .into_report() + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Ok(res_json) + Ok(Box::new(noon::NoonPaymentsResponse::from(resource))) } } diff --git a/crates/router/src/connector/nuvei.rs b/crates/router/src/connector/nuvei.rs index 15702829d378..ebc0ba5996d4 100644 --- a/crates/router/src/connector/nuvei.rs +++ b/crates/router/src/connector/nuvei.rs @@ -25,7 +25,7 @@ use crate::{ storage::enums, ErrorResponse, Response, }, - utils::{self as common_utils, ByteSliceExt, Encode}, + utils::{self as common_utils, ByteSliceExt}, }; #[derive(Debug, Clone)] @@ -963,12 +963,13 @@ impl api::IncomingWebhook for Nuvei { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let body = serde_urlencoded::from_str::(&request.query_params) .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let payment_response = nuvei::NuveiPaymentsResponse::from(body); - Encode::::encode_to_value(&payment_response).switch() + // Encode::::encode_to_value(&payment_response).switch() + Ok(Box::new(payment_response)) } } diff --git a/crates/router/src/connector/opayo.rs b/crates/router/src/connector/opayo.rs index cc517ca1f3b8..2de0ec4cdc81 100644 --- a/crates/router/src/connector/opayo.rs +++ b/crates/router/src/connector/opayo.rs @@ -533,7 +533,7 @@ impl api::IncomingWebhook for Opayo { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/opennode.rs b/crates/router/src/connector/opennode.rs index 3151403a5534..6a8f6ddd6ae9 100644 --- a/crates/router/src/connector/opennode.rs +++ b/crates/router/src/connector/opennode.rs @@ -420,11 +420,12 @@ impl api::IncomingWebhook for Opennode { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let notif = serde_urlencoded::from_bytes::(request.body) .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Encode::::encode_to_value(¬if.status) - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + // Encode::::encode_to_value(¬if.status) + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif.status)) } } diff --git a/crates/router/src/connector/payeezy.rs b/crates/router/src/connector/payeezy.rs index 8bb8eaa8b4c2..9a407d9694f6 100644 --- a/crates/router/src/connector/payeezy.rs +++ b/crates/router/src/connector/payeezy.rs @@ -585,7 +585,7 @@ impl api::IncomingWebhook for Payeezy { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/payme.rs b/crates/router/src/connector/payme.rs index ef10c6d00878..7ca67e0ef0b9 100644 --- a/crates/router/src/connector/payme.rs +++ b/crates/router/src/connector/payme.rs @@ -1077,32 +1077,38 @@ impl api::IncomingWebhook for Payme { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let resource = serde_urlencoded::from_bytes::(request.body) .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - let res_json = match resource.notify_type { + match resource.notify_type { transformers::NotifyType::SaleComplete | transformers::NotifyType::SaleAuthorized | transformers::NotifyType::SaleFailure => { - serde_json::to_value(payme::PaymePaySaleResponse::from(resource)) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + // serde_json::to_value(payme::PaymePaySaleResponse::from(resource)) + // .into_report() + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(payme::PaymePaySaleResponse::from(resource))) } transformers::NotifyType::Refund => { - serde_json::to_value(payme::PaymeQueryTransactionResponse::from(resource)) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + // serde_json::to_value(payme::PaymeQueryTransactionResponse::from(resource)) + // .into_report() + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(payme::PaymeQueryTransactionResponse::from( + resource, + ))) } transformers::NotifyType::SaleChargeback - | transformers::NotifyType::SaleChargebackRefund => serde_json::to_value(resource) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed), - }?; - - Ok(res_json) + | transformers::NotifyType::SaleChargebackRefund => + // serde_json::to_value(resource) + // .into_report() + // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed), + { + Ok(Box::new(resource)) + } + } } fn get_dispute_details( diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs index d4ab481eb9de..3a9a5634d58e 100644 --- a/crates/router/src/connector/paypal.rs +++ b/crates/router/src/connector/paypal.rs @@ -1189,33 +1189,24 @@ impl api::IncomingWebhook for Paypal { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: paypal::PaypalWebhooksBody = request .body .parse_struct("PaypalWebhooksBody") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - let sync_payload = match details.resource { - paypal::PaypalResource::PaypalCardWebhooks(resource) => serde_json::to_value( + Ok(match details.resource { + paypal::PaypalResource::PaypalCardWebhooks(resource) => Box::new( paypal::PaypalPaymentsSyncResponse::try_from((*resource, details.event_type))?, - ) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?, - paypal::PaypalResource::PaypalRedirectsWebhooks(resource) => serde_json::to_value( + ), + paypal::PaypalResource::PaypalRedirectsWebhooks(resource) => Box::new( paypal::PaypalOrdersResponse::try_from((*resource, details.event_type))?, - ) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?, - paypal::PaypalResource::PaypalRefundWebhooks(resource) => serde_json::to_value( + ), + paypal::PaypalResource::PaypalRefundWebhooks(resource) => Box::new( paypal::RefundSyncResponse::try_from((*resource, details.event_type))?, - ) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?, - paypal::PaypalResource::PaypalDisputeWebhooks(_) => serde_json::to_value(details) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?, - }; - Ok(sync_payload) + ), + paypal::PaypalResource::PaypalDisputeWebhooks(_) => Box::new(details), + }) } fn get_dispute_details( diff --git a/crates/router/src/connector/payu.rs b/crates/router/src/connector/payu.rs index 9a8d4734f837..8b30d4d3771f 100644 --- a/crates/router/src/connector/payu.rs +++ b/crates/router/src/connector/payu.rs @@ -758,7 +758,7 @@ impl api::IncomingWebhook for Payu { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/powertranz.rs b/crates/router/src/connector/powertranz.rs index 04851dd1781a..4bfbe18645b8 100644 --- a/crates/router/src/connector/powertranz.rs +++ b/crates/router/src/connector/powertranz.rs @@ -610,7 +610,7 @@ impl api::IncomingWebhook for Powertranz { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/prophetpay.rs b/crates/router/src/connector/prophetpay.rs index 417c34207e05..1ed40b021a0e 100644 --- a/crates/router/src/connector/prophetpay.rs +++ b/crates/router/src/connector/prophetpay.rs @@ -540,7 +540,7 @@ impl api::IncomingWebhook for Prophetpay { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/rapyd.rs b/crates/router/src/connector/rapyd.rs index cd8893d0d7b1..536fd29a7015 100644 --- a/crates/router/src/connector/rapyd.rs +++ b/crates/router/src/connector/rapyd.rs @@ -900,7 +900,7 @@ impl api::IncomingWebhook for Rapyd { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let webhook: transformers::RapydIncomingWebhook = request .body .parse_struct("RapydIncomingWebhook") @@ -923,7 +923,7 @@ impl api::IncomingWebhook for Rapyd { .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)? } }; - Ok(res_json) + Ok(Box::new(res_json)) } fn get_dispute_details( diff --git a/crates/router/src/connector/shift4.rs b/crates/router/src/connector/shift4.rs index 98eb895db548..a1b8967f752e 100644 --- a/crates/router/src/connector/shift4.rs +++ b/crates/router/src/connector/shift4.rs @@ -815,11 +815,13 @@ impl api::IncomingWebhook for Shift4 { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: shift4::Shift4WebhookObjectResource = request .body .parse_struct("Shift4WebhookObjectResource") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(details.data) + // Ideally this should be a strict type that has type information + // PII information is likely being logged here when this response will be logged + Ok(Box::new(details.data)) } } diff --git a/crates/router/src/connector/square.rs b/crates/router/src/connector/square.rs index 1d4d7e95dfa3..28a1f998a1fe 100644 --- a/crates/router/src/connector/square.rs +++ b/crates/router/src/connector/square.rs @@ -915,24 +915,19 @@ impl api::IncomingWebhook for Square { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: square::SquareWebhookBody = request .body .parse_struct("SquareWebhookObject") .change_context(errors::ConnectorError::WebhookEventTypeNotFound)?; - let reference_object = match details.data.object { + Ok(match details.data.object { square::SquareWebhookObject::Payment(square_payments_response_details) => { - serde_json::to_value(square_payments_response_details) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)? + Box::new(square_payments_response_details) } square::SquareWebhookObject::Refund(square_refund_response_details) => { - serde_json::to_value(square_refund_response_details) - .into_report() - .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)? + Box::new(square_refund_response_details) } - }; - Ok(reference_object) + }) } } diff --git a/crates/router/src/connector/stax.rs b/crates/router/src/connector/stax.rs index 0cfd2b89cd1a..1cd1e617a030 100644 --- a/crates/router/src/connector/stax.rs +++ b/crates/router/src/connector/stax.rs @@ -886,10 +886,10 @@ impl api::IncomingWebhook for Stax { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let reference_object: serde_json::Value = serde_json::from_slice(request.body) .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(reference_object) + Ok(Box::new(reference_object)) } } diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 3f1263657e83..f91bb546927e 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -2057,13 +2057,13 @@ impl api::IncomingWebhook for Stripe { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: stripe::WebhookEventObjectResource = request .body .parse_struct("WebhookEventObjectResource") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(details.data.object) + Ok(Box::new(details.data.object)) } fn get_dispute_details( &self, diff --git a/crates/router/src/connector/trustpay.rs b/crates/router/src/connector/trustpay.rs index 7509131afeef..9706efa87d4c 100644 --- a/crates/router/src/connector/trustpay.rs +++ b/crates/router/src/connector/trustpay.rs @@ -906,16 +906,16 @@ impl api::IncomingWebhook for Trustpay { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details: trustpay::TrustpayWebhookResponse = request .body .parse_struct("TrustpayWebhookResponse") .switch()?; - let res_json = utils::Encode::::encode_to_value( - &details.payment_information, - ) - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(res_json) + // let res_json = utils::Encode::::encode_to_value( + // &details.payment_information, + // ) + // .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; + Ok(Box::new(details.payment_information)) } fn get_webhook_source_verification_algorithm( diff --git a/crates/router/src/connector/tsys.rs b/crates/router/src/connector/tsys.rs index 71cef4be2afd..110aaac9ee38 100644 --- a/crates/router/src/connector/tsys.rs +++ b/crates/router/src/connector/tsys.rs @@ -625,7 +625,7 @@ impl api::IncomingWebhook for Tsys { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/volt.rs b/crates/router/src/connector/volt.rs index 3697b8c8923f..474df98bdc78 100644 --- a/crates/router/src/connector/volt.rs +++ b/crates/router/src/connector/volt.rs @@ -589,7 +589,7 @@ impl api::IncomingWebhook for Volt { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/wise.rs b/crates/router/src/connector/wise.rs index 5eba54eab4f7..7417dcb3d5e4 100644 --- a/crates/router/src/connector/wise.rs +++ b/crates/router/src/connector/wise.rs @@ -710,7 +710,7 @@ impl api::IncomingWebhook for Wise { fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::WebhooksNotImplemented).into_report() } } diff --git a/crates/router/src/connector/worldline.rs b/crates/router/src/connector/worldline.rs index 7fcca08d8bfe..1cbfc6b2e556 100644 --- a/crates/router/src/connector/worldline.rs +++ b/crates/router/src/connector/worldline.rs @@ -808,14 +808,16 @@ impl api::IncomingWebhook for Worldline { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let details = request .body .parse_struct::("WorldlineWebhookObjectId") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)? .payment .ok_or(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(details) + // Ideally this should be a strict type that has type information + // PII information is likely being logged here when this response will be logged + Ok(Box::new(details)) } fn get_webhook_api_response( diff --git a/crates/router/src/connector/worldpay.rs b/crates/router/src/connector/worldpay.rs index 60579fb5dd3e..d914bf25e4dc 100644 --- a/crates/router/src/connector/worldpay.rs +++ b/crates/router/src/connector/worldpay.rs @@ -754,15 +754,15 @@ impl api::IncomingWebhook for Worldpay { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let body: WorldpayWebhookEventType = request .body .parse_struct("WorldpayWebhookEventType") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; let psync_body = WorldpayEventResponse::try_from(body)?; - let res_json = serde_json::to_value(psync_body) - .into_report() - .change_context(errors::ConnectorError::WebhookResponseEncodingFailed)?; - Ok(res_json) + // let res_json = serde_json::to_value(psync_body) + // .into_report() + // .change_context(errors::ConnectorError::WebhookResponseEncodingFailed)?; + Ok(Box::new(psync_body)) } } diff --git a/crates/router/src/connector/zen.rs b/crates/router/src/connector/zen.rs index bdbdf623f934..c65b9c7c17c1 100644 --- a/crates/router/src/connector/zen.rs +++ b/crates/router/src/connector/zen.rs @@ -668,11 +668,11 @@ impl api::IncomingWebhook for Zen { fn get_webhook_resource_object( &self, request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + ) -> CustomResult, errors::ConnectorError> { let reference_object: serde_json::Value = serde_json::from_slice(request.body) .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(reference_object) + Ok(Box::new(reference_object)) } fn get_webhook_api_response( &self, diff --git a/crates/router/src/core/webhooks.rs b/crates/router/src/core/webhooks.rs index 51d5d80e936b..dad192f1b9bd 100644 --- a/crates/router/src/core/webhooks.rs +++ b/crates/router/src/core/webhooks.rs @@ -858,24 +858,29 @@ pub async fn webhooks_wrapper RouterResponse { let start_instant = Instant::now(); - let (application_response, webhooks_response_tracker) = webhooks_core::( - state.clone(), - req, - merchant_account.clone(), - key_store, - connector_name_or_mca_id, - body.clone(), - ) - .await?; + let (application_response, webhooks_response_tracker, serialized_req) = + webhooks_core::( + state.clone(), + req, + merchant_account.clone(), + key_store, + connector_name_or_mca_id, + body.clone(), + ) + .await?; let request_duration = Instant::now() .saturating_duration_since(start_instant) .as_millis(); - let body_vec: Vec = body.to_vec(); - let serialized_request: serde_json::Value = serde_json::from_slice(&body_vec) + // let body_vec: Vec = body.to_vec(); + // let serialized_request: serde_json::Value = serde_json::from_slice(&body_vec) + // .into_report() + // .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)?; + let serialized_request = serde_json::to_value(&serialized_req) .into_report() - .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)?; + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Could not convert webhook effect to string")?; let request_id = RequestId::extract(req) .await @@ -918,7 +923,7 @@ pub async fn webhooks_wrapper( state: AppState, @@ -930,6 +935,7 @@ pub async fn webhooks_core errors::RouterResult<( services::ApplicationResponse, WebhookResponseTracker, + Box, )> { metrics::WEBHOOK_INCOMING_COUNT.add( &metrics::CONTEXT, @@ -1011,7 +1017,7 @@ pub async fn webhooks_core = Box::new(()); let webhook_effect = if process_webhook_further && !matches!(flow_type, api::WebhookFlow::ReturnResponse) { @@ -1110,14 +1117,17 @@ pub async fn webhooks_core::encode_to_vec(&event_object) + resource_object: serde_json::to_vec(&event_object) + .into_report() + .change_context(errors::ParsingError::EncodeError("byte-vec")) + .attach_printable_lazy(|| format!("Unable to convert webhook paylaod to a value")) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable( "There was an issue when encoding the incoming webhook body to bytes", @@ -1222,7 +1232,7 @@ pub async fn webhooks_core, - ) -> CustomResult; + ) -> CustomResult, errors::ConnectorError>; fn get_webhook_api_response( &self, From de60989e239cb7f20b080841feed0bd15a0c7b4c Mon Sep 17 00:00:00 2001 From: Prasunna Soppa Date: Mon, 13 Nov 2023 18:19:00 +0530 Subject: [PATCH 2/2] code refactoring --- crates/router/src/connector/braintree.rs | 4 ---- crates/router/src/connector/cashtocode.rs | 3 --- crates/router/src/connector/coinbase.rs | 3 +-- crates/router/src/connector/cryptopay.rs | 3 +-- crates/router/src/connector/globalpay.rs | 9 +++++---- crates/router/src/connector/iatapay.rs | 3 +-- crates/router/src/connector/noon.rs | 4 ---- crates/router/src/connector/nuvei.rs | 2 +- crates/router/src/connector/opennode.rs | 3 +-- crates/router/src/connector/payme.rs | 22 ++++------------------ crates/router/src/connector/trustpay.rs | 4 ---- crates/router/src/connector/worldpay.rs | 3 --- crates/router/src/core/webhooks.rs | 10 ++++------ crates/router/src/events/event_logger.rs | 1 + 14 files changed, 19 insertions(+), 55 deletions(-) diff --git a/crates/router/src/connector/braintree.rs b/crates/router/src/connector/braintree.rs index ea0b7aa72ed5..4494055af60d 100644 --- a/crates/router/src/connector/braintree.rs +++ b/crates/router/src/connector/braintree.rs @@ -1424,10 +1424,6 @@ impl api::IncomingWebhook for Braintree { let response = decode_webhook_payload(notif.bt_payload.replace('\n', "").as_bytes())?; - // let res_json = serde_json::to_value(response) - // .into_report() - // .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(Box::new(response)) } diff --git a/crates/router/src/connector/cashtocode.rs b/crates/router/src/connector/cashtocode.rs index 1381d5f3408d..88be55ad920c 100644 --- a/crates/router/src/connector/cashtocode.rs +++ b/crates/router/src/connector/cashtocode.rs @@ -396,9 +396,6 @@ impl api::IncomingWebhook for Cashtocode { .body .parse_struct("CashtocodeIncomingWebhook") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - // let res_json = - // utils::Encode::::encode_to_value(&webhook) - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(Box::new(webhook)) } diff --git a/crates/router/src/connector/coinbase.rs b/crates/router/src/connector/coinbase.rs index 853267d20a84..93d659563e3d 100644 --- a/crates/router/src/connector/coinbase.rs +++ b/crates/router/src/connector/coinbase.rs @@ -431,8 +431,7 @@ impl api::IncomingWebhook for Coinbase { .body .parse_struct("CoinbaseWebhookDetails") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - // Encode::::encode_to_value(¬if.event) - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif.event)) } } diff --git a/crates/router/src/connector/cryptopay.rs b/crates/router/src/connector/cryptopay.rs index 00dd221428dc..854939697c72 100644 --- a/crates/router/src/connector/cryptopay.rs +++ b/crates/router/src/connector/cryptopay.rs @@ -461,8 +461,7 @@ impl api::IncomingWebhook for Cryptopay { .body .parse_struct("CryptopayWebhookDetails") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - // Encode::::encode_to_value(¬if) - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif)) } } diff --git a/crates/router/src/connector/globalpay.rs b/crates/router/src/connector/globalpay.rs index 68aff8e561c0..da96efeb8685 100644 --- a/crates/router/src/connector/globalpay.rs +++ b/crates/router/src/connector/globalpay.rs @@ -936,10 +936,11 @@ impl api::IncomingWebhook for Globalpay { let details = std::str::from_utf8(request.body) .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - let res_json = serde_json::from_str(details) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - Ok(Box::new(res_json)) + Ok(Box::new( + serde_json::from_str(details) + .into_report() + .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?, + )) } } diff --git a/crates/router/src/connector/iatapay.rs b/crates/router/src/connector/iatapay.rs index c78542a98e82..a843c173ca91 100644 --- a/crates/router/src/connector/iatapay.rs +++ b/crates/router/src/connector/iatapay.rs @@ -697,8 +697,7 @@ impl api::IncomingWebhook for Iatapay { .body .parse_struct("IatapayPaymentsResponse") .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - // Encode::::encode_to_value(¬if) - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif)) } } diff --git a/crates/router/src/connector/noon.rs b/crates/router/src/connector/noon.rs index 95465e7a2d57..2f0b0d5823a3 100644 --- a/crates/router/src/connector/noon.rs +++ b/crates/router/src/connector/noon.rs @@ -742,10 +742,6 @@ impl api::IncomingWebhook for Noon { .parse_struct("NoonWebhookObject") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; - // let res_json = serde_json::to_value(noon::NoonPaymentsResponse::from(resource)) - // .into_report() - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Ok(Box::new(noon::NoonPaymentsResponse::from(resource))) } } diff --git a/crates/router/src/connector/nuvei.rs b/crates/router/src/connector/nuvei.rs index ebc0ba5996d4..ce47cbb39c67 100644 --- a/crates/router/src/connector/nuvei.rs +++ b/crates/router/src/connector/nuvei.rs @@ -968,7 +968,7 @@ impl api::IncomingWebhook for Nuvei { .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let payment_response = nuvei::NuveiPaymentsResponse::from(body); - // Encode::::encode_to_value(&payment_response).switch() + Ok(Box::new(payment_response)) } } diff --git a/crates/router/src/connector/opennode.rs b/crates/router/src/connector/opennode.rs index 6a8f6ddd6ae9..fc4f4bf4f7ba 100644 --- a/crates/router/src/connector/opennode.rs +++ b/crates/router/src/connector/opennode.rs @@ -424,8 +424,7 @@ impl api::IncomingWebhook for Opennode { let notif = serde_urlencoded::from_bytes::(request.body) .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - // Encode::::encode_to_value(¬if.status) - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) + Ok(Box::new(notif.status)) } } diff --git a/crates/router/src/connector/payme.rs b/crates/router/src/connector/payme.rs index 7ca67e0ef0b9..337a70c96c3d 100644 --- a/crates/router/src/connector/payme.rs +++ b/crates/router/src/connector/payme.rs @@ -1087,27 +1087,13 @@ impl api::IncomingWebhook for Payme { transformers::NotifyType::SaleComplete | transformers::NotifyType::SaleAuthorized | transformers::NotifyType::SaleFailure => { - // serde_json::to_value(payme::PaymePaySaleResponse::from(resource)) - // .into_report() - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) Ok(Box::new(payme::PaymePaySaleResponse::from(resource))) } - transformers::NotifyType::Refund => { - // serde_json::to_value(payme::PaymeQueryTransactionResponse::from(resource)) - // .into_report() - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) - Ok(Box::new(payme::PaymeQueryTransactionResponse::from( - resource, - ))) - } + transformers::NotifyType::Refund => Ok(Box::new( + payme::PaymeQueryTransactionResponse::from(resource), + )), transformers::NotifyType::SaleChargeback - | transformers::NotifyType::SaleChargebackRefund => - // serde_json::to_value(resource) - // .into_report() - // .change_context(errors::ConnectorError::WebhookBodyDecodingFailed), - { - Ok(Box::new(resource)) - } + | transformers::NotifyType::SaleChargebackRefund => Ok(Box::new(resource)), } } diff --git a/crates/router/src/connector/trustpay.rs b/crates/router/src/connector/trustpay.rs index 9706efa87d4c..53f9701eb24d 100644 --- a/crates/router/src/connector/trustpay.rs +++ b/crates/router/src/connector/trustpay.rs @@ -911,10 +911,6 @@ impl api::IncomingWebhook for Trustpay { .body .parse_struct("TrustpayWebhookResponse") .switch()?; - // let res_json = utils::Encode::::encode_to_value( - // &details.payment_information, - // ) - // .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; Ok(Box::new(details.payment_information)) } diff --git a/crates/router/src/connector/worldpay.rs b/crates/router/src/connector/worldpay.rs index d914bf25e4dc..3d1294ac63e5 100644 --- a/crates/router/src/connector/worldpay.rs +++ b/crates/router/src/connector/worldpay.rs @@ -760,9 +760,6 @@ impl api::IncomingWebhook for Worldpay { .parse_struct("WorldpayWebhookEventType") .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; let psync_body = WorldpayEventResponse::try_from(body)?; - // let res_json = serde_json::to_value(psync_body) - // .into_report() - // .change_context(errors::ConnectorError::WebhookResponseEncodingFailed)?; Ok(Box::new(psync_body)) } } diff --git a/crates/router/src/core/webhooks.rs b/crates/router/src/core/webhooks.rs index dad192f1b9bd..cf7e3402ef8f 100644 --- a/crates/router/src/core/webhooks.rs +++ b/crates/router/src/core/webhooks.rs @@ -873,11 +873,7 @@ pub async fn webhooks_wrapper = body.to_vec(); - // let serialized_request: serde_json::Value = serde_json::from_slice(&body_vec) - // .into_report() - // .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)?; - let serialized_request = serde_json::to_value(&serialized_req) + let serialized_request = masking::masked_serialize(&serialized_req) .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Could not convert webhook effect to string")?; @@ -1127,7 +1123,9 @@ pub async fn webhooks_core