From ee0461e9a57b2ff77d26b4a543bd1e407f3fcc1c Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 00:20:02 +0000 Subject: [PATCH 1/3] chore(version): 2024.01.18.0 --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9b01fe4e915..b17ee4964b41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,31 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.01.18.0 + +### Features + +- **connector_events:** Added api to fetch connector event logs ([#3319](https://github.com/juspay/hyperswitch/pull/3319)) ([`68a3a28`](https://github.com/juspay/hyperswitch/commit/68a3a280676c8309f9becffae545b134b5e1f2ea)) +- **payment_method:** Add capability to store bank details using /payment_methods endpoint ([#3113](https://github.com/juspay/hyperswitch/pull/3113)) ([`01c2de2`](https://github.com/juspay/hyperswitch/commit/01c2de223f60595d77c06a59a40dfe041e02cfee)) + +### Bug Fixes + +- **core:** Add validation for authtype and metadata in update payment connector ([#3305](https://github.com/juspay/hyperswitch/pull/3305)) ([`52f38d3`](https://github.com/juspay/hyperswitch/commit/52f38d3d5a7d035e8211e1f51c8f982232e2d7ab)) +- **events:** Fix event generation for paymentmethods list ([#3337](https://github.com/juspay/hyperswitch/pull/3337)) ([`ac8d81b`](https://github.com/juspay/hyperswitch/commit/ac8d81b32b3d91b875113d32782a8c62e39ba2a8)) + +### Refactors + +- **connector:** [cybersource] recurring mandate flow ([#3354](https://github.com/juspay/hyperswitch/pull/3354)) ([`387c1c4`](https://github.com/juspay/hyperswitch/commit/387c1c491bdc413ae361d04f0be25eaa58e72fa9)) +- [Noon] adding new field max_amount to mandate request ([#3209](https://github.com/juspay/hyperswitch/pull/3209)) ([`eb2a61d`](https://github.com/juspay/hyperswitch/commit/eb2a61d8597995838f21b8233653c691118b2191)) + +### Miscellaneous Tasks + +- **router:** Remove recon from default features ([#3370](https://github.com/juspay/hyperswitch/pull/3370)) ([`928beec`](https://github.com/juspay/hyperswitch/commit/928beecdd7fe9e09b38ffe750627ca4af94ffc93)) + +**Full Changelog:** [`2024.01.17.0...2024.01.18.0`](https://github.com/juspay/hyperswitch/compare/2024.01.17.0...2024.01.18.0) + +- - - + ## 2024.01.17.0 ### Features From acb329672297cd7337d0b0239e4c662257812e8a Mon Sep 17 00:00:00 2001 From: Swangi Kumari <85639103+swangi-kumari@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:27:32 +0530 Subject: [PATCH 2/3] refactor(connector): [Volt] Refactor Payments and Refunds Webhooks (#3377) --- crates/router/src/connector/volt.rs | 71 +++++++++---------- .../router/src/connector/volt/transformers.rs | 10 ++- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/crates/router/src/connector/volt.rs b/crates/router/src/connector/volt.rs index 39296bb64340..f125f90d93aa 100644 --- a/crates/router/src/connector/volt.rs +++ b/crates/router/src/connector/volt.rs @@ -635,43 +635,40 @@ impl api::IncomingWebhook for Volt { &self, request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - let x_volt_type = - utils::get_header_key_value(webhook_headers::X_VOLT_TYPE, request.headers)?; - if x_volt_type == "refund_confirmed" || x_volt_type == "refund_failed" { - let refund_webhook_body: volt::VoltRefundWebhookBodyReference = request - .body - .parse_struct("VoltRefundWebhookBodyReference") - .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; - - let refund_reference = match refund_webhook_body.external_reference { - Some(external_reference) => { - api_models::webhooks::RefundIdType::RefundId(external_reference) - } - None => api_models::webhooks::RefundIdType::ConnectorRefundId( - refund_webhook_body.refund, - ), - }; - Ok(api_models::webhooks::ObjectReferenceId::RefundId( - refund_reference, - )) - } else { - let webhook_body: volt::VoltPaymentWebhookBodyReference = request - .body - .parse_struct("VoltPaymentWebhookBodyReference") - .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; - let reference = match webhook_body.merchant_internal_reference { - Some(merchant_internal_reference) => { - api_models::payments::PaymentIdType::PaymentAttemptId( - merchant_internal_reference, - ) - } - None => api_models::payments::PaymentIdType::ConnectorTransactionId( - webhook_body.payment, - ), - }; - Ok(api_models::webhooks::ObjectReferenceId::PaymentId( - reference, - )) + let parsed_webhook_response = request + .body + .parse_struct::("VoltRefundWebhookBodyReference") + .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; + + match parsed_webhook_response { + volt::WebhookResponse::Payment(payment_response) => { + let reference = match payment_response.merchant_internal_reference { + Some(merchant_internal_reference) => { + api_models::payments::PaymentIdType::PaymentAttemptId( + merchant_internal_reference, + ) + } + None => api_models::payments::PaymentIdType::ConnectorTransactionId( + payment_response.payment, + ), + }; + Ok(api_models::webhooks::ObjectReferenceId::PaymentId( + reference, + )) + } + volt::WebhookResponse::Refund(refund_response) => { + let refund_reference = match refund_response.external_reference { + Some(external_reference) => { + api_models::webhooks::RefundIdType::RefundId(external_reference) + } + None => api_models::webhooks::RefundIdType::ConnectorRefundId( + refund_response.refund, + ), + }; + Ok(api_models::webhooks::ObjectReferenceId::RefundId( + refund_reference, + )) + } } } diff --git a/crates/router/src/connector/volt/transformers.rs b/crates/router/src/connector/volt/transformers.rs index 8b9bbecb0889..b1d77f3416ff 100644 --- a/crates/router/src/connector/volt/transformers.rs +++ b/crates/router/src/connector/volt/transformers.rs @@ -46,7 +46,6 @@ pub mod webhook_headers { pub const X_VOLT_SIGNED: &str = "X-Volt-Signed"; pub const X_VOLT_TIMED: &str = "X-Volt-Timed"; pub const USER_AGENT: &str = "User-Agent"; - pub const X_VOLT_TYPE: &str = "X-Volt-Type"; } #[derive(Debug, Serialize)] @@ -488,6 +487,15 @@ pub struct VoltRefundWebhookBodyReference { pub external_reference: Option, } +#[derive(Debug, Deserialize, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum WebhookResponse { + // the enum order shouldn't be changed as this is being used during serialization and deserialization + Refund(VoltRefundWebhookBodyReference), + Payment(VoltPaymentWebhookBodyReference), +} + #[derive(Debug, Deserialize, Serialize)] #[serde(untagged)] pub enum VoltWebhookBodyEventType { From 2f693ad1fd857280ef30c6cc0297fb926f0e79e8 Mon Sep 17 00:00:00 2001 From: Apoorv Dixit <64925866+apoorvdixit88@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:51:47 +0530 Subject: [PATCH 3/3] fix(user): fetch profile_id for sample data (#3358) --- crates/router/src/utils/user/sample_data.rs | 23 ++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs index dcf635595e0f..3fa2a10629e5 100644 --- a/crates/router/src/utils/user/sample_data.rs +++ b/crates/router/src/utils/user/sample_data.rs @@ -52,7 +52,7 @@ pub async fn generate_sample_data( let business_label_default = merchant_parsed_details.first().map(|x| x.business.clone()); - let profile_id = crate::core::utils::get_profile_id_from_business_details( + let profile_id = match crate::core::utils::get_profile_id_from_business_details( business_country_default, business_label_default.as_ref(), &merchant_from_db, @@ -61,8 +61,25 @@ pub async fn generate_sample_data( false, ) .await - .change_context(SampleDataError::InternalServerError) - .attach_printable("Failed to get business profile")?; + { + Ok(id) => id.clone(), + Err(error) => { + router_env::logger::error!( + "Profile ID not found in business details. Attempting to fetch from the database {error:?}" + ); + + state + .store + .list_business_profile_by_merchant_id(&merchant_id) + .await + .change_context(SampleDataError::InternalServerError) + .attach_printable("Failed to get business profile")? + .first() + .ok_or(SampleDataError::InternalServerError)? + .profile_id + .clone() + } + }; // 10 percent payments should be failed #[allow(clippy::as_conversions)]